[or-cvs] r16178: Make generic address manipulation functions work better. Swi (in tor/trunk: . src/common src/or)

nickm at seul.org nickm at seul.org
Thu Jul 24 13:44:04 UTC 2008


Author: nickm
Date: 2008-07-24 09:44:04 -0400 (Thu, 24 Jul 2008)
New Revision: 16178

Modified:
   tor/trunk/
   tor/trunk/src/common/compat.c
   tor/trunk/src/common/compat.h
   tor/trunk/src/common/util.c
   tor/trunk/src/common/util.h
   tor/trunk/src/or/connection.c
   tor/trunk/src/or/connection_or.c
   tor/trunk/src/or/control.c
   tor/trunk/src/or/dirserv.c
   tor/trunk/src/or/dnsserv.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/policies.c
   tor/trunk/src/or/rendcommon.c
   tor/trunk/src/or/router.c
   tor/trunk/src/or/routerlist.c
   tor/trunk/src/or/routerparse.c
   tor/trunk/src/or/test.c
Log:
 r17346 at aud-055:  nickm | 2008-07-24 15:37:19 +0200
 Make generic address manipulation functions work better.  Switch address policy code to use tor_addr_t, so it can handle IPv6.  That is a good place to start.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r17346] on 49666b30-7950-49c5-bedf-9dc8f3168102

Modified: tor/trunk/src/common/compat.c
===================================================================
--- tor/trunk/src/common/compat.c	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/common/compat.c	2008-07-24 13:44:04 UTC (rev 16178)
@@ -960,6 +960,22 @@
   }
 }
 
+/** DOCDOC */
+void
+tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa)
+{
+  memset(&a, 0, sizeof(tor_addr_t));
+  if (sa->sa_family == AF_INET) {
+    struct sockaddr_in *sin = (struct sockaddr_in *) sa;
+    a->family = AF_INET;
+    a->addr.in_addr.s_addr = sin->sin_addr.s_addr;
+  } else if (sa->sa_family == AF_INET6) {
+    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
+    a->family = AF_INET6;
+    memcpy(&a->addr.in6_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
+  }
+}
+
 /** Set *addr to the IP address (in dotted-quad notation) stored in c.
  * Return 1 on success, 0 if c is badly formatted.  (Like inet_aton(c,addr),
  * but works on Windows and Solaris.)

Modified: tor/trunk/src/common/compat.h
===================================================================
--- tor/trunk/src/common/compat.h	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/common/compat.h	2008-07-24 13:44:04 UTC (rev 16178)
@@ -361,17 +361,18 @@
 /* DOCDOC*/
 static INLINE uint32_t tor_addr_to_ipv4n(const tor_addr_t *a);
 static INLINE uint32_t tor_addr_to_ipv4h(const tor_addr_t *a);
-static INLINE uint32_t tor_addr_to_mapped_ipv4n(const tor_addr_t *a);
+static INLINE uint32_t tor_addr_to_mapped_ipv4h(const tor_addr_t *a);
 static INLINE sa_family_t tor_addr_family(const tor_addr_t *a);
 static INLINE const struct in_addr *tor_addr_to_in(const tor_addr_t *a);
 static INLINE const struct in6_addr *tor_addr_to_in6(const tor_addr_t *a);
 socklen_t tor_addr_to_sockaddr(const tor_addr_t *a, uint16_t port,
                                struct sockaddr *sa_out);
+void tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa);
 
 static INLINE const struct in6_addr *
 tor_addr_to_in6(const tor_addr_t *a)
 {
-  return &a->addr.in6_addr;
+  return a->family == AF_INET6 ? &a->addr.in6_addr : NULL;
 }
 
 #define tor_addr_to_in6_addr16(x) S6_ADDR16(*tor_addr_to_in6(x))
@@ -380,7 +381,7 @@
 static INLINE uint32_t
 tor_addr_to_ipv4n(const tor_addr_t *a)
 {
-  return a->addr.in_addr.s_addr;
+  return a->family == AF_INET ? a->addr.in_addr.s_addr : 0;
 }
 static INLINE uint32_t
 tor_addr_to_ipv4h(const tor_addr_t *a)
@@ -388,7 +389,7 @@
   return ntohl(tor_addr_to_ipv4n(a));
 }
 static INLINE uint32_t
-tor_addr_to_mapped_ipv4n(const tor_addr_t *a)
+tor_addr_to_mapped_ipv4h(const tor_addr_t *a)
 {
   return ntohl(tor_addr_to_in6_addr32(a)[3]);
 }
@@ -400,11 +401,12 @@
 static INLINE const struct in_addr *
 tor_addr_to_in(const tor_addr_t *a)
 {
-  return &a->addr.in_addr;
+  return a->family == AF_INET ? &a->addr.in_addr : NULL;
 }
 
 #define INET_NTOA_BUF_LEN 16 /* 255.255.255.255 */
-#define TOR_ADDR_BUF_LEN 46 /* ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255 */
+#define TOR_ADDR_BUF_LEN 48 /* [ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255]
+                             */
 
 int tor_inet_aton(const char *cp, struct in_addr *addr) ATTR_NONNULL((1,2));
 const char *tor_inet_ntop(int af, const void *src, char *dst, size_t len);

Modified: tor/trunk/src/common/util.c
===================================================================
--- tor/trunk/src/common/util.c	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/common/util.c	2008-07-24 13:44:04 UTC (rev 16178)
@@ -2230,17 +2230,27 @@
 
 /** Convert a tor_addr_t <b>addr</b> into a string, and store it in
  *  <b>dest</b> of size <b>len</b>.  Returns a pointer to dest on success,
- *  or NULL on failure.
+ *  or NULL on failure.  If <b>decorate</b>, surround IPv6 addresses with
+ *  brackets.
  */
 const char *
-tor_addr_to_str(char *dest, const tor_addr_t *addr, int len)
+tor_addr_to_str(char *dest, const tor_addr_t *addr, int len, int decorate)
 {
   const char *ptr;
   tor_assert(addr && dest);
 
   switch (tor_addr_family(addr)) {
     case AF_INET:
-      ptr = tor_inet_ntop(AF_INET, &addr->addr.in_addr, dest, len);
+      if (len<3)
+        return NULL;
+      if (decorate)
+        ptr = tor_inet_ntop(AF_INET, &addr->addr.in_addr, dest+1, len-2);
+      else
+        ptr = tor_inet_ntop(AF_INET, &addr->addr.in_addr, dest, len);
+      if (ptr && decorate) {
+        *dest = '[';
+        memcpy(dest+strlen(dest), "]", 2);
+      }
       break;
     case AF_INET6:
       ptr = tor_inet_ntop(AF_INET6, &addr->addr.in6_addr, dest, len);
@@ -2739,6 +2749,29 @@
   //return 1;
 }
 
+/** Return true iff <b>addr</b> is a loopback address */
+int
+tor_addr_is_loopback(const tor_addr_t *addr)
+{
+  tor_assert(addr);
+  switch (tor_addr_family(addr)) {
+    case AF_INET6: {
+      /* ::1 */
+      uint32_t *a32 = tor_addr_to_in6_addr32(addr);
+      return (a32[0] == 0) && (a32[1] == 0) && (a32[2] == 0) && (a32[3] == 1);
+    }
+    case AF_INET:
+      /* 127.0.0.1 */
+      return (tor_addr_to_ipv4h(addr) & 0xff000000) == 0x7f000000;
+    case AF_UNSPEC:
+      return 0;
+    default:
+      tor_fragile_assert();
+      return 0;
+  }
+}
+
+
 /** Given an IPv4 in_addr struct *<b>in</b> (in network order, as usual),
  *  write it as a string into the <b>buf_len</b>-byte buffer in
  *  <b>buf</b>.
@@ -2756,12 +2789,11 @@
 
 /** Take a 32-bit host-order ipv4 address <b>v4addr</b> and store it in the
  *  tor_addr *<b>dest</b>.
- *
- *  XXXX_IP6 Temporary, for use while 32-bit int addresses are still being
- *  passed around.
  */
+/*  XXXX_IP6 Temporary, for use while 32-bit int addresses are still being
+ *  passed around. */
 void
-tor_addr_from_ipv4(tor_addr_t *dest, uint32_t v4addr)
+tor_addr_from_ipv4h(tor_addr_t *dest, uint32_t v4addr)
 {
   tor_assert(dest);
   memset(dest, 0, sizeof(dest));
@@ -2816,12 +2848,22 @@
   v_family[0] = tor_addr_family(addr1);
   v_family[1] = tor_addr_family(addr2);
 
+  if (v_family[0] == AF_UNSPEC) {
+    if (v_family[1] == AF_UNSPEC)
+      return 0;
+    else
+      return 1;
+  } else {
+    if (v_family[1] == AF_UNSPEC)
+      return -1;
+  }
+
   if (v_family[0] == AF_INET) { /* If this is native IPv4, note the address */
     /* Later we risk overwriting a v4-mapped address */
     ip4a = tor_addr_to_ipv4h(addr1);
   } else if ((v_family[0] == AF_INET6) && tor_addr_is_v4(addr1)) {
     v_family[0] = AF_INET;
-    ip4a = tor_addr_to_mapped_ipv4n(addr1);
+    ip4a = tor_addr_to_mapped_ipv4h(addr1);
   }
 
   if (v_family[1] == AF_INET) { /* If this is native IPv4, note the address */
@@ -2829,7 +2871,7 @@
     ip4b = tor_addr_to_ipv4h(addr2);
   } else if ((v_family[1] == AF_INET6) && tor_addr_is_v4(addr2)) {
     v_family[1] = AF_INET;
-    ip4b = tor_addr_to_mapped_ipv4n(addr2);
+    ip4b = tor_addr_to_mapped_ipv4h(addr2);
   }
 
   if (v_family[0] > v_family[1]) /* Comparison of virtual families */
@@ -2885,11 +2927,40 @@
 
 }
 
+
+/** Return a hash code based on the address addr */
+unsigned int
+tor_addr_hash(const tor_addr_t *addr)
+{
+  switch (tor_addr_family(addr)) {
+  case AF_INET:
+    return tor_addr_to_ipv4h(addr);
+  case AF_UNSPEC:
+    return 0x4e4d5342;
+  case AF_INET6: {
+    const uint32_t *u = tor_addr_to_in6_addr32(addr);
+    return u[0] + u[1] + u[2] + u[3];
+    }
+  default:
+    tor_fragile_assert();
+    return 0;
+  }
+}
+
+/** Return a newly allocatd string with a representation of <b>addr</b>. */
+char *
+tor_dup_addr(const tor_addr_t *addr)
+{
+  char buf[TOR_ADDR_BUF_LEN];
+  tor_addr_to_str(buf, addr, sizeof(buf), 0);
+  return tor_strdup(buf);
+}
+
 /** Given a host-order <b>addr</b>, call tor_inet_ntop() on it
  *  and return a strdup of the resulting address.
  */
 char *
-tor_dup_addr(uint32_t addr)
+tor_dup_ip(uint32_t addr)
 {
   char buf[TOR_ADDR_BUF_LEN];
   struct in_addr in;

Modified: tor/trunk/src/common/util.h
===================================================================
--- tor/trunk/src/common/util.h	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/common/util.h	2008-07-24 13:44:04 UTC (rev 16178)
@@ -276,23 +276,27 @@
 int addr_mask_get_bits(uint32_t mask);
 int addr_mask_cmp_bits(uint32_t a1, uint32_t a2, maskbits_t bits);
 int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len);
-char *tor_dup_addr(uint32_t addr) ATTR_MALLOC;
+char *tor_dup_addr(const tor_addr_t *addr) ATTR_MALLOC;
+char *tor_dup_ip(uint32_t addr) ATTR_MALLOC;
 int get_interface_address(int severity, uint32_t *addr);
 
 int get_interface_address6(int severity, sa_family_t family, tor_addr_t *addr);
 int tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2);
 int tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
                             maskbits_t mask);
+unsigned int tor_addr_hash(const tor_addr_t *addr);
 int tor_addr_is_v4(const tor_addr_t *addr);
 int tor_addr_is_internal(const tor_addr_t *ip, int for_listening) ATTR_PURE;
 int tor_addr_parse_mask_ports(const char *s,
                               tor_addr_t *addr_out, maskbits_t *mask_out,
                               uint16_t *port_min_out, uint16_t *port_max_out);
-const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, int len);
+const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, int len,
+                             int decorate);
 int tor_addr_from_str(tor_addr_t *addr, const char *src);
 void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src);
-void tor_addr_from_ipv4(tor_addr_t *dest, uint32_t v4addr);
+void tor_addr_from_ipv4h(tor_addr_t *dest, uint32_t v4addr);
 int tor_addr_is_null(const tor_addr_t *addr);
+int tor_addr_is_loopback(const tor_addr_t *addr);
 
 /* Process helpers */
 void start_daemon(void);

Modified: tor/trunk/src/or/connection.c
===================================================================
--- tor/trunk/src/or/connection.c	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/or/connection.c	2008-07-24 13:44:04 UTC (rev 16178)
@@ -1036,7 +1036,7 @@
     /* remember the remote address */
     newconn->addr = ntohl(remote.sin_addr.s_addr);
     newconn->port = ntohs(remote.sin_port);
-    newconn->address = tor_dup_addr(newconn->addr);
+    newconn->address = tor_dup_ip(newconn->addr);
 
   } else if (conn->socket_family == AF_UNIX) {
     /* For now only control ports can be unix domain sockets

Modified: tor/trunk/src/or/connection_or.c
===================================================================
--- tor/trunk/src/or/connection_or.c	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/or/connection_or.c	2008-07-24 13:44:04 UTC (rev 16178)
@@ -434,7 +434,7 @@
                     conn->identity_digest, DIGEST_LEN);
     }
     tor_free(conn->_base.address);
-    conn->_base.address = tor_dup_addr(addr);
+    conn->_base.address = tor_dup_ip(addr);
   }
 }
 

Modified: tor/trunk/src/or/control.c
===================================================================
--- tor/trunk/src/or/control.c	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/or/control.c	2008-07-24 13:44:04 UTC (rev 16178)
@@ -1382,7 +1382,7 @@
     uint32_t addr;
     if (router_pick_published_address(get_options(), &addr) < 0)
       return -1;
-    *answer = tor_dup_addr(addr);
+    *answer = tor_dup_ip(addr);
   } else if (!strcmp(question, "dir-usage")) {
     *answer = directory_dump_request_log();
   } else if (!strcmp(question, "fingerprint")) {

Modified: tor/trunk/src/or/dirserv.c
===================================================================
--- tor/trunk/src/or/dirserv.c	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/or/dirserv.c	2008-07-24 13:44:04 UTC (rev 16178)
@@ -2165,7 +2165,7 @@
   }
   if (!strchr(hostname, '.')) {
     tor_free(hostname);
-    hostname = tor_dup_addr(addr);
+    hostname = tor_dup_ip(addr);
   }
   if (crypto_pk_get_digest(private_key, signing_key_digest)<0) {
     log_err(LD_BUG, "Error computing signing key digest");

Modified: tor/trunk/src/or/dnsserv.c
===================================================================
--- tor/trunk/src/or/dnsserv.c	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/or/dnsserv.c	2008-07-24 13:44:04 UTC (rev 16178)
@@ -118,7 +118,7 @@
 
   TO_CONN(conn)->addr = ntohl(sin->sin_addr.s_addr);
   TO_CONN(conn)->port = ntohs(sin->sin_port);
-  TO_CONN(conn)->address = tor_dup_addr(TO_CONN(conn)->addr);
+  TO_CONN(conn)->address = tor_dup_ip(TO_CONN(conn)->addr);
 
   if (q->type == EVDNS_TYPE_A)
     conn->socks_request->command = SOCKS_COMMAND_RESOLVE;

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/or/or.h	2008-07-24 13:44:04 UTC (rev 16178)
@@ -1148,8 +1148,7 @@
   maskbits_t maskbits; /**< Accept/reject all addresses <b>a</b> such that the
                  * first <b>maskbits</b> bits of <b>a</b> match
                  * <b>addr</b>. */
-  /* XXXX_IP6 make this ipv6-capable */
-  uint32_t addr; /**< Base address to accept or reject. */
+  tor_addr_t addr; /**< Base address to accept or reject. */
   uint16_t prt_min; /**< Lowest port number to accept/reject. */
   uint16_t prt_max; /**< Highest port number to accept/reject. */
 } addr_policy_t;
@@ -3635,7 +3634,8 @@
 int policy_is_reject_star(smartlist_t *policy);
 int getinfo_helper_policies(control_connection_t *conn,
                             const char *question, char **answer);
-int policy_write_item(char *buf, size_t buflen, addr_policy_t *item);
+int policy_write_item(char *buf, size_t buflen, addr_policy_t *item,
+                      int format_for_desc);
 
 void addr_policy_list_free(smartlist_t *p);
 void addr_policy_free(addr_policy_t *p);

Modified: tor/trunk/src/or/policies.c
===================================================================
--- tor/trunk/src/or/policies.c	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/or/policies.c	2008-07-24 13:44:04 UTC (rev 16178)
@@ -45,7 +45,9 @@
 {
   static const char *private_nets[] = {
     "0.0.0.0/8", "169.254.0.0/16",
-    "127.0.0.0/8", "192.168.0.0/16", "10.0.0.0/8", "172.16.0.0/12", NULL };
+    "127.0.0.0/8", "192.168.0.0/16", "10.0.0.0/8", "172.16.0.0/12",
+    // "fc00::/7", "fe80::/10", "fec0::/10", "::/127",
+    NULL };
   uint16_t port_min, port_max;
 
   int i;
@@ -67,9 +69,8 @@
        memcpy(&policy, p, sizeof(addr_policy_t));
        policy.is_private = 0;
        policy.is_canonical = 0;
-       if (parse_addr_and_port_range(private_nets[i],
-                                     &policy.addr,
-                                     &policy.maskbits, &port_min, &port_max)) {
+       if (tor_addr_parse_mask_ports(private_nets[i], &policy.addr,
+                                  &policy.maskbits, &port_min, &port_max)<0) {
          tor_assert(0);
        }
        smartlist_add(tmp, addr_policy_get_canonical_entry(&policy));
@@ -408,7 +409,7 @@
     return r;
   if ((r=((int)a->is_private - (int)b->is_private)))
     return r;
-  if ((r=((int)a->addr - (int)b->addr)))
+  if ((r=tor_addr_compare(&a->addr, &b->addr)))
     return r;
   if ((r=((int)a->maskbits - (int)b->maskbits)))
     return r;
@@ -464,7 +465,7 @@
   if (a->is_private)
     r = 0x1234abcd;
   else
-    r = (unsigned int)a->addr;
+    r = tor_addr_hash(&a->addr);
   r += a->prt_min << 8;
   r += a->prt_max << 16;
   r += a->maskbits;
@@ -522,7 +523,7 @@
  * addresses (127.0.0.1, and so on).  But we'll try this for now.
  */
 addr_policy_result_t
-compare_addr_to_addr_policy(uint32_t addr, uint16_t port,
+compare_addr_to_addr_policy(uint32_t _addr, uint16_t port,
                             smartlist_t *policy)
 {
   int maybe_reject = 0;
@@ -530,13 +531,18 @@
   int match = 0;
   int maybe = 0;
   int i, len;
+  int addr_is_unknown;
+  tor_addr_t addr;
+  /*XXXX021 ipv6 this function should take a tor_addr_t, not a uint32_t. */
+  tor_addr_from_ipv4h(&addr, _addr);
+  addr_is_unknown = tor_addr_is_null(&addr);
 
   len = policy ? smartlist_len(policy) : 0;
 
   for (i = 0; i < len; ++i) {
     addr_policy_t *tmpe = smartlist_get(policy, i);
     maybe = 0;
-    if (!addr) {
+    if (addr_is_unknown) {
       /* Address is unknown. */
       if ((port >= tmpe->prt_min && port <= tmpe->prt_max) ||
            (!port && tmpe->prt_min<=1 && tmpe->prt_max>=65535)) {
@@ -552,7 +558,7 @@
       }
     } else {
       /* Address is known */
-      if (!addr_mask_cmp_bits(addr, tmpe->addr, tmpe->maskbits)) {
+      if (!tor_addr_compare_masked(&addr, &tmpe->addr, tmpe->maskbits)) {
         if (port >= tmpe->prt_min && port <= tmpe->prt_max) {
           /* Exact match for the policy */
           match = 1;
@@ -595,7 +601,7 @@
     /* a has more fixed bits than b; it can't possibly cover b. */
     return 0;
   }
-  if (addr_mask_cmp_bits(a->addr, b->addr, a->maskbits)) {
+  if (tor_addr_compare_masked(&a->addr, &b->addr, a->maskbits)) {
     /* There's a fixed bit in a that's set differently in b. */
     return 0;
   }
@@ -618,7 +624,7 @@
     minbits = a->maskbits;
   else
     minbits = b->maskbits;
-  if (addr_mask_cmp_bits(a->addr, b->addr, minbits))
+  if (tor_addr_compare_masked(&a->addr, &b->addr, minbits))
     return 0;
   if (a->prt_max < b->prt_min || b->prt_max < a->prt_min)
     return 0;
@@ -670,8 +676,8 @@
       tor_assert(j > i);
       if (addr_policy_covers(ap, tmp)) {
         char p1[POLICY_BUF_LEN], p2[POLICY_BUF_LEN];
-        policy_write_item(p1, sizeof(p1), tmp);
-        policy_write_item(p2, sizeof(p2), ap);
+        policy_write_item(p1, sizeof(p1), tmp, 0);
+        policy_write_item(p2, sizeof(p2), ap, 0);
         log(LOG_DEBUG, LD_CONFIG, "Removing exit policy %s (%d).  It is made "
             "redundant by %s (%d).", p1, j, p2, i);
         smartlist_del_keeporder(dest, j--);
@@ -699,8 +705,8 @@
       } else { /* policy_types are equal. */
         if (addr_policy_covers(tmp, ap)) {
           char p1[POLICY_BUF_LEN], p2[POLICY_BUF_LEN];
-          policy_write_item(p1, sizeof(p1), ap);
-          policy_write_item(p2, sizeof(p2), tmp);
+          policy_write_item(p1, sizeof(p1), ap, 0);
+          policy_write_item(p2, sizeof(p2), tmp, 0);
           log(LOG_DEBUG, LD_CONFIG, "Removing exit policy %s.  It is already "
               "covered by %s.", p1, p2);
           smartlist_del_keeporder(dest, i--);
@@ -774,8 +780,8 @@
         continue; /* Doesn't cover our port. */
       if (p->maskbits > 8)
         continue; /* Narrower than a /8. */
-      if ((p->addr & 0xff000000ul) == 0x7f000000ul)
-        continue; /* 127.x */
+      if (tor_addr_is_loopback(&p->addr))
+        continue; /* 127.x or ::1. */
       /* We have a match that is at least a /8. */
       if (p->policy_type == ADDR_POLICY_ACCEPT) {
         ++n_allowed;
@@ -807,16 +813,18 @@
 /** Write a single address policy to the buf_len byte buffer at buf.  Return
  * the number of characters written, or -1 on failure. */
 int
-policy_write_item(char *buf, size_t buflen, addr_policy_t *policy)
+policy_write_item(char *buf, size_t buflen, addr_policy_t *policy,
+                  int format_for_desc)
 {
-  struct in_addr in;
   size_t written = 0;
-  char addrbuf[INET_NTOA_BUF_LEN];
+  char addrbuf[TOR_ADDR_BUF_LEN];
   const char *addrpart;
   int result;
+  const int is_accept = policy->policy_type == ADDR_POLICY_ACCEPT;
+  const int is_ip6 = tor_addr_family(&policy->addr) == AF_INET6;
 
-  in.s_addr = htonl(policy->addr);
-  tor_inet_ntoa(&in, addrbuf, sizeof(addrbuf));
+  tor_addr_to_str(buf, &policy->addr, sizeof(buf), 1);
+
   /* write accept/reject 1.2.3.4 */
   if (policy->is_private)
     addrpart = "private";
@@ -824,8 +832,11 @@
     addrpart = "*";
   else
     addrpart = addrbuf;
-  result = tor_snprintf(buf, buflen, "%s %s",
-            policy->policy_type == ADDR_POLICY_ACCEPT ? "accept" : "reject",
+
+  result = tor_snprintf(buf, buflen, "%s%s%s %s",
+                        (is_ip6&&format_for_desc)?"opt ":"",
+                        is_accept ? "accept" : "reject",
+                        (is_ip6&&format_for_desc)?"6":"",
                         addrpart);
   if (result < 0)
     return -1;

Modified: tor/trunk/src/or/rendcommon.c
===================================================================
--- tor/trunk/src/or/rendcommon.c	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/or/rendcommon.c	2008-07-24 13:44:04 UTC (rev 16178)
@@ -200,7 +200,7 @@
       goto done;
     }
     /* Assemble everything for this introduction point. */
-    address = tor_dup_addr(info->addr);
+    address = tor_dup_ip(info->addr);
     res = tor_snprintf(unenc + unenc_written, unenc_len - unenc_written,
                          "introduction-point %s\n"
                          "ip-address %s\n"

Modified: tor/trunk/src/or/router.c
===================================================================
--- tor/trunk/src/or/router.c	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/or/router.c	2008-07-24 13:44:04 UTC (rev 16178)
@@ -1252,7 +1252,7 @@
 
   ri = tor_malloc_zero(sizeof(routerinfo_t));
   ri->cache_info.routerlist_index = -1;
-  ri->address = tor_dup_addr(addr);
+  ri->address = tor_dup_ip(addr);
   ri->nickname = tor_strdup(options->Nickname);
   ri->addr = addr;
   ri->or_port = options->ORPort;
@@ -1728,7 +1728,7 @@
     int i;
     for (i = 0; i < smartlist_len(router->exit_policy); ++i) {
       tmpe = smartlist_get(router->exit_policy, i);
-      result = policy_write_item(s+written, maxlen-written, tmpe);
+      result = policy_write_item(s+written, maxlen-written, tmpe, 1);
       if (result < 0) {
         log_warn(LD_BUG,"descriptor policy_write_item ran out of room!");
         return -1;

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/or/routerlist.c	2008-07-24 13:44:04 UTC (rev 16178)
@@ -204,7 +204,7 @@
       if (cert->addr && cert->dir_port &&
           (ds->addr != cert->addr ||
            ds->dir_port != cert->dir_port)) {
-        char *a = tor_dup_addr(cert->addr);
+        char *a = tor_dup_ip(cert->addr);
         log_notice(LD_DIR, "Updating address for directory authority %s "
                    "from %s:%d to %s:%d based on in certificate.",
                    ds->nickname, ds->address, (int)ds->dir_port,

Modified: tor/trunk/src/or/routerparse.c
===================================================================
--- tor/trunk/src/or/routerparse.c	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/or/routerparse.c	2008-07-24 13:44:04 UTC (rev 16178)
@@ -23,9 +23,11 @@
  */
 typedef enum {
   K_ACCEPT = 0,
+  K_ACCEPT6,
   K_DIRECTORY_SIGNATURE,
   K_RECOMMENDED_SOFTWARE,
   K_REJECT,
+  K_REJECT6,
   K_ROUTER,
   K_SIGNED_DIRECTORY,
   K_SIGNING_KEY,
@@ -214,7 +216,9 @@
 static token_rule_t routerdesc_token_table[] = {
   T0N("reject",              K_REJECT,              ARGS,    NO_OBJ ),
   T0N("accept",              K_ACCEPT,              ARGS,    NO_OBJ ),
-  T1_START( "router",              K_ROUTER,              GE(5),   NO_OBJ ),
+  T0N("reject6",             K_REJECT6,             ARGS,    NO_OBJ ),
+  T0N("accept6",             K_ACCEPT6,             ARGS,    NO_OBJ ),
+  T1_START( "router",        K_ROUTER,              GE(5),   NO_OBJ ),
   T1( "signing-key",         K_SIGNING_KEY,         NO_ARGS, NEED_KEY_1024 ),
   T1( "onion-key",           K_ONION_KEY,           NO_ARGS, NEED_KEY_1024 ),
   T1_END( "router-signature",    K_ROUTER_SIGNATURE,    NO_ARGS, NEED_OBJ ),
@@ -2607,12 +2611,12 @@
     log_warn(LD_DIR, "Error reading address policy: %s", tok->error);
     goto err;
   }
-  if (tok->tp != K_ACCEPT && tok->tp != K_REJECT) {
+  if (tok->tp != K_ACCEPT && tok->tp != K_ACCEPT6 &&
+      tok->tp != K_REJECT && tok->tp != K_REJECT6) {
     log_warn(LD_DIR, "Expected 'accept' or 'reject'.");
     goto err;
   }
 
-  /* Now that we've gotten an addr policy, add it to the router. */
   r = router_parse_addr_policy(tok);
   goto done;
  err:
@@ -2638,6 +2642,17 @@
   if (! router->exit_policy)
     router->exit_policy = smartlist_create();
 
+  if (((tok->tp == K_ACCEPT6 || tok->tp == K_REJECT6) &&
+       tor_addr_family(&newe->addr) == AF_INET)
+      ||
+      ((tok->tp == K_ACCEPT || tok->tp == K_REJECT) &&
+       tor_addr_family(&newe->addr) == AF_INET6)) {
+    log_warn(LD_DIR, "Mismatch between field type and address type in exit "
+             "policy");
+    addr_policy_free(newe);
+    return -1;
+  }
+
   smartlist_add(router->exit_policy, newe);
 
   return 0;
@@ -2651,7 +2666,8 @@
   addr_policy_t newe;
   char *arg;
 
-  tor_assert(tok->tp == K_REJECT || tok->tp == K_ACCEPT);
+  tor_assert(tok->tp == K_REJECT || tok->tp == K_REJECT6 ||
+             tok->tp == K_ACCEPT || tok->tp == K_ACCEPT6);
 
   if (tok->n_args != 1)
     return NULL;
@@ -2662,18 +2678,18 @@
 
   memset(&newe, 0, sizeof(newe));
 
-  newe.policy_type = (tok->tp == K_REJECT) ? ADDR_POLICY_REJECT
-    : ADDR_POLICY_ACCEPT;
+  if (tok->tp == K_REJECT || tok->tp == K_REJECT6)
+    newe.policy_type = ADDR_POLICY_REJECT;
+  else
+    newe.policy_type = ADDR_POLICY_ACCEPT;
 
-  if (parse_addr_and_port_range(arg, &newe.addr, &newe.maskbits,
-                                &newe.prt_min, &newe.prt_max))
-    goto policy_read_failed;
+  if (tor_addr_parse_mask_ports(arg, &newe.addr, &newe.maskbits,
+                                &newe.prt_min, &newe.prt_max) < 0) {
+    log_warn(LD_DIR,"Couldn't parse line %s. Dropping", escaped(arg));
+    return NULL;
+  }
 
   return addr_policy_get_canonical_entry(&newe);
-
-policy_read_failed:
-  log_warn(LD_DIR,"Couldn't parse line %s. Dropping", escaped(arg));
-  return NULL;
 }
 
 /** Parse an exit policy line of the format "accept/reject private:...".
@@ -2700,8 +2716,10 @@
     return NULL;
 
   memset(&result, 0, sizeof(result));
-  result.policy_type = (tok->tp == K_REJECT) ? ADDR_POLICY_REJECT
-    : ADDR_POLICY_ACCEPT;
+  if (tok->tp == K_REJECT || tok->tp == K_REJECT6)
+    result.policy_type = ADDR_POLICY_REJECT;
+  else
+    result.policy_type = ADDR_POLICY_ACCEPT;
   result.is_private = 1;
   result.prt_min = port_min;
   result.prt_max = port_max;
@@ -3076,8 +3094,9 @@
 {
   smartlist_t *out = smartlist_create();
   SMARTLIST_FOREACH(s, directory_token_t *, t,
-                    if (t->tp == K_ACCEPT || t->tp == K_REJECT)
-                      smartlist_add(out,t));
+      if (t->tp == K_ACCEPT || t->tp == K_ACCEPT6 ||
+          t->tp == K_REJECT || t->tp == K_REJECT6)
+        smartlist_add(out,t));
   return out;
 }
 

Modified: tor/trunk/src/or/test.c
===================================================================
--- tor/trunk/src/or/test.c	2008-07-24 13:23:24 UTC (rev 16177)
+++ tor/trunk/src/or/test.c	2008-07-24 13:44:04 UTC (rev 16178)
@@ -2519,11 +2519,11 @@
   ex1 = tor_malloc_zero(sizeof(addr_policy_t));
   ex2 = tor_malloc_zero(sizeof(addr_policy_t));
   ex1->policy_type = ADDR_POLICY_ACCEPT;
-  ex1->addr = 0;
+  tor_addr_from_ipv4h(&ex1->addr, 0);
   ex1->maskbits = 0;
   ex1->prt_min = ex1->prt_max = 80;
   ex2->policy_type = ADDR_POLICY_REJECT;
-  ex2->addr = 18 << 24;
+  tor_addr_from_ipv4h(&ex2->addr, 18<<24);
   ex2->maskbits = 8;
   ex2->prt_min = ex2->prt_max = 24;
   r2 = tor_malloc_zero(sizeof(routerinfo_t));
@@ -3279,9 +3279,10 @@
   policy = smartlist_create();
 
   p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1);
+  test_assert(p != NULL);
   test_eq(ADDR_POLICY_REJECT, p->policy_type);
-  tor_addr_from_ipv4(&tar, 0xc0a80000u);
-  test_assert(p->addr == 0xc0a80000u);
+  tor_addr_from_ipv4h(&tar, 0xc0a80000u);
+  test_eq(0, tor_addr_compare(&p->addr, &tar));
   test_eq(16, p->maskbits);
   test_eq(1, p->prt_min);
   test_eq(65535, p->prt_max);



More information about the tor-commits mailing list