diff --git a/substrate/core/cli/src/lib.rs b/substrate/core/cli/src/lib.rs index 8fa133ea79..d2c3cccebe 100644 --- a/substrate/core/cli/src/lib.rs +++ b/substrate/core/cli/src/lib.rs @@ -359,6 +359,8 @@ fn fill_network_configuration( config.in_peers = cli.in_peers; config.out_peers = cli.out_peers; + config.enable_mdns = !cli.no_mdns; + Ok(()) } diff --git a/substrate/core/cli/src/params.rs b/substrate/core/cli/src/params.rs index 4c2fb53502..321cf17efb 100644 --- a/substrate/core/cli/src/params.rs +++ b/substrate/core/cli/src/params.rs @@ -118,6 +118,11 @@ pub struct NetworkConfigurationParams { #[structopt(long = "in-peers", value_name = "IN_PEERS", default_value = "25")] pub in_peers: u32, + /// By default, the network will use mDNS to discover other nodes on the local network. This + /// disables it. + #[structopt(long = "no-mdns")] + pub no_mdns: bool, + #[allow(missing_docs)] #[structopt(flatten)] pub node_key_params: NodeKeyParams diff --git a/substrate/core/network-libp2p/src/behaviour.rs b/substrate/core/network-libp2p/src/behaviour.rs index 25c5592e09..f93665ce76 100644 --- a/substrate/core/network-libp2p/src/behaviour.rs +++ b/substrate/core/network-libp2p/src/behaviour.rs @@ -20,8 +20,10 @@ use libp2p::NetworkBehaviour; use libp2p::core::{Multiaddr, PeerId, ProtocolsHandler, PublicKey}; use libp2p::core::swarm::{ConnectedPoint, NetworkBehaviour, NetworkBehaviourAction}; use libp2p::core::swarm::{NetworkBehaviourEventProcess, PollParameters}; +use libp2p::core::swarm::toggle::Toggle; use libp2p::identify::{Identify, IdentifyEvent, protocol::IdentifyInfo}; use libp2p::kad::{Kademlia, KademliaOut}; +use libp2p::mdns::{Mdns, MdnsEvent}; use libp2p::ping::{Ping, PingEvent}; use log::{debug, trace, warn}; use std::{cmp, io, fmt, time::Duration, time::Instant}; @@ -41,6 +43,8 @@ pub struct Behaviour { discovery: DiscoveryBehaviour, /// Periodically identifies the remote and responds to incoming requests. identify: Identify, + /// Discovers nodes on the local network. + mdns: Toggle>, /// Queue of events to produce for the outside. #[behaviour(ignore)] @@ -55,6 +59,7 @@ impl Behaviour { protocol: RegisteredProtocol, known_addresses: Vec<(PeerId, Multiaddr)>, peerset: substrate_peerset::PeersetMut, + enable_mdns: bool, ) -> Self { let identify = { let proto_version = "/substrate/1.0".to_string(); @@ -78,6 +83,17 @@ impl Behaviour { duration_to_next_kad: Duration::from_secs(1), }, identify, + mdns: if enable_mdns { + match Mdns::new() { + Ok(mdns) => Some(mdns).into(), + Err(err) => { + warn!(target: "sub-libp2p", "Failed to initialize mDNS: {:?}", err); + None.into() + } + } + } else { + None.into() + }, events: Vec::new(), } } @@ -283,6 +299,19 @@ impl NetworkBehaviourEventProcess for Behaviour } } +impl NetworkBehaviourEventProcess for Behaviour { + fn inject_event(&mut self, event: MdnsEvent) { + match event { + MdnsEvent::Discovered(list) => { + for (peer_id, _) in list { + self.custom_protocols.add_discovered_node(&peer_id); + } + }, + MdnsEvent::Expired(_) => {} + } + } +} + impl Behaviour { fn poll(&mut self) -> Async>> { if !self.events.is_empty() { diff --git a/substrate/core/network-libp2p/src/config.rs b/substrate/core/network-libp2p/src/config.rs index 61fae1a398..74f9280005 100644 --- a/substrate/core/network-libp2p/src/config.rs +++ b/substrate/core/network-libp2p/src/config.rs @@ -48,6 +48,9 @@ pub struct NetworkConfiguration { pub client_version: String, /// Name of the node. Sent over the wire for debugging purposes. pub node_name: String, + /// If true, the network will use mDNS to discover other libp2p nodes on the local network + /// and connect to them if they support the same chain. + pub enable_mdns: bool, } impl Default for NetworkConfiguration { @@ -65,6 +68,7 @@ impl Default for NetworkConfiguration { non_reserved_mode: NonReservedPeerMode::Accept, client_version: "unknown".into(), node_name: "unknown".into(), + enable_mdns: false, } } } diff --git a/substrate/core/network-libp2p/src/service_task.rs b/substrate/core/network-libp2p/src/service_task.rs index 12d0572869..37c4b05eaa 100644 --- a/substrate/core/network-libp2p/src/service_task.rs +++ b/substrate/core/network-libp2p/src/service_task.rs @@ -88,7 +88,7 @@ where TMessage: CustomMessage + Send + 'static { // Build the swarm. let (mut swarm, bandwidth) = { let user_agent = format!("{} ({})", config.client_version, config.node_name); - let behaviour = Behaviour::new(user_agent, local_public, registered_custom, known_addresses, peerset_receiver); + let behaviour = Behaviour::new(user_agent, local_public, registered_custom, known_addresses, peerset_receiver, config.enable_mdns); let (transport, bandwidth) = transport::build_transport(local_identity); (Swarm::new(transport, behaviour, local_peer_id.clone()), bandwidth) }; diff --git a/substrate/core/service/test/src/lib.rs b/substrate/core/service/test/src/lib.rs index 66975d4f20..dcdae582fa 100644 --- a/substrate/core/service/test/src/lib.rs +++ b/substrate/core/service/test/src/lib.rs @@ -99,6 +99,7 @@ fn node_config ( non_reserved_mode: NonReservedPeerMode::Accept, client_version: "network/test/0.1".to_owned(), node_name: "unknown".to_owned(), + enable_mdns: false, }; Configuration {