-
Notifications
You must be signed in to change notification settings - Fork 1.7k
dart:io does not use ipv6 on ubuntu 24.04 unless forced #60192
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
Comments
I've been looking at how other languages deal with this: Java has a command-line flag or you can can call We could have a system like Java/Node where we have a command flag and maybe a static property on
This would only apply when connecting to a host by name i.e. if you are connecting via I think that the awkward part would be testing all of this. |
I have a first draft implementation here: https://dart-review.googlesource.com/c/sdk/+/423980/ |
From reading the code, what should happen (if I read it correctly)
So from my reading the code, if the DNS lookups for IPv4 & IPv6 suceed but IPv4 is firewalled, then we should after roughtly 10ms+250ms try to connect via IPv6 which should then succeed. @noctisbeta What exact behavior do you see? Does the connection take longer to establish, does it fail or does it timeout? |
@mkustermann The connection does not fail. It connects over IPv4 normally, then the google api gives an error response returning "unsupported user location" (this is the part where others are suspecting an ipv4 block). The IPv4 does not timeout or take longer. This does not happen over IPv6 (using manual dns lookup and a custom http client adapter), nor does it happen using other tools such as curl, httpie, javascript, python, etc (because they either favor IPv6 or try both at the same time). The main problem is that dart "forces" you to try IPv4 first. This should not require workarounds as it is expected to work like everywhere else. I have not however looked into the original android bug that brought upon this change. Ideally another fix could be found and this hardcoded delay could be reverted. |
Ah, so the root cause here is that the Thanks, that clears clears things up and makes perfect sense! Given you have this problem, you want a mechanism to force IPv6 when connecting to that particular This leads me also to conclude that maybe we shouldn't have a global setting telling to favor IPv4 vs IPv6. This use case wants to force IPv6 for that particular hostname. Maybe other API services may get denied if IPv6 is used but not IPv4. So one may want to configure this per hostname instead of globally. OS configuration
How do you configure the OS DNS resolution? I would assume that if one makes DNS resolutions only return IPv6 addresses then this would be solved. That being said, I'm not advocating for changing the OS settings - as many other use cases it may not even be possible to change OS settings. Current
|
@mkustermann I tried setting priorities for linux's getaddrinfo function by editing /etc/gai.conf. I did this since if the IPv4 of my VPS really was on some sort of blacklist, this would make sure I always prefer IPv6, for other APIs as well. No matter how much I changed the values in gai.conf, dart:io wouldn't give me an IPv6. Maybe an error on my end though. From what I understand, this only changes the order in the list that is returned by the OS getaddrinfo (putting IPv6 in before IPv4), but then dart filters for IPv4 by doing a lookup for InternetAddressType.IPv4 first (because of the delay) so it doesn't matter. I assumed that if it looked up InternetAddressType.any and the OS was configured to return IPv6 first, it would get the IPv6. So this just added to the confusion before I found the delay in the socket patch. In the end I tried a very similar solution to what you've suggested, using custom adapters, to make a workaround. I still wanted to open up an issue, even though my very specific IPv4 google api problem was resolved using manual lookup, because it took a very long time to figure out what was actually going wrong. I did not expect the delayed lookup code to exist, and even changing the OS didn't force it, it was quite a rabbit hole. Thank you for providing an example for the solution. I believe this will make it easier for others to find out the cause of this issue and make it work. |
Glad to hear you have a way to make this work for you, @noctisbeta . And I'm in agreement that |
Uh oh!
There was an error while loading. Please reload this page.
When making http requests to generativelanguage.googleapis.com Dart always goes through ipv4. For some reason, Hetzner's ipv4 addresses for their VPS are blocked. Going through ipv6 works. Other tools (curl, httpie, python) default to ipv6 (but fail when forced to use ipv4 eg. curl -4). Configuring the OS to always prefer ipv6 over ipv4 does not change the dart:io behaviour. The workaround is manually making a request to google's ipv6 address and handling the certificate failure, since this results in a mismatch. Or using a proxy in a custom http client to circumvent the ipv4 block. (this is speculative, but have found others reporting the same block for their ipv4 from Hetzner)
Surely there must be a cleaner way to tell IOClient or HttpClient to use ipv6 instead of ipv4.
This is using
on Ubuntu 24.04.1 LTS.
Edit: Is this the culprit, on line 702? Staggered lookup, which checks ipv4 first.
https://github.com/dart-lang/sdk/blob/main/sdk/lib/_internal/vm/bin/socket_patch.dart
Issue referenced: #50868
Edit 2: Since this looks like a dart wide issue, maybe this should be renamed to account for new information. Dart outright refusing to use ipv6 over ipv4 is in contradiction with other tools and works against expectations. This results in very hard to debug and hard to work with scenarios. That is, if I'm understanding this correctly.
The text was updated successfully, but these errors were encountered: