-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
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
asyn-thread: don't use PF_INET6 for getaddrinfo on Windows #12136
Conversation
It seems to not be able to resolve IPv6 addresses! Fixes #12134 Reported-by: zhengqwe on github
If we knew which Windows version fixed this (if), we might use: #if (defined(WIN32) && \
defined(_WIN32_WINNT) && (_WIN32_WINNT >= _WIN32_WINNT_WIN8))
or something. Nothing readily popped out from the docs suggesting such behaviour for Win7: For XP, IPv6 support must be installed, but that's expected. Perhaps logging the error code might help digging deeper. |
The original report is also on Win 10. |
Ah, okay, missed that! But then, is it possible this is actually working correctly, and in these env the name simply cannot be resolved to IPv6? This seems to be the case on the machine I run the tests. It has a local IPv6 address, but no IPv6 support upstream. If this is the case, this isn't an error, because what happened was that PF_UNSPEC returned an invalid IP or no IPv6 (?) and then it couldn't connect. With 8.3.0, it returns an error right away at resolution. Which seems to be the correct behaviour. 2 cents, I might be missing a lot of things here. |
First, the original user said in the report they could ping -6 to the host so it could be resolved to a IPv6 address with ping but not with curl. Then you said you could reproduce the problem and reverting a commit fixed it. Now you seem to be reverting that statement a little bit so I'm no longer exactly sure what you meant...? 🤔 |
The revert fixed it for OP. This leaves me curious what is going on with this API. |
This comment was marked as outdated.
This comment was marked as outdated.
On Windows if you do not have what it thinks is working IPv6 then it strips AAAA from the results. Their check is apparently different than our check. For example You call getaddrinfo set to PF_INET6 and query AAAA google.com, the request is sent [1] and the answer contains a single AAAA record. but because windows has determined there's no working IPv6 it won't actually provide those records. This is probably a good thing because on Windows a lot of curl will have "working" IPv6 according to our own check even if it's not actually able to connect to anything remotely. They definitely should have documented this behavior. I tried in curl just now on a computer with IPv4 and Link-local IPv6 and Curl_ipv6works is true so PF_INET6 is set, and it does what I described in the paragraph above. getaddrinfo returned WSANO_DATA [1]: There's a local caching DNS that has to be disabled to force the request to be sent (like if you wanted to monitor in wireshark for testing purposes) but the answer is the same, just the aaaa. you can disable the dns caching service |
more info, taken from msdn getaddrinfo and the windows 7 sdk source code comments AI_ADDRCONFIG:
we are not setting that. i searched for it and found this in a local ms sdk source:
So it was indeed intentional, they just didn't document it (on their website). |
But I have working IPv6, so clearly it it is a broken IPv6 detection. If this is what prevents it from working for me. If I use the curl tool Windows 10 ships, it connects to and uses IPv6.
Sure, but that's a failure that just makes IPv6 connects fail so it's a benign error. It's not even actually an error, because clearly IPv6 works on your system, you just can't access remote hosts over it. |
but yes, when I use 8.4.0, I can see that it does not try IPv6 even with a regular command line. Which makes me wonder why the windows-provided version does? |
Yes but the default as I quoted above is actually "getaddrinfo will resolve only if a global address is configured". So are you saying that you have that and it works? |
When I run |
I would agree. Windows has special checks for network connectivity so maybe it's more complicated than whether you have a global IPv6 address, perhaps the OS tried to connect over that address and couldn't. |
The two different curl versions behave differently and that's what triggers my curiosity the most. |
I think we can safely conclude that this PR is not the right thing to do anyway. |
I think we need more testers with working global IPv6 to tell us if this is a problem for them.
If you're going to bisect use winbuild, it's way faster than mingw-w64. Also sanity check that IPv6 is in the features list. |
our build 8.0.1_9 resolves and uses IPv6 fine This is clearly something we broke since. |
The 8.3.0_3 build works. 8.4.0_1 does not |
I don't have a windows development environment setup so I can't bisect this closer right now. |
I don't have a global IPv6 address (my ISP doesn't support IPv6) so hopefully someone else can step in. |
Hello, my ISP provides global IPv6 IPs. I only use Void Linux and FreeBSD most of the time, but I also have a Windows 11 installed on my machine. I want to help if possible, I'm just a bit clumsy with Windows... |
Ok, here is a step-by-step tested in Windows 11 x64 21H2:
|
Thanks. That confirms what was reported. @DHowett do you have any insight why PF_INET6 does not work to resolve IPv6 addresses when there is an IPv6 address configured? All I've been able to find is this. |
I don't see
Is this expected? The curl-8.4.0_5 mingw binary fails here too. So far I couldn't reproduce the issue with a self-built curl: Neither building master nor 8.4.0, with llvm-mingw or with MSVC, with ares or without. Do certain optional dependencies influence the behavior? |
No, it's unexpected. curl can be built with IPv6 support but without IPv6 resolver support and that might be the problem. Lines 582 to 586 in d755a5f
|
My build (w/o Cares) shows for (using my Wsock-trace). |
@gix: Nice catch! Can confirm that curl-for-win (incl. dependencies) did not change between 8.3.0_3 and this, suggesting the change happened in curl sources. curl-for-win used I've switched to CMake two days ago and consistent with that, Ok, so this hunk caused the regression: Surprisingly, This can be fixed three ways:
|
In 8.4.0 we deleted `_mingw.h` as part of purging old-mingw support. Turns out `_mingw.h` had the side-effect of setting a default `_WIN32_WINNT` value expected by `lib/config-win32.h` to enable `getaddinfo` support in `Makefile.mk` mingw-w64 builds. This caused disabling support for this unless specifying the value manually. Restore this header and update its comment to tell why we continue to need it. Regression from 3802910 curl#11625 Reported-by: zhengqwe on github Helped-by: Nico Rieck Fixes curl#12134 Fixes curl#12136 Closes #xxxxx
Test binary here attempting to fix this with #12217: $ x86_64-w64-mingw32-objdump --all-headers curl.exe | grep getaddrinfo
5a1644 168 getaddrinfo Can you verify if this build fixes the issue? |
Shouldn't curl explicitly set |
I think if we start overriding it or setting it ourselves it might make things more confusing. We did so earlier in CMake. If we rely on this value, it's our sources responsibility to include the SDK before using it. We also have this value pre-detected inside CMake, which does rely on SDK headers, not |
It seems you have it backwards. You are right that the curl source itself (especially libcurl) should only use the macro to enable/disable features depending on the targeted OS version. It should never define it, so re-including This just leaves the case where someone else is using libcurl in his project. libcurl may opt to error if |
I don't think I "have it backwards", I think we're saying the same thing: It's not curl's job to set any default, neither on behalf of the SDK nor on behalf of the person building curl. Erroring out if the value isn't defined is an option, though I think it's more helpful to initialize this value to the SDK default, otherwise it will also lead to confusion. The root issue here is that we were using Thanks for the |
The other issue is that the official curl-for-win builds don't set it. If you just let the SDK set the default you get a curl binary that inherits the Windows version of whatever SDK your build server used which is most likely not what you want. If you do that with a recent SDK you target Windows 11 22H2, and nothing earlier. |
Yes, setting that in curl-for-win might be a good idea, though a different issue. The build should work consistently without setting a value manually. I remember the default used to be ~Vista (supporting
In my build of mingw-w64 v11.0.1, curl-for-win CMake builds detect This suggests that we cannot use |
I re-verified and curl isn't using any feature specific to higher Windows versions than 0x0600 (Vista). It means that targeting the default 0x0a00 (Win10) results in a binary running fine on pre-Win10 versions (for sure it runs on Win7). Speaking of future curl versions and especially dependencies, setting the target version might still be useful. This will need further tests to see how they all behave in that case. |
These two tests confirm that explicitly setting I plan to set it for an assurance to keep it that way. Thanks for the suggestion @gix. |
8.4.0_6 is out which sets the target Windows version explicitly. This acts as a workaround for this issue while also ensures Vista compatibility going forward. Aside this regression, this change tested as a no-op, meaning curl-for-win was/is Vista compatible as advertised. The new release also comes with nghttp2 1.78.0 (which builds faster, amongst others), adds dumping of curl/curl-for-win@55ccad2 Can't test for this issue but |
I can confirm it works:
|
Thank you @gix! |
- On Windows if IPv6 is enabled but getaddrinfo is missing then #error the build. curl can be built with IPv6 support (ENABLE_IPV6) but without the ability to resolve hosts to IPv6 addresses (HAVE_GETADDRINFO). On Windows this is highly unlikely and should be considered a bad build configuration. Such a bad configuration has already given us a bug that was hard to diagnose. See curl#12134 and curl#12136 for discussion. Ref: curl#12134 Ref: curl#12136 Closes #xxxx
- On Windows if IPv6 is enabled but getaddrinfo is missing then #error the build. curl can be built with IPv6 support (ENABLE_IPV6) but without the ability to resolve hosts to IPv6 addresses (HAVE_GETADDRINFO). On Windows this is highly unlikely and should be considered a bad build configuration. Such a bad configuration has already given us a bug that was hard to diagnose. See curl#12134 and curl#12136 for discussion. Ref: curl#12134 Ref: curl#12136 Closes #xxxx
Thanks for driving this down! My critical mistake in testing was using the one from the Windows (inbox) build server at 8.4.0, but that one's built with an explicit Win10 SDK reference so it was not susceptible. |
- On Windows if IPv6 is enabled but getaddrinfo is missing then #error the build. curl can be built with IPv6 support (ENABLE_IPV6) but without the ability to resolve hosts to IPv6 addresses (HAVE_GETADDRINFO). On Windows this is highly unlikely and should be considered a bad build configuration. Such a bad configuration has already given us a bug that was hard to diagnose. See #12134 and #12136 for discussion. Ref: #12134 Ref: #12136 Closes #12221
It seems to not be able to resolve IPv6 addresses!
Fixes #12134
Reported-by: zhengqwe on github