node-datachannel back to 0.32.3 (libdatachannel 0.24.3 DTLS startup race); 0.6.2 - #171
Merged
Conversation
node-datachannel 0.33.x bundles libdatachannel 0.24.3, whose new early-ClientHello buffering (libdatachannel#1554) replays the message inside DtlsTransport::start(), where doRecv's unlocked BIO_write races the initial SSL_do_handshake. A ClientHello arrives early whenever the answerer's ICE connects before the offerer has applied the answer — routine with any signaling latency, and reproducible on loopback: 1-2% of connections fail with "Handshake failed: fatal I/O error" (3/150, 3/400, 1/500 in a two-peer loop; 0/600 on 0.32.3). It surfaced as the polyengine-impl unit suite failing one loopback test in ~1 of 14 runs. The lock fix (libdatachannel#1584) is in libdatachannel 0.24.4, which no node-datachannel release bundles yet. The README records the hold and the condition for lifting it. 0.6.2 replaces 0.6.1, which shipped the 0.33.2 pin.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Chasing the
polyengine-implunit-test flake (connectPairyielding an already-failedpeer, ~1 in 14 runs) found an upstream bug in what #170 shipped.Root cause: node-datachannel 0.33.x bundles libdatachannel 0.24.3. That release added buffering of a DTLS ClientHello that arrives before the peer has a DTLS transport (libdatachannel#1554) and replays it synchronously from
registerIncoming()— whichDtlsTransport::start()calls before its ownSSL_set_mtu/SSL_do_handshake. The replayed message reachesdoRecvon a pool thread, whoseBIO_writeis not undermSslMutex, and races the initial handshake:Handshake failed: fatal I/O error→ peer connectionfailed. The early ClientHello happens whenever the answerer's ICE connects before the offerer has applied the answer — i.e. with any signaling latency, and on loopback too.Evidence: two-peer loop on the raw polyfill with libdatachannel's logger: failures at 3/150, 3/400, 1/500 on 0.33.2; the Verbose trace shows
DtlsTransport::incoming size=232logged betweenRegistering incoming callbackandDTLS MTU set to 1232, then the fatal I/O error. 0/600 on 0.32.3 (libdatachannel 0.24.2, which drops the early ClientHello and lets the client retransmit).Upstream status: fixed by libdatachannel#1584 in libdatachannel 0.24.4 (2026-06-08) — same diagnosis, reproduced as intermittent Chrome↔libdatachannel failures on GitHub runners. No node-datachannel release bundles 0.24.4+ yet (0.33.2 and master pin 0.24.3). The README records the hold and its lifting condition.
Cost of reverting: loses libjuice 1.7.1 (in 0.24.3), notably the localhost >1000-datagrams-per-poll connection-kill fix — the likely cause of the much rarer pre-#170
channel-close-flushflake. A rare throughput kill beats a 1–2% handshake failure.0.6.2 replaces 0.6.1 (which shipped the 0.33.2 pin). Patch: API/protocol unchanged.
Gates:
just polyengine-check(13/13 ×4), 600-iteration connect loop clean,just conformance::run-polyengine37/37.Automerge armed.