Blob Blame History Raw
Index: mozilla/nsprpub/pr/include/md/_win95.h
===================================================================
RCS file: /cvsroot/mozilla/nsprpub/pr/include/md/_win95.h,v
retrieving revision 3.30.2.1
diff -u -r3.30.2.1 _win95.h
--- mozilla/nsprpub/pr/include/md/_win95.h	5 Apr 2006 21:51:23 -0000	3.30.2.1
+++ mozilla/nsprpub/pr/include/md/_win95.h	22 Feb 2007 02:14:52 -0000
@@ -61,6 +61,8 @@
 /* newer ws2tcpip.h provides these */
 #ifndef AI_CANONNAME
 #define AI_CANONNAME 0x2
+#define AI_NUMERICHOST 0x4
+#define NI_NUMERICHOST 0x02
 struct addrinfo {
     int ai_flags;
     int ai_family;
Index: mozilla/nsprpub/pr/include/md/_winnt.h
===================================================================
RCS file: /cvsroot/mozilla/nsprpub/pr/include/md/_winnt.h,v
retrieving revision 3.30
diff -u -r3.30 _winnt.h
--- mozilla/nsprpub/pr/include/md/_winnt.h	20 Jun 2005 22:05:20 -0000	3.30
+++ mozilla/nsprpub/pr/include/md/_winnt.h	22 Feb 2007 02:14:52 -0000
@@ -76,6 +76,8 @@
 /* newer ws2tcpip.h provides these */
 #ifndef AI_CANONNAME
 #define AI_CANONNAME 0x2
+#define AI_NUMERICHOST 0x4
+#define NI_NUMERICHOST 0x02
 struct addrinfo {
     int ai_flags;
     int ai_family;
Index: mozilla/nsprpub/pr/src/misc/prnetdb.c
===================================================================
RCS file: /cvsroot/mozilla/nsprpub/pr/src/misc/prnetdb.c,v
retrieving revision 3.47.2.1
diff -u -r3.47.2.1 prnetdb.c
--- mozilla/nsprpub/pr/src/misc/prnetdb.c	14 Nov 2006 17:41:59 -0000	3.47.2.1
+++ mozilla/nsprpub/pr/src/misc/prnetdb.c	22 Feb 2007 02:14:52 -0000
@@ -1772,99 +1772,6 @@
 
 #endif /* !_PR_HAVE_INET_NTOP */
 
-PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr)
-{
-    PRStatus status = PR_SUCCESS;
-    PRIntn rv;
-
-#if defined(_PR_HAVE_INET_NTOP)
-    rv = inet_pton(AF_INET6, string, &addr->ipv6.ip);
-    if (1 == rv)
-    {
-        addr->raw.family = PR_AF_INET6;
-    }
-    else
-    {
-        PR_ASSERT(0 == rv);
-        /* clean up after the failed inet_pton() call */
-        memset(&addr->ipv6.ip, 0, sizeof(addr->ipv6.ip));
-        rv = inet_pton(AF_INET, string, &addr->inet.ip);
-        if (1 == rv)
-        {
-            addr->raw.family = AF_INET;
-        }
-        else
-        {
-            PR_ASSERT(0 == rv);
-            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
-            status = PR_FAILURE;
-        }
-    }
-#else /* _PR_HAVE_INET_NTOP */
-    rv = StringToV6Addr(string, &addr->ipv6.ip);
-    if (1 == rv) {
-        addr->raw.family = PR_AF_INET6;
-        return PR_SUCCESS;
-    }
-    PR_ASSERT(0 == rv);
-    /* clean up after the failed StringToV6Addr() call */
-    memset(&addr->ipv6.ip, 0, sizeof(addr->ipv6.ip));
-
-    addr->inet.family = AF_INET;
-#ifdef XP_OS2_VACPP
-    addr->inet.ip = inet_addr((char *)string);
-#else
-    addr->inet.ip = inet_addr(string);
-#endif
-    if ((PRUint32) -1 == addr->inet.ip)
-    {
-        /*
-         * The string argument is a malformed address string.
-         */
-        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
-        status = PR_FAILURE;
-    }
-#endif /* _PR_HAVE_INET_NTOP */
-
-    return status;
-}
-
-PR_IMPLEMENT(PRStatus) PR_NetAddrToString(
-    const PRNetAddr *addr, char *string, PRUint32 size)
-{
-    if (PR_AF_INET6 == addr->raw.family)
-    {
-#if defined(_PR_HAVE_INET_NTOP)
-        if (NULL == inet_ntop(AF_INET6, &addr->ipv6.ip, string, size))
-#else
-        if (NULL == V6AddrToString(&addr->ipv6.ip, string, size))
-#endif
-        {
-            /* the size of the result buffer is inadequate */
-            PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
-            return PR_FAILURE;
-        }
-    }
-    else
-    {
-        if (size < 16) goto failed;
-        if (AF_INET != addr->raw.family) goto failed;
-        else
-        {
-            unsigned char *byte = (unsigned char*)&addr->inet.ip;
-            PR_snprintf(string, size, "%u.%u.%u.%u",
-                byte[0], byte[1], byte[2], byte[3]);
-        }
-    }
-
-    return PR_SUCCESS;
-
-failed:
-    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
-    return PR_FAILURE;
-
-}  /* PR_NetAddrToString */
-
 /*
  * Convert an IPv4 addr to an (IPv4-mapped) IPv6 addr
  */
@@ -1947,12 +1854,13 @@
 typedef struct addrinfo PRADDRINFO;
 #define GETADDRINFO getaddrinfo
 #define FREEADDRINFO freeaddrinfo
+#define GETNAMEINFO getnameinfo
 
 #elif defined(_PR_INET6_PROBE)
 
 typedef struct addrinfo PRADDRINFO;
 
-/* getaddrinfo/freeaddrinfo prototypes */ 
+/* getaddrinfo/freeaddrinfo/getnameinfo prototypes */ 
 #if defined(WIN32)
 #define FUNC_MODIFIER __stdcall
 #else
@@ -1965,17 +1873,24 @@
      PRADDRINFO **res);
 typedef int (FUNC_MODIFIER * FN_FREEADDRINFO)
     (PRADDRINFO *ai);
+typedef int (FUNC_MODIFIER * FN_GETNAMEINFO)
+    (const struct sockaddr *addr, int addrlen,
+     char *host, int hostlen,
+     char *serv, int servlen, int flags);
 
 /* global state */
 static FN_GETADDRINFO   _pr_getaddrinfo   = NULL;
 static FN_FREEADDRINFO  _pr_freeaddrinfo  = NULL;
+static FN_GETNAMEINFO   _pr_getnameinfo   = NULL;
 
 #if defined(VMS)
 #define GETADDRINFO_SYMBOL getenv("GETADDRINFO")
 #define FREEADDRINFO_SYMBOL getenv("FREEADDRINFO")
+#define GETNAMEINFO_SYMBOL getenv("GETNAMEINFO")
 #else
 #define GETADDRINFO_SYMBOL "getaddrinfo"
 #define FREEADDRINFO_SYMBOL "freeaddrinfo"
+#define GETNAMEINFO_SYMBOL "getnameinfo"
 #endif
 
 PRStatus
@@ -2005,7 +1920,12 @@
         }
         _pr_freeaddrinfo = (FN_FREEADDRINFO)
             PR_FindFunctionSymbol(lib, FREEADDRINFO_SYMBOL);
-        PR_ASSERT(_pr_freeaddrinfo);
+        _pr_getnameinfo = (FN_GETNAMEINFO)
+            PR_FindFunctionSymbol(lib, GETNAMEINFO_SYMBOL);
+        if (!_pr_freeaddrinfo || !_pr_getnameinfo) {
+            PR_UnloadLibrary(lib);
+            continue;
+        }
         /* Keep the library loaded. */
         return PR_SUCCESS;
     }
@@ -2022,8 +1942,10 @@
     }
     _pr_freeaddrinfo = (FN_FREEADDRINFO)
         PR_FindFunctionSymbol(lib, FREEADDRINFO_SYMBOL);
+    _pr_getnameinfo = (FN_GETNAMEINFO)
+        PR_FindFunctionSymbol(lib, GETNAMEINFO_SYMBOL);
     PR_UnloadLibrary(lib);
-    if (!_pr_freeaddrinfo) {
+    if (!_pr_freeaddrinfo || !_pr_getnameinfo) {
         return PR_FAILURE;
     }
     return PR_SUCCESS;
@@ -2032,6 +1954,7 @@
 
 #define GETADDRINFO (*_pr_getaddrinfo)
 #define FREEADDRINFO (*_pr_freeaddrinfo)
+#define GETNAMEINFO (*_pr_getnameinfo)
 
 #endif /* _PR_INET6 */
 
@@ -2201,3 +2124,200 @@
     return fb->has_cname ? fb->hostent.h_name : NULL;
 #endif
 }
+
+#if defined(_PR_HAVE_GETADDRINFO)
+static PRStatus pr_StringToNetAddrGAI(const char *string, PRNetAddr *addr)
+{
+    PRADDRINFO *res, hints;
+    int rv;  /* 0 for success, or the error code EAI_xxx */
+    PRNetAddr laddr;
+    PRStatus status = PR_SUCCESS;
+
+    if (NULL == addr)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_flags = AI_NUMERICHOST;
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+
+    rv = GETADDRINFO(string, NULL, &hints, &res);
+    if (rv != 0)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, rv);
+        return PR_FAILURE;
+    }
+
+    /* pick up the first addr */
+    memcpy(&laddr, res->ai_addr, res->ai_addrlen);
+    if (AF_INET6 == res->ai_addr->sa_family)
+    {
+        addr->ipv6.family = PR_AF_INET6;
+        addr->ipv6.ip = laddr.ipv6.ip;
+        addr->ipv6.scope_id = laddr.ipv6.scope_id;
+    }
+    else if (AF_INET == res->ai_addr->sa_family)
+    {
+        addr->inet.family = PR_AF_INET;
+        addr->inet.ip = laddr.inet.ip;
+    }
+    else
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        status = PR_FAILURE;
+    }
+
+    FREEADDRINFO(res);
+    return status;
+}
+#endif  /* _PR_HAVE_GETADDRINFO */
+
+#if !defined(_PR_HAVE_GETADDRINFO) || defined(_PR_INET6_PROBE)
+static PRStatus pr_StringToNetAddrFB(const char *string, PRNetAddr *addr)
+{
+    PRStatus status = PR_SUCCESS;
+    PRIntn rv;
+
+#if defined(_PR_HAVE_INET_NTOP)
+    rv = inet_pton(AF_INET6, string, &addr->ipv6.ip);
+    if (1 == rv)
+    {
+        addr->raw.family = PR_AF_INET6;
+    }
+    else
+    {
+        PR_ASSERT(0 == rv);
+        /* clean up after the failed inet_pton() call */
+        memset(&addr->ipv6.ip, 0, sizeof(addr->ipv6.ip));
+        rv = inet_pton(AF_INET, string, &addr->inet.ip);
+        if (1 == rv)
+        {
+            addr->raw.family = AF_INET;
+        }
+        else
+        {
+            PR_ASSERT(0 == rv);
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            status = PR_FAILURE;
+        }
+    }
+#else /* _PR_HAVE_INET_NTOP */
+    rv = StringToV6Addr(string, &addr->ipv6.ip);
+    if (1 == rv) {
+        addr->raw.family = PR_AF_INET6;
+        return PR_SUCCESS;
+    }
+    PR_ASSERT(0 == rv);
+    /* clean up after the failed StringToV6Addr() call */
+    memset(&addr->ipv6.ip, 0, sizeof(addr->ipv6.ip));
+
+    addr->inet.family = AF_INET;
+#ifdef XP_OS2_VACPP
+    addr->inet.ip = inet_addr((char *)string);
+#else
+    addr->inet.ip = inet_addr(string);
+#endif
+    if ((PRUint32) -1 == addr->inet.ip)
+    {
+        /*
+         * The string argument is a malformed address string.
+         */
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        status = PR_FAILURE;
+    }
+#endif /* _PR_HAVE_INET_NTOP */
+
+    return status;
+}
+#endif /* !_PR_HAVE_GETADDRINFO || _PR_INET6_PROBE */
+
+PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+#if !defined(_PR_HAVE_GETADDRINFO)
+    return pr_StringToNetAddrFB(string, addr);
+#else
+#if defined(_PR_INET6_PROBE)
+    if (!_pr_ipv6_is_present)
+        return pr_StringToNetAddrFB(string, addr);
+#endif
+    return pr_StringToNetAddrGAI(string, addr);
+#endif
+}
+
+#if defined(_PR_HAVE_GETADDRINFO)
+static PRStatus pr_NetAddrToStringGNI(
+    const PRNetAddr *addr, char *string, PRUint32 size)
+{
+    int addrlen;
+    int rv;  /* 0 for success, or the error code EAI_xxx */
+
+    addrlen = PR_NETADDR_SIZE(addr);
+    rv = GETNAMEINFO((const struct sockaddr *)addr, addrlen,
+        string, size, NULL, 0, NI_NUMERICHOST);
+    if (rv != 0)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, rv);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+#endif  /* _PR_HAVE_GETADDRINFO */
+
+#if !defined(_PR_HAVE_GETADDRINFO) || defined(_PR_INET6_PROBE)
+static PRStatus pr_NetAddrToStringFB(
+    const PRNetAddr *addr, char *string, PRUint32 size)
+{
+    if (PR_AF_INET6 == addr->raw.family)
+    {
+#if defined(_PR_HAVE_INET_NTOP)
+        if (NULL == inet_ntop(AF_INET6, &addr->ipv6.ip, string, size))
+#else
+        if (NULL == V6AddrToString(&addr->ipv6.ip, string, size))
+#endif
+        {
+            /* the size of the result buffer is inadequate */
+            PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
+            return PR_FAILURE;
+        }
+    }
+    else
+    {
+        if (size < 16) goto failed;
+        if (AF_INET != addr->raw.family) goto failed;
+        else
+        {
+            unsigned char *byte = (unsigned char*)&addr->inet.ip;
+            PR_snprintf(string, size, "%u.%u.%u.%u",
+                byte[0], byte[1], byte[2], byte[3]);
+        }
+    }
+
+    return PR_SUCCESS;
+
+failed:
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return PR_FAILURE;
+
+}  /* pr_NetAddrToStringFB */
+#endif  /* !_PR_HAVE_GETADDRINFO || _PR_INET6_PROBE */
+
+PR_IMPLEMENT(PRStatus) PR_NetAddrToString(
+    const PRNetAddr *addr, char *string, PRUint32 size)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+#if !defined(_PR_HAVE_GETADDRINFO)
+    return pr_NetAddrToStringFB(addr, string, size);
+#else
+#if defined(_PR_INET6_PROBE)
+    if (!_pr_ipv6_is_present)
+        return pr_NetAddrToStringFB(addr, string, size);
+#endif
+    return pr_NetAddrToStringGNI(addr, string, size);
+#endif
+}  /* PR_NetAddrToString */