From 636fa807fa5f9c04aac3490e6709b7c980584d81 Mon Sep 17 00:00:00 2001 From: Brian Ginsburg Date: Wed, 11 Oct 2023 14:56:35 -0700 Subject: [PATCH 1/3] feat: Add mDNS and Rendezvous config settings --- .../src/event_handler/swarm_event.rs | 68 +++++++++++-------- homestar-runtime/src/network/swarm.rs | 44 +++++++----- homestar-runtime/src/settings.rs | 12 +++- .../tests/fixtures/test_mdns_connect1.toml | 1 + .../tests/fixtures/test_mdns_connect2.toml | 1 + .../tests/fixtures/test_network1.toml | 2 + .../tests/fixtures/test_network2.toml | 2 + 7 files changed, 82 insertions(+), 48 deletions(-) diff --git a/homestar-runtime/src/event_handler/swarm_event.rs b/homestar-runtime/src/event_handler/swarm_event.rs index 052812e5..5d39d9ce 100644 --- a/homestar-runtime/src/event_handler/swarm_event.rs +++ b/homestar-runtime/src/event_handler/swarm_event.rs @@ -142,25 +142,32 @@ async fn handle_swarm_event( // rendezvous // we are good to register self & discover with any node we contact. more peers = more better! if info.protocols.contains(&RENDEZVOUS_PROTOCOL_NAME) { - // register self with remote - if let Err(err) = behavior.rendezvous_client.register( - Namespace::from_static(RENDEZVOUS_NAMESPACE), - peer_id, - None, - ) { - warn!( - peer_id = peer_id.to_string(), - err = format!("{err}"), - "failed to register with rendezvous peer" - ) + if let Some(rendezvous_client) = event_handler + .swarm + .behaviour_mut() + .rendezvous_client + .as_mut() + { + // register self with remote + if let Err(err) = rendezvous_client.register( + Namespace::from_static(RENDEZVOUS_NAMESPACE), + peer_id, + None, + ) { + warn!( + peer_id = peer_id.to_string(), + err = format!("{err}"), + "failed to register with rendezvous peer" + ) + } + // discover other nodes + rendezvous_client.discover( + Some(Namespace::from_static(RENDEZVOUS_NAMESPACE)), + None, + None, + peer_id, + ); } - // discover other nodes - behavior.rendezvous_client.discover( - Some(Namespace::from_static(RENDEZVOUS_NAMESPACE)), - None, - None, - peer_id, - ); } } identify::Event::Pushed { peer_id } => debug!( @@ -224,17 +231,20 @@ async fn handle_swarm_event( } rendezvous::client::Event::Expired { peer } => { // re-discover records from peer - let cookie = event_handler.rendezvous_cookies.get(&peer).cloned(); - event_handler + if let Some(rendezvous_client) = event_handler .swarm .behaviour_mut() .rendezvous_client - .discover( + .as_mut() + { + let cookie = event_handler.rendezvous_cookies.get(&peer).cloned(); + rendezvous_client.discover( Some(Namespace::from_static(RENDEZVOUS_NAMESPACE)), cookie, None, peer, ); + } } } } @@ -535,14 +545,14 @@ async fn handle_swarm_event( } } SwarmEvent::Behaviour(ComposedEvent::Mdns(mdns::Event::Expired(list))) => { - for (peer_id, multiaddr) in list { - info!("mDNS discover peer has expired: {peer_id}"); - if event_handler.swarm.behaviour_mut().mdns.has_node(&peer_id) { - event_handler - .swarm - .behaviour_mut() - .kademlia - .remove_address(&peer_id, &multiaddr); + let behaviour = event_handler.swarm.behaviour_mut(); + + if let Some(mdns) = behaviour.mdns.as_ref() { + for (peer_id, multiaddr) in list { + info!("mDNS discover peer has expired: {peer_id}"); + if mdns.has_node(&peer_id) { + behaviour.kademlia.remove_address(&peer_id, &multiaddr); + } } } } diff --git a/homestar-runtime/src/network/swarm.rs b/homestar-runtime/src/network/swarm.rs index 0ec8ed13..11d04950 100644 --- a/homestar-runtime/src/network/swarm.rs +++ b/homestar-runtime/src/network/swarm.rs @@ -22,7 +22,7 @@ use libp2p::{ multiaddr::Protocol, noise, rendezvous, request_response::{self, ProtocolSupport}, - swarm::{NetworkBehaviour, Swarm, SwarmBuilder}, + swarm::{behaviour::toggle::Toggle, NetworkBehaviour, Swarm, SwarmBuilder}, tcp, yamux, StreamProtocol, Transport, }; use serde::{Deserialize, Serialize}; @@ -78,18 +78,30 @@ pub(crate) async fn new(settings: &settings::Node) -> Result>, /// [mdns::tokio::Behaviour] behaviour. - pub(crate) mdns: mdns::tokio::Behaviour, + pub(crate) mdns: Toggle, /// [rendezvous::client::Behaviour] behaviour. - pub(crate) rendezvous_client: rendezvous::client::Behaviour, + pub(crate) rendezvous_client: Toggle, /// [rendezvous::server::Behaviour] behaviour. - pub(crate) rendezvous_server: rendezvous::server::Behaviour, + pub(crate) rendezvous_server: Toggle, /// [identify::Behaviour] behaviour. pub(crate) identify: identify::Behaviour, } diff --git a/homestar-runtime/src/settings.rs b/homestar-runtime/src/settings.rs index ce81b10e..0248d30e 100644 --- a/homestar-runtime/src/settings.rs +++ b/homestar-runtime/src/settings.rs @@ -76,12 +76,16 @@ pub struct Network { /// [Swarm]: libp2p::swarm::Swarm #[serde(with = "http_serde::uri")] pub(crate) listen_address: Uri, - /// Mdns IPv6 enable flag. + /// Enable Rendezvous protocol. + pub(crate) enable_rendezvous: bool, + /// Enable mDNS. + pub(crate) enable_mdns: bool, + /// MDNS IPv6 enable flag pub(crate) mdns_enable_ipv6: bool, - /// Mdns query interval. + /// MDNS query interval. #[serde_as(as = "DurationSeconds")] pub(crate) mdns_query_interval: Duration, - /// Mdns TTL. + /// MDNS TTL. #[serde_as(as = "DurationSeconds")] pub(crate) mdns_ttl: Duration, /// Timeout for p2p requests for a provided record. @@ -181,6 +185,8 @@ impl Default for Network { events_buffer_len: 1024, listen_address: Uri::from_static("/ip4/0.0.0.0/tcp/0"), // TODO: we would like to enable this by default, however this breaks mdns on at least some linux distros. Requires further investigation. + enable_rendezvous: true, + enable_mdns: true, mdns_enable_ipv6: false, mdns_query_interval: Duration::from_secs(5 * 60), mdns_ttl: Duration::from_secs(60 * 9), diff --git a/homestar-runtime/tests/fixtures/test_mdns_connect1.toml b/homestar-runtime/tests/fixtures/test_mdns_connect1.toml index b651ae83..d870de70 100644 --- a/homestar-runtime/tests/fixtures/test_mdns_connect1.toml +++ b/homestar-runtime/tests/fixtures/test_mdns_connect1.toml @@ -9,6 +9,7 @@ console_subscriber_port = 5560 rpc_port = 9800 websocket_port = 8000 listen_address = "/ip4/0.0.0.0/tcp/0" +enable_rendezvous = false [node.network.keypair_config] existing = { key_type = "ed25519", path = "./fixtures/__testkey_ed25519.pem" } diff --git a/homestar-runtime/tests/fixtures/test_mdns_connect2.toml b/homestar-runtime/tests/fixtures/test_mdns_connect2.toml index 3dbdf1a0..fe0fe2b3 100644 --- a/homestar-runtime/tests/fixtures/test_mdns_connect2.toml +++ b/homestar-runtime/tests/fixtures/test_mdns_connect2.toml @@ -9,6 +9,7 @@ console_subscriber_port = 5561 rpc_port = 9801 websocket_port = 8001 listen_address = "/ip4/0.0.0.0/tcp/0" +enable_rendezvous = false [node.network.keypair_config] existing = { key_type = "secp256k1", path = "./fixtures/__testkey_secp256k1.der" } diff --git a/homestar-runtime/tests/fixtures/test_network1.toml b/homestar-runtime/tests/fixtures/test_network1.toml index 82a3acc2..1477ae03 100644 --- a/homestar-runtime/tests/fixtures/test_network1.toml +++ b/homestar-runtime/tests/fixtures/test_network1.toml @@ -12,6 +12,8 @@ listen_address = "/ip4/127.0.0.1/tcp/7000" node_addresses = [ "/ip4/127.0.0.1/tcp/7001/p2p/16Uiu2HAm3g9AomQNeEctL2hPwLapap7AtPSNt8ZrBny4rLx1W5Dc", ] +enable_mdns = false +enable_rendezvous = false [node.network.keypair_config] existing = { key_type = "ed25519", path = "./fixtures/__testkey_ed25519.pem" } diff --git a/homestar-runtime/tests/fixtures/test_network2.toml b/homestar-runtime/tests/fixtures/test_network2.toml index a24aa028..d2aa2675 100644 --- a/homestar-runtime/tests/fixtures/test_network2.toml +++ b/homestar-runtime/tests/fixtures/test_network2.toml @@ -12,6 +12,8 @@ listen_address = "/ip4/127.0.0.1/tcp/7001" node_addresses = [ "/ip4/127.0.0.1/tcp/7000/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN", ] +enable_mdns = false +enable_rendezvous = false [node.network.keypair_config] existing = { key_type = "secp256k1", path = "./fixtures/__testkey_secp256k1.der" } From 12880160cfab093519d968171fef1d25dd22948a Mon Sep 17 00:00:00 2001 From: Brian Ginsburg Date: Thu, 12 Oct 2023 12:42:21 -0700 Subject: [PATCH 2/3] chore: MDNS -> mDNS in comments --- homestar-runtime/src/settings.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homestar-runtime/src/settings.rs b/homestar-runtime/src/settings.rs index 0248d30e..6b939382 100644 --- a/homestar-runtime/src/settings.rs +++ b/homestar-runtime/src/settings.rs @@ -80,12 +80,12 @@ pub struct Network { pub(crate) enable_rendezvous: bool, /// Enable mDNS. pub(crate) enable_mdns: bool, - /// MDNS IPv6 enable flag + /// mDNS IPv6 enable flag pub(crate) mdns_enable_ipv6: bool, - /// MDNS query interval. + /// mDNS query interval. #[serde_as(as = "DurationSeconds")] pub(crate) mdns_query_interval: Duration, - /// MDNS TTL. + /// mDNS TTL. #[serde_as(as = "DurationSeconds")] pub(crate) mdns_ttl: Duration, /// Timeout for p2p requests for a provided record. From b9d0e259592170dab45febb5b2b0a1dc1cc21372 Mon Sep 17 00:00:00 2001 From: Brian Ginsburg Date: Thu, 12 Oct 2023 12:49:31 -0700 Subject: [PATCH 3/3] chore: Move peer ID to label on mDNS peer expired --- homestar-runtime/src/event_handler/swarm_event.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/homestar-runtime/src/event_handler/swarm_event.rs b/homestar-runtime/src/event_handler/swarm_event.rs index 5d39d9ce..0cf2e8b8 100644 --- a/homestar-runtime/src/event_handler/swarm_event.rs +++ b/homestar-runtime/src/event_handler/swarm_event.rs @@ -549,7 +549,10 @@ async fn handle_swarm_event( if let Some(mdns) = behaviour.mdns.as_ref() { for (peer_id, multiaddr) in list { - info!("mDNS discover peer has expired: {peer_id}"); + info!( + peer_id = peer_id.to_string(), + "mDNS discover peer has expired" + ); if mdns.has_node(&peer_id) { behaviour.kademlia.remove_address(&peer_id, &multiaddr); }