Skip to content
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

Support Http3 in scenarios where ipv6 has been disabled at the runtime level #113100

Open
mastahg opened this issue Mar 3, 2025 · 14 comments
Open
Labels
area-System.Net.Quic enhancement Product code improvement that does NOT require public API changes/additions
Milestone

Comments

@mastahg
Copy link

mastahg commented Mar 3, 2025

Description

Currently if you attempt to disable ipv6 via System.Net.DisableIPv6 and initiate a Http3 connection it will fail because Socket.OSSupportsIPv6 will return false.

Reproduction Steps

Disable ipv6 via System.Net.DisableIPv6
Create a http3 client with

HttpClient Client = new HttpClient()
        {
            DefaultRequestVersion = HttpVersion.Version30,
            DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact
        };

attempt to use the httpclient and it will throw an exception

Expected behavior

Http3 should work regardless of the presence of ipv6

Actual behavior

It does not work

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Mar 3, 2025
Copy link
Contributor

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

Copy link
Contributor

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

@MihaZupan
Copy link
Member

What issues are you trying to workaround by disabling IPv6?

We're disabling MsQuic if the OS doesn't support IPv6. At the Quic layer we don't know whether that's due to the OS actually not supporting it, or due to it being disabled via the switch.

// MsQuic is using DualMode sockets and that will fail even for IPv4 if AF_INET6 is not available.
if (!Socket.OSSupportsIPv6)
{
NotSupportedReason = "OS does not support dual mode sockets.";
if (NetEventSource.Log.IsEnabled())
{
NetEventSource.Info(null, NotSupportedReason);
}
return;
}

@mastahg
Copy link
Author

mastahg commented Mar 4, 2025

So we recently switched to using cloudflare proxy to protect our servers, they automatically define ipv6 aaaa records which can't be disabled without an enterprise plan, they handle the ipv6->ipv4 conversion which works fine for most users.
Some users however report issues where it seems like their ISP or their router has half-baked ipv6 support. For these users ipv6 is utterly broken, from having extreme timeouts or just being unable to reach the servers. I've had several users ping our services at the os the level and when ipv6 is enabled they'll be unable to contact the cloudflare edge servers. Having them disable ipv6 systemwide resolves the issue.

Disabling ipv6 for my application seems to make the most sense, I was doing this via the System.Net.DisableIPv6 flag, and as you indicated this disables msquic. There is no way to handle this at the application layer when using http3 as the httpclient lacks a callback handler, as tracked in issue #64449

@antonfirsov
Copy link
Member

antonfirsov commented Mar 4, 2025

For these users ipv6 is utterly broken

@mastahg I'm afraid this could mean that msquic (the underlying quic lib) is also doomed to fail given that it uses dual-mode (IPv6) sockets even for IPv4.

ipv6 aaaa records

One possible way to enforce the usage of the IPv4 endpoints (and see if it helps) would be to use an IP address directly in the Uri (while setting the host header).

@mastahg
Copy link
Author

mastahg commented Mar 4, 2025

For these users ipv6 is utterly broken

@mastahg I'm afraid this could mean that msquic (the underlying quic lib) is also doomed to fail given that it uses dual-mode (IPv6) sockets even for IPv4.

I'm evaluating the usage of http3 in censorship prone environments, this effects a much larger portion of my userbase and I'm weighing the pros and cons of each approach. Perhaps this issue would be better directed at the msquic repo. I'm not a expert in sockets but the requirement of dual-mode sockets seems arbitrary.

ipv6 aaaa records

One possible way to enforce the usage of the IPv4 endpoints (and see if it helps) would be to use an IP address directly in the Uri (while setting the host header).

I'll investigate this approach.

@rzikm
Copy link
Member

rzikm commented Mar 4, 2025

this is related to #75343 and (microsoft/msquic#3052). I don't remember from top of my head if there were other reasons than these for checking for IPv6 availability.

@ManickaP
Copy link
Member

ManickaP commented Mar 4, 2025

Perhaps this issue would be better directed at the msquic repo.

I 100% recommend this. Please do file the issue with MsQuic.

For context, this was changed in #87208.

@ManickaP
Copy link
Member

ManickaP commented Mar 4, 2025

Either way, there isn't much we can do about this on .NET level atm.

@wfurt
Copy link
Member

wfurt commented Mar 4, 2025

Either way, there isn't much we can do about this on .NET level atm.

documentation ??? (unless it is already there) While the QuicListener may be problematic, could we make the client work if DualMode socket can be created with IPv4?

@ManickaP ManickaP added enhancement Product code improvement that does NOT require public API changes/additions and removed untriaged New issue has not been triaged by the area owner labels Mar 4, 2025
@ManickaP ManickaP added this to the Future milestone Mar 4, 2025
@mastahg
Copy link
Author

mastahg commented Mar 4, 2025

Either way, there isn't much we can do about this on .NET level atm.

documentation ??? (unless it is already there) While the QuicListener may be problematic, could we make the client work if DualMode socket can be created with IPv4?

This had me wondering, if I patched Socket.OSSupportsIPv6 to always return true would it just work? And it does!

 _harmony = new Harmony("hrmm");
            var thing = typeof(Socket).GetProperty("OSSupportsIPv6");
            if (thing != null)
            {
                _harmony.Patch(thing.GetMethod, postfix: new HarmonyMethod(Postfix));
            }

        static void Postfix(ref bool __result)
        {
            __result = true;
        }

I had both System.Net.DisableIPv6 set to true, and ipv6 disabled on my only network interface.

@mastahg
Copy link
Author

mastahg commented Mar 4, 2025

So I did more testing, I can't even find a local scenario where Socket.OSSupportsIPv6 returns false other then setting System.Net.DisableIPv6. I'm shipping on .net8, so the supported operating system is windows 10 at a minimum. I've tried disabling ipv6 via registry and the network adapter but Socket.OSSupportsIPv6 still returns true. I don't understand how at least one user was able to trigger Socket.OSSupportsIPv6 being false.

@wfurt
Copy link
Member

wfurt commented Mar 4, 2025

there are some ways described in #87208 and Windows is only one OS we care about. It is difficult for Quic layer to know if the address family is truly not supported by Kernel of if OSSupportsIPv6 is false for any other reason.

@ManickaP
Copy link
Member

ManickaP commented Mar 5, 2025

I talked offline with @wfurt, there is potential to improve this on the client side where we could check if we can create the dual mode socket (or even try to create MsQuic connection) despite IPv6 being disabled. We already have separate IsSupported for client and listener, so we can split the behavior here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.Net.Quic enhancement Product code improvement that does NOT require public API changes/additions
Projects
None yet
Development

No branches or pull requests

6 participants