QUIC: fix DCID reassignment on connection ID rotation - #180
Merged
Merged
Conversation
josephnoir
requested review from
agnosticdev,
kkuk24,
rpaulo and
tfpauly
as code owners
September 28, 2026 17:27
rpaulo
approved these changes
Sep 28, 2026
kkuk24
approved these changes
Sep 28, 2026
- When the NEW_CONNECTION_ID frames for seq 1-3 are lost, only the in-use seq 0 is left when a frame with seq 4 and Retire Prior To 1 arrives. Retiring seq 0 leaves only the CID carried by that frame, so the current path must move to it instead of the connection closing - Fails until the following fix
- processNewConnectionIDFrame picked a replacement DCID while retiring CIDs below Retire Prior To, before the frame's own CID was added. With earlier NEW_CONNECTION_ID frames lost, the pool could be empty at that point, so assignNewDCID failed and the connection closed with INTERNAL_ERROR although the replacement was in the frame - Re-point after the insert. RFC 9000 Section 5.1.2 only requires retiring before adding the new CID to the set of active CIDs
josephnoir
force-pushed
the
use-cid-in-frame
branch
from
September 29, 2026 10:08
3030dba to
1eb4e08
Compare
agnosticdev
reviewed
Sep 29, 2026
| // Every caller builds its paths from inside `context.async`, so this runs on the context. | ||
| var path = QUICPath.makeFromExternalTest(parent: self.connection) | ||
| path.set(interface: nil, priority: 1, isInitial: true) // -> .routeEstablished | ||
| path.assignDCID(dcid) // -> .cidAssigned (open for sending) |
Collaborator
There was a problem hiding this comment.
So this will break cross module, right because it is referencing internal objects.
Collaborator
There was a problem hiding this comment.
This is just in tests, right?
Contributor
Author
There was a problem hiding this comment.
Yes. The library change only moves existing code around.
tfpauly
approved these changes
Sep 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I've observed connections closing with "unable to allocate a new DCID" in lossy scenarios and I think this is the issue:
The peer issues new CIDs but the packets carrying them are lost. Then a frame arrives that retires the currently held CIDs.
processNewConnectionIDFrametries to pick the replacement DCID before inserting the CID carried in the same frame. That triggers the failure path.Since the CID in the frame should be sufficient to continue we can insert the new CID first and then do the reassignment.