Files
amethyst/quic
Claude 86b6c609a6 fix(quic): emit PING at Initial/Handshake on PTO pre-handshake (RFC 9002 §6.2.4)
The aioquic interop run revealed bug #3 (after the close-padding and
close-frame-type fixes): when PTO fires before the handshake completes,
the driver sets `pendingPing = true` but the writer only consumed that
flag in the 1-RTT path. Pre-handshake the flag was silently discarded,
so the second drain produced no Initial datagram — the connection sat
mute through every subsequent PTO. Symptom on the wire: exactly one
Initial packet (the close at PN=1, after our internal handshake
timeout), zero retransmits across the full 10-second budget, no chance
for the peer to recover from a dropped first ClientHello.

Fix routes pendingPing through to whatever encryption level is the
highest currently active — preferring 1-RTT, falling through Handshake,
finally Initial. Adds a regression test that drains a fresh connection
with `pendingPing = true` and verifies an Initial-level padded probe
datagram comes out (vs. null pre-fix).

Test relaxes the size assertion to ≥ 1199 due to a separate pre-existing
off-by-one in the writer's padding deficit calculation when the natural
payload uses a 1-byte Length varint that grows to 2 after padding —
that's a follow-up; the regression we care about here is "no probe at
all," not the byte-precise padding edge.

Outstanding from this run:
  - Strict ≥ 1200 padding for tiny payloads (PING-only Initial = 1199)
  - PTO should retransmit unacked CRYPTO bytes, not just emit a PING
    (current PING gets ACK + relies on packet-number-threshold loss
    detection to trigger CRYPTO retransmit; works but suboptimal)

https://claude.ai/code/session_01HcvfQq1ttPV9PkRoJb4nyT
2026-05-06 22:50:02 +00:00
..