Skip to content

Fix TlsSessionTests TLS resume flakiness by using a unique SNI - #132749

Merged
rzikm merged 1 commit into
dotnet:mainfrom
rzikm:tlssession-resume-flake
Aug 25, 2026
Merged

rzikm merged 1 commit into
dotnet:mainfrom
rzikm:tlssession-resume-flake

Conversation

@rzikm

@rzikm rzikm commented Aug 25, 2026

Copy link
Copy Markdown
Member

Fixes #132111

Root cause

This is a test isolation bug, not a product bug.

ServerSession_TlsResume_HonorsAllowTlsResumeOption used the server certificate's name as the client TargetHost. On Linux the client-side OpenSSL session cache lives on a process-wide SSL_CTX, keyed only by (isClient, protocols, client certificate) (Interop.OpenSsl.cs), and that context holds a single session per SNI name (SafeSslContextHandle._sslSessions).

Test classes in this assembly run in parallel, and ~85 call sites use a non-unique TargetHost. So a concurrently running test could overwrite this test's cached ticket with one issued by its own server. The second handshake then offered a ticket that this test's server could not decrypt, so it fell back to a full handshake — and the ClientHello was larger than the first one because of the pre_shared_key extension, which is why the reported failure shows the second handshake exceeding the first.

Verification

I reproduced the failure deterministically with a temporary test that poisons the cache in exactly that way (a client with the same protocols and no client certificate connecting to a different server under the same SNI, in between the two measured handshakes). It reproduced the CI failure byte-for-byte:

Expected resumed handshake to be smaller. first=5513 second=5816

which is identical to the numbers reported in #132111. The temporary repro is not part of this change.

Fix

Use a unique SNI name per run, matching the existing precedent in SslStreamTlsResumeTests, which already does this for the same reason.

Testing

On Linux x64:

  • Baseline ./build.sh clr+libs -rc release — succeeded
  • ServerSession_TlsResume_HonorsAllowTlsResumeOption, all 4 cases — pass
  • Full System.Net.Security.Tests (5041 tests) — clean

Note

This pull request description was generated with the assistance of GitHub Copilot.

ServerSession_TlsResume_HonorsAllowTlsResumeOption used the server
certificate's name as the client TargetHost. The client-side OpenSSL
session cache lives on a process-wide SSL_CTX keyed only by protocols
and client certificate, and holds a single session per SNI name, so a
test running concurrently in the same assembly could overwrite the
cached ticket with one issued by its own server. The second handshake
then offered a ticket this server could not decrypt, falling back to a
full handshake with a larger ClientHello.

Use a unique SNI name per run, matching SslStreamTlsResumeTests.

Fixes dotnet#132111

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings August 25, 2026 14:14
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 4 pipeline(s).
12 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@rzikm
rzikm requested a review from a team August 25, 2026 14:16
@rzikm
rzikm enabled auto-merge (squash) August 25, 2026 14:16
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/ncl, @bartonjs, @vcsjones
See info in area-owners.md if you want to be subscribed.

Copilot AI 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.

Pull request overview

This PR addresses flakiness in System.Net.Security.Tests TLS session resumption testing by ensuring the client’s SNI (TargetHost) is unique per test invocation, reducing cross-test interference when tests run in parallel.

Changes:

  • Replace the previous TargetHost value (derived from the server certificate name) with a per-run unique value (Guid.NewGuid().ToString("N")).
  • Rename MeasureHandshakeBytesAsync parameter from serverName to targetHost and update call sites for clarity.

@rzikm
rzikm merged commit 519e88b into dotnet:main Aug 25, 2026
80 checks passed
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 12.0-preview1 milestone Aug 26, 2026
@ViveliDuCh

Copy link
Copy Markdown
Member

/backport to release/11.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/11.0 (link to workflow run)

ViveliDuCh pushed a commit that referenced this pull request Sep 22, 2026
…ique SNI (#134369)

Backport of #132749 to release/11.0

/cc @ViveliDuCh @rzikm

## Customer Impact

- [ ] Customer reported
- [ ] Found internally

[Select one or both of the boxes. Describe how this issue impacts
customers, citing the expected and actual behaviors and scope of the
issue. If customer-reported, provide the issue number.]

## Regression

- [ ] Yes
- [ ] No

[If yes, specify when the regression was introduced. Provide the PR or
commit if known.]

## Testing

[How was the fix verified? How was the issue missed previously? What
tests were added?]

## Risk

[High/Medium/Low. Justify the indication by mentioning how risks were
measured and addressed.]

**IMPORTANT**: If this backport is for a servicing release, please
verify that:

- For .NET 8 and .NET 9: The PR target branch is `release/X.0-staging`,
not `release/X.0`.
- For .NET 10+: The PR target branch is `release/X.0` (no `-staging`
suffix).

## Package authoring no longer needed in .NET 9

**IMPORTANT**: Starting with .NET 9, you no longer need to edit a NuGet
package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older
versions.

Co-authored-by: Radek Zikmund <32671551+rzikm@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

System.Net.Security.Tests.TlsSessionTests ServerSession_TlsResume_HonorsAllowTlsResumeOption Failed

4 participants