h3: advertise and accept RFC-track SETTINGS_WT_MAX_SESSIONS (0xc671706a) - #363
Open
dgarnier wants to merge 1 commit into
Open
h3: advertise and accept RFC-track SETTINGS_WT_MAX_SESSIONS (0xc671706a)#363dgarnier wants to merge 1 commit into
dgarnier wants to merge 1 commit into
Conversation
WebKit-based browsers (Safari 26) negotiate WebTransport only via the RFC-track codepoint (draft-ietf-webtrans-http3, draft-07+) and cancel their extended CONNECTs when the server's SETTINGS carry just the legacy draft-02 pair (0x2b603742/0x2b603743). Chrome accepts either dialect. Send both dialects, and treat an incoming WT_MAX_SESSIONS > 0 as WebTransport support when parsing peer settings — the peer-side half matters because WebTransportSession::accept rejects sessions when the client's settings lack WebTransport support, and WebKit clients send only the RFC-track codepoint. Verified against Safari 26.6.2 (macOS, trusted local cert): session establishes, bidirectional streams round-trip, and Chrome remains green with both dialects advertised. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Problem
Safari cannot establish WebTransport sessions against h3-webtransport servers. Its extended CONNECTs arrive and are then cancelled by the browser itself (
H3_REQUEST_CANCELLED), while Chrome succeeds against the same server.The cause is settings-dialect negotiation. h3 currently advertises and recognizes only the legacy draft-02 experiment codepoints:
SETTINGS_ENABLE_WEBTRANSPORT = 0x2b603742WEBTRANSPORT_MAX_SESSIONS = 0x2b603743The RFC-track spec (draft-ietf-webtrans-http3, draft-07 and later) negotiates via a different codepoint,
SETTINGS_WT_MAX_SESSIONS = 0xc671706a, and deprecates the legacy pair. WebKit implements only the RFC-track dialect: when the server's SETTINGS lack0xc671706a, Safari concludes the server does not support WebTransport and abandons the CONNECT. Chrome still accepts either dialect for compatibility.Change
17 insertions across
h3/src/proto/frame.rsandh3/src/config.rs:SettingId::WT_MAX_SESSIONS = 0xc671706aand mark it supported.max_webtransport_sessions) alongside the legacy pair, so both dialects are advertised.WT_MAX_SESSIONS > 0as WebTransport support, and prefer its value formax_webtransport_sessions. The parse side matters independently of the send side:WebTransportSession::acceptrejects sessions when the client's settings lack WebTransport support, and WebKit clients send only the RFC-track codepoint.Not included: the capsule-protocol session close/drain semantics from the later drafts. This change is only the settings negotiation — the minimal fix that unblocks WebKit interop. In testing, Safari's
close()still tears the session down cleanly at the QUIC layer.Related but out of scope: #355 (the
max_webtransport_sessionsvalue is advertised but not enforced at runtime). This PR changes which codepoint the value is negotiated under, not its enforcement — the value remains declarative-only under both dialects, exactly as before.Verification
WebTransport.close()tears down cleanly. Same server, certificate, and page either side of the patch — the settings are the only variable.cargo test -p h3 --libpasses (230 tests),cargo fmt --checkclean.wtransport-based interop client, i.e. an independent implementation that itself sends both dialects — passes against the patched crates.Attribution
This investigation and patch were done together with Claude Code (Claude Fable 5): it isolated the failure to settings negotiation by A/B-testing Safari against draft-02-only and dual-dialect servers, wrote the patch, and verified it in a real browser. The commit carries a
Co-Authored-Bytrailer accordingly. A human (me) reviewed and takes responsibility for the change.