Files
amethyst/quic
Claude 0ced269b27 feat(quic): step 3 of RFC 9002 retransmit — drain SentPacket on ACK
QuicConnectionParser's AckFrame handler now drains
state.sentPackets of every entry whose packet number is covered by
the ACK's ranges. The drained SentPackets are returned but
discarded for now; step 5 will route them to loss detection / RTT.

New helper file `connection/recovery/AckedPackets.kt`:

  - forEachAckedPacketNumber(ack, block): inline iterator over an
    AckFrame's ranges in RFC 9000 §19.3.1 order. Walks first range
    [largestAcked - firstAckRange, largestAcked] then each
    additional range with `nextLargest = previousSmallest - gap - 2`,
    `nextSmallest = nextLargest - ackRangeLength`. Defensive clamp
    at PN 0 against malformed peer ACKs.
  - drainAckedSentPackets(sentPackets, ack): walks via
    forEachAckedPacketNumber and removes each matching entry from
    the map. Returns the drained list.

Wired into QuicConnectionParser.kt:165 alongside the existing
ackTracker.purgeBelow call.

Tests added (9, all pass):
  - simpleRange / multipleRanges / singlePacketAck: range walking
    for typical ACK shapes
  - ackForUnsentPn_isNoOp / emptyMap_returnsEmptyDrain: defensive
    paths
  - ackBoundary_pn0Inclusive: PN 0 is correctly included, no
    underflow
  - forEachAckedPacketNumber_iteratesDescending /
    forEachAckedPacketNumber_acrossMultipleRanges_descending:
    iterator semantics
  - returnedDrain_preservesTokens: drained SentPacket retains its
    full tokens list — step 5+ will dispatch these to RTT / loss

Mirror of neqo's `recovery/mod.rs::remove_acked` (one of the 20
recovery tests we owe per
`quic/plans/2026-05-04-control-frame-retransmit.md`). The remaining
loss-detection tests land in step 5.

Full :quic test suite + nestsClient moq-lite tests pass.

https://claude.ai/code/session_01PYYez8a6sjiakyjAxsfCEQ
2026-05-04 22:45:10 +00:00
..