What Linux's getaddrinfo() is doing with IPv6 (on some versions)

February 23, 2010

I've previously noted that Linux's getaddrinfo() implementation doesn't return IPv6 addresses by default if it doesn't think that your system is IPv6 capable, or perhaps if your system has IPv6 disabled (this is most conveniently visible through the Python interface). This behavior is more or less the same as what you'd get if you supplied the AI_ADDRCONFIG flag in the hints structure.

(To be specific, I have seen this behavior on Ubuntu 8.04. It doesn't seem to be present in Ubuntu 6.06, and unfortunately I don't have any other Linux machines with IPv6 disabled to test on.)

This behavior is half-documented in modern getaddrinfo() manpages, which say that if you supply no hints structure you get flags that include AI_ADDRCONFIG. However this is not the full story, since you also get this behavior if you supply a hints structure with ai_family set to 0 (aka AF_UNSPEC).

I would love to report that I had found the code that does this in glibc. However, the glibc getaddrinfo() internals have defeated me; I cannot see any clear code that has this particular side effect. So all I can do is report what I have determined experimentally, which is that supplying a non-zero set of flags in af_flags doesn't make a difference, nor does the type of socket you ask for. The only thing that will get you IPv6 addresses on such a Linux system is putting AF_INET6 in the ai_family field, at which point they will magically appear.

(Note that this behavior is subtly different from turning on the AI_ADDRCONFIG flag all the time, as the flag causes IPv6 results to never get returned, even if you ask for them specifically.)

I assume that this is why 'getents ahostsv6' (from the comments here) will fail on such a system; I expect it is making a plain getaddrinfo() call and filtering the results if you ask specifically for IPv6 addresses.

(The getents behavior may be a bug, but the glibc getaddrinfo() behavior is probably deliberate.)


Comments on this page:

From 143.48.3.13 at 2010-02-23 12:15:07:

A more interesting behavior of IPv6 in glibc is how it deals with the order of AAAA and A records. Say you have a host named server.mydomain.org, and your resolver is configured with the search domain mydomain.org. If you make a request for server.mydomain.org, Linux will query the DNS server for these records, in order:

  • server.mydomain.org/AAAA
  • server.mydomain.org.mydomain.org/AAAA
  • server.mydomain.org/A
  • server.mydomain.org.mydomain.org/A

I only found this behavior by coincidence after turning on BIND logging.

You would really think that it would actually, you know, query the DNS name you actually gave it before just making one up, but if you have some really bizarre DNS layout (which might happen if ICANN moves forward on arbitrary TLDs) then you could conceivably run into some weird collision issues.

--Jeff

From 65.172.155.230 at 2010-02-23 15:24:32:

Jeff is that with the default gai.conf settings? I know I changed mine to prefer Ipv4, but I don't think I've tested it with named :o.

By cks at 2010-02-24 01:18:19:

Current versions of glibc do weird things with DNS queries; for example, I understand that these days they'll send out the A and AAAA queries at the same time to reduce the lookup delays. I don't know how they deal with search path based lookups, since there's a tradeoff between minimum latency and not spraying a huge number of DNS requests at the DNS server.

On tabled: I think that the implementation isn't ideal, and in specific I think it has a bug on IPv6 enabled Linux machines that have bindv6only turned on. This prompted me to write up my current knowledge of creating listening sockets in ModernSocketsListening.

From 84.246.161.93 at 2013-01-15 07:52:10:

Hi,

if you are still interested about getaddrinfo behavior after those years, you can look at:

https://fedoraproject.org/wiki/Features/FixNetworkNameResolution

It links to lots of documents on this topic and there are also contacts.

Cheers,

Pavel Šimerda

Written on 23 February 2010.
« Unix portability and scripting language versions
How to listen on a socket in the modern IPv6-enabled world »

Page tools: View Source, View Normal.
Search:
Login: Password:

Last modified: Tue Feb 23 02:32:40 2010
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.