Skip to content

Commit 10bcedd

Browse files
start adding configuration to iroh-net
and first failing test
1 parent 100e1a9 commit 10bcedd

File tree

5 files changed

+95
-51
lines changed

5 files changed

+95
-51
lines changed

iroh-net/src/endpoint.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ pub struct Builder {
9999
insecure_skip_relay_cert_verify: bool,
100100
addr_v4: Option<SocketAddrV4>,
101101
addr_v6: Option<SocketAddrV6>,
102+
tls_auth: tls::Authentication,
102103
}
103104

104105
impl Default for Builder {
@@ -117,6 +118,7 @@ impl Default for Builder {
117118
insecure_skip_relay_cert_verify: false,
118119
addr_v4: None,
119120
addr_v6: None,
121+
tls_auth: tls::Authentication::X509,
120122
}
121123
}
122124
}
@@ -132,6 +134,7 @@ impl Builder {
132134
let relay_map = self.relay_mode.relay_map();
133135
let secret_key = self.secret_key.unwrap_or_else(SecretKey::generate);
134136
let static_config = StaticConfig {
137+
tls_auth: self.tls_auth,
135138
transport_config: Arc::new(self.transport_config.unwrap_or_default()),
136139
keylog: self.keylog,
137140
secret_key: secret_key.clone(),
@@ -305,6 +308,18 @@ impl Builder {
305308
self
306309
}
307310

311+
/// Use libp2p based self signed certificates for TLS.
312+
pub fn tls_x509(mut self) -> Self {
313+
self.tls_auth = tls::Authentication::X509;
314+
self
315+
}
316+
317+
/// Use TLS Raw Public Keys
318+
pub fn tls_raw_public_keys(mut self) -> Self {
319+
self.tls_auth = tls::Authentication::RawPublicKey;
320+
self
321+
}
322+
308323
#[cfg(feature = "discovery-pkarr-dht")]
309324
/// Configures the endpoint to also use the mainline DHT with default settings.
310325
///
@@ -419,6 +434,7 @@ impl Builder {
419434
/// Configuration for a [`quinn::Endpoint`] that cannot be changed at runtime.
420435
#[derive(Debug)]
421436
struct StaticConfig {
437+
tls_auth: tls::Authentication,
422438
secret_key: SecretKey,
423439
transport_config: Arc<quinn::TransportConfig>,
424440
keylog: bool,
@@ -428,6 +444,7 @@ impl StaticConfig {
428444
/// Create a [`quinn::ServerConfig`] with the specified ALPN protocols.
429445
fn create_server_config(&self, alpn_protocols: Vec<Vec<u8>>) -> Result<ServerConfig> {
430446
let server_config = make_server_config(
447+
self.tls_auth,
431448
&self.secret_key,
432449
alpn_protocols,
433450
self.transport_config.clone(),
@@ -442,13 +459,13 @@ impl StaticConfig {
442459
// used by iroh::node::Node (or rather iroh::node::Builder) to create a plain Quinn
443460
// endpoint.
444461
pub fn make_server_config(
462+
tls_auth: tls::Authentication,
445463
secret_key: &SecretKey,
446464
alpn_protocols: Vec<Vec<u8>>,
447465
transport_config: Arc<TransportConfig>,
448466
keylog: bool,
449467
) -> Result<ServerConfig> {
450-
let quic_server_config =
451-
tls::Authentication::X509.make_server_config(secret_key, alpn_protocols, keylog)?;
468+
let quic_server_config = tls_auth.make_server_config(secret_key, alpn_protocols, keylog)?;
452469
let mut server_config = ServerConfig::with_crypto(Arc::new(quic_server_config));
453470
server_config.transport_config(transport_config);
454471

iroh-net/src/magicsock.rs

Lines changed: 57 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3207,15 +3207,26 @@ mod tests {
32073207
}
32083208

32093209
#[tokio::test]
3210-
async fn test_two_devices_roundtrip_quinn_raw() -> Result<()> {
3210+
async fn test_two_devices_roundtrip_quinn_raw_x509() -> Result<()> {
3211+
test_two_devices_roundtrip_quinn_raw(tls::Authentication::X509).await
3212+
}
3213+
3214+
#[tokio::test]
3215+
async fn test_two_devices_roundtrip_quinn_raw_public_key() -> Result<()> {
3216+
test_two_devices_roundtrip_quinn_raw(tls::Authentication::RawPublicKey).await
3217+
}
3218+
3219+
async fn test_two_devices_roundtrip_quinn_raw(tls_auth: tls::Authentication) -> Result<()> {
32113220
let _guard = iroh_test::logging::setup();
32123221

3213-
let make_conn = |addr: SocketAddr| -> anyhow::Result<quinn::Endpoint> {
3222+
let make_conn = |addr: SocketAddr,
3223+
tls_auth: tls::Authentication|
3224+
-> anyhow::Result<quinn::Endpoint> {
32143225
let key = SecretKey::generate();
32153226
let conn = std::net::UdpSocket::bind(addr)?;
32163227

32173228
let quic_server_config =
3218-
tls::Authentication::X509.make_server_config(&key, vec![ALPN.to_vec()], false)?;
3229+
tls_auth.make_server_config(&key, vec![ALPN.to_vec()], false)?;
32193230
let mut server_config = quinn::ServerConfig::with_crypto(Arc::new(quic_server_config));
32203231
let mut transport_config = quinn::TransportConfig::default();
32213232
transport_config.keep_alive_interval(Some(Duration::from_secs(5)));
@@ -3228,12 +3239,8 @@ mod tests {
32283239
Arc::new(quinn::TokioRuntime),
32293240
)?;
32303241

3231-
let quic_client_config = tls::Authentication::X509.make_client_config(
3232-
&key,
3233-
None,
3234-
vec![ALPN.to_vec()],
3235-
false,
3236-
)?;
3242+
let quic_client_config =
3243+
tls_auth.make_client_config(&key, None, vec![ALPN.to_vec()], false)?;
32373244
let mut client_config = quinn::ClientConfig::new(Arc::new(quic_client_config));
32383245
let mut transport_config = quinn::TransportConfig::default();
32393246
transport_config.max_idle_timeout(Some(Duration::from_secs(10).try_into().unwrap()));
@@ -3243,8 +3250,8 @@ mod tests {
32433250
Ok(quic_ep)
32443251
};
32453252

3246-
let m1 = make_conn("127.0.0.1:0".parse().unwrap())?;
3247-
let m2 = make_conn("127.0.0.1:0".parse().unwrap())?;
3253+
let m1 = make_conn("127.0.0.1:0".parse().unwrap(), tls_auth)?;
3254+
let m2 = make_conn("127.0.0.1:0".parse().unwrap(), tls_auth)?;
32483255

32493256
// msg from a -> b
32503257
macro_rules! roundtrip {
@@ -3362,14 +3369,18 @@ mod tests {
33623369

33633370
#[tokio::test]
33643371
async fn test_two_devices_roundtrip_quinn_rebinding_conn() -> Result<()> {
3372+
let tls_auth = tls::Authentication::X509;
33653373
let _guard = iroh_test::logging::setup();
33663374

3367-
fn make_conn(addr: SocketAddr) -> anyhow::Result<quinn::Endpoint> {
3375+
fn make_conn(
3376+
addr: SocketAddr,
3377+
tls_auth: tls::Authentication,
3378+
) -> anyhow::Result<quinn::Endpoint> {
33683379
let key = SecretKey::generate();
33693380
let conn = UdpConn::bind(addr)?;
33703381

33713382
let quic_server_config =
3372-
tls::Authentication::X509.make_server_config(&key, vec![ALPN.to_vec()], false)?;
3383+
tls_auth.make_server_config(&key, vec![ALPN.to_vec()], false)?;
33733384
let mut server_config = quinn::ServerConfig::with_crypto(Arc::new(quic_server_config));
33743385
let mut transport_config = quinn::TransportConfig::default();
33753386
transport_config.keep_alive_interval(Some(Duration::from_secs(5)));
@@ -3382,12 +3393,8 @@ mod tests {
33823393
Arc::new(quinn::TokioRuntime),
33833394
)?;
33843395

3385-
let quic_client_config = tls::Authentication::X509.make_client_config(
3386-
&key,
3387-
None,
3388-
vec![ALPN.to_vec()],
3389-
false,
3390-
)?;
3396+
let quic_client_config =
3397+
tls_auth.make_client_config(&key, None, vec![ALPN.to_vec()], false)?;
33913398
let mut client_config = quinn::ClientConfig::new(Arc::new(quic_client_config));
33923399
let mut transport_config = quinn::TransportConfig::default();
33933400
transport_config.max_idle_timeout(Some(Duration::from_secs(10).try_into().unwrap()));
@@ -3397,8 +3404,8 @@ mod tests {
33973404
Ok(quic_ep)
33983405
}
33993406

3400-
let m1 = make_conn("127.0.0.1:7770".parse().unwrap())?;
3401-
let m2 = make_conn("127.0.0.1:7771".parse().unwrap())?;
3407+
let m1 = make_conn("127.0.0.1:7770".parse().unwrap(), tls_auth)?;
3408+
let m2 = make_conn("127.0.0.1:7771".parse().unwrap(), tls_auth)?;
34023409

34033410
// msg from a -> b
34043411
macro_rules! roundtrip {
@@ -3611,7 +3618,10 @@ mod tests {
36113618
///
36123619
/// Use [`magicsock_connect`] to establish connections.
36133620
#[instrument(name = "ep", skip_all, fields(me = secret_key.public().fmt_short()))]
3614-
async fn magicsock_ep(secret_key: SecretKey) -> anyhow::Result<(quinn::Endpoint, Handle)> {
3621+
async fn magicsock_ep(
3622+
secret_key: SecretKey,
3623+
tls_auth: tls::Authentication,
3624+
) -> anyhow::Result<(quinn::Endpoint, Handle)> {
36153625
let opts = Options {
36163626
addr_v4: None,
36173627
addr_v6: None,
@@ -3625,6 +3635,7 @@ mod tests {
36253635
};
36263636
let msock = MagicSock::spawn(opts).await?;
36273637
let server_config = crate::endpoint::make_server_config(
3638+
tls_auth,
36283639
&secret_key,
36293640
vec![ALPN.to_vec()],
36303641
Arc::new(quinn::TransportConfig::default()),
@@ -3650,17 +3661,19 @@ mod tests {
36503661
ep_secret_key: SecretKey,
36513662
addr: QuicMappedAddr,
36523663
node_id: NodeId,
3664+
tls_auth: tls::Authentication,
36533665
) -> Result<quinn::Connection> {
36543666
// Endpoint::connect sets this, do the same to have similar behaviour.
36553667
let mut transport_config = quinn::TransportConfig::default();
36563668
transport_config.keep_alive_interval(Some(Duration::from_secs(1)));
36573669

3658-
magicsock_connet_with_transport_config(
3670+
magicsock_connect_with_transport_config(
36593671
ep,
36603672
ep_secret_key,
36613673
addr,
36623674
node_id,
36633675
Arc::new(transport_config),
3676+
tls_auth,
36643677
)
36653678
.await
36663679
}
@@ -3671,20 +3684,17 @@ mod tests {
36713684
///
36723685
/// Uses [`ALPN`], `node_id`, must match `addr`.
36733686
#[instrument(name = "connect", skip_all, fields(me = ep_secret_key.public().fmt_short()))]
3674-
async fn magicsock_connet_with_transport_config(
3687+
async fn magicsock_connect_with_transport_config(
36753688
ep: &quinn::Endpoint,
36763689
ep_secret_key: SecretKey,
36773690
addr: QuicMappedAddr,
36783691
node_id: NodeId,
36793692
transport_config: Arc<quinn::TransportConfig>,
3693+
tls_auth: tls::Authentication,
36803694
) -> Result<quinn::Connection> {
36813695
let alpns = vec![ALPN.to_vec()];
3682-
let quic_client_config = tls::Authentication::X509.make_client_config(
3683-
&ep_secret_key,
3684-
Some(node_id),
3685-
alpns,
3686-
true,
3687-
)?;
3696+
let quic_client_config =
3697+
tls_auth.make_client_config(&ep_secret_key, Some(node_id), alpns, true)?;
36883698
let mut client_config = quinn::ClientConfig::new(Arc::new(quic_client_config));
36893699
client_config.transport_config(transport_config);
36903700
let connect = ep.connect_with(client_config, addr.0, "localhost")?;
@@ -3697,14 +3707,15 @@ mod tests {
36973707
// Regression test: if there is no send_addr we should keep being able to use the
36983708
// Endpoint.
36993709
let _guard = iroh_test::logging::setup();
3710+
let tls_auth = tls::Authentication::X509;
37003711

37013712
let secret_key_1 = SecretKey::from_bytes(&[1u8; 32]);
37023713
let secret_key_2 = SecretKey::from_bytes(&[2u8; 32]);
37033714
let node_id_2 = secret_key_2.public();
37043715
let secret_key_missing_node = SecretKey::from_bytes(&[255u8; 32]);
37053716
let node_id_missing_node = secret_key_missing_node.public();
37063717

3707-
let (ep_1, msock_1) = magicsock_ep(secret_key_1.clone()).await.unwrap();
3718+
let (ep_1, msock_1) = magicsock_ep(secret_key_1.clone(), tls_auth).await.unwrap();
37083719

37093720
// Generate an address not present in the NodeMap.
37103721
let bad_addr = QuicMappedAddr::generate();
@@ -3715,13 +3726,19 @@ mod tests {
37153726
// this speeds up the test.
37163727
let res = tokio::time::timeout(
37173728
Duration::from_millis(500),
3718-
magicsock_connect(&ep_1, secret_key_1.clone(), bad_addr, node_id_missing_node),
3729+
magicsock_connect(
3730+
&ep_1,
3731+
secret_key_1.clone(),
3732+
bad_addr,
3733+
node_id_missing_node,
3734+
tls_auth,
3735+
),
37193736
)
37203737
.await;
37213738
assert!(res.is_err(), "expecting timeout");
37223739

37233740
// Now check we can still create another connection with this endpoint.
3724-
let (ep_2, msock_2) = magicsock_ep(secret_key_2.clone()).await.unwrap();
3741+
let (ep_2, msock_2) = magicsock_ep(secret_key_2.clone(), tls_auth).await.unwrap();
37253742

37263743
// This needs an accept task
37273744
let accept_task = tokio::spawn({
@@ -3769,7 +3786,7 @@ mod tests {
37693786
let addr = msock_1.get_mapping_addr(node_id_2).unwrap();
37703787
let res = tokio::time::timeout(
37713788
Duration::from_secs(10),
3772-
magicsock_connect(&ep_1, secret_key_1.clone(), addr, node_id_2),
3789+
magicsock_connect(&ep_1, secret_key_1.clone(), addr, node_id_2, tls_auth),
37733790
)
37743791
.await
37753792
.expect("timeout while connecting");
@@ -3786,13 +3803,14 @@ mod tests {
37863803
// This specifically tests the `if udp_addr.is_none() && relay_url.is_none()`
37873804
// behaviour of MagicSock::try_send.
37883805
let _logging_guard = iroh_test::logging::setup();
3806+
let tls_auth = tls::Authentication::X509;
37893807

37903808
let secret_key_1 = SecretKey::from_bytes(&[1u8; 32]);
37913809
let secret_key_2 = SecretKey::from_bytes(&[2u8; 32]);
37923810
let node_id_2 = secret_key_2.public();
37933811

3794-
let (ep_1, msock_1) = magicsock_ep(secret_key_1.clone()).await.unwrap();
3795-
let (ep_2, msock_2) = magicsock_ep(secret_key_2.clone()).await.unwrap();
3812+
let (ep_1, msock_1) = magicsock_ep(secret_key_1.clone(), tls_auth).await.unwrap();
3813+
let (ep_2, msock_2) = magicsock_ep(secret_key_2.clone(), tls_auth).await.unwrap();
37963814

37973815
// We need a task to accept the connection.
37983816
let accept_task = tokio::spawn({
@@ -3838,12 +3856,13 @@ mod tests {
38383856
// little slower though.
38393857
let mut transport_config = quinn::TransportConfig::default();
38403858
transport_config.max_idle_timeout(Some(Duration::from_millis(200).try_into().unwrap()));
3841-
let res = magicsock_connet_with_transport_config(
3859+
let res = magicsock_connect_with_transport_config(
38423860
&ep_1,
38433861
secret_key_1.clone(),
38443862
addr_2,
38453863
node_id_2,
38463864
Arc::new(transport_config),
3865+
tls_auth,
38473866
)
38483867
.await;
38493868
assert!(res.is_err(), "expected timeout");
@@ -3873,7 +3892,7 @@ mod tests {
38733892
// We can now connect
38743893
tokio::time::timeout(Duration::from_secs(10), async move {
38753894
info!("establishing new connection");
3876-
let conn = magicsock_connect(&ep_1, secret_key_1.clone(), addr_2, node_id_2)
3895+
let conn = magicsock_connect(&ep_1, secret_key_1.clone(), addr_2, node_id_2, tls_auth)
38773896
.await
38783897
.unwrap();
38793898
info!("have connection");

iroh/src/client/quic.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,19 @@ impl Iroh {
3131

3232
/// Connects to an iroh node at the given RPC address.
3333
pub async fn connect_addr(addr: SocketAddr) -> anyhow::Result<Self> {
34-
let client = connect_raw(addr).await?;
34+
let client = connect_raw(addr, iroh_net::tls::Authentication::X509).await?;
3535
Ok(Iroh::new(client))
3636
}
3737
}
3838

3939
/// Create a raw RPC client to an iroh node running on the same computer, but in a different
4040
/// process.
41-
pub(crate) async fn connect_raw(addr: SocketAddr) -> anyhow::Result<RpcClient> {
41+
pub(crate) async fn connect_raw(
42+
addr: SocketAddr,
43+
tls_auth: iroh_net::tls::Authentication,
44+
) -> anyhow::Result<RpcClient> {
4245
let bind_addr = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0).into();
43-
let endpoint = create_quinn_client(bind_addr, vec![RPC_ALPN.to_vec()], false)?;
46+
let endpoint = create_quinn_client(tls_auth, bind_addr, vec![RPC_ALPN.to_vec()], false)?;
4447

4548
let server_name = "localhost".to_string();
4649
let connection = QuinnConnector::new(endpoint, addr, server_name);
@@ -54,17 +57,14 @@ pub(crate) async fn connect_raw(addr: SocketAddr) -> anyhow::Result<RpcClient> {
5457
}
5558

5659
fn create_quinn_client(
60+
tls_auth: iroh_net::tls::Authentication,
5761
bind_addr: SocketAddr,
5862
alpn_protocols: Vec<Vec<u8>>,
5963
keylog: bool,
6064
) -> anyhow::Result<quinn::Endpoint> {
6165
let secret_key = iroh_net::key::SecretKey::generate();
62-
let tls_client_config = iroh_net::tls::Authentication::X509.make_client_config(
63-
&secret_key,
64-
None,
65-
alpn_protocols,
66-
keylog,
67-
)?;
66+
let tls_client_config =
67+
tls_auth.make_client_config(&secret_key, None, alpn_protocols, keylog)?;
6868
let mut client_config = quinn::ClientConfig::new(Arc::new(tls_client_config));
6969
let mut endpoint = quinn::Endpoint::client(bind_addr)?;
7070
let mut transport_config = quinn::TransportConfig::default();

0 commit comments

Comments
 (0)