Skip to content

QUIC: cap queued RETIRE_CONNECTION_ID frames - #218

Open
deadcaf3 wants to merge 2 commits into
apple:mainfrom
deadcaf3:fix-cap-retire-connid-frames
Open

deadcaf3 wants to merge 2 commits into
apple:mainfrom
deadcaf3:fix-cap-retire-connid-frames

Conversation

@deadcaf3

@deadcaf3 deadcaf3 commented Oct 4, 2026 •

Copy link
Copy Markdown

Problem

processNewConnectionIDFrame queues a RETIRE_CONNECTION_ID frame for every connection ID it retires, and nothing bounds that queue. RFC 9000 §5.1.2 says an endpoint SHOULD limit it and MAY close with CONNECTION_ID_LIMIT_ERROR when the limit is exceeded.

Fix

  • Close with CONNECTION_ID_LIMIT_ERROR when a NEW_CONNECTION_ID frame arrives while at least twice the active connection ID limit of RETIRE_CONNECTION_ID frames are queued (128 with the current limit of 64). Twice the limit is the minimum the RFC asks an endpoint to allow.
  • One guard, placed ahead of both sites that queue a retire frame.
  • Counts unsent frames only, which is more lenient than the RFC's "not yet acknowledged".

Testing

  • New testRetireConnectionIDQueueIsCapped in ConnectionIDRotationTests.
  • Full test suite passes locally on macOS.

// Every frame that gets this far can queue RETIRE_CONNECTION_ID frames
// below, and those only leave the queue once they are sent.
let queuedRetireCount = withPendingItemsForKeyState { $0.retireConnectionIDs.count }
if queuedRetireCount > 2 * remoteCIDs.activeConnectionIDLimit {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can just do >=

@deadcaf3 deadcaf3 Oct 5, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switched to >= in 4e7cd90

- Close with CONNECTION_ID_LIMIT_ERROR in `processNewConnectionIDFrame`
  once twice the active connection ID limit of RETIRE_CONNECTION_ID
  frames are queued, as RFC 9000 section 5.1.2 allows
- Add a test covering the cap
@deadcaf3
deadcaf3 force-pushed the fix-cap-retire-connid-frames branch from 6f86e72 to 4e7cd90 Compare October 5, 2026 18:23
@rpaulo rpaulo added the 🔨 semver/patch No public API change. label Oct 6, 2026
@rpaulo
rpaulo self-requested a review October 6, 2026 21:10

@rpaulo rpaulo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our internal review process flagged two issues:

  • if the frame doesn't retire any CID but the queue is at 128, we will close the connection incorrectly
  • if the queue is at 127, we can still overshoot when the frame being processed retires many CIDs.

- Close with CONNECTION_ID_LIMIT_ERROR only when the frame being
  processed would take the RETIRE_CONNECTION_ID queue past twice the
  active connection ID limit, so the queue cannot overshoot the limit
- Accept a frame that retires nothing even with the queue at the limit
- Add tests covering both cases
@deadcaf3

deadcaf3 commented Oct 6, 2026

Copy link
Copy Markdown
Author

Fixed both in baee899: the guard now counts what the frame would queue before queueing it, and closes only if queued + new > 2 x active_connection_id_limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 semver/patch No public API change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants