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 */