Conversation
Always on, no runtime switch: SPED (DTLS in STUN) via the WebRTC-IceHandshakeDtls field trial passed to configureFieldTrials before the factory is built, SNAP (SCTP INIT in SDP) via enableSctpSnap on the default configuration. Neither engages unless the server negotiates it. Supersedes #1128 and #1094. Co-Authored-By: cloudwebrtc <duanweiwei1982@gmail.com> Co-Authored-By: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
|
||
| // WARP SPED (DTLS in STUN); SNAP is on `LKRTCConfiguration.liveKitDefault()`. | ||
| // Both engage only when the server negotiates them. | ||
| LKRTCPeerConnectionFactory.configureFieldTrials("\(kLKRTCFieldTrialIceHandshakeDtlsKey)/\(kLKRTCFieldTrialEnabledValue)/") |
There was a problem hiding this comment.
🔴 Early data packets lost on WARP servers
On WARP servers, configureFieldTrials enables SPED, and data bursts immediately after connection lose messages. SCTP rejects early packets before ICE becomes writable; retransmission delays fill the server's downlink buffer.
Learn more
SPED carries the DTLS handshake in ICE, so DTLS can report connected before ICE is writable. On a WARP-enabled server, this allows the SFU to send SCTP traffic while the client's association still rejects packets with an invalid verification tag. Retransmission takes long enough for the SFU's subscriber downlink buffer to fill during the 100-packet burst in PublishDataTests. The reported runs lost messages with SPED enabled and passed with SNAP alone or WARP disabled.
Example: Two clients connect to a WARP-enabled server and one publishes 100 reliable packets immediately. The SFU forwards only part of the burst; the receiver never sees the rest, even though every publish call completed.
Recommended fix: Resolve the libwebrtc/Pion SPED readiness interop before enabling the field trial by default. Until then, leave SPED disabled while retaining SNAP, or gate SPED to configurations known to avoid early SCTP loss. Add an end-to-end burst test against a WARP-enabled server.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Blaze, what do you think about this devin's comment, as minimal, I'd think it is a corner cases and shouldn't blocking this PR.
There was a problem hiding this comment.
Unfortunately, based on my measurements the delay is real (>10s) and can hit important use cases like pre-connect audio buffer or initial RPC.
I'm trying to create some WebRTC patch (learn sth from this PR webrtc-sdk/webrtc#287)
|
Stability fixes should come after #1131 |
Enables WARP (draft-uberti-tsvwg-warp). This is the best of #1128 (@cloudwebrtc) and #1094 (@hiroshihorie) merged into one PR, and it supersedes both.
WebRTC-IceHandshakeDtlsfield trial, passed toLKRTCPeerConnectionFactory.configureFieldTrialsright before the factory is built. This avoids the deprecatedLKRTCInitFieldTrialDictionary.enableSctpSnap = trueinLKRTCConfiguration.liveKitDefault(). Every configuration, including thesetConfigurationcalls on quick reconnect and early-publisher adoption, is built from it. So this immutable field never changes after the peer connection exists, which was theINVALID_MODIFICATIONtrap in Add WARP support (DTLS handshake carried in the ICE exchange) #1128.WARP is always on, with no public API and no runtime switch, the same as rust-sdks#1342. The server decides whether WARP engages. A server without WARP ignores the offer and the connection falls back to the standard handshake.
SPED was turned off in #1015 on suspicion of #929. That crash turned out to be the ADM
fine_audio_buffer_null dereference, fixed in #1041.Testing
WARPTestschecks that the offer carries bothgoog-sped-v1anda=sctp-init:. Removing either leg makes it fail (verified).End to end, against local
livekit-server1.13.7 (the latest release; it ships thelivekit/ice v4.4.0-warp.2/dtls v3.1.5-warp.1/webrtc-pion v4.2.18-warp.1forks). The test connects two rooms and sends one reliable packet:rtc.enable_warp: trueDTLS-STUN piggyback complete with success=1, the SFU logsDone with the SPED handshakea=sctp-initin all four SDPs (client offer, SFU answer, SFU offer, client answer)To reproduce, add this to the server config:
rtc: { enable_warp: true }andlogging: { pion_level: debug }.Known issue: SPED plus a data burst right after connect
Against a WARP server,
PublishDataTests(100 concurrent publishes right after connect) loses messages when SPED is on. I ran each variant against the same server:libwebrtc marks DTLS connected but defers
set_writableuntil ICE is writable. The SFU finishes its DTLS side and starts sending SCTP in that gap, and the client's dcsctp rejects those packets (Packet has invalid verification tag: …, expected 00000000). SCTP recovers only after RTO backoff, about 2.5 s. Meanwhile the SFU's downlink buffer for that subscriber fills: it forwarded 83 of 98 messages, about 8 KB, and dropped the rest. The first data-channel packets in each direction are affected.This is interop timing between libwebrtc m150 and the pion WARP forks, not something this PR touches. Other SDKs that already ship SPED (Rust) should behave the same way. The data-stream and data-track suites showed the same symptom against a WARP server. CI's dev server doesn't enable WARP, so CI stays green either way.