-
Notifications
You must be signed in to change notification settings - Fork 1.7k
In Dart HTTP Client, an option is required to set the IPv4 or IPv6 for DNS resolution for the developer #50868
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
For iOS this was supposed to be fixed by d7483c3, so you should not see it. We could enable it on Android as well. /cc @brianquinlan |
Any update in this issue? I'm also facing the same.... Tried to use same http client after initializing once... But connection is losing after some time.... 🤕 |
++ |
Seems like a high impact issue for anybody who uses default IO client. /cc @a-siva |
critical issue for my app |
Any solution? |
I am also facing the same issue |
Same issue here. |
Could someone experiencing this issue on Android please try running this code and report the output: // Test IPv4 performance
final start = DateTime.now();
InternetAddress.lookup(<whatever host that you use that is slow>, type: InternetAddressType.IPv4)
.then((_) => print(DateTime.now().difference(start))); and then, after rebooting your device: // Test IPv6 performance
final start = DateTime.now();
InternetAddress.lookup(<whatever host that you use that is slow>, type: InternetAddressType.IPv6)
.then((_) => print(DateTime.now().difference(start))); I just want to confirm that the issue is with IPv6 lookup. |
Actually, there is an easier way. If you run your flutter project with:
or build it with:
then it will attempt to lookup the host address using IPv4 and IPv6 in parallel. Could someone please try that and see if it fixes the issue? Note that this flag will have no effect on iOS. |
Yes, This actually fixed that. i dont have issues with iOS, this works for android. will HTTP package supports this in future? |
hashimchargemod@ thanks! If you are referring to |
Unless there is a reason not too, I'm going to enable staggered IPv6 resolution on all platforms and remove the flag. |
okay, Happy to help. Just a simple question: Is there any option built for disabling the ipv6 entirely and look only ipv4? |
There is no way to disable lookup with IPv6. |
I've been looking into how name resolution works right now. Currently we are using So the order of the addresses returned should match RFC 3484 - which specifies that, all else being equal, IPv6 addresses should be tried first. When using glibc, If we always prioritize IPv4 connections then we will be violating the RFC and ignoring the user's I'm looking into how other mobile HTTP client implementations deal with this. Also, it occurs to me that there is currently a way to force void main() async {
HttpClient client = HttpClient()
..connectionFactory = (Uri uri, String? proxyHost, int? proxyPort) async {
if (proxyHost != null && proxyPort != null) {
return Socket.startConnect(proxyHost, proxyPort);
}
final ipv4addresses = await InternetAddress.lookup(uri.host,
type: InternetAddressType.IPv4);
// Should actually iterate over every address until we get a successful
// connection.
return Socket.startConnect(ipv4addresses.first, uri.port);
};
final request = await client.getUrl(Uri.http('www.google.com', '/'));
final response = await request.close();
print(response.statusCode);
client.close();
} |
It looks like Chromium runs a probe once a second to check if IPv6 is available: |
@cbracken added you as a CC in case you think that the resolution of this issue could affect your work. |
There are also some semantic differences between requesting IPv4 and IPv6 addresses in one system call vs. two e.g. >>> socket.getaddrinfo('127.0.0.1', 80, proto=socket.IPPROTO_TCP)
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('127.0.0.1', 80))]
>>> # The address is clearly a numeric IPv4 address so only providing AF_INET totally makes sense to me.
>>> socket.getaddrinfo('127.0.0.1', 80, proto=socket.IPPROTO_TCP, family=socket.AF_INET)
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('127.0.0.1', 80))]
>>> # Sure, filtering by IPv4 returns the same result because the result was IPv4-only anyway.
>>> socket.getaddrinfo('127.0.0.1', 80, proto=socket.IPPROTO_TCP, family=socket.AF_INET6)
[(<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('::ffff:127.0.0.1', 80, 0, 0))]
>>> # Ahhh... so if I explicitly ask for IPv6 then you'll give me this address with the IPv4 subnet prefix.
>>> # So asking for IPv4 and IPv6 address separately is *not* the same as asking for both at once. |
I have the outline of a change here: https://dart-review.googlesource.com/c/sdk/+/288621/6/sdk/lib/_internal/vm/bin/socket_patch.dart I'm worried that it doesn't work correctly for servers bound to IPv6 addresses that allow IPv4 connections. Relevant section:
I need to think about this a bit more. |
Bug: #50868 Change-Id: I5ad57f4634287b4299fbf74fde075d518154bf08 Tested: unit Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/288621 Commit-Queue: Brian Quinlan <[email protected]> Reviewed-by: Alexander Aprelev <[email protected]>
I modified the socket connection logic to favor IPv4 connections over IPv6 connections, as we already did on iOS. |
Bug: #50868 Change-Id: I8186d95d1a24c77c4cfade533af26695c7a13b24 CoreLibraryReviewExempt: documentation-only change Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/293020 Commit-Queue: Brian Quinlan <[email protected]> Reviewed-by: Alexander Aprelev <[email protected]>
Fixes didn't address the proposal yet, those fixes are for the SocketException. We should reconsider if manually set lookup address type can be overridable. |
@brianquinlan |
@Stitch-Taotao can you try with a newer version of Flutter, a change was made to favor IPv4 connections over IPv6 connections here https://dart-review.googlesource.com/c/sdk/+/288621 which is probably not it version 3.13.9 |
I am still seeing this with Flutter 3.21.0-16.0.pre.11 / Dart 3.4.0 (build 3.4.0-279.0.dev). Requests randomly and sporadically will take multiple seconds, sometimes even timing out after 20 seconds. At other times, the requests are lightning fast. The slow requests happen about 10% of the time. Sometimes I don't even get timeouts, I get "no address associated with hostname" failures:
Meanwhile, as others have commented, getting the same URL with other tools (e.g. in Chrome) at or around the same time as failed requests returns the result instantly.
Can we get a programmatic way to set this flag at runtime in Personally I don't care if the spec says IPv4 addresses can't be used until IPv6 lookup fails -- I need my app to work fast, every time. |
@brianquinlan can you please reopen this issue -- it is not fixed. |
What platform are you seeing this error on?
This flag is obsolete - Dart currently prioritizes IPv4 addresses over IPv6 addresses on all platforms. |
Sorry, it's on the Android emulator, running on Linux. The issue occurs with the standard
OK, so there may be something else going on. The behavior seems to exactly match the IPv6 name lookup failures that others were seeing, so I assumed that was the cause. Response times are extremely sporadic, either returning instantly or taking 8-20 seconds, or failing with timeout after 20 seconds. This happens with multiple domains -- api.bigdatacloud.net, as shown in the log, but also with my own DyDNS-mapped domain name that is only two hops (basically I expose a server on my local machine via a static IP to my ISP, then connect to my machine from the Android emulator process on the same machine, rather than collecting to localhost, to better simulate hosting in the cloud). It's one hop out to the ISP, then one hop back to my machine. Even those requests can take 20 seconds to fill. I have debugged this as far down the client stack as I could, and as far down the server stack as I could. The problem seems to be happening in the |
I also see these errors with
|
On Android, I'd suggest that you use
|
@brianquinlan Thanks, I didn't know that was an option. With these changes, I'm no longer seeing 20 second delays, but I see 2-3 second delays sometimes. The domain name resolution issues seem to be fixed though. I guess I'll have to assume that there is something going on between the emulator environment and my local network. |
I think I am seeing an issue related to this. I have a Global external application load balancer exposing a HTTP ip v4 url. My Flutter app connects to this using NetworkImage to load images. This is working well for most users most of the time. I have some users somehow getting into a state where all images stop loading. These are very small images (~10KB) which cannot be loaded on a very fast cell signal. When the user switches over to WIFI the images start loading again. |
IDK if this is related to my issue, but I just started building for iOS, on my old iphone 11. On startup, many missing or stalled requests occur. Then if I close the app and IMMEDIATLEY open again, suddenly all the requests come in like normal. |
It appears to be the DNS settings on my physical device causing the issue. I switched to cell internet, and suddenly, NO PROBLEMS. But for WIFI, I was using custom DNS. That is why my Android was working...I have it set to "Automatic". And that is why my iOS simulators were working...no custom DNS. Is this a flutter, dart, or iOS issue? My app would work GREAT upon first install. I was getting all kinds of OS errors related to file descriptors being used up, and puzzling "DNS failed" lookups. Edit: Not totally fixed yet. I added the dart flag, and still getting missing connections on app start on a physical iphone 15. But using 4G results in no missing tiles. I went ahead an opened a question on stack in case anyone is interested: |
Have you found a solution to the problem? |
Still having the issue in 2025 with absolute latest Flutter and Dart. Takes 13 seconds for a trivial HTTP request! Please re-open. |
Could you provide a reproducible example please? |
my rest response time: so something needs to be done |
same issue here |
This feature is a related dart HTTP client, I raised a new feature request in Flutter GitHub ( flutter/flutter#116537). They asked to raise in Dart SDK GitHub as it is a bug in the dart HTTP client.
Target Platform: Android
Target OS version/browser: Android 12+
Devices:
Many Flutter-based Android and iOS apps are very slow during HTTP service calls in the Wifi networks due to failed IPv6 DNS resolution.
As I am requesting this feature as a solution for the three important issues reported by Flutter developers.
In essence, we are facing slowness in the API call execution while using Wifi networks due to failed IPv6 DNS resolution, thereafter it fallback to IPv4 DNS resolution. Hence each API call execution is getting delayed a minimum of 10+ seconds.
It would be great If there would be a feature for manually specifying IPv4 or IPv6 versions during HTTP client initialization.
So I request your kind attention on this important issue, as we are developing business-critical applications using Flutter, for iOS/ Android, and Windows.
The text was updated successfully, but these errors were encountered: