From 594520e14d7308a464151a304d2fcb2fb2b824b4 Mon Sep 17 00:00:00 2001 From: Timothy Wu Date: Wed, 4 Feb 2026 17:52:48 -0500 Subject: [PATCH 01/10] webrtc: Fix InputRejected error during ICE negotiation --- src/transport/webrtc/mod.rs | 47 ++++++++++++++++----------------- src/transport/webrtc/opening.rs | 25 ++++++++---------- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/src/transport/webrtc/mod.rs b/src/transport/webrtc/mod.rs index a82959ca9..d8363bf53 100644 --- a/src/transport/webrtc/mod.rs +++ b/src/transport/webrtc/mod.rs @@ -363,37 +363,36 @@ impl WebRtcTransport { let contents: DatagramRecv = buffer.as_slice().try_into().map_err(|_| Error::InvalidData)?; - // Handle non stun packets. - if !is_stun_packet(&buffer) { - tracing::debug!( + // If an opening connection already exists for this source, route all packets to it + if let Some(opening_conn) = self.opening.get_mut(&source) { + tracing::trace!( target: LOG_TARGET, ?source, - "received non-stun message" + is_stun = is_stun_packet(&buffer), + "routing packet to existing opening connection" ); - match self.opening.get_mut(&source) { - Some(connection) => - if let Err(error) = connection.on_input(contents) { - tracing::error!( - target: LOG_TARGET, - ?error, - ?source, - "failed to handle inbound datagram" - ); - }, - None => { - tracing::warn!( - target: LOG_TARGET, - ?source, - "received non-stun message from unknown peer", - ); - return Err(Error::InvalidData); - } - }; - + if let Err(error) = opening_conn.on_input(contents) { + tracing::error!( + target: LOG_TARGET, + ?error, + ?source, + "failed to handle inbound datagram" + ); + } return Ok(true); } + // No existing connection - this should be a STUN packet to create a new connection + if !is_stun_packet(&buffer) { + tracing::warn!( + target: LOG_TARGET, + ?source, + "received non-stun packet without existing connection, ignoring" + ); + return Ok(false); + } + let stun_message = str0m::ice::StunMessage::parse(&buffer).map_err(|_| Error::InvalidData)?; let Some((ufrag, pass)) = stun_message.split_username() else { diff --git a/src/transport/webrtc/opening.rs b/src/transport/webrtc/opening.rs index f778ca843..3afed15a3 100644 --- a/src/transport/webrtc/opening.rs +++ b/src/transport/webrtc/opening.rs @@ -329,20 +329,17 @@ impl OpeningWebRtcConnection { }, ); - match self.rtc.accepts(&message) { - true => self.rtc.handle_input(message).map_err(|error| { - tracing::debug!(target: LOG_TARGET, source = ?self.peer_address, ?error, "failed to handle data"); - Error::InputRejected - }), - false => { - tracing::warn!( - target: LOG_TARGET, - peer = ?self.peer_address, - "input rejected", - ); - Err(Error::InputRejected) - } - } + // Let str0m handle input validation internally, similar to how the initial STUN packet is + // handled + self.rtc.handle_input(message).map_err(|error| { + tracing::debug!( + target: LOG_TARGET, + source = ?self.peer_address, + ?error, + "failed to handle input" + ); + Error::InputRejected + }) } /// Progress the state of [`OpeningWebRtcConnection`]. From 99498b8b0850e5a4dd22fdcfd3ce3552b9ed6f31 Mon Sep 17 00:00:00 2001 From: Timothy Wu Date: Sun, 8 Feb 2026 01:11:52 -0500 Subject: [PATCH 02/10] webrtc: Add diagnostic logging for notification handshake debugging --- src/protocol/notification/negotiation.rs | 36 +++++++++++++++++++++++- src/transport/webrtc/substream.rs | 5 ++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/protocol/notification/negotiation.rs b/src/protocol/notification/negotiation.rs index 9c53c7606..6509d8274 100644 --- a/src/protocol/notification/negotiation.rs +++ b/src/protocol/notification/negotiation.rs @@ -79,6 +79,7 @@ pub enum HandshakeEvent { } /// Outbound substream's handshake state +#[derive(Debug)] enum HandshakeState { /// Send handshake to remote peer. SendHandshake, @@ -218,6 +219,13 @@ impl Stream for HandshakeService { inner.substreams.iter_mut() { if let Poll::Ready(()) = timer.poll_unpin(cx) { + tracing::trace!( + target: LOG_TARGET, + ?peer, + ?direction, + ?state, + "handshake negotiation timed out", + ); return Poll::Ready(Some(( *peer, HandshakeEvent::NegotiationError { @@ -285,10 +293,36 @@ impl Stream for HandshakeService { }, HandshakeState::ReadHandshake => match pinned.poll_next(cx) { Poll::Ready(Some(Ok(handshake))) => { + tracing::trace!( + target: LOG_TARGET, + ?peer, + handshake_len = handshake.len(), + "successfully read handshake from substream", + ); inner.ready.push_back((*peer, *direction, handshake.freeze().into())); continue 'outer; } - Poll::Ready(Some(Err(_))) | Poll::Ready(None) => { + Poll::Ready(Some(Err(error))) => { + tracing::trace!( + target: LOG_TARGET, + ?peer, + ?error, + "error reading handshake from substream", + ); + return Poll::Ready(Some(( + *peer, + HandshakeEvent::NegotiationError { + peer: *peer, + direction: *direction, + }, + ))); + } + Poll::Ready(None) => { + tracing::trace!( + target: LOG_TARGET, + ?peer, + "substream closed while reading handshake", + ); return Poll::Ready(Some(( *peer, HandshakeEvent::NegotiationError { diff --git a/src/transport/webrtc/substream.rs b/src/transport/webrtc/substream.rs index cf35a1785..c79fe75a0 100644 --- a/src/transport/webrtc/substream.rs +++ b/src/transport/webrtc/substream.rs @@ -171,6 +171,11 @@ impl SubstreamHandle { // This ensures that if a FIN message contains data, we deliver it before closing. if let Some(payload) = message.payload { if !payload.is_empty() { + tracing::trace!( + target: "litep2p::webrtc::substream", + payload_len = payload.len(), + "forwarding payload to substream", + ); self.inbound_tx .send(Event::Message { payload, From 130a647b2b6ac2815f71fe7de37afacec65c3f5e Mon Sep 17 00:00:00 2001 From: Timothy Wu Date: Tue, 24 Feb 2026 15:12:18 -0500 Subject: [PATCH 03/10] webrtc: fix FIN-after-handler-drop race causing silent response loss --- src/transport/webrtc/substream.rs | 114 ++++++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 7 deletions(-) diff --git a/src/transport/webrtc/substream.rs b/src/transport/webrtc/substream.rs index c79fe75a0..f3d173fa0 100644 --- a/src/transport/webrtc/substream.rs +++ b/src/transport/webrtc/substream.rs @@ -118,6 +118,8 @@ impl Substream { shutdown_waker: Arc::clone(&shutdown_waker), write_waker: Arc::clone(&write_waker), read_closed: std::sync::atomic::AtomicBool::new(false), + fin_delivered: std::sync::atomic::AtomicBool::new(false), + sent_reset: false, }; ( @@ -157,6 +159,15 @@ pub struct SubstreamHandle { /// Whether we've already sent RecvClosed to the inbound channel. /// Prevents duplicate RecvClosed events if multiple FIN messages are received. read_closed: std::sync::atomic::AtomicBool, + + /// Whether the remote's FIN was successfully delivered to the Substream. + /// When true, the Substream acknowledged the close, so dropping without + /// explicit shutdown is a clean close (no ResetStream needed). + /// When false and the Substream drops without shutdown, emit ResetStream. + fin_delivered: std::sync::atomic::AtomicBool, + + /// Whether we've already emitted a ResetStream in poll_next. + sent_reset: bool, } impl SubstreamHandle { @@ -176,12 +187,23 @@ impl SubstreamHandle { payload_len = payload.len(), "forwarding payload to substream", ); - self.inbound_tx + if self + .inbound_tx .send(Event::Message { payload, flag: None, }) - .await?; + .await + .is_err() + { + tracing::debug!( + target: "litep2p::webrtc::substream", + "substream dropped, cannot deliver inbound payload", + ); + // Don't return error — outbound data may still need to be flushed. + // The SubstreamHandle will detect the drop via inbound_tx.is_closed() + // in poll_next() and clean up naturally. + } } } @@ -199,8 +221,18 @@ impl SubstreamHandle { return Ok(()); } - // Received FIN from remote, close our read half - self.inbound_tx.send(Event::RecvClosed).await?; + // Notify the Substream that the remote closed its write half. + // If the Substream is already dropped, this is expected for + // request-response protocols where the handler writes the response + // and drops before the FIN arrives. Fall through to still send FIN_ACK. + if self.inbound_tx.send(Event::RecvClosed).await.is_err() { + tracing::debug!( + target: "litep2p::webrtc::substream", + "substream already dropped, skipping RecvClosed notification", + ); + } else { + self.fin_delivered.store(true, std::sync::atomic::Ordering::SeqCst); + } // Send FIN_ACK back to remote using try_send to avoid blocking. // If the channel is full, the remote will timeout waiting for FIN_ACK @@ -275,10 +307,22 @@ impl Stream for SubstreamHandle { } // Check if Substream has been dropped (inbound channel closed) - // When Substream is dropped, there will be no more outbound messages - // Since we've already tried to recv above and got Pending, we know the queue is empty - // Therefore, it's safe to signal closure + // When Substream is dropped, there will be no more outbound messages. + // Since we've already tried to recv above and got Pending, we know the queue is empty. if self.inbound_tx.is_closed() { + // If the Substream was dropped without graceful shutdown AND the remote's + // FIN was never delivered (substream dropped before FIN arrived), emit + // ResetStream to tell the remote that this side closed unexpectedly. + if !self.sent_reset && !self.fin_delivered.load(std::sync::atomic::Ordering::SeqCst) { + let state = *self.state.lock(); + if !matches!(state, State::FinSent | State::FinAcked) { + self.sent_reset = true; + return Poll::Ready(Some(Event::Message { + payload: vec![], + flag: Some(Flag::ResetStream), + })); + } + } return Poll::Ready(None); } @@ -1512,4 +1556,60 @@ mod tests { other => panic!("Expected BrokenPipe error, got: {:?}", other), } } + + #[tokio::test] + async fn fin_after_handler_drop_preserves_response() { + // Regression test for the race condition where a FIN arrives after the + // request-response handler has written its response and dropped the Substream. + // Previously, this caused EssentialTaskClosed which killed the data channel + // before the buffered response could be flushed, causing silent response loss. + + let (mut substream, mut handle) = Substream::new(); + + // Handler writes response data, then drops the Substream (simulates a + // request-response handler that's done processing). + substream.write_all(b"response data").await.unwrap(); + drop(substream); + + // Remote peer sends FIN (half-close: "I'm done sending my request"). + // This must succeed even though the Substream is already dropped. + handle + .on_message(WebRtcMessage { + payload: None, + flag: Some(Flag::Fin), + }) + .await + .unwrap(); + + // Drain the handle — response data must still be available. + // 1. Response data written by the handler + assert_eq!( + handle.next().await, + Some(Event::Message { + payload: b"response data".to_vec(), + flag: None, + }) + ); + + // 2. FIN_ACK sent in response to the remote's FIN + assert_eq!( + handle.next().await, + Some(Event::Message { + payload: vec![], + flag: Some(Flag::FinAck), + }) + ); + + // 3. RESET_STREAM because Substream was dropped without graceful shutdown + assert_eq!( + handle.next().await, + Some(Event::Message { + payload: vec![], + flag: Some(Flag::ResetStream), + }) + ); + + // 4. Stream terminates + assert_eq!(handle.next().await, None); + } } From d51dd0159d654d2520989f6284eae064bdc2e14c Mon Sep 17 00:00:00 2001 From: Timothy Wu Date: Thu, 26 Feb 2026 15:31:19 -0500 Subject: [PATCH 04/10] webrtc: report substream open failure when channel closes unexpectedly --- src/transport/webrtc/connection.rs | 46 ++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/transport/webrtc/connection.rs b/src/transport/webrtc/connection.rs index ffef8a7ae..d6d49947f 100644 --- a/src/transport/webrtc/connection.rs +++ b/src/transport/webrtc/connection.rs @@ -307,8 +307,50 @@ impl WebRtcConnection { "channel closed", ); - self.pending_outbound.remove(&channel_id); - self.channels.remove(&channel_id); + // If this was a pending outbound channel (waiting for DCEP ACK from remote), + // report the failure so the protocol handler can retry. + if let Some(context) = self.pending_outbound.remove(&channel_id) { + tracing::debug!( + target: LOG_TARGET, + peer = ?self.peer, + ?channel_id, + protocol = %context.protocol, + substream_id = ?context.substream_id, + "outbound channel closed before opening, reporting failure", + ); + + let _ = self + .protocol_set + .report_substream_open_failure( + context.protocol, + context.substream_id, + SubstreamError::ConnectionClosed, + ) + .await; + } + + if let Some(ChannelState::OutboundOpening { context, .. }) = + self.channels.remove(&channel_id) + { + tracing::debug!( + target: LOG_TARGET, + peer = ?self.peer, + ?channel_id, + protocol = %context.protocol, + substream_id = ?context.substream_id, + "outbound channel closed during negotiation, reporting failure", + ); + + let _ = self + .protocol_set + .report_substream_open_failure( + context.protocol, + context.substream_id, + SubstreamError::ConnectionClosed, + ) + .await; + } + self.handles.remove(&channel_id); Ok(()) From 8a7082f74bf8453cea0e1076225e116a4a618989 Mon Sep 17 00:00:00 2001 From: Timothy Wu Date: Tue, 3 Mar 2026 12:21:36 -0500 Subject: [PATCH 05/10] webrtc: Update str0m to ChainSafe fork at 0dd05fd --- Cargo.lock | 515 +++++++++++++++++++++++------------- Cargo.toml | 2 +- src/transport/webrtc/mod.rs | 16 +- 3 files changed, 340 insertions(+), 193 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b0834f5ea..0ecdc171f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -214,12 +214,41 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "aws-lc-rs" +version = "1.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94bffc006df10ac2a68c83692d734a465f8ee6c5b384d8545a636f81d858f4bf" +dependencies = [ + "aws-lc-sys", + "untrusted 0.7.1", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4321e568ed89bb5a7d291a7f37997c2c0df89809d7b6d12062c81ddb54aa782e" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "base-x" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base256emoji" version = "1.0.2" @@ -244,15 +273,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.8.3" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" [[package]] name = "bitflags" @@ -341,6 +364,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -350,6 +375,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chacha20" version = "0.9.1" @@ -399,6 +430,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "cmake" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" +dependencies = [ + "cc", +] + [[package]] name = "combine" version = "4.6.7" @@ -491,9 +531,9 @@ dependencies = [ [[package]] name = "crc" -version = "3.4.0" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" dependencies = [ "crc-catalog", ] @@ -551,9 +591,9 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-common" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -642,6 +682,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "const-oid", + "der_derive", + "flagset", + "pem-rfc7468", "zeroize", ] @@ -673,11 +716,22 @@ dependencies = [ "rusticata-macros", ] +[[package]] +name = "der_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "deranged" -version = "0.5.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", ] @@ -702,6 +756,29 @@ dependencies = [ "subtle", ] +[[package]] +name = "dimpl" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53382532e53576983721038702387751067de126c43c3150af8341962e85b456" +dependencies = [ + "arrayvec", + "aws-lc-rs", + "der", + "log", + "nom", + "once_cell", + "pkcs8", + "rand 0.9.2", + "rcgen 0.14.7", + "sec1", + "signature", + "spki", + "subtle", + "time", + "x509-cert", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -725,6 +802,12 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c3cf4824e2d5f025c7b531afcb2325364084a16806f6d47fbc1f5fbd9960590" +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "ed25519" version = "2.2.3" @@ -860,6 +943,12 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +[[package]] +name = "flagset" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe" + [[package]] name = "flate2" version = "1.1.9" @@ -883,21 +972,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.2" @@ -913,6 +987,12 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futures" version = "0.3.32" @@ -1042,9 +1122,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -1080,19 +1160,19 @@ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", ] [[package]] name = "getrandom" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 6.0.0", "rand_core 0.10.0", "wasip2", "wasip3", @@ -1208,15 +1288,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.7", -] - [[package]] name = "http" version = "1.4.0" @@ -1354,19 +1425,19 @@ dependencies = [ [[package]] name = "if-addrs" -version = "0.10.2" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cabb0019d51a643781ff15c9c8a3e5dedc365c47211270f4e8f82812fedd8f0a" +checksum = "c0a05c691e1fae256cf7013d99dad472dc52d5543322761f83ec8d47eab40d2b" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] name = "if-watch" -version = "3.2.1" +version = "3.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf9d64cfcf380606e64f9a0bcf493616b65331199f984151a6fa11a7b3cde38" +checksum = "71c02a5161c313f0cbdbadc511611893584a10a7b6153cb554bdf83ddce99ec2" dependencies = [ "async-io", "core-foundation 0.9.4", @@ -1435,9 +1506,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "itertools" @@ -1454,6 +1525,16 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + [[package]] name = "js-sys" version = "0.3.91" @@ -2189,46 +2270,30 @@ dependencies = [ [[package]] name = "netlink-packet-core" -version = "0.7.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72724faf704479d67b388da142b186f916188505e7e0b26719019c525882eda4" +checksum = "3463cbb78394cb0141e2c926b93fc2197e473394b761986eca3b9da2c63ae0f4" dependencies = [ - "anyhow", - "byteorder", - "netlink-packet-utils", + "paste", ] [[package]] name = "netlink-packet-route" -version = "0.17.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053998cea5a306971f88580d0829e90f270f940befd7cf928da179d4187a5a66" +checksum = "4ce3636fa715e988114552619582b530481fd5ef176a1e5c1bf024077c2c9445" dependencies = [ - "anyhow", - "bitflags 1.3.2", - "byteorder", + "bitflags", "libc", + "log", "netlink-packet-core", - "netlink-packet-utils", -] - -[[package]] -name = "netlink-packet-utils" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ede8a08c71ad5a95cdd0e4e52facd37190977039a4704eb82a283f713747d34" -dependencies = [ - "anyhow", - "byteorder", - "paste", - "thiserror 1.0.69", ] [[package]] name = "netlink-proto" -version = "0.11.5" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72452e012c2f8d612410d89eea01e2d9b56205274abb35d53f60200b2ec41d60" +checksum = "b65d130ee111430e47eed7896ea43ca693c387f097dd97376bffafbf25812128" dependencies = [ "bytes", "futures", @@ -2265,12 +2330,13 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.4" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cfg-if", + "cfg_aliases", "libc", ] @@ -2367,60 +2433,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" -[[package]] -name = "openssl" -version = "0.10.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" -dependencies = [ - "bitflags 2.11.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - [[package]] name = "openssl-probe" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" -[[package]] -name = "openssl-src" -version = "300.5.5+3.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f1787d533e03597a7934fd0a765f0d28e94ecc5fb7789f8053b1e699a56f709" -dependencies = [ - "cc", -] - -[[package]] -name = "openssl-sys" -version = "0.9.111" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" -dependencies = [ - "cc", - "libc", - "openssl-src", - "pkg-config", - "vcpkg", -] - [[package]] name = "parking" version = "2.2.1" @@ -2475,6 +2493,15 @@ dependencies = [ "serde_core", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -2735,7 +2762,7 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" dependencies = [ - "heck 0.5.0", + "heck 0.4.1", "itertools", "log", "multimap", @@ -2891,6 +2918,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "rand" version = "0.8.5" @@ -2918,7 +2951,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8" dependencies = [ - "getrandom 0.4.1", + "getrandom 0.4.2", "rand_core 0.10.0", ] @@ -2993,6 +3026,7 @@ version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10b99e0098aa4082912d4c649628623db6aba77335e4f4569ff5083a6448b32e" dependencies = [ + "aws-lc-rs", "pem 3.0.6", "ring 0.17.14", "rustls-pki-types", @@ -3007,7 +3041,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.0", + "bitflags", ] [[package]] @@ -3085,15 +3119,15 @@ dependencies = [ [[package]] name = "rtnetlink" -version = "0.13.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a552eb82d19f38c3beed3f786bd23aa434ceb9ac43ab44419ca6d67a7e186c0" +checksum = "4b960d5d873a75b5be9761b1e73b146f52dddcd27bac75263f40fba686d4d7b5" dependencies = [ - "futures", + "futures-channel", + "futures-util", "log", "netlink-packet-core", "netlink-packet-route", - "netlink-packet-utils", "netlink-proto", "netlink-sys", "nix", @@ -3137,7 +3171,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.0", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -3245,9 +3279,8 @@ dependencies = [ [[package]] name = "sctp-proto" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "423139d8cca3021b9d800f084a711ba2d23b508ae71b33dba167f11ca33e54c7" +version = "0.7.0" +source = "git+https://github.com/ChainSafe/sctp-proto?rev=b8be59b4bef1ad55655255109533fa78c873fce4#b8be59b4bef1ad55655255109533fa78c873fce4" dependencies = [ "bytes", "crc", @@ -3258,13 +3291,25 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "zeroize", +] + [[package]] name = "security-framework" version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.11.0", + "bitflags", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -3371,16 +3416,6 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.10.7", - "sha1-asm", -] - -[[package]] -name = "sha1-asm" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "286acebaf8b67c1130aedffad26f594eff0c1292389158135327d2e23aed582b" -dependencies = [ - "cc", ] [[package]] @@ -3440,7 +3475,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df350943049174c4ae8ced56c604e28270258faec12a6a48637a7655287c9ce0" dependencies = [ - "bitflags 2.11.0", + "bitflags", ] [[package]] @@ -3548,24 +3583,45 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "str0m" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26890ff5b60e33eb8bedcf44792fc459c8f348ecbf2658edb19477571e547ac2" +version = "0.16.2" +source = "git+https://github.com/chainsafe/str0m?rev=0dd05fddf49c5d56b43538a749d3e2681fa9f699#0dd05fddf49c5d56b43538a749d3e2681fa9f699" dependencies = [ + "arrayvec", "combine", "crc", + "dimpl", "fastrand", - "hmac", - "libc", - "once_cell", - "openssl", - "openssl-sys", "sctp-proto", "serde", - "sha1", + "str0m-aws-lc-rs", + "str0m-proto", + "subtle", + "time", "tracing", ] +[[package]] +name = "str0m-aws-lc-rs" +version = "0.1.2" +source = "git+https://github.com/chainsafe/str0m?rev=0dd05fddf49c5d56b43538a749d3e2681fa9f699#0dd05fddf49c5d56b43538a749d3e2681fa9f699" +dependencies = [ + "aws-lc-rs", + "dimpl", + "str0m-proto", + "time", +] + +[[package]] +name = "str0m-proto" +version = "0.1.2" +source = "git+https://github.com/chainsafe/str0m?rev=0dd05fddf49c5d56b43538a749d3e2681fa9f699#0dd05fddf49c5d56b43538a749d3e2681fa9f699" +dependencies = [ + "base64ct", + "dimpl", + "subtle", + "time", +] + [[package]] name = "subtle" version = "2.6.1" @@ -3619,11 +3675,11 @@ dependencies = [ [[package]] name = "system-configuration" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags 2.11.0", + "bitflags", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -3651,7 +3707,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0" dependencies = [ "fastrand", - "getrandom 0.4.1", + "getrandom 0.4.2", "once_cell", "rustix", "windows-sys 0.61.2", @@ -3714,30 +3770,30 @@ dependencies = [ [[package]] name = "time" -version = "0.3.45" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", "num-conv", "powerfmt", - "serde_core", + "serde", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.7" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.25" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -3770,9 +3826,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.49.0" +version = "1.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" dependencies = [ "bytes", "libc", @@ -3786,9 +3842,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" dependencies = [ "proc-macro2", "quote", @@ -4118,7 +4174,7 @@ version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" dependencies = [ - "getrandom 0.4.1", + "getrandom 0.4.2", "js-sys", "wasm-bindgen", ] @@ -4250,7 +4306,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.11.0", + "bitflags", "hashbrown 0.15.5", "indexmap", "semver", @@ -4325,22 +4381,69 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.53.0" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efc5cf48f83140dcaab716eeaea345f9e93d0018fb81162753a3f76c3397b538" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections", + "windows-core", + "windows-future", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" dependencies = [ "windows-core", - "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.53.0" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dcc5b895a6377f1ab9fa55acedab1fd5ac0db66ad1e6c7f47e28a22e446a5dd" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", "windows-result", - "windows-targets 0.52.6", + "windows-strings", +] + +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core", + "windows-link", + "windows-threading", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] @@ -4349,13 +4452,32 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core", + "windows-link", +] + [[package]] name = "windows-result" -version = "0.1.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-targets 0.52.6", + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", ] [[package]] @@ -4457,6 +4579,15 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -4705,7 +4836,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.11.0", + "bitflags", "indexmap", "log", "serde", @@ -4764,6 +4895,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "x509-cert" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94" +dependencies = [ + "const-oid", + "der", + "spki", +] + [[package]] name = "x509-parser" version = "0.14.0" @@ -4806,6 +4948,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202" dependencies = [ "asn1-rs 0.7.1", + "aws-lc-rs", "data-encoding", "der-parser 10.0.0", "lazy_static", diff --git a/Cargo.toml b/Cargo.toml index eafabdcf5..4a3a13af0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,7 +66,7 @@ rcgen = { version = "0.14.5", optional = true } # End of Quic related dependencies. # WebRTC related dependencies. WebRTC is an experimental feature flag. The dependencies must be updated. -str0m = { version = "0.11.1", optional = true } +str0m = { git = "https://github.com/chainsafe/str0m", rev = "0dd05fddf49c5d56b43538a749d3e2681fa9f699", optional = true } # End of WebRTC related dependencies. # Fuzzing related dependencies. diff --git a/src/transport/webrtc/mod.rs b/src/transport/webrtc/mod.rs index d8363bf53..b0eee9381 100644 --- a/src/transport/webrtc/mod.rs +++ b/src/transport/webrtc/mod.rs @@ -38,10 +38,10 @@ use multiaddr::{multihash::Multihash, Multiaddr, Protocol}; use socket2::{Domain, Socket, Type}; use str0m::{ channel::{ChannelConfig, ChannelId}, - config::{CryptoProvider, DtlsCert, DtlsCertOptions}, + config::DtlsCert, ice::IceCreds, net::{DatagramRecv, Protocol as Str0mProtocol, Receive}, - Candidate, DtlsCertConfig, Input, Rtc, + Candidate, Input, Rtc, }; use tokio::{ @@ -225,9 +225,9 @@ impl WebRtcTransport { ) -> (Rtc, ChannelId) { let mut rtc = Rtc::builder() .set_ice_lite(true) - .set_dtls_cert_config(DtlsCertConfig::PregeneratedCert(self.dtls_cert.clone())) + .set_dtls_cert(self.dtls_cert.clone()) .set_fingerprint_verification(false) - .build(); + .build(std::time::Instant::now()); rtc.add_local_candidate(Candidate::host(destination, Str0mProtocol::Udp).unwrap()); rtc.add_remote_candidate(Candidate::host(source, Str0mProtocol::Udp).unwrap()); rtc.direct_api() @@ -481,10 +481,14 @@ impl TransportBuilder for WebRtcTransport { let socket = UdpSocket::from_std(socket.into())?; let listen_address = socket.local_addr()?; - let dtls_cert = DtlsCert::new(CryptoProvider::OpenSsl, DtlsCertOptions::default()); + let crypto_provider = str0m::crypto::from_feature_flags(); + let dtls_cert = crypto_provider + .dtls_provider + .generate_certificate() + .expect("DTLS certificate generation failed"); let listen_multi_addresses = { - let fingerprint = dtls_cert.fingerprint().bytes; + let fingerprint = dtls_cert.fingerprint(); const MULTIHASH_SHA256_CODE: u64 = 0x12; let certificate = Multihash::wrap(MULTIHASH_SHA256_CODE, &fingerprint) From e72cd9d1c9d2c3667ccd9fa38775218e3817c8fb Mon Sep 17 00:00:00 2001 From: Timothy Wu Date: Tue, 3 Mar 2026 13:28:38 -0500 Subject: [PATCH 06/10] request-response: Close substream before sending feedback on successful response --- src/protocol/request_response/mod.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/protocol/request_response/mod.rs b/src/protocol/request_response/mod.rs index d763fa640..536430f02 100644 --- a/src/protocol/request_response/mod.rs +++ b/src/protocol/request_response/mod.rs @@ -543,9 +543,12 @@ impl RequestResponseProtocol { ?request_id, "timed out while sending response", ), - Ok(Ok(_)) => feedback.take().map_or((), |feedback| { - let _ = feedback.send(()); - }), + Ok(Ok(_)) => { + let _ = substream.close().await; + if let Some(feedback) = feedback.take() { + let _ = feedback.send(()); + } + } Ok(Err(error)) => tracing::trace!( target: LOG_TARGET, ?peer, From ce6d2aea8c03457c7c4339f34d549a568799e845 Mon Sep 17 00:00:00 2001 From: Timothy Wu Date: Tue, 3 Mar 2026 14:30:29 -0500 Subject: [PATCH 07/10] webrtc: Return error when SCTP write buffer is full instead of silently dropping data --- src/transport/webrtc/connection.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/transport/webrtc/connection.rs b/src/transport/webrtc/connection.rs index d6d49947f..d63a4494c 100644 --- a/src/transport/webrtc/connection.rs +++ b/src/transport/webrtc/connection.rs @@ -774,12 +774,18 @@ impl WebRtcConnection { "send data", ); - self.rtc + let written = self + .rtc .channel(channel_id) .ok_or(Error::ChannelDoesntExist)? .write(true, WebRtcMessage::encode(data, flag).as_ref()) - .map_err(Error::WebRtc) - .map(|_| ()) + .map_err(Error::WebRtc)?; + + if !written { + return Err(Error::ChannelClogged); + } + + Ok(()) } /// Open outbound substream. From be4c14b79eaf2f1ba069d3a774fb5491714bd5e2 Mon Sep 17 00:00:00 2001 From: Timothy Wu Date: Tue, 20 Jan 2026 21:30:36 -0500 Subject: [PATCH 08/10] webrtc: Add network-level backpressure using str0m flow control --- src/transport/webrtc/connection.rs | 120 +++++++++++++++++----- src/transport/webrtc/substream.rs | 153 ++++++++++++++++++++++++++++- 2 files changed, 247 insertions(+), 26 deletions(-) diff --git a/src/transport/webrtc/connection.rs b/src/transport/webrtc/connection.rs index d63a4494c..6201a2814 100644 --- a/src/transport/webrtc/connection.rs +++ b/src/transport/webrtc/connection.rs @@ -59,6 +59,9 @@ use std::{ /// Logging target for the file. const LOG_TARGET: &str = "litep2p::webrtc::connection"; +/// Low water mark - resume writes when buffered_amount drops below this. +const BACKPRESSURE_LOW_THRESHOLD: usize = 16 * 1024; // 16 KB + /// Opening channel context. #[derive(Debug)] struct ChannelContext { @@ -281,11 +284,12 @@ impl WebRtcConnection { WebRtcDialerState::propose(context.protocol.clone(), fallback_names)?; let message = WebRtcMessage::encode(message, None); - self.rtc - .channel(channel_id) - .ok_or(Error::ChannelDoesntExist)? - .write(true, message.as_ref()) - .map_err(Error::WebRtc)?; + let mut channel = self.rtc.channel(channel_id).ok_or(Error::ChannelDoesntExist)?; + + // Set threshold for backpressure event + channel.set_buffered_amount_low_threshold(BACKPRESSURE_LOW_THRESHOLD); + + channel.write(true, message.as_ref()).map_err(Error::WebRtc)?; self.channels.insert( channel_id, @@ -393,9 +397,12 @@ impl WebRtcConnection { | ListenerSelectResult::PendingProtocol { message } => (message, None), }; - self.rtc - .channel(channel_id) - .ok_or(Error::ChannelDoesntExist)? + let mut channel = self.rtc.channel(channel_id).ok_or(Error::ChannelDoesntExist)?; + + // Set threshold for backpressure event + channel.set_buffered_amount_low_threshold(BACKPRESSURE_LOW_THRESHOLD); + + channel .write( true, WebRtcMessage::encode(response.to_vec(), None).as_ref(), @@ -759,12 +766,17 @@ impl WebRtcConnection { } /// Handle outbound data with optional flag. + /// + /// Returns `Ok(true)` if backpressure should be applied (buffer too full), + /// `Ok(false)` if write succeeded, or `Err` on failure. fn on_outbound_data( &mut self, channel_id: ChannelId, data: Vec, flag: Option, - ) -> crate::Result<()> { + ) -> crate::Result { + let mut channel = self.rtc.channel(channel_id).ok_or(Error::ChannelDoesntExist)?; + tracing::trace!( target: LOG_TARGET, peer = ?self.peer, @@ -774,18 +786,20 @@ impl WebRtcConnection { "send data", ); - let written = self - .rtc - .channel(channel_id) - .ok_or(Error::ChannelDoesntExist)? + let accepted = channel .write(true, WebRtcMessage::encode(data, flag).as_ref()) .map_err(Error::WebRtc)?; - if !written { - return Err(Error::ChannelClogged); + if !accepted { + tracing::trace!( + target: LOG_TARGET, + peer = ?self.peer, + ?channel_id, + "backpressure applied, str0m write buffer full", + ); } - Ok(()) + Ok(!accepted) } /// Open outbound substream. @@ -918,6 +932,54 @@ impl WebRtcConnection { continue; } + Event::ChannelBufferedAmountLow(channel_id) => { + tracing::trace!( + target: LOG_TARGET, + peer = ?self.peer, + ?channel_id, + "channel buffer low, clearing backpressure", + ); + + if let Some(handle) = self.handles.get_mut(&channel_id) { + // Clear backpressure flag and wake blocked writers + handle.set_backpressure(false); + + // Drain any pending message + if let Some(SubstreamEvent::Message { payload, flag }) = + handle.take_pending() + { + match self.on_outbound_data( + channel_id, + payload.clone(), + flag, + ) { + Ok(false) => {} // Drained successfully + Ok(true) => { + // Still can't write — re-queue and keep backpressure + if let Some(handle) = + self.handles.get_mut(&channel_id) + { + handle.set_backpressure(true); + handle.queue_pending( + SubstreamEvent::Message { payload, flag }, + ); + } + } + Err(error) => { + tracing::debug!( + target: LOG_TARGET, + peer = ?self.peer, + ?channel_id, + ?error, + "failed to drain pending write", + ); + } + } + } + } + + continue; + } event => { tracing::debug!( target: LOG_TARGET, @@ -976,14 +1038,24 @@ impl WebRtcConnection { self.handles.remove(&channel_id); } Some((channel_id, Some(SubstreamEvent::Message { payload, flag }))) => { - if let Err(error) = self.on_outbound_data(channel_id, payload, flag) { - tracing::debug!( - target: LOG_TARGET, - ?channel_id, - ?flag, - ?error, - "failed to send data to remote peer", - ); + match self.on_outbound_data(channel_id, payload.clone(), flag) { + Ok(false) => {} // Write succeeded + Ok(true) => { + // Backpressure - queue message and signal handle + if let Some(handle) = self.handles.get_mut(&channel_id) { + handle.set_backpressure(true); + handle.queue_pending(SubstreamEvent::Message { payload, flag }); + } + } + Err(error) => { + tracing::debug!( + target: LOG_TARGET, + ?channel_id, + ?flag, + ?error, + "failed to send data to remote peer", + ); + } } } Some((_, Some(SubstreamEvent::RecvClosed))) => {} diff --git a/src/transport/webrtc/substream.rs b/src/transport/webrtc/substream.rs index f3d173fa0..950da9f76 100644 --- a/src/transport/webrtc/substream.rs +++ b/src/transport/webrtc/substream.rs @@ -32,7 +32,7 @@ use tokio_util::sync::PollSender; use std::{ pin::Pin, sync::Arc, - task::{Context, Poll}, + task::{Context, Poll, Waker}, time::Duration, }; @@ -43,6 +43,15 @@ const MAX_FRAME_SIZE: usize = 16384; /// Matches go-libp2p's 5 second stream close timeout. const FIN_ACK_TIMEOUT: Duration = Duration::from_secs(5); +/// Shared state for network-level backpressure between Substream and SubstreamHandle. +#[derive(Default)] +struct BackpressureState { + /// True when str0m network buffer is above threshold. + active: bool, + /// Waker to trigger when backpressure clears. + waker: Option, +} + /// Substream event. #[derive(Debug, PartialEq, Eq)] pub enum Event { @@ -99,6 +108,9 @@ pub struct Substream { /// Timeout for waiting on FIN_ACK after sending FIN. /// Boxed to maintain Unpin for Substream while allowing the Sleep to be polled. fin_ack_timeout: Option>>, + + /// Shared state for network-level backpressure. + backpressure: Arc>, } impl Substream { @@ -109,6 +121,7 @@ impl Substream { let state = Arc::new(Mutex::new(State::Open)); let shutdown_waker = Arc::new(AtomicWaker::new()); let write_waker = Arc::new(AtomicWaker::new()); + let backpressure = Arc::new(Mutex::new(BackpressureState::default())); let handle = SubstreamHandle { inbound_tx, @@ -120,6 +133,8 @@ impl Substream { read_closed: std::sync::atomic::AtomicBool::new(false), fin_delivered: std::sync::atomic::AtomicBool::new(false), sent_reset: false, + backpressure: Arc::clone(&backpressure), + pending_write: None, }; ( @@ -131,6 +146,7 @@ impl Substream { shutdown_waker, write_waker, fin_ack_timeout: None, + backpressure, }, handle, ) @@ -168,6 +184,12 @@ pub struct SubstreamHandle { /// Whether we've already emitted a ResetStream in poll_next. sent_reset: bool, + + /// Shared state for network-level backpressure. + backpressure: Arc>, + + /// Pending message that couldn't be written due to backpressure. + pending_write: Option, } impl SubstreamHandle { @@ -288,13 +310,47 @@ impl SubstreamHandle { Ok(()) } + + /// Set backpressure state and wake blocked writers if clearing. + pub fn set_backpressure(&mut self, backpressured: bool) { + let mut state = self.backpressure.lock(); + let was_backpressured = state.active; + state.active = backpressured; + + // If clearing backpressure, wake any blocked writers + if was_backpressured && !backpressured { + if let Some(waker) = state.waker.take() { + waker.wake(); + } + } + } + + /// Store a message that couldn't be written due to backpressure. + pub fn queue_pending(&mut self, event: Event) { + self.pending_write = Some(event); + } + + /// Take any pending message for retry. + pub fn take_pending(&mut self) -> Option { + self.pending_write.take() + } } impl Stream for SubstreamHandle { type Item = Event; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - // First, try to drain any pending outbound messages + // Check backpressure before draining the queue to avoid overwriting + // the single pending_write slot when on_outbound_data returns Ok(true). + { + let mut state = self.backpressure.lock(); + if state.active { + state.waker = Some(cx.waker().clone()); + return Poll::Pending; + } + } + + // Try to drain any pending outbound messages match self.rx.poll_recv(cx) { Poll::Ready(Some(event)) => return Poll::Ready(Some(event)), Poll::Ready(None) => { @@ -387,6 +443,15 @@ impl tokio::io::AsyncWrite for Substream { State::Open => {} } + // Check network backpressure before internal channel check + { + let mut state = self.backpressure.lock(); + if state.active { + state.waker = Some(cx.waker().clone()); + return Poll::Pending; + } + } + match futures::ready!(self.tx.poll_reserve(cx)) { Ok(()) => {} Err(_) => return Poll::Ready(Err(std::io::ErrorKind::BrokenPipe.into())), @@ -1612,4 +1677,88 @@ mod tests { // 4. Stream terminates assert_eq!(handle.next().await, None); } + + #[tokio::test] + async fn network_backpressure_blocks_writes() { + let (mut substream, handle) = Substream::new(); + + // Simulate network backpressure by setting the flag + handle.backpressure.lock().active = true; + + // Write should return Pending + futures::future::poll_fn( + |cx| match Pin::new(&mut substream).poll_write(cx, &[0u8; 100]) { + Poll::Pending => Poll::Ready(()), + _ => panic!("expected Pending when backpressured"), + }, + ) + .await; + } + + #[tokio::test] + async fn network_backpressure_wake_on_clear() { + use tokio::time::{sleep, timeout, Duration}; + + let (mut substream, mut handle) = Substream::new(); + + // Set backpressure + handle.set_backpressure(true); + + // Spawn write that will block + let write_task = tokio::spawn(async move { + substream.write_all(&[1u8; 100]).await.unwrap(); + }); + + // Give writer time to block + sleep(Duration::from_millis(10)).await; + assert!( + !write_task.is_finished(), + "writer should be blocked by backpressure" + ); + + // Clear backpressure - should wake writer + handle.set_backpressure(false); + + // Writer should complete + timeout(Duration::from_secs(1), write_task) + .await + .expect("write should complete after backpressure cleared") + .expect("write task should not panic"); + + // Verify the message was sent + assert_eq!( + handle.next().await, + Some(Event::Message { + payload: vec![1u8; 100], + flag: None, + }) + ); + } + + #[tokio::test] + async fn pending_write_queue_and_take() { + let (_substream, mut handle) = Substream::new(); + + // Initially no pending write + assert!(handle.take_pending().is_none()); + + // Queue a pending write + handle.queue_pending(Event::Message { + payload: vec![1, 2, 3], + flag: None, + }); + + // Take the pending write + let pending = handle.take_pending(); + assert_eq!( + pending, + Some(Event::Message { + payload: vec![1, 2, 3], + flag: None, + }) + ); + + // Should be empty now + assert!(handle.take_pending().is_none()); + } } From 4cefe69403617e20ef5221e1a8aa258e50499b6d Mon Sep 17 00:00:00 2001 From: Timothy Wu Date: Wed, 4 Mar 2026 00:09:25 -0500 Subject: [PATCH 09/10] webrtc: Retry pending writes on Output::Transmit instead of per-channel event --- src/transport/webrtc/connection.rs | 109 ++++++++++++----------------- src/transport/webrtc/opening.rs | 1 + 2 files changed, 47 insertions(+), 63 deletions(-) diff --git a/src/transport/webrtc/connection.rs b/src/transport/webrtc/connection.rs index 6201a2814..ceedb0cd9 100644 --- a/src/transport/webrtc/connection.rs +++ b/src/transport/webrtc/connection.rs @@ -59,9 +59,6 @@ use std::{ /// Logging target for the file. const LOG_TARGET: &str = "litep2p::webrtc::connection"; -/// Low water mark - resume writes when buffered_amount drops below this. -const BACKPRESSURE_LOW_THRESHOLD: usize = 16 * 1024; // 16 KB - /// Opening channel context. #[derive(Debug)] struct ChannelContext { @@ -284,12 +281,11 @@ impl WebRtcConnection { WebRtcDialerState::propose(context.protocol.clone(), fallback_names)?; let message = WebRtcMessage::encode(message, None); - let mut channel = self.rtc.channel(channel_id).ok_or(Error::ChannelDoesntExist)?; - - // Set threshold for backpressure event - channel.set_buffered_amount_low_threshold(BACKPRESSURE_LOW_THRESHOLD); - - channel.write(true, message.as_ref()).map_err(Error::WebRtc)?; + self.rtc + .channel(channel_id) + .ok_or(Error::ChannelDoesntExist)? + .write(true, message.as_ref()) + .map_err(Error::WebRtc)?; self.channels.insert( channel_id, @@ -397,12 +393,9 @@ impl WebRtcConnection { | ListenerSelectResult::PendingProtocol { message } => (message, None), }; - let mut channel = self.rtc.channel(channel_id).ok_or(Error::ChannelDoesntExist)?; - - // Set threshold for backpressure event - channel.set_buffered_amount_low_threshold(BACKPRESSURE_LOW_THRESHOLD); - - channel + self.rtc + .channel(channel_id) + .ok_or(Error::ChannelDoesntExist)? .write( true, WebRtcMessage::encode(response.to_vec(), None).as_ref(), @@ -802,6 +795,42 @@ impl WebRtcConnection { Ok(!accepted) } + /// Retry pending writes on all backpressured channels. + /// + /// Called after `Output::Transmit` when data has left the global buffer, + /// giving previously rejected writes a chance to succeed. + fn retry_pending_writes(&mut self) { + let channel_ids: Vec<_> = self.handles.handles.keys().copied().collect(); + + for channel_id in channel_ids { + let pending = self.handles.get_mut(&channel_id).and_then(|h| h.take_pending()); + let Some(SubstreamEvent::Message { payload, flag }) = pending else { + continue; + }; + + match self.on_outbound_data(channel_id, payload.clone(), flag) { + Ok(false) => + if let Some(handle) = self.handles.get_mut(&channel_id) { + handle.set_backpressure(false); + }, + Ok(true) => + if let Some(handle) = self.handles.get_mut(&channel_id) { + handle.set_backpressure(true); + handle.queue_pending(SubstreamEvent::Message { payload, flag }); + }, + Err(error) => { + tracing::debug!( + target: LOG_TARGET, + peer = ?self.peer, + ?channel_id, + ?error, + "failed to retry pending write", + ); + } + } + } + } + /// Open outbound substream. fn on_open_substream( &mut self, @@ -882,6 +911,7 @@ impl WebRtcConnection { ); self.socket.try_send_to(&v.contents, v.destination).unwrap(); + self.retry_pending_writes(); continue; } Output::Event(v) => match v { @@ -932,54 +962,7 @@ impl WebRtcConnection { continue; } - Event::ChannelBufferedAmountLow(channel_id) => { - tracing::trace!( - target: LOG_TARGET, - peer = ?self.peer, - ?channel_id, - "channel buffer low, clearing backpressure", - ); - - if let Some(handle) = self.handles.get_mut(&channel_id) { - // Clear backpressure flag and wake blocked writers - handle.set_backpressure(false); - - // Drain any pending message - if let Some(SubstreamEvent::Message { payload, flag }) = - handle.take_pending() - { - match self.on_outbound_data( - channel_id, - payload.clone(), - flag, - ) { - Ok(false) => {} // Drained successfully - Ok(true) => { - // Still can't write — re-queue and keep backpressure - if let Some(handle) = - self.handles.get_mut(&channel_id) - { - handle.set_backpressure(true); - handle.queue_pending( - SubstreamEvent::Message { payload, flag }, - ); - } - } - Err(error) => { - tracing::debug!( - target: LOG_TARGET, - peer = ?self.peer, - ?channel_id, - ?error, - "failed to drain pending write", - ); - } - } - } - } - - continue; - } + Event::ChannelBufferedAmountLow(_) => continue, event => { tracing::debug!( target: LOG_TARGET, diff --git a/src/transport/webrtc/opening.rs b/src/transport/webrtc/opening.rs index 3afed15a3..43ee9062c 100644 --- a/src/transport/webrtc/opening.rs +++ b/src/transport/webrtc/opening.rs @@ -487,6 +487,7 @@ impl OpeningWebRtcConnection { return WebRtcEvent::ConnectionClosed; } }, + Event::ChannelBufferedAmountLow(_) => {} event => { tracing::warn!(target: LOG_TARGET, ?event, "unhandled event"); } From 3a074bbc49a39ba49ec02b73a61d366a0b8486a0 Mon Sep 17 00:00:00 2001 From: Timothy Wu Date: Mon, 16 Mar 2026 18:35:06 -0400 Subject: [PATCH 10/10] Update str0m to c1e24a5 (v0.17.0) with sctp-proto 0.9.0 --- Cargo.lock | 373 ++++++++++------------------- Cargo.toml | 2 +- src/transport/webrtc/connection.rs | 42 +++- 3 files changed, 172 insertions(+), 245 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ecdc171f..f84a46b0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,9 +66,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anyhow" @@ -97,7 +97,7 @@ dependencies = [ "asn1-rs-derive 0.4.0", "asn1-rs-impl 0.1.0", "displaydoc", - "nom", + "nom 7.1.3", "num-traits", "rusticata-macros", "thiserror 1.0.69", @@ -113,7 +113,7 @@ dependencies = [ "asn1-rs-derive 0.6.0", "asn1-rs-impl 0.2.0", "displaydoc", - "nom", + "nom 7.1.3", "num-traits", "rusticata-macros", "thiserror 2.0.18", @@ -216,9 +216,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.16.1" +version = "1.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bffc006df10ac2a68c83692d734a465f8ee6c5b384d8545a636f81d858f4bf" +checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc" dependencies = [ "aws-lc-sys", "untrusted 0.7.1", @@ -227,9 +227,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.38.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4321e568ed89bb5a7d291a7f37997c2c0df89809d7b6d12062c81ddb54aa782e" +checksum = "1fa7e52a4c5c547c741610a2c6f123f3881e409b714cd27e6798ef020c514f0a" dependencies = [ "cc", "cmake", @@ -273,9 +273,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.7.3" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bitflags" @@ -359,9 +359,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.56" +version = "1.2.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" dependencies = [ "find-msvc-tools", "jobserver", @@ -531,9 +531,9 @@ dependencies = [ [[package]] name = "crc" -version = "3.2.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" dependencies = [ "crc-catalog", ] @@ -672,7 +672,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ab67060fc6b8ef687992d439ca0fa36e7ed17e9a0b16b25b601e8757df720de" dependencies = [ "data-encoding", - "syn 1.0.109", + "syn 2.0.117", ] [[package]] @@ -696,7 +696,7 @@ checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" dependencies = [ "asn1-rs 0.5.2", "displaydoc", - "nom", + "nom 7.1.3", "num-bigint", "num-traits", "rusticata-macros", @@ -710,7 +710,7 @@ checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" dependencies = [ "asn1-rs 0.7.1", "displaydoc", - "nom", + "nom 7.1.3", "num-bigint", "num-traits", "rusticata-macros", @@ -729,9 +729,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ "powerfmt", ] @@ -758,15 +758,15 @@ dependencies = [ [[package]] name = "dimpl" -version = "0.3.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53382532e53576983721038702387751067de126c43c3150af8341962e85b456" +checksum = "5ffb781459bc33976be951aa31815deadcd74fb63781da5a4dc48f7001e567d3" dependencies = [ "arrayvec", "aws-lc-rs", "der", "log", - "nom", + "nom 8.0.0", "once_cell", "pkcs8", "rand 0.9.2", @@ -885,9 +885,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f" +checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" dependencies = [ "log", "regex", @@ -895,9 +895,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.9" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d" +checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" dependencies = [ "env_filter", "log", @@ -1494,14 +1494,15 @@ checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" [[package]] name = "ipconfig" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +checksum = "4d40460c0ce33d6ce4b0630ad68ff63d6661961c48b6dba35e5a4d81cfb48222" dependencies = [ - "socket2 0.5.10", + "socket2 0.6.3", "widestring", - "windows-sys 0.48.0", - "winreg", + "windows-registry", + "windows-result", + "windows-sys 0.61.2", ] [[package]] @@ -1510,6 +1511,18 @@ version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" +[[package]] +name = "is" +version = "0.7.0" +source = "git+https://github.com/algesten/str0m?rev=c1e24a5cf408426bd37f1a556dd2c40db679710a#c1e24a5cf408426bd37f1a556dd2c40db679710a" +dependencies = [ + "crc", + "serde", + "str0m-proto", + "subtle", + "tracing", +] + [[package]] name = "itertools" version = "0.14.0" @@ -1521,9 +1534,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jobserver" @@ -1568,9 +1581,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.182" +version = "0.2.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" [[package]] name = "libp2p" @@ -1954,9 +1967,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.24" +version = "1.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4735e9cbde5aac84a5ce588f6b23a90b9b0b528f6c5a8db8a4aff300463a0839" +checksum = "d52f4c29e2a68ac30c9087e1b772dc9f44a2b66ed44edf2266cf2be9b03dafc1" dependencies = [ "cc", "pkg-config", @@ -2036,7 +2049,7 @@ dependencies = [ "webpki", "x25519-dalek 2.0.1", "x509-parser 0.17.0", - "yamux 0.13.9", + "yamux 0.13.10", "yasna", "zeroize", ] @@ -2161,9 +2174,9 @@ dependencies = [ [[package]] name = "moka" -version = "0.12.14" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85f8024e1c8e71c778968af91d43700ce1d11b219d127d79fb2934153b82b42b" +checksum = "957228ad12042ee839f93c8f257b62b4c0ab5eaae1d4fa60de53b27c9d7c5046" dependencies = [ "crossbeam-channel", "crossbeam-epoch", @@ -2356,6 +2369,15 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -2377,9 +2399,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" [[package]] name = "num-integer" @@ -2419,9 +2441,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" dependencies = [ "critical-section", "portable-atomic", @@ -2762,7 +2784,7 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "itertools", "log", "multimap", @@ -2905,9 +2927,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.44" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -3162,7 +3184,7 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" dependencies = [ - "nom", + "nom 7.1.3", ] [[package]] @@ -3226,9 +3248,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" dependencies = [ "ring 0.17.14", "rustls-pki-types", @@ -3254,9 +3276,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] @@ -3279,8 +3301,9 @@ dependencies = [ [[package]] name = "sctp-proto" -version = "0.7.0" -source = "git+https://github.com/ChainSafe/sctp-proto?rev=b8be59b4bef1ad55655255109533fa78c873fce4#b8be59b4bef1ad55655255109533fa78c873fce4" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fa56c3ed91240d1659d269815d4e181f66c6f52bcfd60f89d3e7e3911aa6085" dependencies = [ "bytes", "crc", @@ -3529,12 +3552,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3583,14 +3606,15 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "str0m" -version = "0.16.2" -source = "git+https://github.com/chainsafe/str0m?rev=0dd05fddf49c5d56b43538a749d3e2681fa9f699#0dd05fddf49c5d56b43538a749d3e2681fa9f699" +version = "0.17.0" +source = "git+https://github.com/algesten/str0m?rev=c1e24a5cf408426bd37f1a556dd2c40db679710a#c1e24a5cf408426bd37f1a556dd2c40db679710a" dependencies = [ "arrayvec", + "base64ct", "combine", - "crc", "dimpl", "fastrand", + "is", "sctp-proto", "serde", "str0m-aws-lc-rs", @@ -3602,8 +3626,8 @@ dependencies = [ [[package]] name = "str0m-aws-lc-rs" -version = "0.1.2" -source = "git+https://github.com/chainsafe/str0m?rev=0dd05fddf49c5d56b43538a749d3e2681fa9f699#0dd05fddf49c5d56b43538a749d3e2681fa9f699" +version = "0.2.0" +source = "git+https://github.com/algesten/str0m?rev=c1e24a5cf408426bd37f1a556dd2c40db679710a#c1e24a5cf408426bd37f1a556dd2c40db679710a" dependencies = [ "aws-lc-rs", "dimpl", @@ -3613,11 +3637,13 @@ dependencies = [ [[package]] name = "str0m-proto" -version = "0.1.2" -source = "git+https://github.com/chainsafe/str0m?rev=0dd05fddf49c5d56b43538a749d3e2681fa9f699#0dd05fddf49c5d56b43538a749d3e2681fa9f699" +version = "0.3.0" +source = "git+https://github.com/algesten/str0m?rev=c1e24a5cf408426bd37f1a556dd2c40db679710a#c1e24a5cf408426bd37f1a556dd2c40db679710a" dependencies = [ "base64ct", "dimpl", + "fastrand", + "serde", "subtle", "time", ] @@ -3702,9 +3728,9 @@ checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" [[package]] name = "tempfile" -version = "3.26.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", "getrandom 0.4.2", @@ -3770,30 +3796,30 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", "num-conv", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", @@ -3811,9 +3837,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" dependencies = [ "tinyvec_macros", ] @@ -3835,7 +3861,7 @@ dependencies = [ "mio", "parking_lot", "pin-project-lite 0.2.17", - "socket2 0.6.2", + "socket2 0.6.3", "tokio-macros", "windows-sys 0.61.2", ] @@ -3957,9 +3983,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "matchers", "nu-ansi-term", @@ -4092,9 +4118,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "da36089a805484bcccfffe0739803392c8298778a2d2f09febf76fac5ad9025b" [[package]] name = "unicode-xid" @@ -4170,9 +4196,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.21.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" +checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" dependencies = [ "getrandom 0.4.2", "js-sys", @@ -4462,6 +4488,17 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] + [[package]] name = "windows-result" version = "0.4.1" @@ -4495,31 +4532,13 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", + "windows-targets", ] [[package]] @@ -4531,21 +4550,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - [[package]] name = "windows-targets" version = "0.52.6" @@ -4555,30 +4559,13 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", + "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - [[package]] name = "windows-threading" version = "0.2.1" @@ -4594,190 +4581,90 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - [[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "wit-bindgen" version = "0.51.0" @@ -4917,7 +4804,7 @@ dependencies = [ "data-encoding", "der-parser 8.2.0", "lazy_static", - "nom", + "nom 7.1.3", "oid-registry 0.6.1", "rusticata-macros", "thiserror 1.0.69", @@ -4934,7 +4821,7 @@ dependencies = [ "data-encoding", "der-parser 10.0.0", "lazy_static", - "nom", + "nom 7.1.3", "oid-registry 0.8.1", "rusticata-macros", "thiserror 2.0.18", @@ -4952,7 +4839,7 @@ dependencies = [ "data-encoding", "der-parser 10.0.0", "lazy_static", - "nom", + "nom 7.1.3", "oid-registry 0.8.1", "ring 0.17.14", "rusticata-macros", @@ -4976,9 +4863,9 @@ dependencies = [ [[package]] name = "yamux" -version = "0.13.9" +version = "0.13.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c650efd29044140aa63caaf80129996a9e2659a2ab7045a7e061807d02fc8549" +checksum = "1991f6690292030e31b0144d73f5e8368936c58e45e7068254f7138b23b00672" dependencies = [ "futures", "log", @@ -5024,18 +4911,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.40" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a789c6e490b576db9f7e6b6d661bcc9799f7c0ac8352f56ea20193b2681532e5" +checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.40" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f65c489a7071a749c849713807783f70672b28094011623e200cb86dcb835953" +checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 4a3a13af0..07395bd45 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,7 +66,7 @@ rcgen = { version = "0.14.5", optional = true } # End of Quic related dependencies. # WebRTC related dependencies. WebRTC is an experimental feature flag. The dependencies must be updated. -str0m = { git = "https://github.com/chainsafe/str0m", rev = "0dd05fddf49c5d56b43538a749d3e2681fa9f699", optional = true } +str0m = { git = "https://github.com/algesten/str0m", rev = "c1e24a5cf408426bd37f1a556dd2c40db679710a", optional = true } # End of WebRTC related dependencies. # Fuzzing related dependencies. diff --git a/src/transport/webrtc/connection.rs b/src/transport/webrtc/connection.rs index ceedb0cd9..659a22ac0 100644 --- a/src/transport/webrtc/connection.rs +++ b/src/transport/webrtc/connection.rs @@ -383,7 +383,47 @@ impl WebRtcConnection { "handle opening inbound substream", ); - let payload = WebRtcMessage::decode(&data)?.payload.ok_or(Error::InvalidData)?; + let rtc_message = WebRtcMessage::decode(&data)?; + + // During negotiation the remote may send protobuf messages that carry only a flag + // (e.g. FIN, RESET_STREAM) with no multistream-select payload, or an empty payload + // alongside a flag. Treat close-related flags as fatal and skip empty payloads so + // the channel stays open for the next protocol proposal. + match (&rtc_message.flag, &rtc_message.payload) { + (Some(Flag::ResetStream | Flag::StopSending), _) => { + tracing::debug!( + target: LOG_TARGET, + peer = ?self.peer, + ?channel_id, + flag = ?rtc_message.flag, + "remote sent close flag during inbound negotiation", + ); + return Err(Error::InvalidState); + } + (_, None) => { + tracing::trace!( + target: LOG_TARGET, + peer = ?self.peer, + ?channel_id, + flag = ?rtc_message.flag, + "ignoring empty payload during inbound negotiation, waiting for next message", + ); + return Ok(None); + } + (_, Some(p)) if p.is_empty() => { + tracing::trace!( + target: LOG_TARGET, + peer = ?self.peer, + ?channel_id, + flag = ?rtc_message.flag, + "ignoring empty payload during inbound negotiation, waiting for next message", + ); + return Ok(None); + } + _ => {} + } + + let payload = rtc_message.payload.expect("non-empty payload checked above"); let protocols = self.protocol_set.protocols_with_keep_alives(); let protocol_names = protocols.keys().cloned().collect(); let (response, negotiated) =