From owner-freebsd-hackers@FreeBSD.ORG Sat Jul 14 23:49:52 2012 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 213DF106564A for ; Sat, 14 Jul 2012 23:49:52 +0000 (UTC) (envelope-from lichray@gmail.com) Received: from mail-ob0-f182.google.com (mail-ob0-f182.google.com [209.85.214.182]) by mx1.freebsd.org (Postfix) with ESMTP id DEC528FC17 for ; Sat, 14 Jul 2012 23:49:51 +0000 (UTC) Received: by obbun3 with SMTP id un3so8822363obb.13 for ; Sat, 14 Jul 2012 16:49:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=F134qe6cOu9CP+1Hmw9810ZCkC+aornvtDzoHnJJUZA=; b=QtmeghteLDfSmA457sHy+gwW6tf19Ar1QJYLE3vXz0Rqlv5tXAHj6bd8thFYRDklR0 Mm/n7dk9fq6m11uwIh0HQrq0691Ylu2wqaJ2s5UrfyvV3bQdyygoKUPb8+yOns7oCcPZ WL7sBG/EcyvnAmYDEt65Uam7GLxeRFunaBTDnedNJKYi0Se5vEdW+Vh6vipQLxihC4am I9V/Y8zjcW2iCKcUujfS3DNOqj3GlIAJ2Np1V3zybIgt7UtqoJgo2Q7iGsepzh2FL6kU rYknIfmPC7aCtkeyVG1PTe9FaMk/doX/LlTziS5R630yZuFtRcpnrKtC7/lIPGIW682e ZZpA== MIME-Version: 1.0 Received: by 10.50.213.1 with SMTP id no1mr2154933igc.71.1342309791167; Sat, 14 Jul 2012 16:49:51 -0700 (PDT) Received: by 10.231.72.133 with HTTP; Sat, 14 Jul 2012 16:49:51 -0700 (PDT) Date: Sat, 14 Jul 2012 18:49:51 -0500 Message-ID: From: Zhihao Yuan To: freebsd-hackers@freebsd.org Content-Type: text/plain; charset=UTF-8 Subject: Interesting facts about AI_ADDRCONFIG X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 14 Jul 2012 23:49:52 -0000 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/