Skip to content
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

DialAddr should do Happy Eyeballs #3772

Open
marten-seemann opened this issue Apr 13, 2023 · 1 comment
Open

DialAddr should do Happy Eyeballs #3772

marten-seemann opened this issue Apr 13, 2023 · 1 comment

Comments

@marten-seemann
Copy link
Member

Following up on #3755 (comment), I believe our DialAddr method is not doing the right thing:

  1. It currently uses ResolveUDPAddr, which prefers IPv4 over IPv6 (we should do the opposite!). See http3: client always prefers IPv4 #3755 for more details.
  2. ResolveUDPAddr is a misleading function anyway, since it returns a single result. A typical DNS response will contain multiple A and AAAA records.

After discussing this on the QUIC Slack, I believe this is what a "correct" implementation would look like:

  1. We need to do DNS resolution ourselves (using a net.Resolver).
  2. If we receive both A and AAAA, we should start dialing IPv6 first, and try IPv4 shortly after if that doesn't work. This is the Happy Eyeballs logic described in RFC 8305.
  3. This results in two loops, dialing A and AAAA addresses in parallel. If a connection timeout times out, we should start dialing the next address.

Unfortunately, this is some significant complexity. DialAddr would not be a very thin wrapper around Dial any more. However, most users of quic-go probably want to connect to a domain, and not only an IP address, so it seems like this logic either belongs into quic-go or into a wrapper around quic-go, otherwise it would have to be reimplemented again and again.

This results in interesting interactions between the dial context timeout and the handshake timeout. Specifically, the dial context timeout needs to be larger than the handshake timeout for us to be able to proceed to the second A / AAAA record if the first one fails. As the context deadline is set by the deadline, there's not a lot we can do about this, other than being very clear how the logic works.

@marten-seemann
Copy link
Member Author

It's not clear how this interacts with 0-RTT. The safest option would be to just send the 0-RTT data on the first connection, and treat subsequent connections as "0-RTT rejected". It's not immediately clear how this would best be exposed on the API, since DialAddrEarly will return the connection struct directly, and now it needs to be substituted with a different connection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant