Skip to content

Discard client Initial keys when Handshake write keys are installed#6047

Open
guhetier wants to merge 2 commits into
mainfrom
guhetier/fix-5998-handshake-stall_copilot
Open

Discard client Initial keys when Handshake write keys are installed#6047
guhetier wants to merge 2 commits into
mainfrom
guhetier/fix-5998-handshake-stall_copilot

Conversation

@guhetier

@guhetier guhetier commented May 28, 2026

Copy link
Copy Markdown
Collaborator

Description

Fixes #5998.

After a previous fix moving the initial key discard to the packet builder (instead of discarding them only when sending a crypto frame), it was still possible for handshake packets to be blocked by CC because:

  • the CC quota freed by discarding the keys is not available by the packet builder during the current send flush
  • another send flush was never scheduled because a send flush was already in progress when the CC quota was made available

This is fixed by scheduling a new send flush if there still are things to send after discarding the keys.

Testing

Covered by Handshake/WithHandshakeArgs4.RandomLoss*. Locally validated:

  • All 24 Handshake/WithHandshakeArgs4.RandomLoss/* variants pass over 100 iterations on a local device
  • spinquic both -timeout:20000 -repeat_count:1 exits cleanly.

Documentation

No documentation impact.

@codecov

codecov Bot commented May 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.71%. Comparing base (ada1bbf) to head (881a2c8).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6047      +/-   ##
==========================================
- Coverage   85.96%   85.71%   -0.25%     
==========================================
  Files          60       60              
  Lines       18847    18850       +3     
==========================================
- Hits        16202    16158      -44     
- Misses       2645     2692      +47     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@guhetier guhetier marked this pull request as ready for review June 5, 2026 19:00
@guhetier guhetier requested a review from a team as a code owner June 5, 2026 19:00
@mtfriesen mtfriesen requested a review from Copilot June 10, 2026 17:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR updates MsQuic’s client key lifecycle handling to align with RFC 9001 §4.9.1 by deferring the discard of Initial keys until after a Handshake packet has been sent, aiming to avoid mutating congestion-control state while QuicSendFlush’s packet builder is mid-loop.

Changes:

  • Adds a HandshakePacketSent bit to QUIC_PACKET_BUILDER to record that a Handshake-level packet was finalized/committed for sending.
  • Sets HandshakePacketSent during QuicPacketBuilderFinalize when finalizing a Handshake-level packet.
  • Moves the client Initial-key discard from QuicPacketBuilderPrepare to the end of QuicSendFlush (after QuicPacketBuilderCleanup).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/core/send.c Defers client Initial key discard to the end of QuicSendFlush based on a builder “Handshake packet happened” bit.
src/core/packet_builder.h Adds HandshakePacketSent to QUIC_PACKET_BUILDER.
src/core/packet_builder.c Removes inline Initial-key discard from Prepare; sets HandshakePacketSent from Finalize.

Comment thread src/core/send.c Outdated
Comment thread src/core/packet_builder.h
Comment thread src/core/packet_builder.c Outdated
@mtfriesen

Copy link
Copy Markdown
Contributor

This looked familiar - it seems to be churning code very similar to #5994.

I admit I haven't looked through the logic particularly closely yet, but what can we do to make sure the test gap is reliably closed?

@guhetier

Copy link
Copy Markdown
Collaborator Author

This looked familiar - it seems to be churning code very similar to #5994.

I admit I haven't looked through the logic particularly closely yet, but what can we do to make sure the test gap is reliably closed?

It is, the first case addressed one corner case but left a second corner.
The random loss test hit this in the CI from time to time, but I don't have a local repro (even over multiple runs). The scenario is pretty loss and timing dependent.

Actually, sending this back to draft, I realized I am not addressing one path correctly yet.

@guhetier guhetier marked this pull request as draft June 10, 2026 23:34
@guhetier guhetier force-pushed the guhetier/fix-5998-handshake-stall_copilot branch from 227061d to a8aad04 Compare June 16, 2026 16:58
When a client discards Initial keys mid-flush (per RFC 9001 s4.9.1),
the implicit ACK of Initial bytes frees congestion control capacity.
However, Builder.SendAllowance was snapshot'd at the start of the flush
and is now stale. Without re-flushing, Handshake CRYPTO frames may not
be sent because the loop thinks it is CC-blocked.

Add an InitialKeysDiscarded flag to the packet builder, set only when
QuicCryptoDiscardKeys actually discards (returns TRUE). When set, treat
the flush result as QUIC_SEND_INCOMPLETE so the operation is re-queued
and the next flush recomputes SendAllowance with the freed capacity.

Fixes #5998.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@guhetier guhetier force-pushed the guhetier/fix-5998-handshake-stall_copilot branch from a8aad04 to c14a600 Compare June 17, 2026 19:11
@guhetier guhetier requested a review from Copilot June 19, 2026 21:16

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

Comment thread src/core/packet_builder.c
Comment thread src/core/send.c Outdated
Comment thread src/core/packet_builder.c
@guhetier guhetier marked this pull request as ready for review June 19, 2026 21:51
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.

[CI - FAILURE]: / Handshake_WithHandshakeArgs4.RandomLoss_5 (msquictest.exe)

3 participants