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.2.17=dveditz.
authorHonza Bambas <honzab.moz@firemni.cz>
Thu, 27 Jan 2011 15:55:40 -0800
changeset 35007 c5d74bcd7421
parent 35006 c6d9cb8e77ab
child 35008 5e68ad3bb017
push id1861
push userdbaron@mozilla.com
push date2011-03-20 16:15 +0000
reviewerswtc
bugs614526
milestone1.9.2.17pre
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.2.17=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.