Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebRTC connection doesn't close after timeout #5213

Open
b-zee opened this issue Mar 7, 2024 · 2 comments
Open

WebRTC connection doesn't close after timeout #5213

b-zee opened this issue Mar 7, 2024 · 2 comments

Comments

@b-zee
Copy link
Contributor

b-zee commented Mar 7, 2024

Summary

Two nodes are connected by WebRTC and start pinging. When one node disconnects, the ping will fail, but the failing connection will never be detected and Ping continues to timeout (ping protocol negotiation timed out). Replacing WebRTC with QUIC, a ConnectionClosed is emitted.

Expected behavior

A ConnectionClosed event to be emitted

Actual behavior

I see Stream dropped without graceful close, sending Reset messages, but this occurs more often than just when a peer disappears.

Relevant log output

No response

Possible Solution

No response

Version

0.53.2

Would you like to work on fixing this bug ?

No

@dariusc93
Copy link
Contributor

Is this still applicable @b-zee?

@b-zee
Copy link
Contributor Author

b-zee commented Apr 15, 2024

Looks the same to me. When changing the ping example to use WebRTC:

$ cargo run --release --bin=ping-example -- /ip4/127.0.0.1/udp/37273/webrtc-direct/certhash/uEiBRkOLFJL7kZS7pteN3RmJ20sRzpr7-Pie_ZqDak71SVA
    Finished release [optimized] target(s) in 0.17s
     Running `target/release/ping-example /ip4/127.0.0.1/udp/37273/webrtc-direct/certhash/uEiBRkOLFJL7kZS7pteN3RmJ20sRzpr7-Pie_ZqDak71SVA`
Dialed /ip4/127.0.0.1/udp/37273/webrtc-direct/certhash/uEiBRkOLFJL7kZS7pteN3RmJ20sRzpr7-Pie_ZqDak71SVA
Listening on "/ip4/127.0.0.1/udp/53704/webrtc-direct/certhash/uEiBqf_AbMhEV1YEhKh-13LtkrXZiAoEum-l-8mWoheGYsg"
ConnectionEstablished { peer_id: PeerId("12D3KooWQo8LAqhzEP81qhecgCHfbqSaqzBc7wMs9PMoyKtUDP7s"), connection_id: ConnectionId(1), endpoint: Dialer { address: "/ip4/127.0.0.1/udp/37273/webrtc-direct/certhash/uEiBRkOLFJL7kZS7pteN3RmJ20sRzpr7-Pie_ZqDak71SVA", role_override: Dialer }, num_established: 1, concurrent_dial_errors: Some([]), established_in: 206.669401ms }
Behaviour(Event { peer: PeerId("12D3KooWQo8LAqhzEP81qhecgCHfbqSaqzBc7wMs9PMoyKtUDP7s"), connection: ConnectionId(1), result: Ok(129.214µs) })
Behaviour(Event { peer: PeerId("12D3KooWQo8LAqhzEP81qhecgCHfbqSaqzBc7wMs9PMoyKtUDP7s"), connection: ConnectionId(1), result: Err(Other { error: Custom { kind: TimedOut, error: "ping protocol negotiation timed out" } }) })
Behaviour(Event { peer: PeerId("12D3KooWQo8LAqhzEP81qhecgCHfbqSaqzBc7wMs9PMoyKtUDP7s"), connection: ConnectionId(1), result: Err(Other { error: Custom { kind: TimedOut, error: "ping protocol negotiation timed out" } }) })
Behaviour(Event { peer: PeerId("12D3KooWQo8LAqhzEP81qhecgCHfbqSaqzBc7wMs9PMoyKtUDP7s"), connection: ConnectionId(1), result: Err(Other { error: Custom { kind: TimedOut, error: "ping protocol negotiation timed out" } }) })
Behaviour(Event { peer: PeerId("12D3KooWQo8LAqhzEP81qhecgCHfbqSaqzBc7wMs9PMoyKtUDP7s"), connection: ConnectionId(1), result: Err(Other { error: Custom { kind: TimedOut, error: "ping protocol negotiation timed out" } }) })
Behaviour(Event { peer: PeerId("12D3KooWQo8LAqhzEP81qhecgCHfbqSaqzBc7wMs9PMoyKtUDP7s"), connection: ConnectionId(1), result: Err(Other { error: Custom { kind: TimedOut, error: "ping protocol negotiation timed out" } }) })

Where it seems like the timeout goes on indefinitely. This is different from using either TCP or QUIC.

My changes to the `ping` example for future reference.
diff --git a/Cargo.lock b/Cargo.lock
index eeed878cb..404ccbedc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4349,6 +4349,8 @@ version = "0.1.0"
 dependencies = [
  "futures",
  "libp2p",
+ "libp2p-webrtc",
+ "rand 0.8.5",
  "tokio",
  "tracing",
  "tracing-subscriber",
diff --git a/examples/ping/Cargo.toml b/examples/ping/Cargo.toml
index 6c74f4619..57ef6e836 100644
--- a/examples/ping/Cargo.toml
+++ b/examples/ping/Cargo.toml
@@ -11,6 +11,8 @@ release = false
 [dependencies]
 futures = "0.3.30"
 libp2p = { path = "../../libp2p", features = ["noise", "ping", "tcp", "tokio", "yamux"] }
+libp2p-webrtc = { workspace = true, features = ["tokio"] }
+rand = "0.8"
 tokio = { version = "1.37.0", features = ["full"] }
 tracing = { workspace = true }
 tracing-subscriber = { version = "0.3", features = ["env-filter"] }
diff --git a/examples/ping/src/main.rs b/examples/ping/src/main.rs
index 911b0384f..a2b031d5f 100644
--- a/examples/ping/src/main.rs
+++ b/examples/ping/src/main.rs
@@ -21,7 +21,10 @@
 #![doc = include_str!("../README.md")]
 
 use futures::prelude::*;
-use libp2p::{noise, ping, swarm::SwarmEvent, tcp, yamux, Multiaddr};
+use libp2p::{
+    core::muxing::StreamMuxerBox, multiaddr::Protocol, ping, swarm::SwarmEvent, Multiaddr,
+    Transport,
+};
 use std::{error::Error, time::Duration};
 use tracing_subscriber::EnvFilter;
 
@@ -33,18 +36,23 @@ async fn main() -> Result<(), Box<dyn Error>> {
 
     let mut swarm = libp2p::SwarmBuilder::with_new_identity()
         .with_tokio()
-        .with_tcp(
-            tcp::Config::default(),
-            noise::Config::new,
-            yamux::Config::default,
-        )?
+        .with_other_transport(|id_keys| {
+            Ok(libp2p_webrtc::tokio::Transport::new(
+                id_keys.clone(),
+                libp2p_webrtc::tokio::Certificate::generate(&mut rand::thread_rng())?,
+            )
+            .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn))))
+        })?
         .with_behaviour(|_| ping::Behaviour::default())?
         .with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(u64::MAX)))
         .build();
 
     // Tell the swarm to listen on all interfaces and a random, OS-assigned
     // port.
-    swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
+    let address_webrtc = Multiaddr::from(std::net::Ipv4Addr::UNSPECIFIED)
+        .with(Protocol::Udp(0))
+        .with(Protocol::WebRTCDirect);
+    swarm.listen_on(address_webrtc)?;
 
     // Dial the peer identified by the multi-address given as the second
     // command-line argument, if any.
@@ -57,8 +65,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
     loop {
         match swarm.select_next_some().await {
             SwarmEvent::NewListenAddr { address, .. } => println!("Listening on {address:?}"),
-            SwarmEvent::Behaviour(event) => println!("{event:?}"),
-            _ => {}
+            event => println!("{event:?}"),
         }
     }
 }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants