You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2011/08/05 02:52:50 UTC

svn commit: r1154056 - in /trafficserver/traffic/trunk: CHANGES iocore/dns/I_DNSProcessor.h iocore/dns/SplitDNS.cc lib/ts/ink_res_init.cc lib/ts/ink_resolver.h

Author: amc
Date: Fri Aug  5 00:52:50 2011
New Revision: 1154056

URL: http://svn.apache.org/viewvc?rev=1154056&view=rev
Log:
TS-903 IPv6 upgrade and cleanup of resolver code.

Modified:
    trafficserver/traffic/trunk/CHANGES
    trafficserver/traffic/trunk/iocore/dns/I_DNSProcessor.h
    trafficserver/traffic/trunk/iocore/dns/SplitDNS.cc
    trafficserver/traffic/trunk/lib/ts/ink_res_init.cc
    trafficserver/traffic/trunk/lib/ts/ink_resolver.h

Modified: trafficserver/traffic/trunk/CHANGES
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/CHANGES?rev=1154056&r1=1154055&r2=1154056&view=diff
==============================================================================
--- trafficserver/traffic/trunk/CHANGES (original)
+++ trafficserver/traffic/trunk/CHANGES Fri Aug  5 00:52:50 2011
@@ -1,6 +1,11 @@
                                                          -*- coding: utf-8 -*-
 
 Changes with Apache Traffic Server 3.1.0
+  *) [TS-903] Internal resolver library now IPv6 compatible.
+     IP address matching libraries removed, replaced with IpMap which is
+     faster and IPv6 compatible. SOCKS and IpAllow configurations files
+     will now parse IPv6 ranges, although they do not current have effect.
+
   *) [TS-901] Valgrind found minor leaks and uninitialized variables.
    Author: William Bardwell.
 

Modified: trafficserver/traffic/trunk/iocore/dns/I_DNSProcessor.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/dns/I_DNSProcessor.h?rev=1154056&r1=1154055&r2=1154056&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/dns/I_DNSProcessor.h (original)
+++ trafficserver/traffic/trunk/iocore/dns/I_DNSProcessor.h Fri Aug  5 00:52:50 2011
@@ -96,7 +96,7 @@ struct DNSProcessor: public Processor
   //
   EThread *thread;
   DNSHandler *handler;
-  __ink_res_state l_res;
+  ts_imp_res_state l_res;
   Action *getby(const char *x, int len, int type, Continuation *cont, DNSHandler *adnsH = NULL, int timeout = 0);
   void dns_init();
 };

Modified: trafficserver/traffic/trunk/iocore/dns/SplitDNS.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/dns/SplitDNS.cc?rev=1154056&r1=1154055&r2=1154056&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/dns/SplitDNS.cc (original)
+++ trafficserver/traffic/trunk/iocore/dns/SplitDNS.cc Fri Aug  5 00:52:50 2011
@@ -512,9 +512,9 @@ SplitDNSRecord::Init(matcher_line * line
   }
 
   DNSHandler *dnsH = new DNSHandler;
-  ink_res_state res = new __ink_res_state;
+  ink_res_state res = new ts_imp_res_state;
 
-  memset(res, 0, sizeof(__ink_res_state));
+  memset(res, 0, sizeof(ts_imp_res_state));
   if ((-1 == ink_res_init(res, m_servers.x_server_ip, m_servers.x_dns_server_port,
                           m_servers.x_def_domain, m_servers.x_domain_srch_list, NULL))) {
     snprintf(errBuf, errBufLen, "Failed to build res record for the servers %u ... on port %d",

Modified: trafficserver/traffic/trunk/lib/ts/ink_res_init.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/lib/ts/ink_res_init.cc?rev=1154056&r1=1154055&r2=1154056&view=diff
==============================================================================
--- trafficserver/traffic/trunk/lib/ts/ink_res_init.cc (original)
+++ trafficserver/traffic/trunk/lib/ts/ink_res_init.cc Fri Aug  5 00:52:50 2011
@@ -88,19 +88,12 @@
 
 #include "ink_string.h"
 #include "ink_resolver.h"
-
-#if !defined(linux)
-int inet_aton(register const char *cp, struct in_addr *addr);
-#endif
+#include "ink_inet.h"
 
 #if !defined(isascii)           /* XXX - could be a function */
 # define isascii(c) (!(c & 0200))
 #endif
 
-#define DOT_SEPARATED(_x)                                   \
-  ((unsigned char*)&(_x))[0], ((unsigned char*)&(_x))[1],   \
-    ((unsigned char*)&(_x))[2], ((unsigned char*)&(_x))[3]
-
 /*%
  * This routine is for closing the socket if a virtual circuit is used and
  * the program wants to close it.  This provides support for endhostent()
@@ -118,98 +111,32 @@ ink_res_nclose(ink_res_state statp) {
 }
 
 static void
-ink_res_ndestroy(ink_res_state statp) {
-  ink_res_nclose(statp);
-  if (statp->_u._ext.ext != NULL)
-    free(statp->_u._ext.ext);
-  statp->options &= ~INK_RES_INIT;
-  statp->_u._ext.ext = NULL;
-}
-
-static void
-ink_res_setservers(ink_res_state statp, const union ink_res_sockaddr_union *set, int cnt) {
-  int i, nserv;
-  size_t size;
-
+ink_res_setservers(ink_res_state statp, ts_ip_endpoint const* set, int cnt) {
   /* close open servers */
   ink_res_nclose(statp);
 
   /* cause rtt times to be forgotten */
-  statp->_u._ext.nscount = 0;
-
-  nserv = 0;
-  for (i = 0; i < cnt && nserv < INK_MAXNS; i++) {
-    switch (set->sin.sin_family) {
-      case AF_INET:
-        size = sizeof(set->sin);
-        if (statp->_u._ext.ext)
-          memcpy(&statp->_u._ext.ext->nsaddrs[nserv], &set->sin, size);
-        if (size <= sizeof(statp->nsaddr_list[nserv].sin))
-          memcpy(&statp->nsaddr_list[nserv].sin, &set->sin, size);
-        else
-          statp->nsaddr_list[nserv].sin.sin_family = 0;
-        nserv++;
-        break;
-
-#ifdef HAS_INET6_STRUCTS
-      case AF_INET6:
-        size = sizeof(set->sin6);
-        if (statp->_u._ext.ext)
-          memcpy(&statp->_u._ext.ext->nsaddrs[nserv], &set->sin6, size);
-        if (size <= sizeof(statp->nsaddr_list[nserv].sin6))
-          memcpy(&statp->nsaddr_list[nserv].sin6, &set->sin6, size);
-        else
-          statp->nsaddr_list[nserv].sin6.sin6_family = 0;
-        nserv++;
-        break;
-#endif
+  statp->nscount = 0;
 
-      default:
-        break;
-    }
-    set++;
+  int nserv = 0;
+  for ( ts_ip_endpoint const* limit = set + cnt ; nserv < INK_MAXNS && set < limit ; ++set ) {
+    if (ink_inet_copy(&statp->nsaddr_list[nserv].sa, &set->sa)) ++nserv;
   }
   statp->nscount = nserv;
 }
 
 int
-ink_res_getservers(ink_res_state statp, union ink_res_sockaddr_union *set, int cnt) {
-  int i;
-  size_t size;
-  u_int16_t family;
-
-  for (i = 0; i < statp->nscount && i < cnt; i++) {
-    if (statp->_u._ext.ext)
-      family = statp->_u._ext.ext->nsaddrs[i].sin.sin_family;
-    else
-      family = statp->nsaddr_list[i].sin.sin_family;
-
-    switch (family) {
-      case AF_INET:
-        size = sizeof(set->sin);
-        if (statp->_u._ext.ext)
-          memcpy(&set->sin, &statp->_u._ext.ext->nsaddrs[i], size);
-        else
-          memcpy(&set->sin, &statp->nsaddr_list[i].sin, size);
-        break;
+ink_res_getservers(ink_res_state statp, sockaddr *set, int cnt) {
+  int zret = 0; // return count.
+  ts_ip_endpoint const* src = statp->nsaddr_list;
 
-#ifdef HAS_INET6_STRUCTS
-      case AF_INET6:
-        size = sizeof(set->sin6);
-        if (statp->_u._ext.ext)
-          memcpy(&set->sin6, &statp->_u._ext.ext->nsaddrs[i], size);
-        else
-          memcpy(&set->sin6, &statp->nsaddr_list[i].sin6, size);
-        break;
-#endif
-
-      default:
-        set->sin.sin_family = 0;
-        break;
+  for (int i = 0; i < statp->nscount && i < cnt; ++i, ++src) {
+    if (ink_inet_copy(set, &src->sa)) {
+      ++set;
+      ++zret;
     }
-    set++;
   }
-  return (statp->nscount);
+  return zret;
 }
 
 static void
@@ -317,6 +244,39 @@ ink_res_randomid(void) {
   return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
 }
 
+int ink_res_init(
+  ink_res_state statp,
+  in_addr_t const* pHostList,
+  int const* pPortList,
+  const char *pDefDomain,
+  const char *pSearchList,
+  const char *pResolvConf
+) {
+  size_t n = 0;
+  sockaddr_in* ip_ptr;
+  sockaddr const** ptr_refs;
+  
+  // Count addresses.
+  if (pHostList)
+    for ( in_addr_t const* p = pHostList ; INADDR_ANY != *p ; ++p, ++n )
+      ; // empty
+
+  sockaddr_in* addrs = n ? static_cast<sockaddr_in*>(alloca(n * sizeof(sockaddr_in))) : 0;
+  // one extra for terminating null.
+  sockaddr const** refs = static_cast<sockaddr const**>(alloca((n + 1) * sizeof(sockaddr*)));
+
+  for ( ip_ptr = addrs, ptr_refs = refs
+      ; n
+      ; --n, ++pHostList, ++pPortList, ++ptr_refs, ++ip_ptr
+  ) {
+    ink_inet_ip4_set(ip_ptr, *pHostList, *pPortList);
+    *ptr_refs = ink_inet_sa_cast(ip_ptr);
+  }
+  *ptr_refs = 0;
+  return ink_res_init(statp, refs, pDefDomain, pSearchList, pResolvConf);
+}
+
+
 /*%
  * Set up default settings.  If the configuration file exist, the values
  * there will have precedence.  Otherwise, the server address is set to
@@ -337,11 +297,17 @@ ink_res_randomid(void) {
  * in the configuration file.
  *
  * Return 0 if completes successfully, -1 on error
+ *
+ * @internal This function has to be reachable by res_data.c but not publically.
  */
-/*% This function has to be reachable by res_data.c but not publically. */
 int
-ink_res_init(ink_res_state statp, const unsigned int *pHostList, const int *pPort, const char *pDefDomain, const char *pSearchList,
-             const char *pResolvConf) {
+ink_res_init(
+  ink_res_state statp, ///< State object to update.
+  sockaddr const** pHostList, ///< Additional servers.
+  const char *pDefDomain, ///< Default domain (may be NULL).
+  const char *pSearchList, ///< Unknown
+  const char *pResolvConf ///< Path to configuration file.
+) {
   register FILE *fp;
   register char *cp, **pp;
   register int n;
@@ -354,8 +320,6 @@ ink_res_init(ink_res_state statp, const 
 
   // INK_RES_SET_H_ERRNO(statp, 0);
   statp->res_h_errno = 0;
-  if (statp->_u._ext.ext != NULL)
-    ink_res_ndestroy(statp);
 
   statp->retrans = INK_RES_TIMEOUT;
   statp->retry = INK_RES_DFLRETRY;
@@ -369,28 +333,6 @@ ink_res_init(ink_res_state statp, const 
   statp->_flags = 0;
   statp->qhook = NULL;
   statp->rhook = NULL;
-  statp->_u._ext.nscount = 0;
-  statp->_u._ext.ext = (struct __ink_res_state_ext*)malloc(sizeof(*statp->_u._ext.ext));
-  if (statp->_u._ext.ext != NULL) {
-    memset(statp->_u._ext.ext, 0, sizeof(*statp->_u._ext.ext));
-    statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr_list[0].sin;
-  } else {
-    /*
-     * Historically res_init() rarely, if at all, failed.
-     * Examples and applications exist which do not check
-     * our return code.  Furthermore several applications
-     * simply call us to get the systems domainname.  So
-     * rather then immediately fail here we store the
-     * failure, which is returned later, in h_errno.  And
-     * prevent the collection of 'nameserver' information
-     * by setting maxns to 0.  Thus applications that fail
-     * to check our return code wont be able to make
-     * queries anyhow.
-     */
-    // INK_RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
-    statp->res_h_errno = NETDB_INTERNAL;
-    maxns = 0;
-  }
 
 #ifdef	SOLARIS2
   /*
@@ -494,12 +436,10 @@ ink_res_init(ink_res_state statp, const 
   /* -------------------------------------------
      we must be provided with atleast a named!
      ------------------------------------------- */
-  /* TODO we should figure out the IPV6 resolvers here. */
-  while (pHostList && pHostList[nserv] != 0 && nserv < INK_MAXNS) {
-    statp->nsaddr_list[nserv].sin.sin_addr.s_addr = pHostList[nserv];
-    statp->nsaddr_list[nserv].sin.sin_family = AF_INET;
-    statp->nsaddr_list[nserv].sin.sin_port = htons(pPort[nserv]);
-    nserv++;
+  for ( ; nserv< INK_MAXNS && pHostList && pHostList[nserv] && ink_inet_is_ip(pHostList[nserv]) 
+        ; ++nserv
+  ) {
+    ink_inet_copy(&statp->nsaddr_list[nserv].sa, pHostList[nserv]);
   }
 
 #define	MATCH(line, name)                       \
@@ -570,8 +510,6 @@ ink_res_init(ink_res_state statp, const 
       if (MATCH(buf, "nameserver") && nserv < maxns) {
         struct addrinfo hints, *ai;
         char sbuf[NI_MAXSERV];
-        const size_t minsiz =
-          sizeof(statp->_u._ext.ext->nsaddrs[0]);
 
         cp = buf + sizeof("nameserver") - 1;
         while (*cp == ' ' || *cp == '\t')
@@ -583,17 +521,13 @@ ink_res_init(ink_res_state statp, const 
           hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
           hints.ai_flags = AI_NUMERICHOST;
           sprintf(sbuf, "%d", NAMESERVER_PORT);
-          if (getaddrinfo(cp, sbuf, &hints, &ai) == 0 &&
-              ai->ai_addrlen <= minsiz) {
-            if (statp->_u._ext.ext != NULL) {
-              memcpy(&statp->_u._ext.ext->nsaddrs[nserv], ai->ai_addr, ai->ai_addrlen);
-            }
-            if (ai->ai_addrlen <= sizeof(statp->nsaddr_list[nserv].sin)) {
-              memcpy(&statp->nsaddr_list[nserv].sin, ai->ai_addr, ai->ai_addrlen);
-            } else
-              statp->nsaddr_list[nserv].sin.sin_family = 0;
+          if (getaddrinfo(cp, sbuf, &hints, &ai) == 0) {
+            if (ink_inet_copy(
+                &statp->nsaddr_list[nserv].sa,
+                ai->ai_addr
+            ))
+              ++nserv;
             freeaddrinfo(ai);
-            nserv++;
           }
         }
         continue;

Modified: trafficserver/traffic/trunk/lib/ts/ink_resolver.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/lib/ts/ink_resolver.h?rev=1154056&r1=1154055&r2=1154056&view=diff
==============================================================================
--- trafficserver/traffic/trunk/lib/ts/ink_resolver.h (original)
+++ trafficserver/traffic/trunk/lib/ts/ink_resolver.h Fri Aug  5 00:52:50 2011
@@ -180,20 +180,23 @@
 } while (0)
 #endif
 
-union ink_res_sockaddr_union {
-        struct sockaddr_in      sin;
-#ifdef IN6ADDR_ANY_INIT
-        struct sockaddr_in6     sin6;
-#endif
-#ifdef ISC_ALIGN64
-        int64_t                 __align64;      /*%< 64bit alignment */
-#else
-        int32_t                 __align32;      /*%< 32bit alignment */
-#endif
-        char                    __space[128];   /*%< max size */
+/** A union to hold the standard IP address structures.
+    We use the term "endpoint" because these contain more than just the
+    raw address, all of the data for an IP endpoint is present.
+
+    @internal This might be useful to promote to avoid strict aliasing
+    problems.  Experiment with it here to see how it works in the
+    field.
+
+ */
+union ts_ip_endpoint {
+  struct sockaddr_in      sin; ///< IPv4
+  struct sockaddr_in6     sin6; ///< IPv6
+  struct sockaddr         sa; ///< Generic addres.
 };
 
-struct __ink_res_state {
+// Do we really need these to be C compatible? - AMC
+struct ts_imp_res_state {
   int     retrans;                /*%< retransmission time interval */
   int     retry;                  /*%< number of times to retransmit */
 #ifdef sun
@@ -202,8 +205,7 @@ struct __ink_res_state {
   u_long  options;                /*%< option flags - see below. */
 #endif
   int     nscount;                /*%< number of name servers */
-  union ink_res_sockaddr_union nsaddr_list[INK_MAXNS];     /*%< address of name server */
-#define nsaddr  nsaddr_list[0]          /*%< for backward compatibility */
+  union ts_ip_endpoint nsaddr_list[INK_MAXNS];    /*%< address of name server */
   u_short id;                     /*%< current message id */
   char    *dnsrch[MAXDNSRCH+1];   /*%< components of domain to search */
   char    defdname[256];          /*%< default domain (deprecated) */
@@ -221,34 +223,32 @@ struct __ink_res_state {
   int     _vcsock;                /*%< PRIVATE: for res_send VC i/o */
   u_int   _flags;                 /*%< PRIVATE: see below */
   u_int   _pad;                   /*%< make _u 64 bit aligned */
-  union {
-    /* On an 32-bit arch this means 512b total. */
-    char    pad[72 - 4*sizeof (int) - 2*sizeof (void *)];
-    struct {
-      u_int16_t               nscount;
-      u_int16_t               nstimes[INK_MAXNS]; /*%< ms. */
-      struct __ink_res_state_ext *ext;    /*%< extention for IPv6 */
-    } _ext;
-  } _u;
-};
-typedef __ink_res_state *ink_res_state;
-
-struct __ink_res_state_ext {
-  union ink_res_sockaddr_union nsaddrs[INK_MAXNS];
+  u_int16_t              _nstimes[INK_MAXNS]; /*%< ms. */
 };
+typedef ts_imp_res_state *ink_res_state;
 
+int ink_res_init(
+  ink_res_state,
+  sockaddr const** pHostList,
+  const char *pDefDomain = NULL,
+  const char *pSearchList = NULL,
+  const char *pResolvConf = NULL
+);
+
+// Backwards compatibility version.
+int ink_res_init(
+  ink_res_state,
+  in_addr_t const* pHostList,
+  int const* pPortList = NULL,
+  const char *pDefDomain = NULL,
+  const char *pSearchList = NULL,
+  const char *pResolvConf = NULL
+);
 
-int ink_res_init(ink_res_state, const unsigned int *pHostList, const int *pPort = NULL, const char *pDefDomain = NULL,
-                 const char *pSearchList = NULL, const char *pResolvConf = NULL);
 int ink_res_mkquery(ink_res_state, int, const char *, int, int,
                     const unsigned char *, int, const unsigned char *, unsigned char *, int);
 
-#if !defined(linux)
-int inet_aton(register const char *cp, struct in_addr *addr);
-#endif
-
 int ink_ns_name_ntop(const u_char *src, char *dst, size_t dstsiz);
 
-
 #endif   /* _ink_resolver_h_ */