views:

839

answers:

3

I'm working on a network client program that connects to public servers, specified by the user. If the user gives me a hostname to connect to that has both IPv4 and IPv6 addresses (commonly, a DNS name with both A and AAAA records), I'm not sure how I should decide which address I should connect to.

The problem is that it's quite common for machines to support both IPv4 and IPv6, but only to have global connectivity over IPv4. The most common case of this is when only IPv6 link-local addresses are configured. At the moment the best alternatives I can come up with are:

  1. Try the IPv6 address(es) first - if the connection fails, try the IPv4 address(es); or
  2. Just let the user specify it as a config setting ("prefer_ipv6" versus "prefer_ipv4").

The problem I can see with option 1 is that the connection might not fail straight away - it might take quite a while to time out.

A: 

Some ideas:

  1. Allow the user to specify the preference on a per-site basis.
  2. Try IPv4 first.
  3. Attempt IPv6 in parallel upon the first connection.
  4. On subsequent connections, use IPv6 if the connection was successful previously.

I say to try IPv4 first because that is the protocol which is better established and tested.

Will Bickford
SSL should also always try DES first because that's the encryption standard that's better established and tested.
Omnifarious
IPv4 and IPv6 are not security protocols. It isn't the same.
Will Bickford
A: 

Have you thought about Teredo? http://www.codeproject.com/KB/IP/ipv6.aspx

DotDot
I do use Teredo for development, but my question is about how a dual-stack aware application should behave on J. Random User's machine where it doesn't know if she's using Teredo (or some other way of getting global IPv6 connectivity) or not.
caf
+4  A: 

Please do try IPv6. In the significant majority of installations, trying to create an IPv6 connection will fail right away if it can't succeed for some reason:

  • if the system doesn't support IPv6 sockets, creating the socket will fail
  • if the system does support IPv6, and has link-local addresses configured, there won't be any routing table entry for the global IPv6 addresses. Again, the local kernel will report failure without sending any packets.
  • if the system does have a global IP address, but some link necessary for routing is missing, the source should be getting an ICMPv6 error message, indicating that the destination cannot be reached; likewise if the destination has an IPv6 address, but the service isn't listening on it.

There are of course cases where things can break, e.g. if a global (or tunnel) address is configured, and something falsely filters out ICMPv6 error messages. You shouldn't worry about this case - it may be just as well that IPv4 connectivity is somehow broken.

Of course, it's debatable whether you really need to try the IPv6 addresses first - you might just as well try them second. In general, you should try addresses in the order in which they are returned from getaddrinfo. Today, systems support configuration options that let administators decide in what order addresses should be returned from getaddrinfo.

Martin v. Löwis
+1 Examples of "configuration options" are gai.conf on Linux and ip6addrctrl.conf on FreeBSD.
bortzmeyer
I'm going to run with this. (Although I do need to decide the order to try addresses, because I'm using an asynchronous resolver library rather than the blocking `getaddrinfo()` - that's still good advice for those who are using the latter though).
caf
Martin, I would say the developer *should* worry about the case of blackholed IPv6 :-) - take a look at http://lists.cluenet.de/pipermail/ipv6-ops/2009-November/002658.html and the threads around. At present, it is a real-world problem. And given the setup (typically the ones who implement IPv6 are server sites, and the ones that are broken are the eyeball networks), it creates a catch22 for the migration. (Unlike the TCP widespread window scaling brokennes a couple of years ago). Otherwise, +1.
Andrew Y
@Andrew: Notice that this is a different problem. As Tore reports, the majority of problems is caused by Opera, which (apparently) doesn't implement fallback to IPv4 properly. There are then additional failures - however, there are also other web browsers which show the same flaw. There are then also misconfigurations in the IPv6 net causing such problems; those get likely fixed as people run into them. So activating a dual-stack webserver indeed needs to be considered carefully. If you write TCP clients, I stand by my recommendation to use the OS configuration.
Martin v. Löwis
@Martin: I did not disagree with the idea of using the OS configuration as much as possible. Just that the blackholes are real and sometimes could be not very trivial to fix. But depends on deployment model. Still given that there are two ways to establish connection, in some environments (home PCs? there is frequently no administrator) it might be useful to have some additional robustness at the application level - for the user experience, not technical reasons. Purely technically I am 200% with you - "the broken" should be noticeable so it gets fixed.
Andrew Y