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. r=wtc. a1.9.1.19=dveditz.
authorHonza Bambas <honzab.moz@firemni.cz>
Thu, 27 Jan 2011 15:55:40 -0800
changeset 27369 7564dd07fd03c7bfe5ab7f4975a9021ca291c29a
parent 27366 8bd29f61a666c64e31f5196691bda202d10f08f4
child 27370 aeeba2b6d48747da0d99e90fa49771039bc9e14e
push id2695
push userdbaron@mozilla.com
push dateSun, 20 Mar 2011 16:16:38 +0000
reviewerswtc
bugs614526
milestone1.9.1.19pre
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. r=wtc. a1.9.1.19=dveditz.
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.