Bug 614526: Pass AI_ADDRCONFIG to getaddrinfo if PR_AI_ADDRCONFIG is set.
authorWan-Teh Chang <wtc@google.com>
Thu, 27 Jan 2011 15:55:40 -0800
changeset 61417 00bf6b6767d31def2a2d37acf3d5529bb8714f82
parent 61416 3211c8b1b76109ba025ec76afe57ad8a916749e0
child 61418 81d830ef76fd06057743a10395993de9e89d24f2
push id18355
push userwtc@google.com
push dateThu, 27 Jan 2011 23:55:56 +0000
treeherdermozilla-central@00bf6b6767d3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs614526
milestone2.0b11pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 614526: Pass AI_ADDRCONFIG to getaddrinfo if PR_AI_ADDRCONFIG is set. Filter the various localhost names to work around a AI_ADDRCONFIG problem with loopback addresses in some implementations. The patch is contributed by Honza Bambas <honzab.moz@firemni.cz>. r=wtc. a=blocking+approval2.0.
nsprpub/pr/src/misc/prnetdb.c
--- a/nsprpub/pr/src/misc/prnetdb.c
+++ b/nsprpub/pr/src/misc/prnetdb.c
@@ -2034,17 +2034,42 @@ PR_IMPLEMENT(PRAddrInfo *) PR_GetAddrInf
 
         /*
          * we assume a RFC 2553 compliant getaddrinfo.  this may at some
          * point need to be customized as platforms begin to adopt the
          * RFC 3493.
          */
 
         memset(&hints, 0, sizeof(hints));
-        hints.ai_flags = (flags & PR_AI_NOCANONNAME) ? 0: AI_CANONNAME;
+        if (flags & PR_AI_NOCANONNAME)
+            hints.ai_flags |= AI_CANONNAME;
+#ifdef AI_ADDRCONFIG
+        /* 
+         * Propagate AI_ADDRCONFIG to the GETADDRINFO call if PR_AI_ADDRCONFIG
+         * is set.
+         * 
+         * Need a workaround for loopback host addresses:         
+         * The problem is that in glibc and Windows, AI_ADDRCONFIG applies the
+         * existence of an outgoing network interface to IP addresses of the
+         * loopback interface, due to a strict interpretation of the
+         * specification.  For example, if a computer does not have any
+         * outgoing IPv6 network interface, but its loopback network interface
+         * supports IPv6, a getaddrinfo call on "localhost" with AI_ADDRCONFIG
+         * won't return the IPv6 loopback address "::1", because getaddrinfo
+         * thinks the computer cannot connect to any IPv6 destination,
+         * ignoring the remote vs. local/loopback distinction.
+         */
+        if ((flags & PR_AI_ADDRCONFIG) &&
+            strcmp(hostname, "localhost") != 0 &&
+            strcmp(hostname, "localhost.localdomain") != 0 &&
+            strcmp(hostname, "localhost6") != 0 &&
+            strcmp(hostname, "localhost6.localdomain6") != 0) {
+            hints.ai_flags |= AI_ADDRCONFIG;
+        }
+#endif
         hints.ai_family = (af == PR_AF_INET) ? AF_INET : AF_UNSPEC;
 
         /*
          * it is important to select a socket type in the hints, otherwise we
          * will get back repetitive entries: one for each socket type.  since
          * we do not expose ai_socktype through our API, it is okay to do this
          * here.  the application may still choose to create a socket of some
          * other type.