fix(s2n-quic-transport): treat clean connection close as dc complete - #3193
Open
boquan-fang wants to merge 3 commits into
Open
fix(s2n-quic-transport): treat clean connection close as dc complete#3193boquan-fang wants to merge 3 commits into
boquan-fang wants to merge 3 commits into
Conversation
boquan-fang
force-pushed
the
boquan-fang/stateless-fix-use-close-pr
branch
from
August 13, 2026 23:47
f5968a1 to
32eb154
Compare
boquan-fang
force-pushed
the
boquan-fang/stateless-fix-use-close-pr
branch
from
August 13, 2026 23:54
32eb154 to
978a025
Compare
* introducing two distinct error codes * add a note for backward compatibility * intercept the error with human readable messages
boquan-fang
force-pushed
the
boquan-fang/stateless-fix-use-close-pr
branch
from
August 14, 2026 21:42
f626eec to
ab9384e
Compare
boquan-fang
marked this pull request as ready for review
August 14, 2026 21:43
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.
Release Summary:
Fix a bug that server never receives its ACK and therefore not moving to the dc complete state.
Resolved issues:
resolves #3055.
Description of changes:
Currently, the server must receive the ACK of the
DC_STATELESS_RESET_TOKENin order for it to move on to dc complete:s2n-quic/quic/s2n-quic-transport/src/dc/manager.rs
Lines 206 to 220 in 1c11f00
However, as specified by #3055, under heavy packet losses or packet reordering, the connection might already be closed before the ACK is received by the server. Hence, the server remains at
ServerTokensSentstate instead ofCompletestate.The fix that this PR proposed is to treat a clean
CONNECTION_CLOSEas the proof that server can move on to dc complete state.Analysis of such fix:
The assumption of receiving a clean
CONNECTION_CLOSEis based on how the client finishes the handshake andConfirmComplete. For the client, it will only reaches dc state complete once theDC_STATELESS_RESET_TOKENis received:s2n-quic/quic/s2n-quic-transport/src/dc/manager.rs
Lines 196 to 203 in 1c11f00
The client would close the connection only once
ConfirmComplete::wait_readyfinished running.Therefore, on the happy path, the server can conclude that receiving a clean CONNECTION_CLOSE frame from the client means the server's token was received by the client.
Changes we have to make for the soundness of the assumption
There is a situation where the client sends a clean CONNECTION_CLOSE without actually receiving the token. According to the io's handshake function
s2n-quic/dc/s2n-quic-dc/src/psk/io.rs
Lines 529 to 546 in 1c11f00
The client's
ConfirmComplete::wait_readymight timeout or errors, but the handshake function would still cleanly close the connection, because theDropimpl forConnectionis set to always close the connection with no errors:s2n-quic/quic/s2n-quic-transport/src/connection/api.rs
Lines 86 to 103 in 1c11f00
Hence, on this error path, our assumption that receiving a clean CONNECTION_CLOSE means the client has received the token is wrong.
However, that behavior sounds wrong: if the client determines the handshake failed as specified by the comments, it should explicitly close the connection with an error code instead of closing the connection with no error code. This PR changes that behavior: the client should explicitly call
.close(error_code)if it determines the handshake wasn't successful.Call-outs:
DC_HANDSHAKE_INCOMPLETE_ERROR
I set up a DC_HANDSHAKE_INCOMPLETE_ERROR code for the connection closure while handshake failed. I don't think there is a proper error code in s2n-quic can be reused for our usecase.
Test structure
Since I need to configure the server and client in a certain way: specifically need to add a packet interceptor for test purposes, I can not reuse the test helper functions like
self_test_inner. I add another test helper functiondc_completes_through_closeto perform the test for this PR.Also, I basically drop all standalone ACKs for the server, so MTU probing can't be performed. I pinned all MTU settings to be the same value to avoid probing.
Testing:
I add two integration tests:
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.