From f2c6ee618758771fc6c847713fff8a7108f67814 Mon Sep 17 00:00:00 2001 From: Victor Ermolaev Date: Fri, 26 Nov 2021 16:03:07 +0100 Subject: [PATCH 1/6] Use IPv6 configuration instead of the default. --- protocols/mdns/src/behaviour.rs | 12 ++++++------ protocols/mdns/tests/smoke.rs | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index 156c805a4d7..ee32b850276 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -144,12 +144,12 @@ impl Mdns { } }; let send_socket = { - let addrs = [ - SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0), - SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), 0), - ]; + let addr = match config.multicast_addr { + IpAddr::V4(_) => SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0), + IpAddr::V6(_) => SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), 0), + }; - let socket = std::net::UdpSocket::bind(&addrs[..])?; + let socket = std::net::UdpSocket::bind(addr)?; Async::new(socket)? }; let if_watch = if_watch::IfWatcher::new().await?; @@ -406,7 +406,7 @@ impl NetworkBehaviour for Mdns { while let Some(pos) = self .discovered_nodes .iter() - .position(|(_, _, exp)| *exp < now) + .position(|(_, _, exp)| *exp <= now) { let (peer_id, addr, _) = self.discovered_nodes.remove(pos); expired.push((peer_id, addr)); diff --git a/protocols/mdns/tests/smoke.rs b/protocols/mdns/tests/smoke.rs index 3d374dd4563..62cc8e92667 100644 --- a/protocols/mdns/tests/smoke.rs +++ b/protocols/mdns/tests/smoke.rs @@ -85,7 +85,7 @@ async fn test_discovery_async_std_ipv4() -> Result<(), Box> { async fn test_discovery_async_std_ipv6() -> Result<(), Box> { let mut config = MdnsConfig::default(); config.multicast_addr = *IPV6_MDNS_MULTICAST_ADDRESS; - run_test(MdnsConfig::default()).await + run_test(config).await } #[tokio::test] @@ -97,5 +97,5 @@ async fn test_discovery_tokio_ipv4() -> Result<(), Box> { async fn test_discovery_tokio_ipv6() -> Result<(), Box> { let mut config = MdnsConfig::default(); config.multicast_addr = *IPV6_MDNS_MULTICAST_ADDRESS; - run_test(MdnsConfig::default()).await + run_test(config).await } From 4dc85486455d273f7dfe190892597a242ded1f9f Mon Sep 17 00:00:00 2001 From: Victor Ermolaev Date: Fri, 26 Nov 2021 16:26:54 +0100 Subject: [PATCH 2/6] Generate expiration event and test it. --- protocols/mdns/tests/smoke.rs | 109 ++++++++++++++++++++++++++++++++-- 1 file changed, 104 insertions(+), 5 deletions(-) diff --git a/protocols/mdns/tests/smoke.rs b/protocols/mdns/tests/smoke.rs index 62cc8e92667..0fb5da4b29c 100644 --- a/protocols/mdns/tests/smoke.rs +++ b/protocols/mdns/tests/smoke.rs @@ -26,6 +26,8 @@ use libp2p::{ PeerId, }; use std::error::Error; +use std::future::Future; +use std::time::Duration; async fn create_swarm(config: MdnsConfig) -> Result, Box> { let id_keys = identity::Keypair::generate_ed25519(); @@ -37,7 +39,7 @@ async fn create_swarm(config: MdnsConfig) -> Result, Box> Ok(swarm) } -async fn run_test(config: MdnsConfig) -> Result<(), Box> { +async fn run_discovery_test(config: MdnsConfig) -> Result<(), Box> { let mut a = create_swarm(config.clone()).await?; let mut b = create_swarm(config).await?; let mut discovered_a = false; @@ -78,24 +80,121 @@ async fn run_test(config: MdnsConfig) -> Result<(), Box> { #[async_std::test] async fn test_discovery_async_std_ipv4() -> Result<(), Box> { - run_test(MdnsConfig::default()).await + run_discovery_test(MdnsConfig::default()).await } #[async_std::test] async fn test_discovery_async_std_ipv6() -> Result<(), Box> { let mut config = MdnsConfig::default(); config.multicast_addr = *IPV6_MDNS_MULTICAST_ADDRESS; - run_test(config).await + run_discovery_test(config).await } #[tokio::test] async fn test_discovery_tokio_ipv4() -> Result<(), Box> { - run_test(MdnsConfig::default()).await + run_discovery_test(MdnsConfig::default()).await } #[tokio::test] async fn test_discovery_tokio_ipv6() -> Result<(), Box> { let mut config = MdnsConfig::default(); config.multicast_addr = *IPV6_MDNS_MULTICAST_ADDRESS; - run_test(config).await + run_discovery_test(config).await } + +async fn run_peer_expiration_test(config: MdnsConfig) -> Result<(), Box> { + let mut a = create_swarm(config.clone()).await?; + let mut b = create_swarm(config).await?; + + loop { + futures::select! { + ev = a.select_next_some() => match ev { + SwarmEvent::Behaviour(MdnsEvent::Expired(peers)) => { + for (peer, _addr) in peers { + if peer == *b.local_peer_id() { + return Ok(()); + } + } + } + _ => {} + }, + ev = b.select_next_some() => match ev { + SwarmEvent::Behaviour(MdnsEvent::Expired(peers)) => { + for (peer, _addr) in peers { + if peer == *a.local_peer_id() { + return Ok(()); + } + } + } + _ => {} + } + + } + } +} + +#[async_std::test] +async fn test_expired_async_std_ipv4() -> Result<(), Box> { + let config = MdnsConfig { + ttl: Duration::from_millis(500), + query_interval: Duration::from_secs(1), + ..Default::default() + }; + + run_timebound_test( + run_peer_expiration_test(config), + Duration::from_secs(6) + ).await +} + +#[async_std::test] +async fn test_expired_async_std_ipv6() -> Result<(), Box> { + let config = MdnsConfig { + ttl: Duration::from_millis(500), + query_interval: Duration::from_secs(1), + multicast_addr: *IPV6_MDNS_MULTICAST_ADDRESS, + }; + + run_timebound_test( + run_peer_expiration_test(config), + Duration::from_secs(6) + ).await +} + +#[tokio::test] +async fn test_expired_tokio_ipv4() -> Result<(), Box> { + let config = MdnsConfig { + ttl: Duration::from_millis(500), + query_interval: Duration::from_secs(1), + ..Default::default() + }; + + run_timebound_test( + run_peer_expiration_test(config), + Duration::from_secs(6) + ).await +} + +#[tokio::test] +async fn test_expired_tokio_ipv6() -> Result<(), Box> { + let config = MdnsConfig { + ttl: Duration::from_millis(500), + query_interval: Duration::from_secs(1), + multicast_addr: *IPV6_MDNS_MULTICAST_ADDRESS, + }; + + run_timebound_test( + run_peer_expiration_test(config), + Duration::from_secs(6) + ).await +} + +async fn run_timebound_test(fut: impl Future>>, bound: Duration) -> Result<(), Box> { + let result = async_std::future::timeout(bound, fut) + .await; + + match result { + Ok(res) => res, + Err(err) => Err::<(), Box>(Box::new(err)) + } +} \ No newline at end of file From 56fa6b0904164d4207ce123a7bf96c103576b664 Mon Sep 17 00:00:00 2001 From: Victor Ermolaev Date: Fri, 26 Nov 2021 16:40:09 +0100 Subject: [PATCH 3/6] Add a changelog entry. --- protocols/mdns/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/protocols/mdns/CHANGELOG.md b/protocols/mdns/CHANGELOG.md index 10d9d0d58e7..609c70ab8d7 100644 --- a/protocols/mdns/CHANGELOG.md +++ b/protocols/mdns/CHANGELOG.md @@ -1,3 +1,9 @@ +# 0.35.0 [unreleased] + +- Fix generation of the peer expiration event, see [PR 2359] + +[PR 2359]: https://github.com/libp2p/rust-libp2p/pull/2359 + # 0.34.0 [unreleased] - Update dependencies. From 0162394ad3043026b96a08992f432a84723d95e0 Mon Sep 17 00:00:00 2001 From: Victor Ermolaev Date: Tue, 30 Nov 2021 17:04:53 +0100 Subject: [PATCH 4/6] Address PR comments. --- protocols/mdns/CHANGELOG.md | 10 +++---- protocols/mdns/Cargo.toml | 2 +- protocols/mdns/src/behaviour.rs | 6 +++- protocols/mdns/tests/smoke.rs | 51 ++++++++++++++++++++++----------- 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/protocols/mdns/CHANGELOG.md b/protocols/mdns/CHANGELOG.md index 609c70ab8d7..74e6066afe6 100644 --- a/protocols/mdns/CHANGELOG.md +++ b/protocols/mdns/CHANGELOG.md @@ -1,9 +1,3 @@ -# 0.35.0 [unreleased] - -- Fix generation of the peer expiration event, see [PR 2359] - -[PR 2359]: https://github.com/libp2p/rust-libp2p/pull/2359 - # 0.34.0 [unreleased] - Update dependencies. @@ -17,10 +11,14 @@ - Migrate to Rust edition 2021 (see [PR 2339]). +- Fix generation of peer expiration event and listen on specified IP version (see [PR 2359]). + [PR 2339]: https://github.com/libp2p/rust-libp2p/pull/2339 [PR 2311]: https://github.com/libp2p/rust-libp2p/pull/2311/ +[PR 2359]: https://github.com/libp2p/rust-libp2p/pull/2359 + # 0.33.0 [2021-11-16] - Update dependencies. diff --git a/protocols/mdns/Cargo.toml b/protocols/mdns/Cargo.toml index 1f6fde5ede0..42c666f3328 100644 --- a/protocols/mdns/Cargo.toml +++ b/protocols/mdns/Cargo.toml @@ -28,4 +28,4 @@ void = "1.0.2" [dev-dependencies] async-std = { version = "1.9.0", features = ["attributes"] } libp2p = { path = "../.." } -tokio = { version = "1.2.0", default-features = false, features = ["macros", "rt", "rt-multi-thread"] } +tokio = { version = "1.2.0", default-features = false, features = ["macros", "rt", "rt-multi-thread", "time"] } diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index ee32b850276..7f9e9524395 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -54,7 +54,11 @@ pub struct MdnsConfig { /// peer joins the network. Receiving an mdns packet resets the timer /// preventing unnecessary traffic. pub query_interval: Duration, - /// IP address for multicast. + /// Internet protocol version (v4 or v6) to use. + /// + /// Note that the provided IP address itself is ignored and instead the + /// unspecified address (`0.0.0.0` or `::`) of the corresponding version is + /// used. pub multicast_addr: IpAddr, } diff --git a/protocols/mdns/tests/smoke.rs b/protocols/mdns/tests/smoke.rs index 0fb5da4b29c..6137650754e 100644 --- a/protocols/mdns/tests/smoke.rs +++ b/protocols/mdns/tests/smoke.rs @@ -142,9 +142,11 @@ async fn test_expired_async_std_ipv4() -> Result<(), Box> { }; run_timebound_test( + TestRuntime::StdAsync, run_peer_expiration_test(config), - Duration::from_secs(6) - ).await + Duration::from_secs(6), + ) + .await } #[async_std::test] @@ -156,9 +158,11 @@ async fn test_expired_async_std_ipv6() -> Result<(), Box> { }; run_timebound_test( + TestRuntime::StdAsync, run_peer_expiration_test(config), - Duration::from_secs(6) - ).await + Duration::from_secs(6), + ) + .await } #[tokio::test] @@ -170,9 +174,11 @@ async fn test_expired_tokio_ipv4() -> Result<(), Box> { }; run_timebound_test( + TestRuntime::Tokio, run_peer_expiration_test(config), - Duration::from_secs(6) - ).await + Duration::from_secs(6), + ) + .await } #[tokio::test] @@ -184,17 +190,30 @@ async fn test_expired_tokio_ipv6() -> Result<(), Box> { }; run_timebound_test( + TestRuntime::Tokio, run_peer_expiration_test(config), - Duration::from_secs(6) - ).await + Duration::from_secs(6), + ) + .await } -async fn run_timebound_test(fut: impl Future>>, bound: Duration) -> Result<(), Box> { - let result = async_std::future::timeout(bound, fut) - .await; - - match result { - Ok(res) => res, - Err(err) => Err::<(), Box>(Box::new(err)) +async fn run_timebound_test( + runtime: TestRuntime, + fut: impl Future>>, + bound: Duration, +) -> Result<(), Box> { + match runtime { + TestRuntime::Tokio => tokio::time::timeout(bound, fut) + .await + .map_err(|e| Box::new(e) as Box), + TestRuntime::StdAsync => async_std::future::timeout(bound, fut) + .await + .map_err(|e| Box::new(e) as Box), } -} \ No newline at end of file + .map(|_| ()) +} + +enum TestRuntime { + Tokio, + StdAsync, +} From 53ea9e9e749bf685cf85b12951b31a281a9b2551 Mon Sep 17 00:00:00 2001 From: Victor Ermolaev Date: Wed, 1 Dec 2021 18:06:43 +0100 Subject: [PATCH 5/6] Flatten the tests. --- protocols/mdns/tests/smoke.rs | 60 ++++++++--------------------------- 1 file changed, 14 insertions(+), 46 deletions(-) diff --git a/protocols/mdns/tests/smoke.rs b/protocols/mdns/tests/smoke.rs index 6137650754e..707ad9f39ab 100644 --- a/protocols/mdns/tests/smoke.rs +++ b/protocols/mdns/tests/smoke.rs @@ -26,7 +26,6 @@ use libp2p::{ PeerId, }; use std::error::Error; -use std::future::Future; use std::time::Duration; async fn create_swarm(config: MdnsConfig) -> Result, Box> { @@ -141,12 +140,10 @@ async fn test_expired_async_std_ipv4() -> Result<(), Box> { ..Default::default() }; - run_timebound_test( - TestRuntime::StdAsync, - run_peer_expiration_test(config), - Duration::from_secs(6), - ) - .await + async_std::future::timeout(Duration::from_secs(6), run_peer_expiration_test(config)) + .await + .map(|_| ()) + .map_err(|e| Box::new(e) as Box) } #[async_std::test] @@ -157,12 +154,10 @@ async fn test_expired_async_std_ipv6() -> Result<(), Box> { multicast_addr: *IPV6_MDNS_MULTICAST_ADDRESS, }; - run_timebound_test( - TestRuntime::StdAsync, - run_peer_expiration_test(config), - Duration::from_secs(6), - ) - .await + async_std::future::timeout(Duration::from_secs(6), run_peer_expiration_test(config)) + .await + .map(|_| ()) + .map_err(|e| Box::new(e) as Box) } #[tokio::test] @@ -173,12 +168,9 @@ async fn test_expired_tokio_ipv4() -> Result<(), Box> { ..Default::default() }; - run_timebound_test( - TestRuntime::Tokio, - run_peer_expiration_test(config), - Duration::from_secs(6), - ) - .await + tokio::time::timeout(Duration::from_secs(6), run_peer_expiration_test(config)) + .await + .unwrap() } #[tokio::test] @@ -189,31 +181,7 @@ async fn test_expired_tokio_ipv6() -> Result<(), Box> { multicast_addr: *IPV6_MDNS_MULTICAST_ADDRESS, }; - run_timebound_test( - TestRuntime::Tokio, - run_peer_expiration_test(config), - Duration::from_secs(6), - ) - .await -} - -async fn run_timebound_test( - runtime: TestRuntime, - fut: impl Future>>, - bound: Duration, -) -> Result<(), Box> { - match runtime { - TestRuntime::Tokio => tokio::time::timeout(bound, fut) - .await - .map_err(|e| Box::new(e) as Box), - TestRuntime::StdAsync => async_std::future::timeout(bound, fut) - .await - .map_err(|e| Box::new(e) as Box), - } - .map(|_| ()) -} - -enum TestRuntime { - Tokio, - StdAsync, + tokio::time::timeout(Duration::from_secs(6), run_peer_expiration_test(config)) + .await + .unwrap() } From 05f26691dc0826d37ceb1025c472362658fbf2fd Mon Sep 17 00:00:00 2001 From: Victor Ermolaev Date: Thu, 2 Dec 2021 08:24:09 +0100 Subject: [PATCH 6/6] Revert an incorrect comment. --- protocols/mdns/src/behaviour.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index 7f9e9524395..ee32b850276 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -54,11 +54,7 @@ pub struct MdnsConfig { /// peer joins the network. Receiving an mdns packet resets the timer /// preventing unnecessary traffic. pub query_interval: Duration, - /// Internet protocol version (v4 or v6) to use. - /// - /// Note that the provided IP address itself is ignored and instead the - /// unspecified address (`0.0.0.0` or `::`) of the corresponding version is - /// used. + /// IP address for multicast. pub multicast_addr: IpAddr, }