Initially, most IPv6 deployments will be "Dual Stack". In this case, a host will be able to connect via IPv4 and IPv6. This brings up the question which protocol will be preferred, and if multiple addresses are possible, which source and destination address are used. RFC 6724 describes the current standard how addresses should be selected, but operating systems and applications, in particular browsers, do not always obey this RFC.
Lets consider a case where a web browser attempts to connect to a web server. Initially, the browser will resolve the web servers host name. The reply may include multiple IPv4 and IPv6 addresses, and the browser needs to select one destination address from the set of addresses returned. RFC 6724 offers a number of rules to accomplish this selection. I don't want to recite the detailed rules (which are a bit hard to parse and best left to the original RFC), but instead focus on the rules that are used in current operating systems and can explain some behavior seen in connections:
Rule 1: Rule one allows the operating system to maintain a list of addresses that turned out to be unreachable in the past. OS X for example does so. This rule takes into account that some connections may use tunnels or other mechanisms that make IPv6 (and later maybe IPv4) less stable. However, if an address once turned out to be bad and got blacklisted, it will remain unused even if connectivity is later repaired.
Rule 7: To continue with unstable tunneling mechanisms, Rule 7 will prefer native connectivity over tunneled connectivity. A "native" IPv4 address will be preferred over an automatically configured 6-to-4 tunnel with a 2002::/16 prefix. Teredo, another tunnel mechanism, was for example never meant to be preferred over IPv4 and is considered a connection of last resort. But for other tunnels it may not be obvious that they are tunnels (e.g. statically configured tunnels) and they are treated as native addresses)
In addition, applications may try to recover from a bad address choice on their own. This algorithm is usually referred to as "Happy Eyeballs" and Chrome is probably the most prominent implementation of it at this point. Normally, the preferred address pair is determined using an algorithm like the one outlined in RFC 6724, and a connection is attempted. Only after the connection timed out (which can take a while), the respective address is considered unreachable and a different address is used. Chrome on the other hand will wait only 300 ms to consider an address "bad". In addition, the address will not be added to a blacklist. Instead the address may be attempted again for the next connection. The result is that Chrome may flip forth and back between IPv4 and IPv6 as it connects to retrieve multiple pages from a dual stack web server. This can make it for example more difficult to analyze logs or conduct network forensics.
Happy Eyeballs is defined in more detail in RFC6555. It suggests not giving up too quickly on the IPv6 connection to avoid wasted network bandwidth. The recommended timeout per this RFC is 150-250ms.Defending Web Applications Security Essentials - SANS San Francisco Winter 2019
Mar 25th 2013
6 years ago