msquic: Cannot connect via IPv4 when listener binds on IPv6
Describe the bug
Discovered when investigating https://github.com/dotnet/runtime/issues/67442.
For purposes of an HTTP3 servers, we want to listen to all connections from any IP, which makes the server listen on an IPv6 “AnyAddress” and configure the socket such that it also receives IPv4 traffic (via mapped IPs).
Debugging shows that while MsQuic receives UDP datagrams sent using IPv4 addresses, the datagram will not get matched to any existing listener and the connection will get immediately closed with a TLS alert corresponding to a failed ALPN negotiation.
Affected OS
- All
- Windows Server 2022
- Windows 11
- Windows Insider Preview (specify affected build below)
- Ubuntu
- Debian
- Other (specify below)
Additional OS information
Reproduced on Linux, haven’t tried reproducing on Windows.
MsQuic version
main
Steps taken to reproduce bug
- Create a server that listens on an “IPv6 Any” address or IPv6 loopback address
- Try to connect to the server using its IPv4 Address
The code I used to reproduce can be found at https://github.com/dotnet/runtime/tree/main/src/libraries/System.Net.Http/tests/StressTests/HttpStress, but the setup may be a bit complicated:
- Build the .NET runtime (e.g. by running
build.sh -s clr+libs+libs.tests -c Releasein the repo root) - either install MsQuic globally or put built binaries in
$repoRoot/artifacts/bin/testhost/net7.0-Linux-Release-x64/shared/Microsoft.NETCore.App/7.0.0/ - run
build-local.sh Release Releasefrom the directory above - run both sides of the application:
- server:
$repoRoot/artifacts/bin/testhost/net7.0-Linux-Release-x64/dotnet ./bin/Release/net7.0/HttpStress.dll -runMode server -http 3.0 -serverUri https://+:5001 - client:
$repoRoot/artifacts/bin/testhost/net7.0-Linux-Release-x64/dotnet ./bin/Release/net7.0/HttpStress.dll -runMode server -http 3.0 -serverUri https://127.0.0.1:5001
- server:
Expected behavior
Connection is established without problems
Actual outcome
Connection is closed by the server with a TLS alert 120 (failed ALPN negotiation)
Additional details
No response
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 24 (19 by maintainers)
This code swallows the Task Exceptions.
If you change it to:
On Linux this gives:
Did you verify this on Windows as well?
cc @maolson-msft would you mind weighing in here, at least in respect to Windows TCP behavior. How does Windows TCP handle dual-stack listeners?
But regardless, the current behavior is by design for MsQuic, and it would be a breaking change to modify it, which will not unless there is an extremely strong reason to do so. Matching a TCP behavior isn’t enough.