Apply the Happy Eyeballs philosophy to parallel c-ares queries - #3699
Closed
b-spencer wants to merge 4 commits into
Closed
Apply the Happy Eyeballs philosophy to parallel c-ares queries#3699b-spencer wants to merge 4 commits into
b-spencer wants to merge 4 commits into
Conversation
Merge from upstream curl
Pull upstream master
Pull upstream master
bagder
approved these changes
Mar 22, 2019
bagder
left a comment
Member
There was a problem hiding this comment.
Sounds like an excellent idea and approach!
Member
|
the only test fail is the libssh2 test failure which is unrelated (but I don't know why it started fail in all CI builds...) |
Member
|
Just to play this safe as there's a release coming in just a few days, I want to merge this after the pending release to give this slightly more time to cook before it ships. |
| /* How long we are willing to wait for additional parallel responses after | ||
| obtaining a "definitive" one. | ||
|
|
||
| This is intended to equal the c-ares default timeout. cURL always uses that |
Member
There was a problem hiding this comment.
This should be "curl", but that nitpick can be fixed by the committer rather than require a fresh rebase IMHO.
Author
There was a problem hiding this comment.
Oops. I've been spelling it what I guess is the old-fashioned way!
Thanks!
BTW, maybe someone should fix the Wikipedia article's spelling :)
Member
|
Thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When it supports both IPv4 and IPv6, cURL follows the happy eyeballs algorithm by trying to connect via both protocols in a staggered fashion. When cURL is configured to use c-ares, this also means doing two simultaneous, parallel DNS requests, one for the A record and one for the AAAA record, so that cURL can have both the IPv4 and IPv6 address in hand. (Ideally, there'd be a single request, but that's not the case for a variety of reasons.)
Today, cURL issues both of these requests at the same time, which is good. However, this parallelism is encapsulated within the c-ares driver, so the larger cURL logic is unaware that there are actually two requests and not just a single (combined A and AAAA) DNS request. The rest of cURL waits for this meta request to finish before it tries to start any connections.
Unfortunately, when either one of the parallel c-ares requests takes a long time to finish, cURL sits and waits for it, even if the c-ares driver does have a viable DNS result from the other request. Practically speaking, this means that if you are on a network that claims to support IPv6 and allows binding such sockets and addresses locally, but whose DNS server is misconfigured and can't properly respond to AAAA requests, you can find yourself in a situation where you have the usable A record in hand, but you're waiting for a series of timeouts and/or failures from all the malfunctioning DNS servers in the list.
This PR makes a small tweak to the existing c-ares driver that takes same "happy eyeballs" philosophy from the actual TCP connections (connect to one and then after a short timeout, try the other) and it applies it to the parallel DNS requests themselves. With this change, once a usable DNS response is in hand (be it A or AAAA), c-ares will only wait a short time before giving up on the second response and just going with what it has.
The exact algorithm and rationale are documented in the comments inside the PR. The changes were specifically chosen to be simple and not overly aggressive. This might not be the best "fix", but it seems better than the status quo, and I hope that it can at least be the start of a discussion on how to handle real-world cases like this.