Hurricane Electric's IPv6 Tunnel Broker Forums Specific Topics => Questions & Answers => Topic started by: CaroleSeaton on June 21, 2013, 09:57:02 AM

Title: Getting around Apple's "Hampering Eyeballs"
Post by: CaroleSeaton on June 21, 2013, 09:57:02 AM
Users of Apple products may have noticed that Apple operating systems are absurdly aggressive in seeking out IPv4 connections when IPv6 is available, what Emile Aben called "hampering eyeballs". NAT64/DNS64 can be used to force a preference for IPv6, since DNS64 ignores A records whenever AAAA records are available, but there really aren't any NAT64 implementations suitable for home use right now.

For the sake of people who find this irksome, would it be possible for Hurricane to dedicate a conventional DNS server that replicates this behavior, returning A records only when no AAAA records are available?
Title: Re: Getting around Apple's "Hampering Eyeballs"
Post by: kasperd on June 21, 2013, 03:15:05 PM
I think you might not have understood how DNS64 works. It does not remove or ignore any DNS records. It creates synthetic AAAA records on domains, which were otherwise IPv4 only. But it does not remove any A records.

The only reason this would cause clients to prefer IPv6 is due to the clients typically having no IPv4 connectivity. It is the lack of IPv4 connectivity, which cause them to prefer IPv6. In case of dual stack domains, DNS64 does nothing. It only creates synthetic AAAA records, if there are none.

Suppressing A records on dual stack domains may be a useful feature in some cases. I have however not found any existing support for this in any of the DNS servers, I knew of.
Title: Re: Getting around Apple's "Hampering Eyeballs"
Post by: aandaluz on June 23, 2013, 05:05:18 AM
I also hate how apple has implemented happy eyeballs in osx, as emile described in  this nice article (
 If you use Chrome as your web browser, you can enable the built in asyncronous Dns client ( to bypass OSX's address resolution mechanism and use chrome's happy eyeballs implementation, which uses a 300ms timeout. This way, most hosts will be reachable over ipv6 by default:

chrome async dns( ( osx 10.8 dns( (
This is far from an universal bugfix. For instance, I cannot reach  over ipv6 unless i disable completely ipv4. It is pretty normal, since latency is abnormally high in the ipv6 path

PING ( 56 data bytes
64 bytes from icmp_seq=0 ttl=44 time=64.973 ms
64 bytes from icmp_seq=1 ttl=44 time=70.106 ms
64 bytes from icmp_seq=2 ttl=44 time=67.604 ms

PING6(56=40+8+8 bytes) 2001:470:7b31::d8ce:f1b9:731f:23e6 --> 2001:420:81:101::c:15c0:4664
16 bytes from 2001:420:81:101::c:15c0:4664, icmp_seq=0 hlim=51 time=389.828 ms
16 bytes from 2001:420:81:101::c:15c0:4664, icmp_seq=1 hlim=51 time=465.396 ms
16 bytes from 2001:420:81:101::c:15c0:4664, icmp_seq=2 hlim=51 time=489.043 ms
--- ping6 statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 389.828/433.681/489.043/44.334 ms


traceroute to (, 64 hops max, 52 byte packets
 1 (  1.101 ms  0.848 ms  0.763 ms
 2 (  20.398 ms  20.567 ms  20.480 ms
 3 (  20.896 ms  20.977 ms  20.879 ms
 4 (  35.082 ms  23.396 ms  34.402 ms
 5 (  20.309 ms  20.711 ms  20.271 ms
 6 (  23.078 ms  22.370 ms  23.773 ms
 7 (  21.974 ms  22.560 ms  21.453 ms
 8 (  23.583 ms  23.299 ms  24.781 ms
 9 (  21.385 ms  21.520 ms  21.685 ms
10 (  43.921 ms  39.135 ms  39.795 ms
11 (  38.919 ms  38.332 ms  38.670 ms
12 (  37.903 ms  38.584 ms  38.290 ms
13 (  49.269 ms  49.571 ms  50.014 ms
14 (  50.184 ms  49.472 ms  49.515 ms
15 (  50.437 ms  49.170 ms  49.678 ms
16 (  49.818 ms  49.961 ms  50.248 ms
17 (  50.296 ms  50.748 ms  50.267 ms
18 (  50.092 ms  50.019 ms  49.814 ms
19  * * *
20  * * *
21  * * *

traceroute6 to (2001:420:81:101::c:15c0:4664) from 2001:470:7b31::d8ce:f1b9:731f:23e6, 64 hops max, 12 byte packets
 1  2001:470:7b31::1  5.535 ms  0.955 ms  0.835 ms
 2  67.188 ms  68.240 ms  67.754 ms
 3  62.892 ms  63.229 ms  73.253 ms
 4  81.217 ms  78.039 ms  75.962 ms
 5  139.029 ms  138.334 ms  148.079 ms
 6  157.721 ms  167.701 ms  158.859 ms
 7  179.830 ms  186.978 ms  181.190 ms
 8  245.792 ms  294.949 ms  321.921 ms
 9  221.109 ms  216.493 ms  206.568 ms
10  211.545 ms  306.828 ms  294.148 ms
11  2001:420:80:8::2  212.289 ms  210.035 ms  231.959 ms
12  2001:420:81:100::2  483.688 ms  409.067 ms  407.829 ms
13  * * *
14  * * *
15  * * *
16  * * *
17  * * *
18  * * *
19  * * *
Title: Re: Getting around Apple's "Hampering Eyeballs"
Post by: aandaluz on July 10, 2015, 11:42:30 AM
Sorry for the thread necromacy, but it seems that osx elcapitan and ios9 will finally get rid of hampering eyeballs  :D
Hi everyone,

Today Apple released the first public seeds of iOS 9 and OS X El Capitan.
These seeds (and the third developer seeds released yesterday) include an improved version of Happy Eyeballs.

Based on our testing, this makes our Happy Eyeballs implementation go from roughly 50/50 IPv4/IPv6 in iOS 8 and Yosemite
to ~99% IPv6 in iOS 9 and El Capitan betas.

While our previous implementation from four years ago was designed to select the connection with lowest latency
no matter what, we agree that the Internet has changed since then and reports indicate that biasing towards IPv6 is now
beneficial for our customers: IPv6 is now mainstream instead of being an exception, there are less broken IPv6 tunnels,
IPv4 carrier-grade NATs are increasing in numbers, and throughput may even be better on average over IPv6.

The updated implementation performs the following:
- Query the DNS resolver for A and AAAA.
   If the DNS records are not in the cache, the requests are sent back to back on the wire, AAAA first.
- If the first reply we get is AAAA, we send out the v6 SYN immediately
- If the first reply we get is A and we're expecting a AAAA, we start a 25ms timer
   - If the timer fires, we send out the v4 SYN
   - If we get the AAAA during that 25ms window, we move on to address selection
- When we have a list of IP addresses (either from the DNS cache or by receiving them close together with v4 before v6),
   we perform our own address selection algorithm to sort them. This algorithm uses historical RTT data to prefer addresses
   that have lower latency - but has a 25ms leeway: if the historical RTT of two compared address are within 25ms of each
   other, we use RFC3484 to pick the best one.
- Once the list is sorted, we send out the SYN for the first address and start timers based on average and variance of the
   historical TCP RTT. Roughly speaking, we start the second address around the same time we send out a SYN retransmission
   for the first address.
- The first address to reply with a SYN-ACK wins the race, we then cancel the other TCP connection attempts.

If this behavior proves successful during the beta period, you should expect more IPv6 traffic from Apple products in the future.
Note however that this only describes the current beta and all these details are subject to change.

Please test this out if you have the means to, we'd love to see test results and receive feedback!

I would like to personally thank Jason Fesler and Paul Saab for their help investigating these issues and testing this.

David Schinazi
CoreOS Networking Engineer