Skip to content

Conversation

@LindonAliu
Copy link

Description

Closes: #5520

  • Clean up connection callback contexts on ShutdownComplete so handlers set via ConnectionRef are freed automatically (no leak).
  • Allow connection callbacks to return success when the context was already cleared (e.g., post-cleanup), avoiding panics.
  • Add a regression test that asserts the server-side ConnectionRef handler is dropped after shutdown.
    Testing

Testing

  • cargo test

Documentation

Is there any documentation impact for this change?

@LindonAliu LindonAliu requested a review from a team as a code owner November 21, 2025 23:00
@LindonAliu
Copy link
Author

@microsoft-github-policy-service agree

@codecov
Copy link

codecov bot commented Nov 22, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@b69aa08). Learn more about missing BASE report.
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #5618   +/-   ##
=======================================
  Coverage        ?   85.28%           
=======================================
  Files           ?       60           
  Lines           ?    18663           
  Branches        ?        0           
=======================================
  Hits            ?    15917           
  Misses          ?     2746           
  Partials        ?        0           

☔ View full report in Codecov by Sentry.
📢 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.

@LindonAliu LindonAliu requested a review from guhetier November 22, 2025 12:55
}
}
// Context already cleaned (e.g. after ShutdownComplete). Nothing to do.
None => StatusCode::QUIC_STATUS_SUCCESS.into(),
Copy link
Collaborator

@guhetier guhetier Nov 25, 2025

Choose a reason for hiding this comment

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

I don't think this scenario is possible assuming the logic is sound. ShutdownComplete is the last event delivered to an application by MsQuic (see QUIC_CONNECTION_EVENT.md), and the rust wrapper own the context so it should never be freed before ShutdownComplete.

We can expect it to be present, I think.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for the review! I found a case where the context can be None:
When Connection::drop() is called from outside the callback (e.g., after transferring ownership via a channel), close_inner() does:

  1. take_callback_ctx() → context becomes null
  2. ConnectionClose() → MsQuic triggers ShutdownComplete synchronously before returning
  3. The callback is invoked with a null context

This is demonstrated in the test where we drop(server_conn) from the main thread. Should we:

  1. Keep handling None to support both patterns (close from callback vs close from outside)?
  2. Or change close_inner() to drop the context after the handle is fully closed?

I lean towards option 2, dropping the context after ConnectionClose() returns would ensure the callback always has a valid context, and expect() would be safe. This also aligns better with your expectation that ShutdownComplete always has a context. What do you think?

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.

Unintended handle context leak in Rust

2 participants