-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Don't bind to IPv6 when the OS doesn't support it #64734
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Alternatively we can also/instead just change
case IPEndPoint ip:
listenSocket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
// Kestrel expects IPv6Any to bind to both IPv6 and IPv4
- if (ip.Address.Equals(IPAddress.IPv6Any))
+ if (Socket.OSSupportsIPv6 && ip.Address.Equals(IPAddress.IPv6Any))
|
There was a problem hiding this comment.
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 the issue of Kestrel attempting to bind to IPv6 addresses on systems that don't support IPv6. The change proactively checks Socket.OSSupportsIPv6 before attempting to bind, avoiding unnecessary binding failures and the associated fallback mechanism.
Key Changes:
- Modified
AnyIPListenOptionsconstructor to check IPv6 support before choosing the IP address type - Added test coverage for non-IPv6 environments using
RemoteExecutor - Added
Microsoft.DotNet.RemoteExecutorpackage reference for testing
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/Servers/Kestrel/Core/src/AnyIPListenOptions.cs |
Updated constructor to check Socket.OSSupportsIPv6 and use IPAddress.Any when IPv6 is not supported, otherwise use IPAddress.IPv6Any |
src/Servers/Kestrel/Core/test/AddressBinderTests.cs |
Added new test ParseAddressOnOSWithoutIPv6 using RemoteExecutor to verify behavior on systems without IPv6 support |
src/Servers/Kestrel/Core/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests.csproj |
Added reference to Microsoft.DotNet.RemoteExecutor package for testing |
| [ConditionalFact] | ||
| [RemoteExecutionSupported] | ||
| public void ParseAddressOnOSWithoutIPv6() | ||
| { | ||
| var tmpDir = Directory.CreateTempSubdirectory(); | ||
|
|
||
| try | ||
| { | ||
| var options = new RemoteInvokeOptions(); | ||
| options.StartInfo.WorkingDirectory = tmpDir.FullName; | ||
| options.StartInfo.EnvironmentVariables["DOTNET_SYSTEM_NET_DISABLEIPV6"] = "1"; | ||
|
|
||
| using var remoteHandle = RemoteExecutor.Invoke(static () => | ||
| { | ||
| Assert.False(Socket.OSSupportsIPv6); | ||
|
|
||
| var listenOptions = AddressBinder.ParseAddress($"http://*:80", out var https); | ||
| Assert.IsType<AnyIPListenOptions>(listenOptions); | ||
| Assert.IsType<IPEndPoint>(listenOptions.EndPoint); | ||
| Assert.Equal(IPAddress.Any, listenOptions.IPEndPoint.Address); | ||
| Assert.Equal(80, listenOptions.IPEndPoint.Port); | ||
| Assert.False(https); | ||
| }, options); | ||
| } | ||
| finally | ||
| { | ||
| tmpDir.Delete(recursive: true); | ||
| } | ||
| } |
Copilot
AI
Dec 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding test cases that verify the fallback mechanism in BindAsync still works correctly when Socket.OSSupportsIPv6 is true but binding fails. The new logic prevents unnecessary attempts to bind to IPv6 when the OS doesn't support it, but the try-catch fallback in BindAsync should still be tested to ensure it handles cases where Socket.OSSupportsIPv6 reports true but binding still fails for other reasons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot What could be the other reasons ?

Contributes to dotnet/runtime#122435