[or-cvs] r16234: More test coverage for tor_addr_t; fix a couple of bugs. (in tor/trunk: . src/common src/or)

nickm at seul.org nickm at seul.org
Tue Jul 29 00:34:50 UTC 2008


Author: nickm
Date: 2008-07-28 20:34:50 -0400 (Mon, 28 Jul 2008)
New Revision: 16234

Modified:
   tor/trunk/
   tor/trunk/Makefile.am
   tor/trunk/src/common/address.c
   tor/trunk/src/common/address.h
   tor/trunk/src/or/test.c
Log:
 r17426 at tombo:  nickm | 2008-07-28 20:34:03 -0400
 More test coverage for tor_addr_t; fix a couple of bugs.



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

Modified: tor/trunk/Makefile.am
===================================================================
--- tor/trunk/Makefile.am	2008-07-28 16:00:45 UTC (rev 16233)
+++ tor/trunk/Makefile.am	2008-07-29 00:34:50 UTC (rev 16234)
@@ -67,7 +67,7 @@
 check-spaces:
 	./contrib/checkSpace.pl -C                    \
 	        src/common/*.h                        \
-		src/common/[^asO]*.c                  \
+		src/common/[^asO]*.c src/common/address.c \
 		src/or/[^et]*.[ch] src/or/t*.c src/or/eventdns_tor.h
 
 check-docs:

Modified: tor/trunk/src/common/address.c
===================================================================
--- tor/trunk/src/common/address.c	2008-07-28 16:00:45 UTC (rev 16233)
+++ tor/trunk/src/common/address.c	2008-07-29 00:34:50 UTC (rev 16234)
@@ -7,12 +7,8 @@
   "$Id$";
 
 /**
- * \file compat.c
- * \brief Wrappers to make calls more portable.  This code defines
- * functions such as tor_malloc, tor_snprintf, get/set various data types,
- * renaming, setting socket options, switching user IDs.  It is basically
- * where the non-portable items are conditionally included depending on
- * the platform.
+ * \file address.c
+ * \brief DOCDOC
  **/
 
 /* This is required on rh7 to make strptime not complain.
@@ -102,21 +98,30 @@
 #include <sys/syslimits.h>
 #endif
 
-/** DOCDOC */
+/** Convert the tor_addr_t in <b>a</b>, with port in <b>port</b>, into a
+ * socklen object in *<b>sa_out</b> of object size <b>len</b>.  If not enough
+ * room is free, or on error, return -1.  Else return the length of the
+ * sockaddr. */
 socklen_t
 tor_addr_to_sockaddr(const tor_addr_t *a,
                      uint16_t port,
-                     struct sockaddr *sa_out)
+                     struct sockaddr *sa_out,
+                     socklen_t len)
 {
   if (a->family == AF_INET) {
-    struct sockaddr_in *sin = (struct sockaddr_in *)sa_out;
+    struct sockaddr_in *sin;
+    if (len < sizeof(struct sockaddr_in))
+      return -1;
+    sin = (struct sockaddr_in *)sa_out;
     sin->sin_family = AF_INET;
     sin->sin_port = port;
     sin->sin_addr.s_addr = a->addr.in_addr.s_addr;
     return sizeof(struct sockaddr_in);
   } else if (a->family == AF_INET6) {
-    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa_out;
-    tor_assert(a->family == AF_INET6);
+    struct sockaddr_in6 *sin6;
+    if (len < sizeof(struct sockaddr_in6))
+      return -1;
+    sin6 = (struct sockaddr_in6 *)sa_out;
     memset(sin6, 0, sizeof(struct sockaddr_in6));
     sin6->sin6_family = AF_INET6;
     sin6->sin6_port = port;
@@ -127,11 +132,14 @@
   }
 }
 
-/** DOCDOC */
+/** Set the tor_addr_t in <b>a</b> to contain the socket address contained in
+ * <b>sa</b>. */
 void
 tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa)
 {
-  memset(&a, 0, sizeof(tor_addr_t));
+  tor_assert(a);
+  tor_assert(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;
@@ -140,6 +148,8 @@
     struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
     a->family = AF_INET6;
     memcpy(&a->addr.in6_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
+  } else {
+    a->family = AF_UNSPEC;
   }
 }
 
@@ -161,7 +171,7 @@
   struct in6_addr iaddr6;
   tor_assert(name);
   tor_assert(addr);
-  tor_assert(family == AF_INET || family == AF_UNSPEC);
+  tor_assert(family == AF_INET || family == AF_INET6 || family == AF_UNSPEC);
   memset(addr, 0, sizeof(addr)); /* Clear the extraneous fields. */
   if (!*name) {
     /* Empty address is an error. */
@@ -340,18 +350,20 @@
     case AF_INET:
       if (len<3)
         return NULL;
+        ptr = tor_inet_ntop(AF_INET, &addr->addr.in_addr, dest, len);
+      break;
+    case AF_INET6:
       if (decorate)
-        ptr = tor_inet_ntop(AF_INET, &addr->addr.in_addr, dest+1, len-2);
+        ptr = tor_inet_ntop(AF_INET6, &addr->addr.in6_addr, dest+1, len-2);
       else
-        ptr = tor_inet_ntop(AF_INET, &addr->addr.in_addr, dest, len);
+        ptr = tor_inet_ntop(AF_INET6, &addr->addr.in6_addr, dest, len);
       if (ptr && decorate) {
         *dest = '[';
         memcpy(dest+strlen(dest), "]", 2);
+        tor_assert(ptr == dest+1);
+        ptr = dest;
       }
       break;
-    case AF_INET6:
-      ptr = tor_inet_ntop(AF_INET6, &addr->addr.in6_addr, dest, len);
-      break;
     default:
       return NULL;
   }
@@ -683,12 +695,24 @@
       case AF_INET: {
         uint32_t a1 = ntohl(addr1->addr.in_addr.s_addr);
         uint32_t a2 = ntohl(addr2->addr.in_addr.s_addr);
+        a1 >>= (32-mbits);
+        a2 >>= (32-mbits);
         return (a1 < a2) ? -1 : (a1 == a2) ? 0 : 1;
       }
       case AF_INET6: {
-        uint32_t *a1 = S6_ADDR32(addr1->addr.in6_addr);
-        uint32_t *a2 = S6_ADDR32(addr2->addr.in6_addr);
-        return memcmp(a1, a2, 16);
+        uint8_t *a1 = addr1->addr.in6_addr.s6_addr;
+        uint8_t *a2 = addr2->addr.in6_addr.s6_addr;
+        const int bytes = mbits >> 3;
+        const int leftover_bits = mbits & 7;
+        if (bytes && (r = memcmp(a1, a2, bytes))) {
+          return r;
+        } else if (leftover_bits) {
+          uint8_t b1 = a1[bytes] >> (8-leftover_bits);
+          uint8_t b2 = a2[bytes] >> (8-leftover_bits);
+          return (b1 < b2) ? -1 : (b1 == b2) ? 0 : 1;
+        } else {
+          return 0;
+        }
       }
       default:
         tor_fragile_assert();
@@ -706,6 +730,7 @@
   v_family[0] = tor_addr_family(addr1);
   v_family[1] = tor_addr_family(addr2);
 
+  /* All UNSPEC addresses are equal; they are unequal to all other addresses.*/
   if (v_family[0] == AF_UNSPEC) {
     if (v_family[1] == AF_UNSPEC)
       return 0;
@@ -785,7 +810,6 @@
 
 }
 
-
 /** Return a hash code based on the address addr */
 unsigned int
 tor_addr_hash(const tor_addr_t *addr)
@@ -825,7 +849,6 @@
   return tor_addr_parse_mask_ports(src, addr, NULL, NULL, NULL);
 }
 
-
 /** Set *<b>addr</b> to the IP address (if any) of whatever interface
  * connects to the internet.  This address should only be used in checking
  * whether our address has changed.  Return 0 on success, -1 on failure.
@@ -991,7 +1014,7 @@
 }
 
 /** Compare two addresses <b>a1</b> and <b>a2</b> for equality under a
- *  etmask of <b>mbits</b> bits.  Return -1, 0, or 1.
+ * netmask of <b>mbits</b> bits.  Return -1, 0, or 1.
  *
  * XXXX_IP6 Temporary function to allow masks as bitcounts everywhere.  This
  * will be replaced with an IPv6-aware version as soon as 32-bit addresses are
@@ -1184,7 +1207,6 @@
   return tor_strdup(buf);
 }
 
-
 /**
  * Set *<b>addr</b> to the host-order IPv4 address (if any) of whatever
  * interface connects to the internet.  This address should only be used in
@@ -1202,3 +1224,4 @@
     *addr = tor_addr_to_ipv4h(&local_addr);
   return r;
 }
+

Modified: tor/trunk/src/common/address.h
===================================================================
--- tor/trunk/src/common/address.h	2008-07-28 16:00:45 UTC (rev 16233)
+++ tor/trunk/src/common/address.h	2008-07-29 00:34:50 UTC (rev 16234)
@@ -37,8 +37,9 @@
 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);
+static INLINE int tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u);
 socklen_t tor_addr_to_sockaddr(const tor_addr_t *a, uint16_t port,
-                               struct sockaddr *sa_out);
+                               struct sockaddr *sa_out, socklen_t len);
 void tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa);
 
 static INLINE const struct in6_addr *
@@ -47,6 +48,7 @@
   return a->family == AF_INET6 ? &a->addr.in6_addr : NULL;
 }
 
+#define tor_addr_to_in6_addr8(x) tor_addr_to_in6(x)->s6_addr
 #define tor_addr_to_in6_addr16(x) S6_ADDR16(*tor_addr_to_in6(x))
 #define tor_addr_to_in6_addr32(x) S6_ADDR32(*tor_addr_to_in6(x))
 
@@ -75,6 +77,11 @@
 {
   return a->family == AF_INET ? &a->addr.in_addr : NULL;
 }
+static INLINE int
+tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u)
+{
+  return a->family == AF_INET ? (tor_addr_to_ipv4h(a) == u) : 0;
+}
 
 #define TOR_ADDR_BUF_LEN 48 /* [ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255]
                              */

Modified: tor/trunk/src/or/test.c
===================================================================
--- tor/trunk/src/or/test.c	2008-07-28 16:00:45 UTC (rev 16233)
+++ tor/trunk/src/or/test.c	2008-07-29 00:34:50 UTC (rev 16234)
@@ -1316,10 +1316,59 @@
   uint16_t port1, port2;
   maskbits_t mask;
   const char *p1;
+  struct sockaddr_storage sa_storage;
+  struct sockaddr_in *sin;
+  struct sockaddr_in6 *sin6;
 
   //  struct in_addr b1, b2;
   /* Test tor_inet_ntop and tor_inet_pton: IPv6 */
 
+  /* ==== Converting to and from sockaddr_t. */
+  sin = (struct sockaddr_in *)&sa_storage;
+  sin->sin_family = AF_INET;
+  sin->sin_port = 9090;
+  sin->sin_addr.s_addr = htonl(0x7f7f0102); /*127.127.1.2*/
+  tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin);
+  test_eq(tor_addr_family(&t1), AF_INET);
+  test_eq(tor_addr_to_ipv4h(&t1), 0x7f7f0102);
+
+  memset(&sa_storage, 0, sizeof(sa_storage));
+  test_eq(sizeof(struct sockaddr_in),
+          tor_addr_to_sockaddr(&t1, 1234, (struct sockaddr *)&sa_storage,
+                               sizeof(sa_storage)));
+  test_eq(1234, sin->sin_port);
+  test_eq(0x7f7f0102, ntohl(sin->sin_addr.s_addr));
+
+  memset(&sa_storage, 0, sizeof(sa_storage));
+  sin6 = (struct sockaddr_in6 *)&sa_storage;
+  sin6->sin6_family = AF_INET6;
+  sin6->sin6_port = 7070;
+  sin6->sin6_addr.s6_addr[0] = 128;
+  tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6);
+  test_eq(tor_addr_family(&t1), AF_INET6);
+  p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0);
+  test_streq(p1, "8000::");
+
+  memset(&sa_storage, 0, sizeof(sa_storage));
+  test_eq(sizeof(struct sockaddr_in6),
+          tor_addr_to_sockaddr(&t1, 9999, (struct sockaddr *)&sa_storage,
+                               sizeof(sa_storage)));
+  test_eq(AF_INET6, sin6->sin6_family);
+  test_eq(9999, sin6->sin6_port);
+  test_eq(0x80000000, ntohl(S6_ADDR32(sin6->sin6_addr)[0]));
+
+  /* ==== tor_addr_lookup: static cases.  (Can't test dns without knowing we
+   * have a good resolver. */
+  test_eq(0, tor_addr_lookup("127.128.129.130", AF_UNSPEC, &t1));
+  test_eq(AF_INET, tor_addr_family(&t1));
+  test_eq(tor_addr_to_ipv4h(&t1), 0x7f808182);
+
+  test_eq(0, tor_addr_lookup("9000::5", AF_UNSPEC, &t1));
+  test_eq(AF_INET6, tor_addr_family(&t1));
+  test_eq(0x90, tor_addr_to_in6_addr8(&t1)[0]);
+  test_assert(tor_mem_is_zero((char*)tor_addr_to_in6_addr8(&t1)+1, 14));
+  test_eq(0x05, tor_addr_to_in6_addr8(&t1)[15]);
+
   /* === Test pton: valid af_inet6 */
   /* Simple, valid parsing. */
   r = tor_inet_pton(AF_INET6,
@@ -1436,6 +1485,7 @@
   test_internal_ip("::ffff:169.254.0.0", 0);
   test_internal_ip("::ffff:169.254.255.255", 0);
   test_external_ip("::ffff:169.255.0.0", 0);
+  test_assert(is_internal_IP(0x7f000001, 0));
 
   /* tor_addr_compare(tor_addr_t x2) */
   test_addr_compare("ffff::", ==, "ffff::0");
@@ -1456,6 +1506,14 @@
   test_addr_compare_masked("0::2:2:1", <, "0::8000:2:1", 81);
   test_addr_compare_masked("0::2:2:1", ==, "0::8000:2:1", 80);
 
+  /* Test decorated addr_to_string. */
+  test_eq(AF_INET6, tor_addr_from_str(&t1, "[123:45:6789::5005:11]"));
+  p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
+  test_streq(p1, "[123:45:6789::5005:11]");
+  test_eq(AF_INET, tor_addr_from_str(&t1, "18.0.0.1"));
+  p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
+  test_streq(p1, "18.0.0.1");
+
   /* test tor_addr_parse_mask_ports */
   test_addr_mask_ports_parse("[::f]/17:47-95", AF_INET6,
                              0, 0, 0, 0x0000000f, 17, 47, 95);



More information about the tor-commits mailing list