trafficserver-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a..@apache.org
Subject svn commit: r1154652 - in /trafficserver/traffic/trunk: ./ iocore/dns/ lib/ts/ mgmt/
Date Sun, 07 Aug 2011 03:41:33 GMT
Author: amc
Date: Sun Aug  7 03:41:32 2011
New Revision: 1154652

URL: http://svn.apache.org/viewvc?rev=1154652&view=rev
Log:
TS-597 (IPv6 for DNS) and TS-907 (bind DNS source address)

Modified:
    trafficserver/traffic/trunk/CHANGES
    trafficserver/traffic/trunk/iocore/dns/DNS.cc
    trafficserver/traffic/trunk/iocore/dns/DNSConnection.cc
    trafficserver/traffic/trunk/iocore/dns/I_DNSProcessor.h
    trafficserver/traffic/trunk/iocore/dns/P_DNSConnection.h
    trafficserver/traffic/trunk/iocore/dns/P_DNSProcessor.h
    trafficserver/traffic/trunk/iocore/dns/P_SplitDNSProcessor.h
    trafficserver/traffic/trunk/iocore/dns/SplitDNS.cc
    trafficserver/traffic/trunk/lib/ts/ink_inet.cc
    trafficserver/traffic/trunk/lib/ts/ink_inet.h
    trafficserver/traffic/trunk/lib/ts/ink_res_init.cc
    trafficserver/traffic/trunk/lib/ts/ink_resolver.h
    trafficserver/traffic/trunk/mgmt/RecordsConfig.cc

Modified: trafficserver/traffic/trunk/CHANGES
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/CHANGES?rev=1154652&r1=1154651&r2=1154652&view=diff
==============================================================================
--- trafficserver/traffic/trunk/CHANGES (original)
+++ trafficserver/traffic/trunk/CHANGES Sun Aug  7 03:41:32 2011
@@ -1,6 +1,12 @@
                                                          -*- coding: utf-8 -*-
 
 Changes with Apache Traffic Server 3.1.0
+  *) [TS-592] DNS internals are now IPv6 compatible. Externally this means
+     DNS servers with IPv6 addresses can be used although only IPv4 responses
+     are useful until other IPv6 upgrades are done.
+
+  *) [TS-907] The source address for DNS requests can be set.
+
   *) [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

Modified: trafficserver/traffic/trunk/iocore/dns/DNS.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/dns/DNS.cc?rev=1154652&r1=1154651&r2=1154652&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/dns/DNS.cc (original)
+++ trafficserver/traffic/trunk/iocore/dns/DNS.cc Sun Aug  7 03:41:32 2011
@@ -22,6 +22,7 @@
  */
 
 #include "P_DNS.h" /* MAGIC_EDITING_TAG */
+#include <ts/ink_inet.h>
 
 #ifdef SPLIT_DNS
 #include "I_SplitDNS.h"
@@ -51,7 +52,27 @@ int dns_ns_rr = 0;
 int dns_ns_rr_init_down = 1;
 char *dns_ns_list = NULL;
 char *dns_resolv_conf = NULL;
+char *dns_local_ipv6 = NULL;
+char *dns_local_ipv4 = NULL;
 int dns_thread = 0;
+int dns_prefer_ipv6 = 0;
+namespace {
+  inline bool prefer_ipv6_p() { return 0 != dns_prefer_ipv6; }
+  inline int preferred_query_type() { return prefer_ipv6_p() ? T_AAAA : T_A; }
+  // Currently only used for A and AAAA.
+  inline char const* QtypeName(int qtype) {
+    return T_AAAA == qtype ? "AAAA" : T_A == qtype ? "A" : "*";
+  }
+  inline void set_loopback(sockaddr* addr) {
+    if (prefer_ipv6_p())
+      ink_inet_ip6_set(addr, in6addr_any, DOMAIN_SERVICE_PORT);
+    else
+      ink_inet_ip4_set(addr, INADDR_LOOPBACK, DOMAIN_SERVICE_PORT);
+  }
+  inline void set_loopback(ts_ip_endpoint* ip) {
+    set_loopback(&ip->sa);
+  }
+}
 
 DNSProcessor dnsProcessor;
 ClassAllocator<DNSEntry> dnsEntryAllocator("dnsEntryAllocator");
@@ -95,7 +116,61 @@ void HostEnt::free() {
   dnsBufAllocator.free(this);
 }
 
-//
+inline bool is_addr_type_reply(int qtype) {
+  return qtype == T_A || qtype == T_AAAA;
+}
+
+void
+make_ipv4_ptr(in_addr_t addr, char *buffer)
+{
+    char *p = buffer;
+    uint8_t const* u = reinterpret_cast<uint8_t*>(&addr);
+
+    if (u[3] > 99)
+      *p++ = (u[3] / 100) + '0';
+    if (u[3] > 9)
+      *p++ = ((u[3] / 10) % 10) + '0';
+    *p++ = u[3] % 10 + '0';
+    *p++ = '.';
+    if (u[2] > 99)
+      *p++ = (u[2] / 100) + '0';
+    if (u[2] > 9)
+      *p++ = ((u[2] / 10) % 10) + '0';
+    *p++ = u[2] % 10 + '0';
+    *p++ = '.';
+    if (u[1] > 99)
+      *p++ = (u[1] / 100) + '0';
+    if (u[1] > 9)
+      *p++ = ((u[1] / 10) % 10) + '0';
+    *p++ = u[1] % 10 + '0';
+    *p++ = '.';
+    if (u[0] > 99)
+      *p++ = (u[0] / 100) + '0';
+    if (u[0] > 9)
+      *p++ = ((u[0] / 10) % 10) + '0';
+    *p++ = u[0] % 10 + '0';
+    *p++ = '.';
+    ink_strncpy(p, "in-addr.arpa", MAXDNAME - (p - buffer + 1));    
+}
+
+void
+make_ipv6_ptr(in6_addr const* addr, char *buffer)
+{
+    const char hex_digit[] = "0123456789abcdef";
+    char *p = buffer;
+    uint8_t const* src = addr->s6_addr;
+    int i;
+
+    for (i = INK_IP6_SIZE-1 ; i >= 0; --i) {
+        *p++ = hex_digit[src[i] & 0x0f];
+        *p++ = '.';
+        *p++ = hex_digit[src[i] >> 4];
+        *p++ = '.';
+    }
+
+    ink_strncpy(p, "ip6.arpa", MAXDNAME - (p - buffer + 1));
+}
+
 //  Public functions
 //
 //  See documentation is header files and Memos
@@ -114,8 +189,11 @@ DNSProcessor::start(int) {
   IOCORE_EstablishStaticConfigInt32(dns_validate_qname, "proxy.config.dns.validate_query_name");
   IOCORE_EstablishStaticConfigInt32(dns_ns_rr, "proxy.config.dns.round_robin_nameservers");
   IOCORE_ReadConfigStringAlloc(dns_ns_list, "proxy.config.dns.nameservers");
+  IOCORE_ReadConfigStringAlloc(dns_local_ipv4, "proxy.config.dns.local_ipv4");
+  IOCORE_ReadConfigStringAlloc(dns_local_ipv6, "proxy.config.dns.local_ipv6");
   IOCORE_ReadConfigStringAlloc(dns_resolv_conf, "proxy.config.dns.resolv_conf");
   IOCORE_EstablishStaticConfigInt32(dns_thread, "proxy.config.dns.dedicated_thread");
+  IOCORE_EstablishStaticConfigInt32(dns_prefer_ipv6, "proxy.config.dns.prefer_ipv6");
 
   if (dns_thread > 0) {
     ET_DNS = eventProcessor.spawn_event_threads(1, "ET_DNS"); // TODO: Hmmm, should we just get a single thread some other way?
@@ -141,15 +219,20 @@ DNSProcessor::start(int) {
 }
 
 void
-DNSProcessor::open(unsigned int aip, int aport, int aoptions)
+DNSProcessor::open(sockaddr const* target, int aoptions)
 {
   DNSHandler *h = NEW(new DNSHandler);
 
   h->options = aoptions;
   h->mutex = thread->mutex;
   h->m_res = &l_res;
-  h->ip = aip;
-  h->port = aport;
+  ink_inet_copy(&h->local_ipv4.sa, &local_ipv4.sa);
+  ink_inet_copy(&h->local_ipv6.sa, &local_ipv6.sa);
+
+  if (target)
+    ink_inet_copy(&h->ip, target);
+  else
+    ink_inet_invalidate(&h->ip); // marked to use default.
 
   if (!dns_handler_initialized)
     handler = h;
@@ -168,56 +251,88 @@ DNSProcessor::dns_init()
   Debug("dns", "localhost=%s\n", try_server_names[0]);
   Debug("dns", "Round-robin nameservers = %d\n", dns_ns_rr);
 
+  ts_ip_endpoint nameserver[MAX_NAMED];
+  size_t nserv = 0;
+
   if (dns_ns_list) {
     Debug("dns", "Nameserver list specified \"%s\"\n", dns_ns_list);
-    uint32_t nameserver_ip[MAX_NAMED];
-    int nameserver_port[MAX_NAMED];
-    int i, j;
-    char *last, *ndx;
+    int i;
+    char *last;
     char *ns_list = xstrdup(dns_ns_list);
     char *ns = (char *) ink_strtok_r(ns_list, " ,;\t\r", &last);
 
-    for (i = 0, j = 0; (i < MAX_NAMED) && ns; i++) {
+    for (i = 0, nserv = 0 ; (i < MAX_NAMED) && ns ; ++i) {
       Debug("dns", "Nameserver list - parsing \"%s\"\n", ns);
-      int err = 0;
+      bool err = false;
       int prt = DOMAIN_SERVICE_PORT;
-      if ((ndx = strchr(ns, ':'))) {
-        *ndx = '\0';
+      char* colon = 0; // where the port colon is.
+      // Check for IPv6 notation.
+      if ('[' == *ns) {
+        char* ndx = strchr(ns+1, ']');
+        if (ndx) {
+          if (':' == ndx[1]) colon = ndx+1;
+        } else {
+          err = true;
+          Warning("Unmatched '[' in address for nameserver '%s', discarding.", ns);
+        }
+      } else colon = strchr(ns, ':');
+
+      if (!err && colon) {
+        *colon = '\0';
         // coverity[secure_coding]
-        if (sscanf(ndx + 1, "%d%*s", &prt) != 1) {
-          Debug("dns", "Unable to parse port number '%s' for nameserver '%s', discarding", ndx + 1, ns);
-          Warning("Unable to parse port number '%s' for nameserver '%s', discarding", ndx + 1, ns);
-          err = 1;
+        if (sscanf(colon + 1, "%d%*s", &prt) != 1) {
+          Debug("dns", "Unable to parse port number '%s' for nameserver '%s', discardin.", colon + 1, ns);
+          Warning("Unable to parse port number '%s' for nameserver '%s', discarding.", colon + 1, ns);
+          err = true;
         }
       }
-      nameserver_ip[j] = ink_inet_addr(ns);
-      nameserver_port[j] = prt;
-      if ((int) nameserver_ip[j] == -1) {
+
+      if (!err && 0 != ink_inet_pton(ns, &nameserver[nserv].sa)) {
         Debug("dns", "Invalid IP address given for nameserver '%s', discarding", ns);
         Warning("Invalid IP address given for nameserver '%s', discarding", ns);
-        err = 1;
+        err = true;
       }
 
       if (!err) {
-        Debug("dns", "Adding nameserver %d.%d.%d.%d:%d to nameserver list",
-              DOT_SEPARATED(nameserver_ip[j]), nameserver_port[j]);
-        ++j;
-      } else
-        nameserver_ip[j] = 0;
+        ip_port_text_buffer buff;
+
+        ink_inet_port_cast(&nameserver[nserv].sa) = htons(prt);
+
+        Debug("dns", "Adding nameserver %s to nameserver list",
+          ink_inet_nptop(&nameserver[nserv].sa, buff, sizeof(buff))
+        );
+        ++nserv;
+      }
 
       ns = (char *) ink_strtok_r(NULL, " ,;\t\r", &last);
     }
     xfree(ns_list);
-    // Terminate the list for ink_res_init
-    nameserver_ip[j] = 0;
+  }
+  // The default domain (4th param) and search list (5th param) will
+  // come from /etc/resolv.conf.
+  if (ink_res_init(&l_res, nameserver, nserv, NULL, NULL, dns_resolv_conf) < 0)
+    Warning("Failed to build DNS res records for the servers (%s).  Using resolv.conf.", dns_ns_list);
+
+  // Check for local forced bindings.
+
+  if (dns_local_ipv6) {
+    if (0 != ink_inet_pton(dns_local_ipv6, &local_ipv6)) {
+      ink_inet_invalidate(&local_ipv6);
+      Warning("Invalid IP address '%s' for dns.local_ipv6 value, discarding.", dns_local_ipv6);
+    } else if (!ink_inet_is_ip6(&local_ipv6.sa)) {
+      ink_inet_invalidate(&local_ipv6);
+      Warning("IP address '%s' for dns.local_ipv6 value was not IPv6, discarding.", dns_local_ipv6);
+    }
+  }
 
-    // The default domain (4th param) and search list (5th param) will
-    // come from /etc/resolv.conf.
-    if (ink_res_init(&l_res, &nameserver_ip[0], &nameserver_port[0], NULL, NULL, dns_resolv_conf) < 0)
-      Warning("Failed to build DNS res records for the servers (%s).  Using resolv.conf.", dns_ns_list);
-  } else {
-    if (ink_res_init(&l_res, NULL, NULL, NULL, NULL, dns_resolv_conf) < 0)
-      Warning("Failed to build DNS res records for the servers (%s).  Using resolv.conf.", dns_ns_list);
+  if (dns_local_ipv4) {
+    if (0 != ink_inet_pton(dns_local_ipv4, &local_ipv4)) {
+      ink_inet_invalidate(&local_ipv4);
+      Warning("Invalid IP address '%s' for dns.local_ipv4 value, discarding.", dns_local_ipv4);
+    } else if (!ink_inet_is_ip4(&local_ipv4.sa)) {
+      ink_inet_invalidate(&local_ipv4);
+      Warning("IP address '%s' for dns.local_ipv4 value was not IPv4, discarding.", dns_local_ipv4);
+    }
   }
 }
 
@@ -239,6 +354,8 @@ DNSProcessor::DNSProcessor()
   : thread(NULL), handler(NULL)
 {
   memset(&l_res, 0, sizeof(l_res));
+  memset(&local_ipv6, 0, sizeof local_ipv6);
+  memset(&local_ipv4, 0, sizeof local_ipv4);
 }
 
 void
@@ -265,7 +382,7 @@ DNSEntry::init(const char *x, int len, i
 
   mutex = dnsH->mutex;
 
-  if (qtype == T_A || qtype == T_SRV) {
+  if (is_addr_type_reply(qtype) || qtype == T_SRV) {
     if (len) {
       len = len > (MAXDNAME - 1) ? (MAXDNAME - 1) : len;
       memcpy(qname, x, len);
@@ -277,34 +394,13 @@ DNSEntry::init(const char *x, int len, i
       qname_len = strlen(qname);
     }
   } else {                    //T_PTR
-    char *p = qname;
-    unsigned char *u = (unsigned char *) x;
-
-    if (u[3] > 99)
-      *p++ = (u[3] / 100) + '0';
-    if (u[3] > 9)
-      *p++ = ((u[3] / 10) % 10) + '0';
-    *p++ = u[3] % 10 + '0';
-    *p++ = '.';
-    if (u[2] > 99)
-      *p++ = (u[2] / 100) + '0';
-    if (u[2] > 9)
-      *p++ = ((u[2] / 10) % 10) + '0';
-    *p++ = u[2] % 10 + '0';
-    *p++ = '.';
-    if (u[1] > 99)
-      *p++ = (u[1] / 100) + '0';
-    if (u[1] > 9)
-      *p++ = ((u[1] / 10) % 10) + '0';
-    *p++ = u[1] % 10 + '0';
-    *p++ = '.';
-    if (u[0] > 99)
-      *p++ = (u[0] / 100) + '0';
-    if (u[0] > 9)
-      *p++ = ((u[0] / 10) % 10) + '0';
-    *p++ = u[0] % 10 + '0';
-    *p++ = '.';
-    ink_strncpy(p, "in-addr.arpa", MAXDNAME - (p - qname + 1));
+    sockaddr const* ip = reinterpret_cast<sockaddr const*>(x);
+    if (ink_inet_is_ip6(ip))
+      make_ipv6_ptr(&ink_inet_ip6_addr_cast(ip), qname);
+    else if (ink_inet_is_ip4(ip))
+      make_ipv4_ptr(ink_inet_ip4_addr_cast(ip), qname);
+    else
+      ink_assert(!"T_PTR query to DNS must be IP address.");
   }
 
   SET_HANDLER((DNSEntryHandler) & DNSEntry::mainEvent);
@@ -316,15 +412,15 @@ DNSEntry::init(const char *x, int len, i
 
 */
 void
-DNSHandler::open_con(unsigned int aip, int aport, bool failed, int icon)
+DNSHandler::open_con(sockaddr const* target, bool failed, int icon)
 {
+  ip_port_text_buffer ip_text;
   PollDescriptor *pd = get_PollDescriptor(dnsProcessor.thread);
 
-  Debug("dns", "open_con: opening connection %d.%d.%d.%d:%d", DOT_SEPARATED(aip), aport);
+  Debug("dns", "open_con: opening connection %s", ink_inet_nptop(target, ip_text, sizeof ip_text));
 
   if (!icon) {
-    ip = aip;
-    port = aport;
+    ink_inet_copy(&ip, target);
   }
 
   if (con[icon].fd != NO_FD) {  // Remove old FD from epoll fd
@@ -332,8 +428,16 @@ DNSHandler::open_con(unsigned int aip, i
     con[icon].close();
   }
 
-  if (con[icon].connect(aip, aport, NON_BLOCKING_CONNECT, CONNECT_WITH_UDP, NON_BLOCKING, BIND_RANDOM_PORT) < 0) {
-    Debug("dns", "opening connection %d.%d.%d.%d:%d FAILED for %d", DOT_SEPARATED(aip), aport, icon);
+  if (con[icon].connect(
+      target, DNSConnection::Options()
+        .setNonBlockingConnect(true)
+        .setNonBlockingIo(true)
+        .setUseTcp(false)
+        .setBindRandomPort(true)
+        .setLocalIpv6(&local_ipv6.sa)
+        .setLocalIpv4(&local_ipv4.sa)
+    ) < 0) {
+    Debug("dns", "opening connection %s FAILED for %d", ip_text, icon);
     if (!failed) {
       if (dns_ns_rr)
         rr_failure(icon);
@@ -347,11 +451,24 @@ DNSHandler::open_con(unsigned int aip, i
       Error("[iocore_dns] open_con: Failed to add %d server to epoll list\n", icon);
     } else {
       con[icon].num = icon;
-      Debug("dns", "opening connection %d.%d.%d.%d:%d SUCCEEDED for %d", DOT_SEPARATED(aip), aport, icon);
+      Debug("dns", "opening connection %s SUCCEEDED for %d", ip_text, icon);
     }
   }
 }
 
+void
+DNSHandler::validate_ip() {
+  if (!ink_inet_is_ip(&ip.sa)) {
+    // Invalid, switch to default.
+    // seems that res_init always sets m_res.nscount to at least 1!
+    if (!m_res->nscount || !ink_inet_copy(&ip.sa, &m_res->nsaddr_list[0].sa)) {
+      Warning("bad nameserver config, fallback to %s loopback",
+        prefer_ipv6_p() ? "IPv6" : "IPv4"
+      );
+      set_loopback(&ip);
+    }
+  }
+}
 /**
   Initial state of the DNSHandler. Can reinitialize the running DNS
   handler to a new nameserver.
@@ -363,18 +480,9 @@ DNSHandler::startEvent(int event, Event 
   NOWARN_UNUSED(event);
   //
   // If this is for the default server, get it
-  //
   Debug("dns", "DNSHandler::startEvent: on thread %d\n", e->ethread->id);
-  if (ip == DEFAULT_DOMAIN_NAME_SERVER) {
-    // seems that res_init always sets m_res.nscount to at least 1!
-    if (!m_res->nscount)
-      Warning("bad configurations: no nameservers given");
-    struct sockaddr_in *sa = &m_res->nsaddr_list[0].sin;
-    ip = sa->sin_addr.s_addr;
-    if (!ip)
-      ip = ink_inet_addr("127.0.0.1");
-    port = ntohs(sa->sin_port);
-  }
+
+  this->validate_ip();
 
   if (!dns_handler_initialized) {
     //
@@ -389,18 +497,20 @@ DNSHandler::startEvent(int event, Event 
         max_nscount = MAX_NAMED;
       n_con = 0;
       for (int i = 0; i < max_nscount; i++) {
-        struct sockaddr_in *sa = &m_res->nsaddr_list[i].sin;
-        ip = sa->sin_addr.s_addr;
-        if (ip) {
-          port = ntohs(sa->sin_port);
-          open_con(ip, port, false, n_con);
+        ip_port_text_buffer buff;
+        sockaddr *sa = &m_res->nsaddr_list[i].sa;
+        if (ink_inet_is_ip(sa)) {
+          open_con(sa, false, n_con);
           ++n_con;
-          Debug("dns_pas", "opened connection to %d.%d.%d.%d:%d, n_con = %d", DOT_SEPARATED(ip), port, n_con);
+          Debug("dns_pas", "opened connection to %s, n_con = %d",
+            ink_inet_nptop(sa, buff, sizeof(buff)),
+            n_con
+          );
         }
       }
       dns_ns_rr_init_down = 0;
     } else {
-      open_con(ip, port);
+      open_con(&ip.sa);
       n_con = 1;
     }
     e->ethread->schedule_every(this, DNS_PERIOD);
@@ -421,20 +531,10 @@ DNSHandler::startEvent_sdns(int event, E
 {
   NOWARN_UNUSED(event);
   Debug("dns", "DNSHandler::startEvent_sdns: on thread %d\n", e->ethread->id);
-
-  if (ip == DEFAULT_DOMAIN_NAME_SERVER) {
-    // seems that res_init always sets m_res.nscount to at least 1!
-    if (!m_res->nscount)
-      Warning("bad nameserver config, fallback to 127.0.0.1");
-    struct sockaddr_in *sa = &m_res->nsaddr_list[0].sin;
-    ip = sa->sin_addr.s_addr;
-    if (!ip)
-      ip = ink_inet_addr("127.0.0.1");
-    port = ntohs(sa->sin_port);
-  }
+  this->validate_ip();
 
   SET_HANDLER(&DNSHandler::mainEvent);
-  open_con(ip, port, false, n_con);
+  open_con(&ip.sa, false, n_con);
   ++n_con;                      // TODO should n_con be zeroed?
 
   e->schedule_every(DNS_PERIOD);
@@ -453,7 +553,8 @@ _ink_res_mkquery(ink_res_state res, char
 void
 DNSHandler::recover()
 {
-  Warning("connection to DNS server %d.%d.%d.%d restored", DOT_SEPARATED(ip));
+  ip_text_buffer buff;
+  Warning("connection to DNS server %s restored", ink_inet_ntop(&ip.sa, buff, sizeof(buff)));
   name_server = 0;
   switch_named(name_server);
 }
@@ -465,17 +566,12 @@ DNSHandler::retry_named(int ndx, ink_hrt
     Debug("dns", "retry_named: reopening DNS connection for index %d", ndx);
     last_primary_reopen = t;
     con[ndx].close();
-    struct sockaddr_in *sa;
-    sa = &m_res->nsaddr_list[ndx].sin;
-    ip = sa->sin_addr.s_addr;
-    port = ntohs(sa->sin_port);
-
-    open_con(ip, port, true, ndx);
+    open_con(&m_res->nsaddr_list[ndx].sa, true, ndx);
   }
 
   char buffer[MAX_DNS_PACKET_LEN];
   Debug("dns", "trying to resolve '%s' from DNS connection, ndx %d", try_server_names[try_servers], ndx);
-  int r = _ink_res_mkquery(m_res, try_server_names[try_servers], T_A, buffer);
+  int r = _ink_res_mkquery(m_res, try_server_names[try_servers], preferred_query_type(), buffer);
   try_servers = (try_servers + 1) % SIZE(try_server_names);
   ink_assert(r >= 0);
   if (r >= 0) {                 // looking for a bounce
@@ -491,14 +587,14 @@ DNSHandler::try_primary_named(bool reope
   if (reopen && ((t - last_primary_reopen) > DNS_PRIMARY_REOPEN_PERIOD)) {
     Debug("dns", "try_primary_named: reopening primary DNS connection");
     last_primary_reopen = t;
-    open_con(ip, port, true, 0);
+    open_con(&ip.sa, true, 0);
   }
   if ((t - last_primary_retry) > DNS_PRIMARY_RETRY_PERIOD) {
     char buffer[MAX_DNS_PACKET_LEN];
 
     last_primary_retry = t;
     Debug("dns", "trying to resolve '%s' from primary DNS connection", try_server_names[try_servers]);
-    int r = _ink_res_mkquery(m_res, try_server_names[try_servers], T_A, buffer);
+    int r = _ink_res_mkquery(m_res, try_server_names[try_servers], preferred_query_type(), buffer);
     // if try_server_names[] is not full, round-robin within the
     // filled entries.
     if (local_num_entries < DEFAULT_NUM_TRY_SERVER)
@@ -533,29 +629,35 @@ DNSHandler::failover()
   Debug("dns", "failover: initiating failover attempt, current name_server=%d", name_server);
   // no hope, if we have only one server
   if (m_res->nscount > 1) {
+    ip_text_buffer buff1, buff2;
     int max_nscount = m_res->nscount;
 
     if (max_nscount > MAX_NAMED)
       max_nscount = MAX_NAMED;
-    unsigned int old_ip = m_res->nsaddr_list[name_server].sin.sin_addr.s_addr;
+    sockaddr const* old_addr = &m_res->nsaddr_list[name_server].sa;
     name_server = (name_server + 1) % max_nscount;
     Debug("dns", "failover: failing over to name_server=%d", name_server);
 
-    struct sockaddr_in *sa = &m_res->nsaddr_list[name_server].sin;
+    ts_ip_endpoint target;
+    ink_inet_copy(&target.sa, &m_res->nsaddr_list[name_server].sa);
 
-    Warning("failover: connection to DNS server %d.%d.%d.%d lost, move to %d.%d.%d.%d",
-            DOT_SEPARATED(old_ip), DOT_SEPARATED(sa->sin_addr.s_addr));
+    Warning("failover: connection to DNS server %s lost, move to %s",
+      ink_inet_ntop(old_addr, buff1, sizeof(buff1)),
+      ink_inet_ntop(&target.sa, buff2, sizeof(buff2))
+    );
 
-    unsigned int tip = sa->sin_addr.s_addr;
+    if (!ink_inet_is_ip(&target.sa)) set_loopback(&target.sa);
 
-    if (!tip)
-      tip = ink_inet_addr("127.0.0.1");
-    open_con(tip, ntohs(sa->sin_port), true, name_server);
+    open_con(&target.sa, true, name_server);
     if (n_con <= name_server)
       n_con = name_server + 1;
     switch_named(name_server);
-  } else
-    Warning("failover: connection to DNS server %d.%d.%d.%d lost, retrying", DOT_SEPARATED(ip));
+  } else {
+    ip_text_buffer buff;
+    Warning("failover: connection to DNS server %s lost, retrying",
+      ink_inet_ntop(&ip.sa, buff, sizeof(buff))
+    );
+  }
 }
 
 /** Mark one of the nameservers as down. */
@@ -564,13 +666,13 @@ DNSHandler::rr_failure(int ndx)
 {
   // no hope, if we have only one server
   if (!ns_down[ndx]) {
+    ip_text_buffer buff;
     // mark this nameserver as down
     Debug("dns", "rr_failure: Marking nameserver %d as down", ndx);
     ns_down[ndx] = 1;
-
-    struct sockaddr_in *sa = &m_res->nsaddr_list[ndx].sin;
-    unsigned int tip = sa->sin_addr.s_addr;
-    Warning("connection to DNS server %d.%d.%d.%d lost, marking as down", DOT_SEPARATED(tip));
+    Warning("connection to DNS server %s lost, marking as down",
+      ink_inet_ntop(&m_res->nsaddr_list[ndx].sa, buff, sizeof(buff))
+    );
   }
 
   int nscount = m_res->nscount;
@@ -633,17 +735,18 @@ DNSHandler::recv_dns(int event, Event *e
   NOWARN_UNUSED(event);
   NOWARN_UNUSED(e);
   DNSConnection *dnsc = NULL;
+  ip_text_buffer ipbuff1, ipbuff2;
 
   while ((dnsc = (DNSConnection *) triggered.dequeue())) {
     while (1) {
-      struct sockaddr_in sa_from;
-      socklen_t sa_length = sizeof(sa_from); // TODO: I'm guessing when we support IPv6,this will have to change.
+      ts_ip_endpoint from_ip;
+      socklen_t from_length = sizeof(from_ip);
 
       if (!hostent_cache)
         hostent_cache = dnsBufAllocator.alloc();
       HostEnt *buf = hostent_cache;
 
-      int res = socketManager.recvfrom(dnsc->fd, buf->buf, MAX_DNS_PACKET_LEN, 0, (struct sockaddr *) &sa_from, &sa_length);
+      int res = socketManager.recvfrom(dnsc->fd, buf->buf, MAX_DNS_PACKET_LEN, 0, &from_ip.sa, &from_length);
 
       if (res == -EAGAIN)
         break;
@@ -657,8 +760,11 @@ DNSHandler::recv_dns(int event, Event *e
       }
 
       // verify that this response came from the correct server
-      if (dnsc->sa.sin_addr.s_addr != sa_from.sin_addr.s_addr) {
-        Warning("received DNS response from unexpected named %d.%d.%d.%d", DOT_SEPARATED(sa_from.sin_addr.s_addr));
+      if (!ink_inet_eq(&dnsc->ip.sa, &from_ip.sa)) {
+        Warning("unexpected DNS response from %s (expected %s)",
+          ink_inet_ntop(&from_ip.sa, ipbuff1, sizeof ipbuff1),
+          ink_inet_ntop(&dnsc->ip.sa, ipbuff2, sizeof ipbuff2)
+        );
         continue;
       }
       hostent_cache = 0;
@@ -669,9 +775,9 @@ DNSHandler::recv_dns(int event, Event *e
         if (good_rcode(buf->buf)) {
           received_one(dnsc->num);
           if (ns_down[dnsc->num]) {
-            struct sockaddr_in *sa = &m_res->nsaddr_list[dnsc->num].sin;
-
-            Warning("connection to DNS server %d.%d.%d.%d restored", DOT_SEPARATED(sa->sin_addr.s_addr));
+            Warning("connection to DNS server %s restored",
+              ink_inet_ntop(&m_res->nsaddr_list[dnsc->num].sa, ipbuff1, sizeof ipbuff1)
+            );
             ns_down[dnsc->num] = 0;
           }
         }
@@ -766,10 +872,10 @@ get_entry(DNSHandler *h, char *qname, in
 {
   for (DNSEntry *e = h->entries.head; e; e = (DNSEntry *) e->link.next) {
     if (e->qtype == qtype) {
-      if (qtype == T_A) {
+      if (is_addr_type_reply(qtype)) {
         if (!strcmp(qname, e->qname))
           return e;
-      } else if (*(unsigned int *) qname == *(unsigned int *) e->qname)
+      } else if (0 == memcmp(qname, e->qname, e->qname_len))
         return e;
     }
   }
@@ -874,7 +980,7 @@ write_dns_event(DNSHandler *h, DNSEntry 
     h->release_query_id(e->id[dns_retries - e->retries]);
   }
   e->id[dns_retries - e->retries] = i;
-  Debug("dns", "send query for %s to fd %d", e->qname, h->con[h->name_server].fd);
+  Debug("dns", "send query (qtype=%d) for %s to fd %d", e->qtype, e->qname, h->con[h->name_server].fd);
 
   int s = socketManager.send(h->con[h->name_server].fd, blob._b, r, 0);
   if (s != r) {
@@ -1016,6 +1122,18 @@ dns_result(DNSHandler *h, DNSEntry *e, H
       --(e->retries);
       write_dns(h);
       return;
+    } else if (prefer_ipv6_p() && e->qtype == T_AAAA) {
+      Debug("dns", "Trying A after AAAA failure for %s", e->qname);
+      e->retries = dns_retries;
+      e->qtype = T_A;
+      write_dns(h);
+      return;
+    } else if (!prefer_ipv6_p() && e->qtype == T_A) {
+      Debug("dns", "Trying AAAA after A failure for %s", e->qname);
+      e->retries = dns_retries;
+      e->qtype = T_AAAA;
+      write_dns(h);
+      return;
     } else if (e->domains && *e->domains) {
       do {
         Debug("dns", "domain extending %s", e->qname);
@@ -1074,10 +1192,12 @@ dns_result(DNSHandler *h, DNSEntry *e, H
   }
   h->entries.remove(e);
 
-  if (e->qtype == T_A) {
-    unsigned int tip = ent != NULL ? *(unsigned int *) ent->ent.h_addr_list[0] : 0;
-    Debug("dns", "%s result for %s = %d.%d.%d.%d retry %d",
-          ent ? "SUCCESS" : "FAIL", e->qname, DOT_SEPARATED(tip), retry);
+  if (is_addr_type_reply(e->qtype)) {
+    ip_text_buffer buff;
+    char const* ptr = "<none>";
+    if (ent) ptr = inet_ntop(e->qtype == T_AAAA ? AF_INET6 : AF_INET, ent->ent.h_addr_list[0], buff, sizeof(buff));
+    Debug("dns", "%s result for %s = %s retry %d",
+      ent ? "SUCCESS" : "FAIL", e->qname, ptr, retry);
   } else {
     Debug("dns", "%s result for %s = %s retry %d",
           ent ? "SUCCESS" : "FAIL", e->qname, (ent != NULL ? ent->ent.h_name : "<not found>"), retry);
@@ -1252,7 +1372,7 @@ dns_process(DNSHandler *handler, HostEnt
     }
 
     cp += n + QFIXEDSZ;
-    if (e->qtype == T_A) {
+    if (is_addr_type_reply(e->qtype)) {
       if (-1 == rname_len)
         n = strlen((char *)bp) + 1;
       else
@@ -1327,7 +1447,7 @@ dns_process(DNSHandler *handler, HostEnt
       //
       // Decode cname
       //
-      if (e->qtype == T_A && type == T_CNAME) {
+      if (is_addr_type_reply(e->qtype) && type == T_CNAME) {
         if (ap >= &buf->host_aliases[DNS_MAX_ALIASES - 1])
           continue;
         n = ink_dn_expand((u_char *) h, eom, cp, tbuf, sizeof(tbuf));
@@ -1405,7 +1525,7 @@ dns_process(DNSHandler *handler, HostEnt
 
         buf->srv_hosts.insert(s);
         ++num_srv;
-      } else if (type == T_A) {
+      } else if (is_addr_type_reply(type)) {
         if (answer) {
           if (n != buf->ent.h_length) {
             cp += n;
@@ -1417,7 +1537,7 @@ dns_process(DNSHandler *handler, HostEnt
           buf->ent.h_addrtype = C_IN;
           buf->ent.h_name = (char *) bp;
           nn = strlen((char *) bp) + 1;
-          Debug("dns", "received A name = %s", bp);
+          Debug("dns", "received %s name = %s", QtypeName(type), bp);
           bp += nn;
           buflen -= nn;
         }
@@ -1426,13 +1546,16 @@ dns_process(DNSHandler *handler, HostEnt
           *hap++ = cp;
           cp += n;
         } else {
+          ip_text_buffer ip_string;
           bp = (unsigned char *) align_pointer_forward(bp, sizeof(int));
           if (bp + n >= buf->hostbuf + DNS_HOSTBUF_SIZE) {
             ++error;
             break;
           }
           memcpy((*hap++ = bp), cp, n);
-          Debug("dns", "received A = %d.%d.%d.%d", DOT_SEPARATED(*(unsigned int *) bp));
+          Debug("dns", "received %s = %s", QtypeName(type),
+            inet_ntop(T_AAAA == type ? AF_INET6 : AF_INET, bp, ip_string, sizeof(ip_string))
+          );
           bp += n;
           cp += n;
         }

Modified: trafficserver/traffic/trunk/iocore/dns/DNSConnection.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/dns/DNSConnection.cc?rev=1154652&r1=1154651&r2=1154652&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/dns/DNSConnection.cc (original)
+++ trafficserver/traffic/trunk/iocore/dns/DNSConnection.cc Sun Aug  7 03:41:32 2011
@@ -50,7 +50,7 @@
 DNSConnection::DNSConnection():
   fd(NO_FD), num(0), generator((uint32_t)((uintptr_t)time(NULL) ^ (uintptr_t) this)), handler(NULL)
 {
-  memset(&sa, 0, sizeof(struct sockaddr_in));
+  memset(&ip, 0, sizeof(ip));
 }
 
 DNSConnection::~DNSConnection()
@@ -79,58 +79,79 @@ DNSConnection::trigger()
 }
 
 int
-DNSConnection::connect(unsigned int ip, int port,
-                       bool non_blocking_connect, bool use_tcp, bool non_blocking, bool bind_random_port)
+DNSConnection::connect(sockaddr const* addr, Options const& opt)
+//                       bool non_blocking_connect, bool use_tcp, bool non_blocking, bool bind_random_port)
 {
   ink_assert(fd == NO_FD);
+  ink_assert(ink_inet_is_ip(addr));
 
   int res = 0;
   short Proto;
+  uint8_t af = addr->sa_family;
+  ts_ip_endpoint bind_addr;
+  size_t bind_size = 0;
 
-  if (use_tcp) {
+  if (opt._use_tcp) {
     Proto = IPPROTO_TCP;
-    if ((res = socketManager.socket(AF_INET, SOCK_STREAM, 0)) < 0)
+    if ((res = socketManager.socket(af, SOCK_STREAM, 0)) < 0)
       goto Lerror;
   } else {
     Proto = IPPROTO_UDP;
-    if ((res = socketManager.socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+    if ((res = socketManager.socket(af, SOCK_DGRAM, 0)) < 0)
       goto Lerror;
   }
 
   fd = res;
 
-  if (bind_random_port) {
+  memset(&bind_addr, 0, sizeof bind_addr);
+  bind_addr.sa.sa_family = af;
+
+  if (AF_INET6 == af) {
+    if (ink_inet_is_ip6(opt._local_ipv6)) {
+      ink_inet_copy(&bind_addr.sa, opt._local_ipv6);
+    } else {
+      bind_addr.sin6.sin6_addr = in6addr_any;
+    }
+    bind_size = sizeof(sockaddr_in6);
+  } else if (AF_INET == af) {
+      if (ink_inet_is_ip4(opt._local_ipv4))
+        ink_inet_copy(&bind_addr.sa, opt._local_ipv4);
+      else
+        bind_addr.sin.sin_addr.s_addr = INADDR_ANY;
+      bind_size = sizeof(sockaddr_in);
+  } else {
+    ink_assert(!"Target DNS address must be IP.");
+  }
+
+  if (opt._bind_random_port) {
     int retries = 0;
     while (retries++ < 10000) {
-      struct sockaddr_in bind_sa;
-      memset(&sa, 0, sizeof(bind_sa));
-      bind_sa.sin_family = AF_INET;
-      bind_sa.sin_addr.s_addr = INADDR_ANY;
+      ip_port_text_buffer b;
       uint32_t p = generator.random();
-      p = (uint16_t)((p % (LAST_RANDOM_PORT - FIRST_RANDOM_PORT)) + FIRST_RANDOM_PORT);
-      bind_sa.sin_port = htons(p);
-      Debug("dns", "random port = %u\n", p);
-      if ((res = socketManager.ink_bind(fd, (struct sockaddr *) &bind_sa, sizeof(bind_sa), Proto)) < 0) {
+      p = static_cast<uint16_t>((p % (LAST_RANDOM_PORT - FIRST_RANDOM_PORT)) + FIRST_RANDOM_PORT);
+      ink_inet_port_cast(&bind_addr.sa) = htons(p); // stuff port in sockaddr.
+      Debug("dns", "random port = %s\n", ink_inet_nptop(&bind_addr.sa, b, sizeof b));
+      if ((res = socketManager.ink_bind(fd, &bind_addr.sa, bind_size, Proto)) < 0) {
         continue;
       }
       goto Lok;
     }
     Warning("unable to bind random DNS port");
   Lok:;
+  } else if (ink_inet_is_ip(&bind_addr.sa)) {
+    ip_text_buffer b;
+    res = socketManager.ink_bind(fd, &bind_addr.sa, bind_size, Proto);
+    if (res < 0) Warning("Unable to bind local address to %s.",
+      ink_inet_ntop(&bind_addr.sa, b, sizeof b));
   }
 
-  sa.sin_family = AF_INET;
-  sa.sin_port = htons(port);
-  sa.sin_addr.s_addr = ip;
-  memset(&sa.sin_zero, 0, 8);
-
-  if (non_blocking_connect)
+  if (opt._non_blocking_connect)
     if ((res = safe_nonblocking(fd)) < 0)
       goto Lerror;
 
   // cannot do this after connection on non-blocking connect
 #ifdef SET_TCP_NO_DELAY
-  if (use_tcp)
+  if (opt._use_tcp)
     if ((res = safe_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, ON, sizeof(int))) < 0)
       goto Lerror;
 #endif
@@ -143,12 +164,15 @@ DNSConnection::connect(unsigned int ip, 
     goto Lerror;
 #endif
 
-  res =::connect(fd, (struct sockaddr *) &sa, sizeof(struct sockaddr_in));
+  ink_inet_copy(&ip.sa, addr);
+  res =::connect(fd, addr, ink_inet_ip_size(addr));
 
   if (!res || ((res < 0) && (errno == EINPROGRESS || errno == EWOULDBLOCK))) {
-    if (!non_blocking_connect && non_blocking)
+    if (!opt._non_blocking_connect && opt._non_blocking_io)
       if ((res = safe_nonblocking(fd)) < 0)
         goto Lerror;
+    // Shouldn't we turn off non-blocking when it's a non-blocking connect
+    // and blocking IO?
   } else
     goto Lerror;
 

Modified: trafficserver/traffic/trunk/iocore/dns/I_DNSProcessor.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/dns/I_DNSProcessor.h?rev=1154652&r1=1154651&r2=1154652&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/dns/I_DNSProcessor.h (original)
+++ trafficserver/traffic/trunk/iocore/dns/I_DNSProcessor.h Sun Aug  7 03:41:32 2011
@@ -77,7 +77,8 @@ struct DNSProcessor: public Processor
   Action *gethostbyname(Continuation *cont, const char *name, DNSHandler *adnsH = 0, int timeout = 0);
   Action *getSRVbyname(Continuation *cont, const char *name, DNSHandler *adnsH = 0, int timeout = 0);
   Action *gethostbyname(Continuation *cont, const char *name, int len, int timeout = 0);
-  Action *gethostbyaddr(Continuation *cont, unsigned int ip, int timeout = 0);
+  Action *gethostbyaddr(Continuation *cont, in_addr_t ip, int timeout = 0);
+  Action *gethostbyaddr(Continuation *cont, sockaddr const* ip, int timeout = 0);
 
 
   // Processor API
@@ -88,7 +89,7 @@ struct DNSProcessor: public Processor
 
   // Open/close a link to a 'named' (done in start())
   //
-  void open(unsigned int ip = DEFAULT_DOMAIN_NAME_SERVER, int port = DOMAIN_SERVICE_PORT, int options = _res.options);
+  void open(sockaddr const* ns = 0, int options = _res.options);
 
   DNSProcessor();
 
@@ -97,6 +98,8 @@ struct DNSProcessor: public Processor
   EThread *thread;
   DNSHandler *handler;
   ts_imp_res_state l_res;
+  ts_ip_endpoint local_ipv6;
+  ts_ip_endpoint local_ipv4;
   Action *getby(const char *x, int len, int type, Continuation *cont, DNSHandler *adnsH = NULL, int timeout = 0);
   void dns_init();
 };
@@ -130,9 +133,17 @@ DNSProcessor::gethostbyname(Continuation
 }
 
 inline Action *
-DNSProcessor::gethostbyaddr(Continuation *cont, unsigned int addr, int timeout)
+DNSProcessor::gethostbyaddr(Continuation *cont, in_addr_t addr, int timeout)
 {
-  return getby((char *) &addr, sizeof(addr), T_PTR, cont, NULL, timeout);
+  sockaddr_in ip;
+  ink_inet_ip4_set(&ip, addr);
+  return getby(reinterpret_cast<char const*>(&ip), 0, T_PTR, cont, NULL, timeout);
+}
+
+inline Action *
+DNSProcessor::gethostbyaddr(Continuation *cont, sockaddr const* addr, int timeout)
+{
+  return getby(reinterpret_cast<char const*>(addr), 0, T_PTR, cont, NULL, timeout);
 }
 
 void ink_dns_init(ModuleVersion version);

Modified: trafficserver/traffic/trunk/iocore/dns/P_DNSConnection.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/dns/P_DNSConnection.h?rev=1154652&r1=1154651&r2=1154652&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/dns/P_DNSConnection.h (original)
+++ trafficserver/traffic/trunk/iocore/dns/P_DNSConnection.h Sun Aug  7 03:41:32 2011
@@ -57,24 +57,83 @@
 //
 struct DNSHandler;
 
-struct DNSConnection
-{
+struct DNSConnection {
+  /// Options for connecting.
+  struct Options {
+    typedef Options self; ///< Self reference type.
+
+    /// Connection is done non-blocking.
+    /// Default: @c true.
+    bool _non_blocking_connect;
+    /// Set socket to have non-blocking I/O.
+    /// Default: @c true.
+    bool _non_blocking_io;
+    /// Use TCP if @c true, use UDP if @c false.
+    /// Default: @c false.
+    bool _use_tcp;
+    /// Bind to a random port.
+    /// Default: @c true.
+    bool _bind_random_port;
+    /// Bind to this local address when using IPv6.
+    /// Default: unset, bind to IN6ADDR_ANY.
+    sockaddr const* _local_ipv6;
+    /// Bind to this local address when using IPv4.
+    /// Default: unset, bind to INADDRY_ANY.
+    sockaddr const* _local_ipv4;
+
+    Options();
+
+    self& setUseTcp(bool p);
+    self& setNonBlockingConnect(bool p);
+    self& setNonBlockingIo(bool p);
+    self& setBindRandomPort(bool p);
+    self& setLocalIpv6(sockaddr const* addr);
+    self& setLocalIpv4(sockaddr const* addr);
+  };
+
   int fd;
-  struct sockaddr_in sa;
+  ts_ip_endpoint ip;
   int num;
   LINK(DNSConnection, link);
   EventIO eio;
   InkRand generator;
   DNSHandler* handler;
 
-  int connect(unsigned int ip, int port,
+  int connect(sockaddr const* addr, Options const& opt = DEFAULT_OPTIONS);
+/*
               bool non_blocking_connect = NON_BLOCKING_CONNECT,
               bool use_tcp = CONNECT_WITH_TCP, bool non_blocking = NON_BLOCKING, bool bind_random_port = BIND_ANY_PORT);
+*/
   int close();
   void trigger();
 
   virtual ~DNSConnection();
   DNSConnection();
+
+  static Options const DEFAULT_OPTIONS;
 };
 
+inline DNSConnection::Options::Options() 
+  : _non_blocking_connect(true)
+  , _non_blocking_io(true)
+  , _use_tcp(false)
+  , _bind_random_port(true)
+  , _local_ipv6(0)
+  , _local_ipv4(0)
+{
+}
+
+inline DNSConnection::Options&
+DNSConnection::Options::setNonBlockingIo(bool p) { _non_blocking_io = p; return *this; }
+inline DNSConnection::Options&
+DNSConnection::Options::setNonBlockingConnect(bool p) { _non_blocking_connect = p; return *this; }
+inline DNSConnection::Options&
+DNSConnection::Options::setUseTcp(bool p) { _use_tcp = p; return *this; }
+inline DNSConnection::Options&
+DNSConnection::Options::setBindRandomPort(bool p) { _bind_random_port = p; return *this; }
+inline DNSConnection::Options&
+DNSConnection::Options::setLocalIpv4(sockaddr const* ip) { _local_ipv4 = ip; return *this; }
+inline DNSConnection::Options&
+DNSConnection::Options::setLocalIpv6(sockaddr const* ip) { _local_ipv6 = ip; return *this; }
+
 #endif /*_P_DNSConnection_h*/

Modified: trafficserver/traffic/trunk/iocore/dns/P_DNSProcessor.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/dns/P_DNSProcessor.h?rev=1154652&r1=1154651&r2=1154652&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/dns/P_DNSProcessor.h (original)
+++ trafficserver/traffic/trunk/iocore/dns/P_DNSProcessor.h Sun Aug  7 03:41:32 2011
@@ -198,8 +198,10 @@ struct DNSEntry;
 */
 struct DNSHandler: public Continuation
 {
-  unsigned int ip;
-  int port;
+  /// This is used as the target if round robin isn't set.
+  ts_ip_endpoint ip;
+  ts_ip_endpoint local_ipv6; ///< Local V6 address if set.
+  ts_ip_endpoint local_ipv4; ///< Local V4 address if set.
   int ifd[MAX_NAMED];
   int n_con;
   DNSConnection con[MAX_NAMED];
@@ -225,7 +227,6 @@ struct DNSHandler: public Continuation
   // bitmap of query ids in use
   uint64_t qid_in_flight[(USHRT_MAX+1)/64];
 
-
   void received_one(int i)
   {
     failover_number[i] = failover_soon_number[i] = crossed_failover_number[i] = 0;
@@ -261,7 +262,7 @@ struct DNSHandler: public Continuation
   int startEvent_sdns(int event, Event *e);
   int mainEvent(int event, Event *e);
 
-  void open_con(unsigned int aip, int aport, bool failed = false, int icon = 0);
+  void open_con(sockaddr const* addr, bool failed = false, int icon = 0);
   void failover();
   void rr_failure(int ndx);
   void recover();
@@ -283,14 +284,19 @@ struct DNSHandler: public Continuation
   };
 
   DNSHandler();
+
+private:
+  // Check the IP address and switch to default if needed.
+  void validate_ip();
 };
 
 
 TS_INLINE DNSHandler::DNSHandler()
- : Continuation(NULL), ip(0), port(0), n_con(0), options(0), in_flight(0), name_server(0), in_write_dns(0),
+ : Continuation(NULL), n_con(0), options(0), in_flight(0), name_server(0), in_write_dns(0),
   hostent_cache(0), last_primary_retry(0), last_primary_reopen(0),
   m_res(0), txn_lookup_timeout(0), generator((uint32_t)((uintptr_t)time(NULL) ^ (uintptr_t)this))
 {
+  ink_inet_invalidate(&ip);
   for (int i = 0; i < MAX_NAMED; i++) {
     ifd[i] = -1;
     failover_number[i] = 0;

Modified: trafficserver/traffic/trunk/iocore/dns/P_SplitDNSProcessor.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/dns/P_SplitDNSProcessor.h?rev=1154652&r1=1154651&r2=1154652&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/dns/P_SplitDNSProcessor.h (original)
+++ trafficserver/traffic/trunk/iocore/dns/P_SplitDNSProcessor.h Sun Aug  7 03:41:32 2011
@@ -162,12 +162,11 @@ TS_INLINE bool SplitDNSConfig::isSplitDN
    -------------------------------------------------------------- */
 struct DNSServer
 {
-  unsigned int x_server_ip[MAXNS];
+  ts_ip_endpoint x_server_ip[MAXNS];
   char x_dns_ip_line[MAXDNAME * 2];
 
   char x_def_domain[MAXDNAME];
   char x_domain_srch_list[MAXDNAME];
-  int  x_dns_server_port[MAXNS];
 
   DNSHandler *x_dnsH;
 
@@ -175,7 +174,6 @@ struct DNSServer
   : x_dnsH(NULL)
   {
     memset(x_server_ip, 0, sizeof(x_server_ip));
-    memset(x_dns_server_port, 0, sizeof(x_dns_server_port));
 
     memset(x_def_domain, 0, MAXDNAME);
     memset(x_domain_srch_list, 0, MAXDNAME);
@@ -199,8 +197,8 @@ public:
 
   const char *get_host();
 
-  in_addr_t get_ip();
-  in_addr_t get_client_ip();
+  in_addr_t get_ip(); // unused required virtual method.
+  in_addr_t get_client_ip(); // unused required virtual method.
 
   const char *m_pHost;
 };
@@ -240,7 +238,7 @@ DNSRequestData::get_host()
    -------------------------------------------------------------- */
 TS_INLINE in_addr_t DNSRequestData::get_ip()
 {
-  return (in_addr_t) 0;
+  return 0;
 }
 
 
@@ -249,7 +247,7 @@ TS_INLINE in_addr_t DNSRequestData::get_
    -------------------------------------------------------------- */
 TS_INLINE in_addr_t DNSRequestData::get_client_ip()
 {
-  return (in_addr_t) 0;
+  return 0;
 }
 
 /* --------------------------------------------------------------

Modified: trafficserver/traffic/trunk/iocore/dns/SplitDNS.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/dns/SplitDNS.cc?rev=1154652&r1=1154651&r2=1154652&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/dns/SplitDNS.cc (original)
+++ trafficserver/traffic/trunk/iocore/dns/SplitDNS.cc Sun Aug  7 03:41:32 2011
@@ -364,14 +364,11 @@ SplitDNSRecord::ProcessDNSHosts(char *va
       *tmp = 0;
     }
 
-    unsigned int addr = inet_addr(current);
-
-    if (((uint32_t)-1) == htonl(addr)) {
+    if (0 != ink_inet_pton(current, &m_servers.x_server_ip[i].sa)) {
       return "invalid IP address given for a DNS server";
     }
 
-    m_servers.x_server_ip[i] = addr;
-    m_servers.x_dns_server_port[i] = port ? port : NAMESERVER_PORT;
+    ink_inet_port_cast(&m_servers.x_server_ip[i].sa) = htons(port ? port : NAMESERVER_PORT);
 
     if ((MAXDNAME * 2 - 1) > totsz) {
       sz = strlen(current);
@@ -506,7 +503,7 @@ SplitDNSRecord::Init(matcher_line * line
     }
   }
 
-  if (this->m_servers.x_server_ip[0] == 0) {
+  if (!ink_inet_is_ip(&m_servers.x_server_ip[0].sa)) {
     snprintf(errBuf, errBufLen, "%s No server specified in splitdns.config at line %d", modulePrefix, line_num);
     return errBuf;
   }
@@ -515,18 +512,20 @@ SplitDNSRecord::Init(matcher_line * line
   ink_res_state res = new ts_imp_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,
+  if ((-1 == ink_res_init(res, m_servers.x_server_ip, m_dnsSrvr_cnt,
                           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",
-             m_servers.x_server_ip[0], m_servers.x_dns_server_port[0]);
+    char ab[INET6_ADDRPORTSTRLEN];
+    snprintf(errBuf, errBufLen,
+      "Failed to build res record for the servers %s ...",
+      ink_inet_ntop(&m_servers.x_server_ip[0].sa, ab, sizeof ab)
+    );
     return errBuf;
   }
 
   dnsH->m_res = res;
   dnsH->mutex = SplitDNSConfig::dnsHandler_mutex;
   dnsH->options = res->options;
-  dnsH->ip = DEFAULT_DOMAIN_NAME_SERVER;
-  dnsH->port = DOMAIN_SERVICE_PORT;
+  ink_inet_invalidate(&dnsH->ip.sa); // Mark to use default DNS.
 
   m_servers.x_dnsH = dnsH;
 
@@ -575,13 +574,9 @@ SplitDNSRecord::UpdateMatch(SplitDNSResu
 void
 SplitDNSRecord::Print()
 {
-  struct in_addr address;
-
   for (int i = 0; i < m_dnsSrvr_cnt; i++) {
-    address.s_addr = m_servers.x_server_ip[i];
-    char *pAdr = inet_ntoa(address);
-
-    Debug("splitdns_config", " %s:%d ", pAdr, m_servers.x_dns_server_port[i]);
+    char ab[INET6_ADDRPORTSTRLEN];
+    Debug("splitdns_config", " %s ", ink_inet_ntop(&m_servers.x_server_ip[i].sa, ab, sizeof ab));
   }
 }
 

Modified: trafficserver/traffic/trunk/lib/ts/ink_inet.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/lib/ts/ink_inet.cc?rev=1154652&r1=1154651&r2=1154652&view=diff
==============================================================================
--- trafficserver/traffic/trunk/lib/ts/ink_inet.cc (original)
+++ trafficserver/traffic/trunk/lib/ts/ink_inet.cc Sun Aug  7 03:41:32 2011
@@ -165,18 +165,21 @@ ink_inet_addr(const char *s)
 
 const char *ink_inet_ntop(const struct sockaddr *addr, char *dst, size_t size)
 {
-  void *address = NULL;
+  char const* zret = 0;
 
   switch (addr->sa_family) {
   case AF_INET:
-    address = &((struct sockaddr_in *)addr)->sin_addr;
+    zret = inet_ntop(AF_INET, &ink_inet_ip4_addr_cast(addr), dst, size);
     break;
   case AF_INET6:
-    address = &((struct sockaddr_in6 *)addr)->sin6_addr;
+    zret = inet_ntop(AF_INET6, &ink_inet_ip6_addr_cast(addr), dst, size);
+    break;
+  default:
+    zret = dst;
+    snprintf(dst, size, "*Not IP address [%u]*", addr->sa_family);
     break;
   }
-
-  return inet_ntop(addr->sa_family, address, dst, size);
+  return zret;
 }
 
 uint16_t ink_inet_port(const struct sockaddr *addr)
@@ -195,19 +198,58 @@ uint16_t ink_inet_port(const struct sock
   return port;
 }
 
+char const* ink_inet_nptop(
+  sockaddr const* addr,
+  char* dst, size_t size
+) {
+  char buff[INET6_ADDRSTRLEN];
+  snprintf(dst, size, "%s:%u",
+    ink_inet_ntop(addr, buff, sizeof(buff)),
+    ink_inet_get_port(addr)
+  );
+  return dst;
+}
+
 int ink_inet_pton(char const* text, sockaddr* addr) {
   int zret = -1;
   addrinfo hints; // [out]
   addrinfo *ai; // [in]
+  char* copy; // needed for handling brackets.
+
+  if ('[' == *text) {
+    /* Ugly. In a number of places we must use bracket notation
+       to support port numbers. Rather than mucking with that
+       everywhere, we'll tweak it here. Experimentally we can't
+       depend on getaddrinfo to handle it. Note that the text
+       buffer size includes space for the nul, so a bracketed
+       address is at most that size - 1 + 2 -> size+1.
+
+       It just gets better. In order to bind link local addresses
+       the scope_id must be set to the interface index. That's
+       most easily done by appending a %intf (where "intf" is the
+       name of the interface) to the address. Which makes
+       the address potentially larger than the standard maximum.
+       So we can't depend on that sizing.
+    */
+
+    size_t n = strlen(text);
+    copy = static_cast<char*>(alloca(n)); // n-1 would probably be OK.
+    if (']' == text[n-1]) {
+      strncpy(copy, text+1, n-2);
+      copy[n-2] = 0;
+      text = copy;
+    } else {
+      // Bad format, getaddrinfo isn't going to succeed.
+      return zret;
+    }
+  }
 
   memset(&hints, 0, sizeof(hints));
   hints.ai_family = PF_UNSPEC;
   hints.ai_flags = AI_NUMERICHOST|AI_PASSIVE;
   if (0 == (zret = getaddrinfo(text, 0, &hints, &ai))) {
-    if (addr) {
-      if (ink_inet_copy(addr, ai->ai_addr))
-        zret = 0;
-    } else if (ink_inet_is_ip(addr)) {
+    if (ink_inet_is_ip(ai->ai_addr)) {
+      if (addr) ink_inet_copy(addr, ai->ai_addr);
       zret = 0;
     }
     freeaddrinfo(ai);

Modified: trafficserver/traffic/trunk/lib/ts/ink_inet.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/lib/ts/ink_inet.h?rev=1154652&r1=1154651&r2=1154652&view=diff
==============================================================================
--- trafficserver/traffic/trunk/lib/ts/ink_inet.h (original)
+++ trafficserver/traffic/trunk/lib/ts/ink_inet.h Sun Aug  7 03:41:32 2011
@@ -31,6 +31,27 @@
 #define INK_GETHOSTBYNAME_R_DATA_SIZE 1024
 #define INK_GETHOSTBYADDR_R_DATA_SIZE 1024
 
+/** A union to hold the standard IP address structures.
+    By standard we mean @c sockaddr compliant.
+
+    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.
+
+    @internal @c sockaddr_storage is not present because it is so
+    large and the benefits of including it are small. Use of this
+    structure will make it easy to add if that becomes necessary.
+
+ */
+union ts_ip_endpoint {
+  struct sockaddr_in      sin; ///< IPv4
+  struct sockaddr_in6     sin6; ///< IPv6
+  struct sockaddr         sa; ///< Generic address.
+};
+
 struct ink_gethostbyname_r_data
 {
   int herrno;
@@ -92,34 +113,40 @@ uint16_t ink_inet_port(const struct sock
 
 // --
 /// Size in bytes of an IPv6 address.
-size_t const INK_IP6_SIZE = sizeof(in6_addr);
+static size_t const INK_IP6_SIZE = sizeof(in6_addr);
 
 /// Reset an address to invalid.
 /// @note Useful for marking a member as not yet set.
 inline void ink_inet_invalidate(sockaddr* addr) {
   addr->sa_family = AF_UNSPEC;
 }
+inline void ink_inet_invalidate(sockaddr_in6* addr) {
+  addr->sin6_family = AF_UNSPEC;
+}
+inline void ink_inet_invalidate(ts_ip_endpoint* ip) {
+  ip->sa.sa_family = AF_UNSPEC;
+}
 
 /// Test for IP protocol.
 /// @return @c true if the address is IP, @c false otherwise.
 inline bool ink_inet_is_ip(sockaddr const* addr) {
-  return AF_INET == addr->sa_family || AF_INET6 == addr->sa_family;
+  return addr && (AF_INET == addr->sa_family || AF_INET6 == addr->sa_family);
 }
 /// Test for IPv4 protocol.
 /// @return @c true if the address is IPv4, @c false otherwise.
 inline bool ink_inet_is_ip4(sockaddr const* addr) {
-  return AF_INET == addr->sa_family;
+  return addr && AF_INET == addr->sa_family;
 }
 /// Test for IPv4 protocol.
 /// @note Convenience overload.
 /// @return @c true if the address is IPv4, @c false otherwise.
 inline bool ink_inet_is_ip4(sockaddr_in6 const* addr) {
-  return AF_INET == addr->sin6_family;
+  return addr && AF_INET == addr->sin6_family;
 }
 /// Test for IPv6 protocol.
 /// @return @c true if the address is IPv6, @c false otherwise.
 inline bool ink_inet_is_ip6(sockaddr const* addr) {
-  return AF_INET6 == addr->sa_family;
+  return addr && AF_INET6 == addr->sa_family;
 }
 /// @return @c true if the address families are compatible.
 inline bool ink_inet_are_compatible(
@@ -129,6 +156,16 @@ inline bool ink_inet_are_compatible(
   return lhs->sa_family == rhs->sa_family;
 }
 
+/// @return An appropriate size based on the address family.
+inline size_t ink_inet_ip_size(
+  sockaddr const* addr ///< Address object.
+) {
+  return AF_INET == addr->sa_family ? sizeof(sockaddr_in)
+    : AF_INET6 == addr->sa_family ? sizeof(sockaddr_in6)
+    : 0
+    ;
+}
+
 // IP address casting.
 // sa_cast to cast to sockaddr*.
 // ss_cast to cast to sockaddr_storage*.
@@ -292,6 +329,28 @@ inline in_addr_t const& ink_inet_ip4_add
 inline in6_addr& ink_inet_ip6_addr_cast(sockaddr* addr) {
   return ink_inet_ip6_cast(addr)->sin6_addr;
 }
+inline in6_addr const& ink_inet_ip6_addr_cast(sockaddr const* addr) {
+  return ink_inet_ip6_cast(addr)->sin6_addr;
+}
+
+/** Cast an IP address to an array of @c uint32_t.
+    @note The size of the array is dependent on the address type which
+    must be checked independently of this function.
+    @return A pointer to the address information in @a addr or @c NULL
+    if @a addr is not an IP address.
+*/
+inline uint32_t* ink_inet_ip_addr32_cast(sockaddr* addr) {
+  uint32_t* zret = 0;
+  switch(addr->sa_family) {
+  case AF_INET: zret = reinterpret_cast<uint32_t*>(&ink_inet_ip4_addr_cast(addr)); break;
+  case AF_INET6: zret = reinterpret_cast<uint32_t*>(&ink_inet_ip6_addr_cast(addr)); break;
+  }
+  return zret;
+}
+inline uint32_t const* ink_inet_ip_addr32_cast(sockaddr const* addr) {
+  return ink_inet_ip_addr32_cast(const_cast<sockaddr*>(addr));
+}
+
   
 /// @name Address operators
 //@{
@@ -315,6 +374,25 @@ inline bool ink_inet_copy(
   return n != 0;
 }
 
+inline bool ink_inet_copy(
+  sockaddr_in6* dst, ///< Destination object.
+  sockaddr const* src ///< Source object.
+) {
+  return ink_inet_copy(ink_inet_sa_cast(dst), src);
+}
+inline bool ink_inet_copy(
+  ts_ip_endpoint* dst,
+  sockaddr const* src
+) {
+  return ink_inet_copy(&dst->sa, src);
+}
+inline bool ink_inet_copy(
+  sockaddr* dst,
+  ts_ip_endpoint const* src
+) {
+  return ink_inet_copy(dst, &src->sa);
+}
+
 /** Compare two addresses.
     This is useful for IPv4, IPv6, and the unspecified address type.
     If the addresses are of different types they are ordered
@@ -385,6 +463,14 @@ inline int ink_inet_cmp(sockaddr_in6 con
   return ink_inet_cmp(ink_inet_sa_cast(lhs), ink_inet_sa_cast(rhs));
 }
 
+/** Check if two addresses are equal.
+    @return @c true if @a lhs and @a rhs point to equal addresses,
+    @c false otherwise.
+*/
+inline bool ink_inet_eq(sockaddr const* lhs, sockaddr const* rhs) {
+  return 0 == ink_inet_cmp(lhs, rhs);
+}
+
 //@}
 
 /// Get IP TCP/UDP port.
@@ -443,6 +529,28 @@ inline void ink_inet_ip4_set(
   ink_inet_ip4_set(ink_inet_ip4_cast(dst), ip4, port);
 }
 
+/// Write IPv6 address to storage @a dst.
+/// @note convenience overload.
+inline void ink_inet_ip6_set(
+  sockaddr_in6* dst, ///< Destination storage.
+  in6_addr const& addr, ///< address in network order.
+  uint16_t port = 0 ///< Port, network order.
+) {
+  memset(dst, 0, sizeof(*dst));
+  dst->sin6_family = AF_INET6;
+  memcpy(&dst->sin6_addr, &addr, sizeof addr);
+  dst->sin6_port = port;
+}
+
+/// Write IPv6 address to storage @a dst.
+inline void ink_inet_ip6_set(
+  sockaddr* dst, ///< Destination storage.
+  in6_addr const& addr, ///< address in network order.
+  uint16_t port = 0 ///< Port, network order.
+) {
+  ink_inet_ip6_set(ink_inet_ip6_cast(dst), addr, port);
+}
+
 /** Write a null terminated string for @a addr to @a dst.
     A buffer of size INET6_ADDRSTRLEN suffices, including a terminating nul.
  */
@@ -452,7 +560,12 @@ char const* ink_inet_ntop(
   size_t size ///< Length of buffer.
 );
 
+/// Buffer size sufficient for IPv6 address and port.
 static size_t const INET6_ADDRPORTSTRLEN = INET6_ADDRSTRLEN + 6;
+/// Convenience type for address formatting.
+typedef char ip_text_buffer[INET6_ADDRSTRLEN];
+/// Convenience type for address formatting.
+typedef char ip_port_text_buffer[INET6_ADDRPORTSTRLEN];
 
 /** Write a null terminated string for @a addr to @a dst with port.
     A buffer of size INET6_ADDRPORTSTRLEN suffices, including a terminating nul.
@@ -496,6 +609,13 @@ inline int ink_inet_pton(
   return ink_inet_pton(text, ink_inet_sa_cast(addr));
 }
 
+inline int ink_inet_pton(
+  char const* text, ///< [in] text.
+  ts_ip_endpoint* addr ///< [out] address
+) {
+  return ink_inet_pton(text, &addr->sa);
+}
+
 /** Storage for an IP address.
     In some cases we want to store just the address and not the
     ancillary information (such as port, or flow data) in

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=1154652&r1=1154651&r2=1154652&view=diff
==============================================================================
--- trafficserver/traffic/trunk/lib/ts/ink_res_init.cc (original)
+++ trafficserver/traffic/trunk/lib/ts/ink_res_init.cc Sun Aug  7 03:41:32 2011
@@ -244,39 +244,6 @@ 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
@@ -303,7 +270,8 @@ int ink_res_init(
 int
 ink_res_init(
   ink_res_state statp, ///< State object to update.
-  sockaddr const** pHostList, ///< Additional servers.
+  ts_ip_endpoint const* pHostList, ///< Additional servers.
+  size_t pHostListSize, ///< # of entries in @a pHostList.
   const char *pDefDomain, ///< Default domain (may be NULL).
   const char *pSearchList, ///< Unknown
   const char *pResolvConf ///< Path to configuration file.
@@ -312,11 +280,11 @@ ink_res_init(
   register char *cp, **pp;
   register int n;
   char buf[BUFSIZ];
-  int nserv = 0;
+  size_t nserv = 0;
   int haveenv = 0;
   int havesearch = 0;
   int dots;
-  int maxns = INK_MAXNS;
+  size_t maxns = INK_MAXNS;
 
   // INK_RES_SET_H_ERRNO(statp, 0);
   statp->res_h_errno = 0;
@@ -436,10 +404,15 @@ ink_res_init(
   /* -------------------------------------------
      we must be provided with atleast a named!
      ------------------------------------------- */
-  for ( ; nserv< INK_MAXNS && pHostList && pHostList[nserv] && ink_inet_is_ip(pHostList[nserv]) 
+  if (pHostList) {
+    if (pHostListSize > INK_MAXNS) pHostListSize = INK_MAXNS;
+    for (
+        ; nserv < pHostListSize
+          && ink_inet_is_ip(&pHostList[nserv].sa) 
         ; ++nserv
-  ) {
-    ink_inet_copy(&statp->nsaddr_list[nserv].sa, pHostList[nserv]);
+    ) {
+      ink_inet_copy(&statp->nsaddr_list[nserv].sa, &pHostList[nserv].sa);
+    }
   }
 
 #define	MATCH(line, name)                       \

Modified: trafficserver/traffic/trunk/lib/ts/ink_resolver.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/lib/ts/ink_resolver.h?rev=1154652&r1=1154651&r2=1154652&view=diff
==============================================================================
--- trafficserver/traffic/trunk/lib/ts/ink_resolver.h (original)
+++ trafficserver/traffic/trunk/lib/ts/ink_resolver.h Sun Aug  7 03:41:32 2011
@@ -70,6 +70,7 @@
 #define	_ink_resolver_h_
 
 #include "ink_platform.h"
+#include <ts/ink_inet.h>
 #include <resolv.h>
 #include <arpa/nameser.h>
 #ifdef HAVE_NET_PPP_DEFS_H
@@ -180,21 +181,6 @@
 } while (0)
 #endif
 
-/** 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.
-};
-
 // Do we really need these to be C compatible? - AMC
 struct ts_imp_res_state {
   int     retrans;                /*%< retransmission time interval */
@@ -205,7 +191,7 @@ struct ts_imp_res_state {
   u_long  options;                /*%< option flags - see below. */
 #endif
   int     nscount;                /*%< number of name servers */
-  union ts_ip_endpoint nsaddr_list[INK_MAXNS];    /*%< address of name server */
+  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) */
@@ -229,17 +215,8 @@ 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,
+  ts_ip_endpoint const* pHostList,
+  size_t pHostListSize,
   const char *pDefDomain = NULL,
   const char *pSearchList = NULL,
   const char *pResolvConf = NULL

Modified: trafficserver/traffic/trunk/mgmt/RecordsConfig.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/mgmt/RecordsConfig.cc?rev=1154652&r1=1154651&r2=1154652&view=diff
==============================================================================
--- trafficserver/traffic/trunk/mgmt/RecordsConfig.cc (original)
+++ trafficserver/traffic/trunk/mgmt/RecordsConfig.cc Sun Aug  7 03:41:32 2011
@@ -1050,6 +1050,10 @@ RecordElement RecordsConfig[] = {
   ,
   {RECT_CONFIG, "proxy.config.dns.nameservers", RECD_STRING, NULL, RECU_DYNAMIC, RR_NULL, RECC_NULL, NULL, RECA_NULL}
   ,
+  {RECT_CONFIG, "proxy.config.dns.local_ipv6", RECD_STRING, NULL, RECU_RESTART_TS, RR_NULL, RECC_STR, NULL, RECA_NULL} 
+  ,
+  {RECT_CONFIG, "proxy.config.dns.local_ipv4", RECD_STRING, NULL, RECU_RESTART_TS, RR_NULL, RECC_STR, NULL, RECA_NULL} 
+  ,
   {RECT_CONFIG, "proxy.config.dns.resolv_conf", RECD_STRING, "/etc/resolv.conf", RECU_RESTART_TS, RR_NULL, RECC_NULL, NULL, RECA_NULL}
   ,
   {RECT_CONFIG, "proxy.config.dns.round_robin_nameservers", RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_NULL, NULL, RECA_NULL}



Mime
View raw message