Skip to content

fix(quic): suppress authenticated packet replays before recovery - #29

Merged
hatoo merged 1 commit into
masterfrom
codex/fix-quic-duplicate-recovery-20261012
Oct 12, 2026
Merged

hatoo merged 1 commit into
masterfrom
codex/fix-quic-duplicate-recovery-20261012

Conversation

@hatoo

@hatoo hatoo commented Oct 12, 2026 •

Copy link
Copy Markdown
Owner

An authenticated QUIC packet replay currently runs frame handlers again and clears pending PTO probes. This also happens after ACK-of-ACK pruning removes the packet's ACK range: the same PATH_CHALLENGE schedules another response and STREAM data queues another readable event.

Keep a separate receive history for each packet-number space and discard authenticated duplicates before key rotation, frame dispatch, and recovery resets, as required by RFC 9000 section 12.3. History retains up to 256 ranges with a monotone floor for evicted packets; in-order traffic uses one range. ACK pruning does not erase replay history. New packet-number retransmissions and unseen gaps above the floor remain eligible. Existing byte accounting and authenticated-packet idle handling remain intact.

Validation:

  • Four new protected-packet regressions fail on the previous implementation. Coverage includes all three number spaces, ACK-of-ACK, forged packets, old/current key phases, coalescing, sparse history eviction, new-number retransmission, and malformed new packets.
  • A 24,000-event independent set model checks bounded history, range merging, and eviction. A Quinn peer with immediate and delayed ciphertext replay completes exactly 512 responses with zero errors and 512 status entries and latency samples.
  • Debug, release, Rust 1.91, and musl each pass 476 unit tests and 62 integration tests (two existing ignored tests); formatting and Clippy with warnings denied pass.
  • Disposable instrumented builds count 8,256 frame dispatches before and zero after for 64 replays of 128 STREAM frames plus a challenge. New packet-number retransmissions still dispatch all 8,256 frames and preserve exact stream credit. These are work counts, not timing results.

This is a correctness repair with no end-to-end throughput claim. Receive history adds at most 4 KiB of range storage per number space; general QUIC recovery is not established by these focused tests.

Ordinary H3 guards used immutable standalone release binaries with matched compiler/profile/dependency fingerprints and a fixed hfast server. Three alternating pairs per workload completed 14,352,384 requests including warmups with zero errors. Median RPS changes were -0.311% (c1/p1) and -0.370% (c16/p64); all six pairs were adverse, with a worst pair of -3.279%. Small ordinary-path cost remains unresolved under known WSL measurement uncertainty. These results establish neither a speedup nor equivalence; no repeated noise controls or threshold relaxation were used.

@hatoo
hatoo enabled auto-merge (squash) October 12, 2026 10:48
@hatoo
hatoo merged commit f9809af into master Oct 12, 2026
4 checks passed
@hatoo
hatoo deleted the codex/fix-quic-duplicate-recovery-20261012 branch October 12, 2026 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant