From 588bd20bce9f7ee01c6d8ad6379c21e0c35da741 Mon Sep 17 00:00:00 2001 From: Benno Zeeman Date: Tue, 16 Apr 2024 13:44:03 +0200 Subject: [PATCH 1/6] feat(networking): add UPnP behavior to open port --- sn_networking/src/driver.rs | 9 +++++++++ sn_networking/src/event/mod.rs | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/sn_networking/src/driver.rs b/sn_networking/src/driver.rs index c104ec14cb..5de26fada3 100644 --- a/sn_networking/src/driver.rs +++ b/sn_networking/src/driver.rs @@ -182,6 +182,7 @@ pub enum VerificationKind { #[derive(NetworkBehaviour)] #[behaviour(to_swarm = "NodeEvent")] pub(super) struct NodeBehaviour { + pub(super) upnp: libp2p::swarm::behaviour::toggle::Toggle, pub(super) request_response: request_response::cbor::Behaviour, pub(super) kademlia: kad::Behaviour, #[cfg(feature = "local-discovery")] @@ -485,6 +486,13 @@ impl NetworkBuilder { main_transport }; + let upnp = if !self.local && !is_client { + Some(libp2p::upnp::tokio::Behaviour::default()) + } else { + None + }; + let upnp = upnp.into(); // Into `Toggle` + let (relay_transport, relay_behaviour) = libp2p::relay::client::new(self.keypair.public().to_peer_id()); let relay_transport = relay_transport @@ -516,6 +524,7 @@ impl NetworkBuilder { let behaviour = NodeBehaviour { relay_client: relay_behaviour, relay_server, + upnp, request_response, kademlia, identify, diff --git a/sn_networking/src/event/mod.rs b/sn_networking/src/event/mod.rs index e4112d1549..0dbb958d73 100644 --- a/sn_networking/src/event/mod.rs +++ b/sn_networking/src/event/mod.rs @@ -35,6 +35,7 @@ use tokio::sync::oneshot; /// NodeEvent enum #[derive(CustomDebug)] pub(super) enum NodeEvent { + Upnp(libp2p::upnp::Event), MsgReceived(libp2p::request_response::Event), Kademlia(libp2p::kad::Event), #[cfg(feature = "local-discovery")] @@ -45,6 +46,12 @@ pub(super) enum NodeEvent { RelayServer(Box), } +impl From for NodeEvent { + fn from(event: libp2p::upnp::Event) -> Self { + NodeEvent::Upnp(event) + } +} + impl From> for NodeEvent { fn from(event: libp2p::request_response::Event) -> Self { NodeEvent::MsgReceived(event) From cc6a8d083d8e641ea2acbdcef2d89b3529f85166 Mon Sep 17 00:00:00 2001 From: Benno Zeeman Date: Mon, 22 Apr 2024 16:52:23 +0200 Subject: [PATCH 2/6] feat(networking): feature gate 'upnp' --- sn_networking/Cargo.toml | 3 ++- sn_networking/src/driver.rs | 6 ++++-- sn_networking/src/event/mod.rs | 2 ++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/sn_networking/Cargo.toml b/sn_networking/Cargo.toml index fc0fb04c98..f01903275d 100644 --- a/sn_networking/Cargo.toml +++ b/sn_networking/Cargo.toml @@ -11,8 +11,9 @@ repository = "https://github.com/maidsafe/safe_network" version = "0.14.4" [features] -default = ["libp2p/quic"] +default = ["libp2p/quic", "upnp"] local-discovery = ["libp2p/mdns"] +upnp = ["libp2p/upnp"] # tcp is automatically enabled when compiling for wasm32 websockets = ["libp2p/tcp"] open-metrics = ["libp2p/metrics", "prometheus-client", "hyper", "sysinfo"] diff --git a/sn_networking/src/driver.rs b/sn_networking/src/driver.rs index 5de26fada3..d274d499f9 100644 --- a/sn_networking/src/driver.rs +++ b/sn_networking/src/driver.rs @@ -182,6 +182,7 @@ pub enum VerificationKind { #[derive(NetworkBehaviour)] #[behaviour(to_swarm = "NodeEvent")] pub(super) struct NodeBehaviour { + #[cfg(feature = "upnp")] pub(super) upnp: libp2p::swarm::behaviour::toggle::Toggle, pub(super) request_response: request_response::cbor::Behaviour, pub(super) kademlia: kad::Behaviour, @@ -486,12 +487,12 @@ impl NetworkBuilder { main_transport }; + #[cfg(feature = "upnp")] let upnp = if !self.local && !is_client { Some(libp2p::upnp::tokio::Behaviour::default()) } else { None - }; - let upnp = upnp.into(); // Into `Toggle` + }.into(); // Into `Toggle` let (relay_transport, relay_behaviour) = libp2p::relay::client::new(self.keypair.public().to_peer_id()); @@ -524,6 +525,7 @@ impl NetworkBuilder { let behaviour = NodeBehaviour { relay_client: relay_behaviour, relay_server, + #[cfg(feature = "upnp")] upnp, request_response, kademlia, diff --git a/sn_networking/src/event/mod.rs b/sn_networking/src/event/mod.rs index 0dbb958d73..4e1552edfd 100644 --- a/sn_networking/src/event/mod.rs +++ b/sn_networking/src/event/mod.rs @@ -35,6 +35,7 @@ use tokio::sync::oneshot; /// NodeEvent enum #[derive(CustomDebug)] pub(super) enum NodeEvent { + #[cfg(feature = "upnp")] Upnp(libp2p::upnp::Event), MsgReceived(libp2p::request_response::Event), Kademlia(libp2p::kad::Event), @@ -46,6 +47,7 @@ pub(super) enum NodeEvent { RelayServer(Box), } +#[cfg(feature = "upnp")] impl From for NodeEvent { fn from(event: libp2p::upnp::Event) -> Self { NodeEvent::Upnp(event) From a6be5c88094bfb6d618ac9f8fff75cb9e2be146b Mon Sep 17 00:00:00 2001 From: Benno Zeeman Date: Mon, 22 Apr 2024 17:08:46 +0200 Subject: [PATCH 3/6] feat(network): add --upnp flag to node --- sn_networking/Cargo.toml | 2 +- sn_networking/src/driver.rs | 18 +++++++++++++++++- sn_node/Cargo.toml | 4 +++- sn_node/src/bin/safenode/main.rs | 7 +++++++ sn_node/src/node.rs | 9 +++++++++ 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/sn_networking/Cargo.toml b/sn_networking/Cargo.toml index f01903275d..f826e14bbe 100644 --- a/sn_networking/Cargo.toml +++ b/sn_networking/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/maidsafe/safe_network" version = "0.14.4" [features] -default = ["libp2p/quic", "upnp"] +default = ["libp2p/quic"] local-discovery = ["libp2p/mdns"] upnp = ["libp2p/upnp"] # tcp is automatically enabled when compiling for wasm32 diff --git a/sn_networking/src/driver.rs b/sn_networking/src/driver.rs index d274d499f9..8d607525a1 100644 --- a/sn_networking/src/driver.rs +++ b/sn_networking/src/driver.rs @@ -208,6 +208,7 @@ pub struct NetworkBuilder { metrics_registry: Option, #[cfg(feature = "open-metrics")] metrics_server_port: u16, + upnp: bool, } impl NetworkBuilder { @@ -225,6 +226,8 @@ impl NetworkBuilder { metrics_registry: None, #[cfg(feature = "open-metrics")] metrics_server_port: 0, + #[cfg(feature = "upnp")] + upnp: false, } } @@ -258,6 +261,11 @@ impl NetworkBuilder { self.metrics_server_port = port; } + #[cfg(feature = "upnp")] + pub fn upnp(&mut self, upnp: bool) { + self.upnp = upnp; + } + /// Creates a new `SwarmDriver` instance, along with a `Network` handle /// for sending commands and an `mpsc::Receiver` for receiving /// network events. It initializes the swarm, sets up the transport, and @@ -317,6 +325,7 @@ impl NetworkBuilder { }; let listen_addr = self.listen_addr; + let upnp = self.upnp; let (network, events_receiver, mut swarm_driver) = self.build( kad_cfg, @@ -324,6 +333,8 @@ impl NetworkBuilder { false, ProtocolSupport::Full, IDENTIFY_NODE_VERSION_STR.to_string(), + #[cfg(feature = "upnp")] + upnp, )?; // Listen on the provided address @@ -375,6 +386,8 @@ impl NetworkBuilder { true, ProtocolSupport::Outbound, IDENTIFY_CLIENT_VERSION_STR.to_string(), + #[cfg(feature = "upnp")] + false )?; Ok((network, net_event_recv, driver)) @@ -388,6 +401,8 @@ impl NetworkBuilder { is_client: bool, req_res_protocol: ProtocolSupport, identify_version: String, + #[cfg(feature = "upnp")] + upnp: bool, ) -> Result<(Network, mpsc::Receiver, SwarmDriver)> { let peer_id = PeerId::from(self.keypair.public()); // vdash metric (if modified please notify at https://github.com/happybeing/vdash/issues): @@ -488,7 +503,8 @@ impl NetworkBuilder { }; #[cfg(feature = "upnp")] - let upnp = if !self.local && !is_client { + let upnp = if !self.local && !is_client && upnp { + debug!("Enabling UPnP port opening behavior"); Some(libp2p::upnp::tokio::Behaviour::default()) } else { None diff --git a/sn_node/Cargo.toml b/sn_node/Cargo.toml index 36ac08adef..73b5f3c439 100644 --- a/sn_node/Cargo.toml +++ b/sn_node/Cargo.toml @@ -14,13 +14,15 @@ name = "safenode" path = "src/bin/safenode/main.rs" [features] -default = ["metrics"] +default = ["metrics", "upnp"] local-discovery = ["sn_networking/local-discovery"] otlp = ["sn_logging/otlp"] metrics = ["sn_logging/process-metrics"] network-contacts = ["sn_peers_acquisition/network-contacts"] open-metrics = ["sn_networking/open-metrics", "prometheus-client"] encrypt-records = ["sn_networking/encrypt-records"] +upnp = ["sn_networking/upnp"] + [dependencies] assert_fs = "1.0.0" diff --git a/sn_node/src/bin/safenode/main.rs b/sn_node/src/bin/safenode/main.rs index e4d23116e2..85fd8817b1 100644 --- a/sn_node/src/bin/safenode/main.rs +++ b/sn_node/src/bin/safenode/main.rs @@ -74,6 +74,11 @@ struct Opt { #[clap(long, default_value_t = false)] home_network: bool, + /// Try to use UPnP to open a port in the home router and allow incoming connections. + #[cfg(feature = "upnp")] + #[clap(long, default_value_t = false)] + upnp: bool, + /// Specify the logging output destination. /// /// Valid values are "stdout", "data-dir", or a custom path. @@ -200,6 +205,8 @@ fn main() -> Result<()> { opt.local, root_dir, opt.owner.clone(), + #[cfg(feature = "upnp")] + opt.upnp, ); node_builder.is_behind_home_network = opt.home_network; #[cfg(feature = "open-metrics")] diff --git a/sn_node/src/node.rs b/sn_node/src/node.rs index 559e41d081..1384ee065d 100644 --- a/sn_node/src/node.rs +++ b/sn_node/src/node.rs @@ -68,6 +68,8 @@ pub struct NodeBuilder { /// Enable hole punching for nodes connecting from home networks. pub is_behind_home_network: bool, owner: String, + #[cfg(feature = "upnp")] + upnp: bool, } impl NodeBuilder { @@ -79,6 +81,8 @@ impl NodeBuilder { local: bool, root_dir: PathBuf, owner: String, + #[cfg(feature = "upnp")] + upnp: bool, ) -> Self { Self { keypair, @@ -90,6 +94,8 @@ impl NodeBuilder { metrics_server_port: 0, is_behind_home_network: false, owner, + #[cfg(feature = "upnp")] + upnp, } } @@ -143,6 +149,9 @@ impl NodeBuilder { network_builder.initial_peers(self.initial_peers.clone()); network_builder.is_behind_home_network(self.is_behind_home_network); + #[cfg(feature = "upnp")] + network_builder.upnp(self.upnp); + let (network, network_event_receiver, swarm_driver) = network_builder.build_node()?; let node_events_channel = NodeEventsChannel::default(); let (node_cmds, _) = broadcast::channel(10); From 71cca561ca9ed35ac1cb7981191b59dd166c51f0 Mon Sep 17 00:00:00 2001 From: Benno Zeeman Date: Wed, 24 Apr 2024 08:39:02 +0200 Subject: [PATCH 4/6] fix(networking): allow wasm32 compilation --- sn_networking/src/driver.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sn_networking/src/driver.rs b/sn_networking/src/driver.rs index 8d607525a1..1180a80682 100644 --- a/sn_networking/src/driver.rs +++ b/sn_networking/src/driver.rs @@ -208,6 +208,7 @@ pub struct NetworkBuilder { metrics_registry: Option, #[cfg(feature = "open-metrics")] metrics_server_port: u16, + #[cfg(feature = "upnp")] upnp: bool, } @@ -325,6 +326,7 @@ impl NetworkBuilder { }; let listen_addr = self.listen_addr; + #[cfg(feature = "upnp")] let upnp = self.upnp; let (network, events_receiver, mut swarm_driver) = self.build( From 7ef96405b5af4723d2410e2e6e9d749fa5ff9e2b Mon Sep 17 00:00:00 2001 From: Benno Zeeman Date: Wed, 24 Apr 2024 14:53:03 +0200 Subject: [PATCH 5/6] style: cargo fmt --- sn_networking/src/driver.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sn_networking/src/driver.rs b/sn_networking/src/driver.rs index 1180a80682..517639d9ad 100644 --- a/sn_networking/src/driver.rs +++ b/sn_networking/src/driver.rs @@ -389,7 +389,7 @@ impl NetworkBuilder { ProtocolSupport::Outbound, IDENTIFY_CLIENT_VERSION_STR.to_string(), #[cfg(feature = "upnp")] - false + false, )?; Ok((network, net_event_recv, driver)) @@ -403,8 +403,7 @@ impl NetworkBuilder { is_client: bool, req_res_protocol: ProtocolSupport, identify_version: String, - #[cfg(feature = "upnp")] - upnp: bool, + #[cfg(feature = "upnp")] upnp: bool, ) -> Result<(Network, mpsc::Receiver, SwarmDriver)> { let peer_id = PeerId::from(self.keypair.public()); // vdash metric (if modified please notify at https://github.com/happybeing/vdash/issues): @@ -510,7 +509,8 @@ impl NetworkBuilder { Some(libp2p::upnp::tokio::Behaviour::default()) } else { None - }.into(); // Into `Toggle` + } + .into(); // Into `Toggle` let (relay_transport, relay_behaviour) = libp2p::relay::client::new(self.keypair.public().to_peer_id()); From f652e982a1f8430032b78aecd5f5bb3d9dce14bf Mon Sep 17 00:00:00 2001 From: Benno Zeeman Date: Mon, 6 May 2024 09:13:47 +0200 Subject: [PATCH 6/6] style: cargo fmt --- sn_node/src/node.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sn_node/src/node.rs b/sn_node/src/node.rs index 1384ee065d..cc93f9f564 100644 --- a/sn_node/src/node.rs +++ b/sn_node/src/node.rs @@ -81,8 +81,7 @@ impl NodeBuilder { local: bool, root_dir: PathBuf, owner: String, - #[cfg(feature = "upnp")] - upnp: bool, + #[cfg(feature = "upnp")] upnp: bool, ) -> Self { Self { keypair,