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

net: provide RFC 6724 address sorting functionality #10552

Closed
mdempsky opened this issue Apr 22, 2015 · 12 comments
Closed

net: provide RFC 6724 address sorting functionality #10552

mdempsky opened this issue Apr 22, 2015 · 12 comments
Milestone

Comments

@mdempsky
Copy link
Member

RFC 6724 describes a policy-based sorting algorithm for IP addresses that's to be applied by procedures like getaddrinfo. Presumably Go's DNS resolver should provide support for this somehow, or at least the recommended default sorting policy.

On Linux with glibc, the system policy is configured via /etc/gai.conf.

@pmarks-net
Copy link
Contributor

If getaddrinfo will no longer be the default resolver in Go 1.5, then this feature needs to be a release blocker. Address selection is a central feature of getaddrinfo which cannot simply be discarded.

Without getaddrinfo, the IPv4/IPv6 address selection is currently race-based. This will cause Go clients to behave unpredictably when connecting to dual-stack names.

@bradfitz bradfitz modified the milestones: Go1.5, Unplanned Jun 25, 2015
@bradfitz
Copy link
Contributor

/cc @mikioh @mdempsky

@mdempsky
Copy link
Member Author

It would help to understand why/how this is release blocking. E.g., is simply implementing the RFC 6724 default sorting functionality sufficient? Or do we need to support glibc /etc/gai.conf (and equivalents on other OSes) too?

@pmarks-net
Copy link
Contributor

Hard-coding the RFC 6724 rules would solve 99% of the problem, and I would not personally object to leaving the full gai.conf parser for post-1.5.

Pragmatically, the parts that really matter for Internet connectivity are:

  • Avoid unusable destinations.
  • If IPv6 would use a 6to4/Teredo/ULA source address, then prefer IPv4.
  • Otherwise prefer IPv6.

The standard approach is to probe each address using UDP connect and getsockname, to obtain reachability and source address information from the kernel.

The current resolver picks IPv4/IPv6 at random. Even if both are available, this is undesirable for network and service operators because it makes IPv6 less effective as a NAT offloading tool, and logging/debugging gets annoying when the client can't make up its mind.

On an IPv4-only or IPv6-only machine, preferring the wrong family causes dialSerial to spin through a few ENETUNREACHes before finding an address that works. This is quite fast on Linux, but I've observed that Windows consistently takes 1 second for connect to fail, which is noticeable but not catastrophic.

6to4/Teredo have proven to be unreliable on the Internet, so not de-preffing those means that a small fraction of users will have a really bad time.

@mikioh
Copy link
Contributor

mikioh commented Jun 26, 2015

I'd like to postpone handling this sort of, dual IP stack, issues to Go 1.6. The upcoming Go 1.5 contains @pmarks-net's Happy Eyeballs implementation and it could provide fairly better TCP connection setup than released versions on various environments such as IPv4-only, IPv6-only, dual IP stack w/o translation techniques or with XLAT, MAP-T or DS-lite, MAP-E-like translation techniques. Performance and connectivity improvements are desirable. But before doing that, I think we need to address issues in the real world carefully.

Random thoughts:

@pmarks-net
Copy link
Contributor

@mikioh I don't understand what point you're trying to convey. Are you suggesting that we leave things as-is, and give users a resolver with random address preference in 1.5?

Real world networks are designed under the assumption that endpoints will attempt to follow the RFCs; that's why the RFCs exist.

I reiterate that random address preference is a Really Bad Idea; Happy Eyeballs would do a reasonable job of hiding the ensuing brokenness, but that isn't enabled by default (and probably shouldn't be, until dialTCP supports cancellation.)

@pmarks-net
Copy link
Contributor

RFC 7050 relates to NAT64, which is unrelated to 6to4. As for why 6to4 source addresses must be de-preferred, this site has relevant data: http://www.fud.no/ipv6/

Back before the first World IPv6 Day, lots of users had broken 6to4 connectivity and preferred IPv6, which resulted in long timeouts when connecting to dual-stack hostnames. The problem largely disappeared in 2011, when the last of the major browsers fixed their address selection rules.

Since the data is browser-based, we no longer know how bad the problem would be if those fixes were dropped. It might be better, might be worse, but nobody is looking anymore.

@mikioh
Copy link
Contributor

mikioh commented Jul 2, 2015

Ouch, I meant https://tools.ietf.org/html/rfc7526.

@mikioh
Copy link
Contributor

mikioh commented Jul 2, 2015

@pmarks-net,

I'm not convinced of implementing non-configurable destination address selection described in RFC 6724 would solve 99% of the problem, because it would probably interfere with user's DNS recursor stuff, and when #11450 would be a solution for it there's no need to use builtin DNS stub resolver, but I may be wrong.

@pmarks-net
Copy link
Contributor

RFC 7526 does not imply that address selectors can delete their 6to4 rules; on the contrary, it means that de-preferring 6to4 is even more important, because wherever 6to4 has been deployed, it is now more likely to provide broken connectivity. Since most other clients follow RFC 3484/6724, this brokenness will predominantly affect clients written in Go.

RFC 7526 explicitly states:

The default address selection rules specified in [RFC6724] are not modified.
...
All hosts using 6to4 MUST support the IPv6-address-selection policy described in [RFC6724].

Could you clarify how RFC 6724 might interfere with DNS recursion?

@mikioh
Copy link
Contributor

mikioh commented Jul 3, 2015

If I understand correctly RFC 6724 leaves issues on various site-specific implementations to site operators. If a site that implements DNS full service resolver stuff prefers IPv4 rather than IPv6, non-configurable address selection policy might annoy the site operator. For example, what if they use a plain-old DNS round-robin as a last resort? This sort of issue happens not only for an IPv6-to-IPv4 fallback case but for an IPv6-to-IPv6 fallback case; what if a node has multiple prefixes and one of the prefixes is not global routable?

I agree on fixing this issue is necessary, and personally hope it comes with some interface for site operators.

@gopherbot
Copy link

CL https://golang.org/cl/12246 mentions this issue.

@golang golang locked and limited conversation to collaborators Jul 18, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants