landing NSPR portion of patch for bug 239358 "DNS: Reverse lookups are degrading performance" NSPRPUB_PRE_4_2_CLIENT_BRANCH
authordarin%meer.net
Mon, 30 Aug 2004 23:29:52 +0000
branchNSPRPUB_PRE_4_2_CLIENT_BRANCH
changeset 3170 a475d91c9b6f28dcfe50112b13a72cc49dbb04e4
parent 3168 4d01a6fa275370c6402d7539728039d533bae90d
child 3175 d84bd5f87a7f02a572e96d43753461932b34e975
push idunknown
push userunknown
push dateunknown
bugs239358
landing NSPR portion of patch for bug 239358 "DNS: Reverse lookups are degrading performance" patch by lorenzo@colitti.com, r=wtc, sr=darin
pr/include/prnetdb.h
pr/src/misc/prnetdb.c
--- a/pr/include/prnetdb.h
+++ b/pr/include/prnetdb.h
@@ -132,20 +132,21 @@ NSPR_API(PRStatus) PR_GetHostByName(
 **                      is allocated by the caller.
 ** RETURN:
 **  PRStatus            PR_SUCCESS if the lookup succeeds. If it fails
 **                      the result will be PR_FAILURE and the reason
 **                      for the failure can be retrieved by PR_GetError().
 ***********************************************************************/
 
 
-#define PR_AI_ALL        0x08
-#define PR_AI_V4MAPPED   0x10
-#define PR_AI_ADDRCONFIG 0x20
-#define PR_AI_DEFAULT    (PR_AI_V4MAPPED | PR_AI_ADDRCONFIG)
+#define PR_AI_ALL         0x08
+#define PR_AI_V4MAPPED    0x10
+#define PR_AI_ADDRCONFIG  0x20
+#define PR_AI_NOCANONNAME 0x8000
+#define PR_AI_DEFAULT     (PR_AI_V4MAPPED | PR_AI_ADDRCONFIG)
 
 NSPR_API(PRStatus) PR_GetIPNodeByName(
     const char *hostname,
     PRUint16 af,
     PRIntn flags,
     char *buf,
     PRIntn bufsize,
     PRHostEnt *hostentry);
@@ -391,18 +392,21 @@ NSPR_API(PRStatus) PR_GetProtoByNumber(
 /***********************************************************************
 ** FUNCTION:
 ** DESCRIPTION: PR_GetAddrInfoByName()
 **  Lookup a host by name. Equivalent to getaddrinfo(host, NULL, ...) of
 **  RFC 3493.
 **
 ** INPUTS:
 **  char *hostname      Character string defining the host name of interest
-**  PRUint16 af         Must be PR_AF_UNSPEC
-**  PRIntn flags        Must be PR_AI_ADDRCONFIG
+**  PRUint16 af         May be PR_AF_UNSPEC or PR_AF_INET.
+**  PRIntn flags        May be either PR_AI_ADDRCONFIG or
+**                      PR_AI_ADDRCONFIG | PR_AI_NOCANONNAME. Include
+**                      PR_AI_NOCANONNAME to suppress the determination of
+**                      the canonical name corresponding to hostname.
 ** RETURN:
 **  PRAddrInfo*         Handle to a data structure containing the results
 **                      of the host lookup. Use PR_EnumerateAddrInfo to
 **                      inspect the PRNetAddr values stored in this object.
 **                      When no longer needed, this handle must be destroyed
 **                      with a call to PR_FreeAddrInfo.  If a lookup error
 **                      occurs, then NULL will be returned.
 ***********************************************************************/
--- a/pr/src/misc/prnetdb.c
+++ b/pr/src/misc/prnetdb.c
@@ -2026,16 +2026,17 @@ PRStatus
 /*
  * If getaddrinfo does not exist, then we will fall back on
  * PR_GetHostByName, which requires that we allocate a buffer for the 
  * PRHostEnt data structure and its members.
  */
 typedef struct PRAddrInfoFB {
     char      buf[PR_NETDB_BUF_SIZE];
     PRHostEnt hostent;
+    PRBool    has_cname;
 } PRAddrInfoFB;
 
 static PRAddrInfo *
 pr_GetAddrInfoByNameFB(const char  *hostname,
                        PRUint16     af,
                        PRIntn       flags)
 {
     PRStatus rv;
@@ -2046,25 +2047,28 @@ pr_GetAddrInfoByNameFB(const char  *host
         PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
         return NULL;
     }
     rv = PR_GetHostByName(hostname, ai->buf, sizeof ai->buf, &ai->hostent);
     if (rv == PR_FAILURE) {
         PR_Free(ai);
         return NULL;
     }
+    ai->has_cname = !(flags & PR_AI_NOCANONNAME);
+
     return (PRAddrInfo *) ai;
 }
 
 PR_IMPLEMENT(PRAddrInfo *) PR_GetAddrInfoByName(const char  *hostname,
                                                 PRUint16     af,
                                                 PRIntn       flags)
 {
     /* restrict input to supported values */
-    if ((af != PR_AF_INET && af != PR_AF_UNSPEC) || flags != PR_AI_ADDRCONFIG) {
+    if ((af != PR_AF_INET && af != PR_AF_UNSPEC) ||
+        (flags & ~ PR_AI_NOCANONNAME) != PR_AI_ADDRCONFIG) {
         PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
         return NULL;
     }
 
     if (!_pr_initialized) _PR_ImplicitInitialization();
 
 #if !defined(_PR_HAVE_GETADDRINFO)
     return pr_GetAddrInfoByNameFB(hostname, af, flags);
@@ -2080,17 +2084,17 @@ 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 = AI_CANONNAME;
+        hints.ai_flags = (flags & PR_AI_NOCANONNAME) ? 0: AI_CANONNAME;
         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.
@@ -2167,16 +2171,19 @@ PR_IMPLEMENT(void *) PR_EnumerateAddrInf
     return (void *) iter;
 #endif
 }
 
 PR_IMPLEMENT(const char *) PR_GetCanonNameFromAddrInfo(const PRAddrInfo *ai)
 {
 #if defined(_PR_HAVE_GETADDRINFO)
 #if defined(_PR_INET6_PROBE)
-    if (!_pr_ipv6_is_present)
-        return ((const PRAddrInfoFB *) ai)->hostent.h_name;
+    if (!_pr_ipv6_is_present) {
+        const PRAddrInfoFB *fb = (const PRAddrInfoFB *) ai;
+        return fb->has_cname ? fb->hostent.h_name : NULL;
+    } 
 #endif
     return ((const PRADDRINFO *) ai)->ai_canonname;
 #else
-    return ((const PRAddrInfoFB *) ai)->hostent.h_name;
+    const PRAddrInfoFB *fb = (const PRAddrInfoFB *) ai;
+    return fb->has_cname ? fb->hostent.h_name : NULL;
 #endif
 }