Android/IPv6

From Segfault
Jump to navigation Jump to search

Introduction

On Android 4.0.3 (Linux 3.0.16-gc764bfb), nslookup from BusyBox v1.18.5 returns AAAA records before the A record:

android$ nslookup www.kame.net
Server:    192.168.0.2
Address 1: 192.168.0.2

Name:      www.kame.net
Address 1: 2001:200:dff:fff1:216:3eff:feb1:44d7
Address 2: 203.178.141.194 orange.kame.net

On Linux (Debian/wheezy), nslookup from dnsutils v9.8.4 returns only the A record:

wheezy$ nslookup www.kame.net
Server:         192.168.0.2
Address:        192.168.0.2#53

Non-authoritative answer:
www.kame.net    canonical name = orange.kame.net.
Name:   orange.kame.net
Address: 203.178.141.194

And host v9.8.4 has it the other way around:

wheezy$  host www.kame.net
www.kame.net is an alias for orange.kame.net.
orange.kame.net has address 203.178.141.194
orange.kame.net has IPv6 address 2001:200:dff:fff1:216:3eff:feb1:44d7

Glibc returns the AAAA record:

wheezy$ getent hosts www.kame.net
2001:200:dff:fff1:216:3eff:feb1:44d7 orange.kame.net www.kame.net

Note:

  • MacOS 10.7.5 seems to behave like Linux here
  • there's no host(1) utility on Android!

The kernel configuration differs only slightly:

$ sysctl -a -r ipv6 | grep -Ev '(conf|neigh)\.(wlan|ip6tnl0|sit0|rmnet|dummy|lo|default|eth0)'
$ diff out.wheezy out.android
6c6,7
< net.ipv6.conf.all.accept_redirects = 0
---
> net.ipv6.conf.all.accept_ra_rtr_pref = 1
> net.ipv6.conf.all.accept_redirects = 1
18c19
< net.ipv6.conf.all.ndisc_notify = 0
---
> net.ipv6.conf.all.optimistic_dad = 0
20a22
> net.ipv6.conf.all.router_probe_interval = 60
28,29c30,31
< net.ipv6.ip6frag_high_thresh = 4194304
< net.ipv6.ip6frag_low_thresh = 3145728
---
> net.ipv6.ip6frag_high_thresh = 262144
> net.ipv6.ip6frag_low_thresh = 196608
41a44
> net.ipv6.xfrm6_gc_thresh = 2048

gai.conf[1] has not been changed on the wheezy system (and is not present on Android):

wheezy$ grep ^[a-z] /etc/gai.conf
precedence ::ffff:0:0/96  100

But this only controls getaddrinfo which seems to be fine for Linux. Changing the resolver should alter the output of dnsutils, but it did not:

wheezy$ cat /etc/resolv.conf
domain example.org
nameserver 192.168.0.2
options inet6

Still, host returns the A record first on Linux / MacOS X.

Problem

What I really like to do is disable IPv6 for certain addresses: some hosts have an AAAA record but are not reachable via IPv6. Some applications do not detect this and try to contact their AAAA record until a timeout is reached.

Links

Android issues:

References