657306392d
Five spec-compliance fixes from the 2026-05-09 audit, all in the same
"hostile-peer hardening" tier.
* RFC 9000 §18.2 — `applyPeerTransportParameters` now closes the
connection with TRANSPORT_PARAMETER_ERROR when the peer advertises
`max_udp_payload_size < 1200`, `ack_delay_exponent > 20`, or
`active_connection_id_limit < 2`. Pre-fix the values were decoded
but never bounds-checked.
* RFC 9000 §13.2.5 — the parser's ACK-delay decoding now uses the
PEER's advertised `ack_delay_exponent` (with the §18.2 default of 3
as the pre-handshake fallback) instead of our own config value.
Defensive coercion to 0..20 is preserved so a bypass of the bounds
check above can't desync the RTT estimator.
* RFC 9114 §7.2.4.1 — `Http3Settings.decodeBody` now rejects the
HTTP/2-reserved SETTINGS ids 0x02, 0x03, 0x04, 0x05 with
H3_SETTINGS_ERROR. Pre-fix they fell through to the generic
1<<32 cap and were accepted.
* RFC 9221 §3 — the writer now drops outbound DATAGRAM frames when
the peer didn't advertise `max_datagram_frame_size` (or advertised
0), or when the encoded frame (type byte + length varint + payload)
would exceed the peer's advertised value. Pre-fix the writer
emitted DATAGRAM regardless and let spec-conformant peers close us
with PROTOCOL_VIOLATION.
* Added `TransportParameterDefaults` for the §18.2 defaults
(ack_delay_exponent=3, max_ack_delay=25ms, active_connection_id_limit=2)
so callers don't hard-code the magic numbers.
Tests: `TransportParameterBoundsTest` (8 cases) drives a real handshake
through the in-process pipe and asserts CLOSED on each violation +
CONNECTED at the boundary; `Http3ReservedSettingsTest` (5 cases) covers
the four reserved ids and the adjacent legal ids. Plan tier dropped
from 🟡 Medium to resolved for all five items.
https://claude.ai/code/session_01XGmmaVuy2wsSZQx2AqN2ik