-
-
Notifications
You must be signed in to change notification settings - Fork 230
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
Implement RFC8305 Happy Eyeballs for dual stack IPv4 and IPv6 hosts #188
Comments
This can be implemented on top of Gun, so I would suggest working on a reference implementation and then we can see about including it directly in Gun. |
Looked a bit more and it should be done in Not sure this implements the whole of RFC6555 but that's a start. Would love a proof of concept PR. |
Keep in mind that RFC6555 has been obsoleted RFC8305. The algorithm is more complex than what you described, but I agree that an easier implementation of dual stack support is also good to have. I've started to implement a work-in-progress sort-of prototype of RFC8305 in Elixir (https://github.com/nroi/eyepatch), it aims to be usable for many HTTP client libraries and I have tested it with hackney. The project is far from done, but I would like to share some insights:
I just glossed over the |
Gun just uses gen_tcp/inet which has those DNS related tests and I suspect a proper implementation of this RFC should sit there. Or at least replicate a lot of the connect functionality, even more than I did in current Gun master which now separates domain lookup from connect and TLS handshake. Basically we could extend domain lookup to get all the records the RFC requires and then extend the connect to eventually try a second connection and do so asynchronously but that's quite a large amount of work so I was just thinking it'd be far easier to do it in front of Gun. And because of how gen_tcp/inet is structured, it'd be far far easier to just try on inet6 first and after a timeout try inet (while leaving inet6 trying to connect) and just pick the first winner. Even if it doesn't implement the RFC fully. And it's unclear to me how much better a full implementation of the RFC would be compared to just doing this. Probably not much. |
By the way, related, gen_tcp:connect might itself benefit from sorting IP addresses, I've seen it with a I'm also curious how the RFC behaves on Windows. In Erlang's case gen_tcp:connect will end up trying to connect 3 times to the given IP, and that is a Windows behavior. Don't know if that can be disabled without tweaking the registry. |
In case anyone really needing this comes upon this ticket, I have no plans to implement it at this time but would be willing to for a paid customer. Please see https://ninenines.eu/services/ for general information about that. |
I finally needed this, and it turns out @stolen has already implemented it years ago at https://github.com/yandex/inet64_tcp so I forked it, tidied it up for rebar3, and it works as promised. The magic bits are in here - https://github.com/skunkwerks/inet64_tcp/blob/main/src/inet64_tcp.erl#L72-L96 |
I think happy eyeballs you must do queries concurrently, and then connects concurrently as well (after some wait time). First connect wins. There's also hrefhref@c5d577e as an attempt to deal with both 4 and 6. |
I've been looking at different Erlang HTTP client libraries, and haven't found a single one which supports happy eyeballs. Using IPv6 exclusively is still not an option since many hosts don't support it yet, and using IPv4 exclusively is also less than ideal: Many ISPs don't even give out new IPv4s to new customers and instead implement something like "Dual Stack Lite", which means that IPv6 works more reliably than IPv4 for those customers.
Some links:
The text was updated successfully, but these errors were encountered: