Skip to content

fix(quic): validate ACK frequency and resize GRO buffers on rebind - #1

Merged
hawkingrei merged 3 commits into
mainfrom
fix/quic-ack-gro-boundaries
Nov 11, 2026
Merged

hawkingrei merged 3 commits into
mainfrom
fix/quic-ack-gro-boundaries

Conversation

@hawkingrei

@hawkingrei hawkingrei commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Follow up Google QUICHE's recent ACK Frequency validation and GRO work with two fixes in the vendored Quinn stack:

  • Reject ACK_FREQUENCY requested delays at or above 2^14 milliseconds and clamp generated requests below that exclusive limit. Invalid requests leave ACK-frequency state unchanged.
  • Reject ACK_FREQUENCY and IMMEDIATE_ACK frames in 0-RTT packets.
  • Grow endpoint receive buffers when a replacement socket supports larger GRO trains. Retain the largest allocation across rebinds so the previous socket can continue receiving complete trains.

Public API signatures, frame encoding, and the default ACK strategy remain unchanged.

Motivation and references

Previously, a peer could request an out-of-range ACK delay, and early-data packets could change ACK behavior before extension negotiation. Separately, replacing a single-segment socket with a 64-segment socket retained the original one-datagram receive capacity, risking GRO truncation.

Related issues: none.

Validation

Added regression coverage for the delay boundaries, legal 1-RTT versus illegal 0-RTT frames, and receive-capacity changes across socket replacements. The PR CI workflow passed all eight jobs for 1f514cc350fa9e37779f022df33320f5d383f0dd: native regression suites on Linux, macOS and Windows, feature profiles, MSRV, HTTP/3, Quinn/UDP, and package verification.

An independent executable using Endpoint::new_with_abstract_socket and rebind_abstract measured the buffers supplied to AsyncUdpSocket::poll_recv:

Scenario Before After
Initial socket, one segment 1472 bytes/slot 1472 bytes/slot
Rebind to 64 segments 1472 bytes/slot 94208 bytes/slot
Rebind again to two segments while the previous socket remains readable 1472 bytes/slot 94208 bytes/slot

These measurements establish receive capacity; they are not throughput or latency benchmarks. Larger buffers are allocated only when a replacement socket requires them and are retained until the endpoint is dropped.

Formatting and git diff --check completed. Regression suites were validated in CI.

@hawkingrei
hawkingrei merged commit 91d4fd1 into main Nov 11, 2026
16 checks passed
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