Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 14 Jul 2012 18:49:51 -0500
From:      Zhihao Yuan <lichray@gmail.com>
To:        freebsd-hackers@freebsd.org
Subject:   Interesting facts about AI_ADDRCONFIG
Message-ID:  <CAGsORuD_W5UXNuycFdX1Frzvo4sbQDWmEchzyRKbPhA=mdj2kA@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
Hi, hackers:

FreeBSD's AI_ADDRCONFIG flag used by getaddrinfo(3) is regarded as broken:

        https://wikispaces.psu.edu/display/ipv6/IPv6+programming#IPv6programming-AIADDRCONFIGflag

The short reason is that it still queries for both A and AAAA even one
of them is not configured. The details are interesting:

In rfc2553, AI_ADDRCONFIG is described as:

- The AI_ADDRCONFIG flag specifies that a query for AAAA records
        should occur only if the node has at least one IPv6 source
        address configured and a query for A records should occur only
        if the node has at least one IPv4 source address configured.

Note that the description applies to getipnodebyname() actually, but
we can expect that it also applies to getaddrinfo().

And compare the above with the description from POSIX.1-2008:

        If the AI_ADDRCONFIG flag is specified, IPv4 addresses shall be
        returned only if an IPv4 address is configured on the local system,
        and IPv6 addresses shall be returned only if an IPv6 address
is configured on the local system.

See the difference? POSIX does not care whether the addresses are
"queried"; it only says that it should be not returned. Hence, you can
query them first and filter them latter...

However, this is not the biggest problem. The main chaos is about
whether a loopback IP address can be considered "configured":

        An embarrassing workaround by Mozilla:
        https://mxr.mozilla.org/mozilla-central/source/nsprpub/pr/src/misc/prnetdb.c#2013

In 2003, rfc3493 responded the problem as:

 - If the AI_ADDRCONFIG flag is specified, IPv4 addresses shall be
   returned only if an IPv4 address is configured on the local system,
   and IPv6 addresses shall be returned only if an IPv6 address is
   configured on the local system.  The loopback address is not
   considered for this case as valid as a configured address.

      For example, when using the DNS, a query for AAAA records should
      occur only if the node has at least one IPv6 address configured
      (other than IPv6 loopback) and a query for A records should occur
      only if the node has at least one IPv4 address configured (other
      than the IPv4 loopback).

Now I think things becomes clear:

  To support AI_ADDRCONFIG in a POSIX+RFC way, getaddrinfo(3) should
detect outbound address availability first, then query.

Let's go back to the code in FreeBSD:

  In lib/libc/net/getaddrinfo.c and lib/libc/net/name6.c ,
AI_ADDRCONFIG is implemented as "filter out the unsupported AFs in
kernel, then query". Obviously it's a misinterpretation of the word
"configured", and the implementation does not confirm with any
standards.

A better impl may be bind9's lwres_getipnodebyname() (in
contrib/bind9/lib/lwres/getipnode.c). It carefully uses ioctl(2) to
obtain the addr info on interfaces, then do query. I'm not sure
whether it handles the loopback problem, but it's much better then
what we have in libc.

So... What we going to do?

-- 
Zhihao Yuan, nickname lichray
The best way to predict the future is to invent it.
___________________________________________________
4BSD -- http://4bsd.biz/



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAGsORuD_W5UXNuycFdX1Frzvo4sbQDWmEchzyRKbPhA=mdj2kA>