[or-cvs] r16435: {tor} Initial conversion of uint32_t addr to tor_addr_t addr in co (in tor/trunk: . doc src/common src/or)

nickm at seul.org nickm at seul.org
Tue Aug 5 20:08:20 UTC 2008


Author: nickm
Date: 2008-08-05 16:08:19 -0400 (Tue, 05 Aug 2008)
New Revision: 16435

Modified:
   tor/trunk/
   tor/trunk/ChangeLog
   tor/trunk/doc/TODO.021
   tor/trunk/src/common/address.c
   tor/trunk/src/common/address.h
   tor/trunk/src/or/circuitbuild.c
   tor/trunk/src/or/circuitlist.c
   tor/trunk/src/or/circuituse.c
   tor/trunk/src/or/command.c
   tor/trunk/src/or/config.c
   tor/trunk/src/or/connection.c
   tor/trunk/src/or/connection_edge.c
   tor/trunk/src/or/connection_or.c
   tor/trunk/src/or/cpuworker.c
   tor/trunk/src/or/directory.c
   tor/trunk/src/or/dirserv.c
   tor/trunk/src/or/dns.c
   tor/trunk/src/or/dnsserv.c
   tor/trunk/src/or/main.c
   tor/trunk/src/or/networkstatus.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/policies.c
   tor/trunk/src/or/relay.c
   tor/trunk/src/or/rendclient.c
   tor/trunk/src/or/rendcommon.c
   tor/trunk/src/or/rendservice.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:
 r17641 at 31-33-44:  nickm | 2008-08-05 16:07:53 -0400
 Initial conversion of uint32_t addr to tor_addr_t addr in connection_t and related types.  Most of the Tor wire formats using these new types are in, but the code to generate and use it is not.  This is a big patch.  Let me know what it breaks for you.



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

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/ChangeLog	2008-08-05 20:08:19 UTC (rev 16435)
@@ -1,3 +1,10 @@
+Changes in version 0.2.1.5-alpha - 2008-08-??
+  o Major features [IPv6 support]:
+    - Convert many internal address representations to optionally hold
+      IPv6 addresses.
+    - Generate and accept IPv6 addresses in many protocol elements.
+
+
 Changes in version 0.2.1.4-alpha - 2008-08-04
   o Major bugfixes:
     - The address part of exit policies was not correctly written

Modified: tor/trunk/doc/TODO.021
===================================================================
--- tor/trunk/doc/TODO.021	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/doc/TODO.021	2008-08-05 20:08:19 UTC (rev 16435)
@@ -180,14 +180,20 @@
     - Proposal to supersede 117 by adding IPv6 support for exits and entries.
       - Internal code support for ipv6:
         o Clone ipv6 functions (inet_ntop, inet_pton) where they don't exist.
-        . Many address variables need to become tor_addr_t
-          - addr in connection_t
-          - n_addr in extend_info_t
+        o Many address variables need to become tor_addr_t
+          o addr in connection_t
+          o n_addr in extend_info_t
         - Teach resolving code how to handle ipv6.
-        . Teach exit policies about ipv6 (consider ipv4/ipv6
-          interaction!)
-        - Generate END_REASON_EXITPOLICY cells and parse them right
-        - Generate new BEGIN cell types and parse them right
+        . Teach exit policies about ipv6 (consider ipv4/ipv6 interaction!)
+	o Use IPv6 in connect/connected/failed-exitpolicy cells
+	- accept ipv6 from socks
+        o Generate END_REASON_EXITPOLICY cells right
+	  . ... and parse them right
+        . Generate new BEGIN cell types and parse them right
+	- Detect availability of ipv6
+	- Advertise availability of ipv6.
+	- Geoip support, if only to add a zone called "ipv6"
+	-
     - 118: Listen on and advertise multiple ports:
       - Tor should be able to have a pool of outgoing IP addresses that it is
         able to rotate through. (maybe.  Possible overlap with proposal 118.)

Modified: tor/trunk/src/common/address.c
===================================================================
--- tor/trunk/src/common/address.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/common/address.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -8,7 +8,7 @@
 
 /**
  * \file address.c
- * \brief DOCDOC
+ * \brief Functions to use and manipulate the tor_addr_t structure.
  **/
 
 /* This is required on rh7 to make strptime not complain.
@@ -27,30 +27,12 @@
 #include <windows.h>
 #endif
 
-#ifdef HAVE_UNAME
-#include <sys/utsname.h>
-#endif
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
-#ifdef HAVE_SYS_FCNTL_H
-#include <sys/fcntl.h>
-#endif
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-#ifdef HAVE_GRP_H
-#include <grp.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif
@@ -60,11 +42,6 @@
 #ifdef HAVE_ARPA_INET_H
 #include <arpa/inet.h>
 #endif
-#ifndef HAVE_GETTIMEOFDAY
-#ifdef HAVE_FTIME
-#include <sys/timeb.h>
-#endif
-#endif
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
 #endif
@@ -79,24 +56,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-#ifdef HAVE_UTIME_H
-#include <utime.h>
-#endif
-#ifdef HAVE_SYS_UTIME_H
-#include <sys/utime.h>
-#endif
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#ifdef HAVE_SYS_SYSLIMITS_H
-#include <sys/syslimits.h>
-#endif
 
 /** 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
@@ -113,9 +72,10 @@
     if (len < sizeof(struct sockaddr_in))
       return -1;
     sin = (struct sockaddr_in *)sa_out;
+    sin->sin_len = sizeof(*sin);
     sin->sin_family = AF_INET;
-    sin->sin_port = port;
-    sin->sin_addr.s_addr = a->addr.in_addr.s_addr;
+    sin->sin_port = htons(port);
+    sin->sin_addr.s_addr = tor_addr_to_ipv4n(a);
     return sizeof(struct sockaddr_in);
   } else if (a->family == AF_INET6) {
     struct sockaddr_in6 *sin6;
@@ -123,8 +83,9 @@
       return -1;
     sin6 = (struct sockaddr_in6 *)sa_out;
     memset(sin6, 0, sizeof(struct sockaddr_in6));
+    sin6->sin6_len = sizeof(sin6);
     sin6->sin6_family = AF_INET6;
-    sin6->sin6_port = port;
+    sin6->sin6_port = htons(port);
     memcpy(&sin6->sin6_addr, &a->addr.in6_addr, sizeof(struct in6_addr));
     return sizeof(struct sockaddr_in6);
   } else {
@@ -134,7 +95,7 @@
 
 /** Set the tor_addr_t in <b>a</b> to contain the socket address contained in
  * <b>sa</b>. */
-void
+int
 tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa)
 {
   tor_assert(a);
@@ -150,9 +111,20 @@
     memcpy(&a->addr.in6_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
   } else {
     a->family = AF_UNSPEC;
+    return -1;
   }
+  return 0;
 }
 
+/** Set address <b>a</b> to the unspecified address.  This address belongs to
+ * no family. */
+void
+tor_addr_make_unspec(tor_addr_t *a)
+{
+  memset(a, 0, sizeof(*a));
+  a->family = AF_UNSPEC;
+}
+
 /** Similar behavior to Unix gethostbyname: resolve <b>name</b>, and set
  * *<b>addr</b> to the proper IP address and family. The <b>family</b>
  * argument (which must be AF_INET, AF_INET6, or AF_UNSPEC) declares a
@@ -178,10 +150,14 @@
     return -1;
   } else if (tor_inet_pton(AF_INET, name, &iaddr)) {
     /* It's an IPv4 IP. */
+    if (family == AF_INET6)
+      return -1;
     addr->family = AF_INET;
     memcpy(&addr->addr.in_addr, &iaddr, sizeof(struct in_addr));
     return 0;
   } else if (tor_inet_pton(AF_INET6, name, &iaddr6)) {
+    if (family == AF_INET)
+      return -1;
     addr->family = AF_INET6;
     memcpy(&addr->addr.in6_addr, &iaddr6, sizeof(struct in6_addr));
     return 0;
@@ -633,26 +609,36 @@
   }
 }
 
-/** 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. */
+/** Set <b>dest</b> to equal the IPv4 address in <b>v4addr</b> (given in
+ * network order. */
 void
-tor_addr_from_ipv4h(tor_addr_t *dest, uint32_t v4addr)
+tor_addr_from_ipv4n(tor_addr_t *dest, uint32_t v4addr)
 {
   tor_assert(dest);
   memset(dest, 0, sizeof(dest));
   dest->family = AF_INET;
-  dest->addr.in_addr.s_addr = htonl(v4addr);
+  dest->addr.in_addr.s_addr = v4addr;
 }
 
+/** Set <b>dest</b> to equal the IPv6 address in the 16 bytes at
+ * <b>ipv6_bytes</b>. */
+void
+tor_addr_from_ipv6_bytes(tor_addr_t *dest, const char *ipv6_bytes)
+{
+  tor_assert(dest);
+  tor_assert(ipv6_bytes);
+  memset(dest, 0, sizeof(dest));
+  dest->family = AF_INET6;
+  memcpy(dest->addr.in6_addr.s6_addr, ipv6_bytes, 16);
+}
+
 /** Copy a tor_addr_t from <b>src</b> to <b>dest</b>.
  */
 void
 tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src)
 {
-  tor_assert(src && dest);
+  tor_assert(src);
+  tor_assert(dest);
   memcpy(dest, src, sizeof(tor_addr_t));
 }
 
@@ -838,6 +824,19 @@
   return tor_strdup(buf);
 }
 
+/** Return a string representing the address <b>addr</b>.  This string is
+ * statically allocated, and must not be freed.  Each call to
+ * <b>fmt_addr</b> invalidates the last result of the function.  This
+ * function is not thread-safe. */
+const char *
+fmt_addr(const tor_addr_t *addr)
+{
+  static char buf[TOR_ADDR_BUF_LEN];
+  if (!addr) return "<null>";
+  tor_addr_to_str(buf, addr, sizeof(buf), 0);
+  return buf;
+}
+
 /** Convert the string in <b>src</b> to a tor_addr_t <b>addr</b>.  The string
  * may be an IPv4 address, an IPv6 address, or an IPv6 address surrounded by
  * square brackets.
@@ -865,6 +864,64 @@
   return result;
 }
 
+/** Parse an address or address-port combination from <b>s</b>, and put the
+    result in <b>addr_out</b? and (optionally) <b>port_out</b>.  Return 0 on
+    success, negative on failure.*/
+int
+tor_addr_port_parse(const char *s, tor_addr_t *addr_out, uint16_t *port_out)
+{
+  const char *port;
+  tor_addr_t addr;
+  uint16_t portval;
+  char *tmp = NULL;
+
+  tor_assert(s);
+  tor_assert(addr_out);
+
+  s = eat_whitespace(s);
+
+  if (*s == '[') {
+    port = strstr(s, "]");
+    if (!port)
+      goto err;
+    tmp = tor_strndup(s+1, port-s);
+    port = port+1;
+    if (*port == ':')
+      port++;
+    else
+      port = NULL;
+  } else {
+    port = strchr(s, ':');
+    if (port)
+      tmp = tor_strndup(s, port-s);
+    else
+      tmp = tor_strdup(s);
+    if (port)
+      ++port;
+  }
+
+  if (tor_addr_lookup(tmp, AF_UNSPEC, &addr) < 0)
+    goto err;
+  tor_free(tmp);
+
+  if (port) {
+    portval = (int) tor_parse_long(port, 10, 1, 65535, NULL, NULL);
+    if (!portval)
+      goto err;
+  } else {
+    portval = 0;
+  }
+
+  if (*port_out)
+    *port_out = portval;
+  tor_addr_copy(addr_out, &addr);
+
+  return 0;
+ err:
+  tor_free(tmp);
+  return -1;
+}
+
 /** 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.

Modified: tor/trunk/src/common/address.h
===================================================================
--- tor/trunk/src/common/address.h	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/common/address.h	2008-08-05 20:08:19 UTC (rev 16435)
@@ -40,7 +40,8 @@
 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, socklen_t len);
-void tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa);
+int tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa);
+void tor_addr_make_unspec(tor_addr_t *a);
 
 static INLINE const struct in6_addr *
 tor_addr_to_in6(const tor_addr_t *a)
@@ -88,9 +89,13 @@
 
 int tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr_out);
 char *tor_dup_addr(const tor_addr_t *addr) ATTR_MALLOC;
+const char *fmt_addr(const tor_addr_t *addr);
 int get_interface_address6(int severity, sa_family_t family, tor_addr_t *addr);
 
-/** DOCDOC */
+/** Flag to specify how to do a comparison between addresses.  In an "exact"
+ * comparison, addresses are equivalent only if they are in the same family
+ * with the same value.  In a "semantic" comparison, IPv4 addresses match all
+ * IPv6 encodings of those addresses. */
 typedef enum {
   CMP_EXACT,
   CMP_SEMANTIC,
@@ -100,10 +105,15 @@
                      tor_addr_comparison_t how);
 int tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
                             maskbits_t mask, tor_addr_comparison_t how);
+/** Return true iff a and b are the same address.  The comparison is done
+ * "exactly". */
+#define tor_addr_eq(a,b) (0==tor_addr_compare((a),(b),CMP_EXACT))
 
 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_port_parse(const char *s, tor_addr_t *addr_out,
+                        uint16_t *port_out);
 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);
@@ -111,7 +121,12 @@
                              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_ipv4h(tor_addr_t *dest, uint32_t v4addr);
+void tor_addr_from_ipv4n(tor_addr_t *dest, uint32_t v4addr);
+/** Set <b>dest</b> to the IPv4 address encoded in <b>v4addr</b> in host
+ * order. */
+#define tor_addr_from_ipv4h(dest, v4addr)       \
+  tor_addr_from_ipv4n((dest), htonl(v4addr))
+void tor_addr_from_ipv6_bytes(tor_addr_t *dest, const char *byets);
 int tor_addr_is_null(const tor_addr_t *addr);
 int tor_addr_is_loopback(const tor_addr_t *addr);
 

Modified: tor/trunk/src/or/circuitbuild.c
===================================================================
--- tor/trunk/src/or/circuitbuild.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/circuitbuild.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -343,8 +343,6 @@
 {
   crypt_path_t *firsthop;
   or_connection_t *n_conn;
-  char tmpbuf[INET_NTOA_BUF_LEN];
-  struct in_addr in;
   int err_reason = 0;
 
   firsthop = onion_next_hop_in_cpath(circ->cpath);
@@ -352,9 +350,8 @@
   tor_assert(firsthop->extend_info);
 
   /* now see if we're already connected to the first OR in 'route' */
-  in.s_addr = htonl(firsthop->extend_info->addr);
-  tor_inet_ntoa(&in, tmpbuf, sizeof(tmpbuf));
-  log_debug(LD_CIRC,"Looking for firsthop '%s:%u'",tmpbuf,
+  log_debug(LD_CIRC,"Looking for firsthop '%s:%u'",
+            fmt_addr(&firsthop->extend_info->addr),
             firsthop->extend_info->port);
 
   n_conn = connection_or_get_by_identity_digest(
@@ -370,7 +367,7 @@
     if (!n_conn || n_conn->_base.or_is_obsolete) { /* launch the connection */
       if (circ->build_state->onehop_tunnel)
         control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DIR, 0);
-      n_conn = connection_or_connect(firsthop->extend_info->addr,
+      n_conn = connection_or_connect(&firsthop->extend_info->addr,
                                      firsthop->extend_info->port,
                                      firsthop->extend_info->identity_digest);
       if (!n_conn) { /* connect failed, forget the whole thing */
@@ -426,7 +423,7 @@
 
       if (tor_digest_is_zero(circ->n_hop->identity_digest)) {
         /* Look at addr/port. This is an unkeyed connection. */
-        if (circ->n_hop->addr != or_conn->_base.addr ||
+        if (!tor_addr_eq(&circ->n_hop->addr, &or_conn->_base.addr) ||
             circ->n_hop->port != or_conn->_base.port)
           continue;
       } else {
@@ -662,7 +659,12 @@
       return 0;
     }
 
-    set_uint32(payload, htonl(hop->extend_info->addr));
+    if (tor_addr_family(&hop->extend_info->addr) != AF_INET) {
+      log_warn(LD_BUG, "Trying to extend to a non-IPv4 address.");
+      return - END_CIRC_REASON_INTERNAL;
+    }
+
+    set_uint32(payload, tor_addr_to_ipv4n(&hop->extend_info->addr));
     set_uint16(payload+4, htons(hop->extend_info->port));
 
     onionskin = payload+2+4;
@@ -758,17 +760,16 @@
    * connection without dropping it immediately... */
   if (!n_conn || n_conn->_base.state != OR_CONN_STATE_OPEN ||
       n_conn->_base.or_is_obsolete) {
-    struct in_addr in;
-    char tmpbuf[INET_NTOA_BUF_LEN];
-    in.s_addr = htonl(n_addr);
-    tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
+    tor_addr_t addr;
+    tor_addr_from_ipv4h(&addr, n_addr);
+
     log_debug(LD_CIRC|LD_OR,"Next router (%s:%d) not connected. Connecting.",
-              tmpbuf, (int)n_port);
+              fmt_addr(&addr), (int)n_port);
 
     circ->n_hop = extend_info_alloc(NULL /*nickname*/,
                                     id_digest,
                                     NULL /*onion_key*/,
-                                    n_addr, n_port);
+                                    &addr, n_port);
 
     circ->n_conn_onionskin = tor_malloc(ONIONSKIN_CHALLENGE_LEN);
     memcpy(circ->n_conn_onionskin, onionskin, ONIONSKIN_CHALLENGE_LEN);
@@ -776,7 +777,7 @@
 
     if (! (n_conn && !n_conn->_base.or_is_obsolete)) {
       /* we should try to open a connection */
-      n_conn = connection_or_connect(n_addr, n_port, id_digest);
+      n_conn = connection_or_connect(&addr, n_port, id_digest);
       if (!n_conn) {
         log_info(LD_CIRC,"Launching n_conn failed. Closing circuit.");
         circuit_mark_for_close(circ, END_CIRC_REASON_CONNECTFAILED);
@@ -1015,7 +1016,7 @@
                                circ->p_conn, &cell, CELL_DIRECTION_IN);
   log_debug(LD_CIRC,"Finished sending 'created' cell.");
 
-  if (!is_local_IP(circ->p_conn->_base.addr) &&
+  if (!is_local_addr(&circ->p_conn->_base.addr) &&
       !connection_or_nonopen_was_started_here(circ->p_conn)) {
     /* record that we could process create cells from a non-local conn
      * that we didn't initiate; presumably this means that create cells
@@ -1589,7 +1590,7 @@
 
     for (i=0; i < smartlist_len(rl->routers); i++) {
       r = smartlist_get(rl->routers, i);
-      if (!fascist_firewall_allows_address_or(r->addr,r->or_port))
+      if (!fascist_firewall_allows_or(r))
         smartlist_add(excluded, r);
     }
   }
@@ -1708,7 +1709,7 @@
 extend_info_t *
 extend_info_alloc(const char *nickname, const char *digest,
                   crypto_pk_env_t *onion_key,
-                  uint32_t addr, uint16_t port)
+                  const tor_addr_t *addr, uint16_t port)
 {
   extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t));
   memcpy(info->identity_digest, digest, DIGEST_LEN);
@@ -1716,7 +1717,7 @@
     strlcpy(info->nickname, nickname, sizeof(info->nickname));
   if (onion_key)
     info->onion_key = crypto_pk_dup_key(onion_key);
-  info->addr = addr;
+  tor_addr_copy(&info->addr, addr);
   info->port = port;
   return info;
 }
@@ -1726,9 +1727,11 @@
 extend_info_t *
 extend_info_from_router(routerinfo_t *r)
 {
+  tor_addr_t addr;
   tor_assert(r);
+  tor_addr_from_ipv4h(&addr, r->addr);
   return extend_info_alloc(r->nickname, r->cache_info.identity_digest,
-                           r->onion_pkey, r->addr, r->or_port);
+                           r->onion_pkey, &addr, r->or_port);
 }
 
 /** Release storage held by an extend_info_t struct. */
@@ -1888,7 +1891,7 @@
     return NULL;
   if (router_is_unreliable(r, need_uptime, need_capacity, 0))
     return NULL;
-  if (!fascist_firewall_allows_address_or(r->addr,r->or_port))
+  if (!fascist_firewall_allows_or(r))
     return NULL;
   return r;
 }
@@ -2781,8 +2784,8 @@
  * ones in the torrc file, but one day we may be able to learn about new
  * bridges on our own, and remember them in the state file. */
 typedef struct {
-  /** IPv4 address of the bridge. */
-  uint32_t addr;
+  /** Address of the bridge. */
+  tor_addr_t addr;
   /** TLS port for the bridge. */
   uint16_t port;
   /** Expected identity digest, or all \0's if we don't know what the
@@ -2814,15 +2817,17 @@
 {
   if (!bridge_list)
     return NULL;
-  SMARTLIST_FOREACH(bridge_list, bridge_info_t *, bridge,
+  SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge)
     {
       if (tor_digest_is_zero(bridge->identity) &&
-          bridge->addr == ri->addr && bridge->port == ri->or_port)
+          tor_addr_eq_ipv4h(&bridge->addr, ri->addr) &&
+          bridge->port == ri->or_port)
         return bridge;
       if (!memcmp(bridge->identity, ri->cache_info.identity_digest,
                   DIGEST_LEN))
         return bridge;
-    });
+    }
+  SMARTLIST_FOREACH_END(bridge);
   return NULL;
 }
 
@@ -2836,10 +2841,10 @@
 /** Remember a new bridge at <b>addr</b>:<b>port</b>. If <b>digest</b>
  * is set, it tells us the identity key too. */
 void
-bridge_add_from_config(uint32_t addr, uint16_t port, char *digest)
+bridge_add_from_config(const tor_addr_t *addr, uint16_t port, char *digest)
 {
   bridge_info_t *b = tor_malloc_zero(sizeof(bridge_info_t));
-  b->addr = addr;
+  tor_addr_copy(&b->addr, addr);
   b->port = port;
   if (digest)
     memcpy(b->identity, digest, DIGEST_LEN);
@@ -2874,7 +2879,7 @@
 
 /** If <b>digest</b> is one of our known bridges, return it. */
 static bridge_info_t *
-find_bridge_by_digest(char *digest)
+find_bridge_by_digest(const char *digest)
 {
   SMARTLIST_FOREACH(bridge_list, bridge_info_t *, bridge,
     {
@@ -2887,36 +2892,36 @@
 /** We need to ask <b>bridge</b> for its server descriptor. <b>address</b>
  * is a helpful string describing this bridge. */
 static void
-launch_direct_bridge_descriptor_fetch(char *address, bridge_info_t *bridge)
+launch_direct_bridge_descriptor_fetch(bridge_info_t *bridge)
 {
+  char *address;
+
   if (connection_get_by_type_addr_port_purpose(
-      CONN_TYPE_DIR, bridge->addr, bridge->port,
+      CONN_TYPE_DIR, &bridge->addr, bridge->port,
       DIR_PURPOSE_FETCH_SERVERDESC))
     return; /* it's already on the way */
-  directory_initiate_command(address, bridge->addr,
+
+  address = tor_dup_addr(&bridge->addr);
+  directory_initiate_command(address, &bridge->addr,
                              bridge->port, 0,
                              0, /* does not matter */
                              1, bridge->identity,
                              DIR_PURPOSE_FETCH_SERVERDESC,
                              ROUTER_PURPOSE_BRIDGE,
                              0, "authority.z", NULL, 0, 0);
+  tor_free(address);
 }
 
 /** Fetching the bridge descriptor from the bridge authority returned a
  * "not found". Fall back to trying a direct fetch. */
 void
-retry_bridge_descriptor_fetch_directly(char *digest)
+retry_bridge_descriptor_fetch_directly(const char *digest)
 {
   bridge_info_t *bridge = find_bridge_by_digest(digest);
-  char address_buf[INET_NTOA_BUF_LEN+1];
-  struct in_addr in;
-
   if (!bridge)
     return; /* not found? oh well. */
 
-  in.s_addr = htonl(bridge->addr);
-  tor_inet_ntoa(&in, address_buf, sizeof(address_buf));
-  launch_direct_bridge_descriptor_fetch(address_buf, bridge);
+  launch_direct_bridge_descriptor_fetch(bridge);
 }
 
 /** For each bridge in our list for which we don't currently have a
@@ -2925,8 +2930,6 @@
 void
 fetch_bridge_descriptors(time_t now)
 {
-  char address_buf[INET_NTOA_BUF_LEN+1];
-  struct in_addr in;
   or_options_t *options = get_options();
   int num_bridge_auths = get_n_authorities(BRIDGE_AUTHORITY);
   int ask_bridge_directly;
@@ -2935,7 +2938,7 @@
   if (!bridge_list)
     return;
 
-  SMARTLIST_FOREACH(bridge_list, bridge_info_t *, bridge,
+  SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge)
     {
       if (bridge->fetch_status.next_attempt_at > now)
         continue; /* don't bother, no need to retry yet */
@@ -2943,9 +2946,6 @@
       /* schedule another fetch as if this one will fail, in case it does */
       bridge_fetch_status_increment(bridge, now);
 
-      in.s_addr = htonl(bridge->addr);
-      tor_inet_ntoa(&in, address_buf, sizeof(address_buf));
-
       can_use_bridge_authority = !tor_digest_is_zero(bridge->identity) &&
                                  num_bridge_auths;
       ask_bridge_directly = !can_use_bridge_authority ||
@@ -2955,9 +2955,10 @@
                 !options->UpdateBridgesFromAuthority, !num_bridge_auths);
 
       if (ask_bridge_directly &&
-          !fascist_firewall_allows_address_or(bridge->addr, bridge->port)) {
+          !fascist_firewall_allows_address_or(&bridge->addr, bridge->port)) {
         log_notice(LD_DIR, "Bridge at '%s:%d' isn't reachable by our "
-                   "firewall policy. %s.", address_buf, bridge->port,
+                   "firewall policy. %s.", fmt_addr(&bridge->addr),
+                   bridge->port,
                    can_use_bridge_authority ?
                      "Asking bridge authority instead" : "Skipping");
         if (can_use_bridge_authority)
@@ -2968,7 +2969,7 @@
 
       if (ask_bridge_directly) {
         /* we need to ask the bridge itself for its descriptor. */
-        launch_direct_bridge_descriptor_fetch(address_buf, bridge);
+        launch_direct_bridge_descriptor_fetch(bridge);
       } else {
         /* We have a digest and we want to ask an authority. We could
          * combine all the requests into one, but that may give more
@@ -2983,7 +2984,8 @@
         directory_get_from_dirserver(DIR_PURPOSE_FETCH_SERVERDESC,
                 ROUTER_PURPOSE_BRIDGE, resource, 0);
       }
-    });
+    }
+  SMARTLIST_FOREACH_END(bridge);
 }
 
 /** We just learned a descriptor for a bridge. See if that

Modified: tor/trunk/src/or/circuitlist.c
===================================================================
--- tor/trunk/src/or/circuitlist.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/circuitlist.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -231,8 +231,7 @@
   if (!circuits_pending_or_conns)
     return;
 
-  SMARTLIST_FOREACH(circuits_pending_or_conns, circuit_t *, circ,
-  {
+  SMARTLIST_FOREACH_BEGIN(circuits_pending_or_conns, circuit_t *, circ) {
     if (circ->marked_for_close)
       continue;
     if (!circ->n_hop)
@@ -240,7 +239,7 @@
     tor_assert(circ->state == CIRCUIT_STATE_OR_WAIT);
     if (tor_digest_is_zero(circ->n_hop->identity_digest)) {
       /* Look at addr/port. This is an unkeyed connection. */
-      if (circ->n_hop->addr != or_conn->_base.addr ||
+      if (!tor_addr_eq(&circ->n_hop->addr, &or_conn->_base.addr) ||
           circ->n_hop->port != or_conn->_base.port)
         continue;
     } else {
@@ -250,7 +249,7 @@
         continue;
     }
     smartlist_add(out, circ);
-  });
+  } SMARTLIST_FOREACH_END(circ);
 }
 
 /** Return the number of circuits in state OR_WAIT, waiting for the given
@@ -573,7 +572,7 @@
       }
     }
     if (!circ->n_conn && circ->n_hop &&
-        circ->n_hop->addr == conn->addr &&
+        tor_addr_eq(&circ->n_hop->addr, &conn->addr) &&
         circ->n_hop->port == conn->port &&
         conn->type == CONN_TYPE_OR &&
         !memcmp(TO_OR_CONN(conn)->identity_digest,

Modified: tor/trunk/src/or/circuituse.c
===================================================================
--- tor/trunk/src/or/circuituse.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/circuituse.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -102,9 +102,10 @@
           return 0; /* this is a circuit to somewhere else */
         if (tor_digest_is_zero(digest)) {
           /* we don't know the digest; have to compare addr:port */
-          struct in_addr in;
-          if (!tor_inet_aton(conn->socks_request->address, &in) ||
-              build_state->chosen_exit->addr != ntohl(in.s_addr) ||
+          tor_addr_t addr;
+          int r = tor_addr_from_str(&addr, conn->socks_request->address);
+          if (r < 0 ||
+              !tor_addr_eq(&build_state->chosen_exit->addr, &addr) ||
               build_state->chosen_exit->port != conn->socks_request->port)
             return 0;
         }
@@ -1082,18 +1083,19 @@
              * we don't have a routerinfo about. Make up an extend_info. */
             char digest[DIGEST_LEN];
             char *hexdigest = conn->chosen_exit_name+1;
-            struct in_addr in;
+            tor_addr_t addr;
             if (strlen(hexdigest) < HEX_DIGEST_LEN ||
                 base16_decode(digest,DIGEST_LEN,hexdigest,HEX_DIGEST_LEN)<0) {
               log_info(LD_DIR, "Broken exit digest on tunnel conn. Closing.");
               return -1;
             }
-            if (!tor_inet_aton(conn->socks_request->address, &in)) {
-              log_info(LD_DIR, "Broken address on tunnel conn. Closing.");
+            if (tor_addr_from_str(&addr, conn->socks_request->address) < 0) {
+              log_info(LD_DIR, "Broken address %s on tunnel conn. Closing.",
+                       escaped_safe_str(conn->socks_request->address));
               return -1;
             }
             extend_info = extend_info_alloc(conn->chosen_exit_name+1,
-                                            digest, NULL, ntohl(in.s_addr),
+                                            digest, NULL, &addr,
                                             conn->socks_request->port);
           } else {
             /* We will need an onion key for the router, and we
@@ -1306,8 +1308,8 @@
   conn_age = (int)(time(NULL) - conn->_base.timestamp_created);
 
   if (conn_age >= get_options()->SocksTimeout) {
-    int severity = (!conn->_base.addr && !conn->_base.port) ?
-                     LOG_INFO : LOG_NOTICE;
+    int severity = (tor_addr_is_null(&conn->_base.addr) && !conn->_base.port) ?
+      LOG_INFO : LOG_NOTICE;
     log_fn(severity, LD_APP,
            "Tried for %d seconds to get a connection to %s:%d. Giving up.",
            conn_age, safe_str(conn->socks_request->address),

Modified: tor/trunk/src/or/command.c
===================================================================
--- tor/trunk/src/or/command.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/command.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -576,22 +576,19 @@
   while (n_other_addrs && cp < end-2) {
     /* Consider all the other addresses; if any matches, this connection is
      * "canonical." */
-    uint8_t other_addr_type = (uint8_t) *cp++;
-    uint8_t other_addr_len = (uint8_t) *cp++;
-    if (cp + other_addr_len >= end) {
-      log_fn(LOG_PROTOCOL_WARN, LD_OR,
-             "Address too long in netinfo cell; closing connection.");
+    tor_addr_t addr;
+    const char *next = decode_address_from_payload(&addr, cp, end-cp);
+    if (next == NULL) {
+      log_fn(LOG_PROTOCOL_WARN,  LD_OR,
+             "Bad ddress in netinfo cell; closing connection.");
       connection_mark_for_close(TO_CONN(conn));
       return;
     }
-    if (other_addr_type == RESOLVED_TYPE_IPV4 && other_addr_len == 4) {
-      uint32_t addr = ntohl(get_uint32(cp));
-      if (addr == conn->real_addr) {
-        conn->is_canonical = 1;
-        break;
-      }
+    if (tor_addr_eq(&addr, &conn->real_addr)) {
+      conn->is_canonical = 1;
+      break;
     }
-    cp += other_addr_len;
+    cp = next;
     --n_other_addrs;
   }
 

Modified: tor/trunk/src/or/config.c
===================================================================
--- tor/trunk/src/or/config.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/config.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -2365,26 +2365,31 @@
   return 0;
 }
 
-/** Return true iff <b>ip</b> (in host order) is judged to be on the
- * same network as us, or on a private network.
+/** Return true iff <b>addr</b> is judged to be on the same network as us, or
+ * on a private network.
  */
 int
-is_local_IP(uint32_t ip)
+is_local_addr(const tor_addr_t *addr)
 {
-  if (is_internal_IP(ip, 0))
+  if (tor_addr_is_internal(addr, 0))
     return 1;
   /* Check whether ip is on the same /24 as we are. */
   if (get_options()->EnforceDistinctSubnets == 0)
     return 0;
-  /* It's possible that this next check will hit before the first time
-   * resolve_my_address actually succeeds.  (For clients, it is likely that
-   * resolve_my_address will never be called at all).  In those cases,
-   * last_resolved_addr will be 0, and so checking to see whether ip is on the
-   * same /24 as last_resolved_addr will be the same as checking whether it
-   * was on net 0, which is already done by is_internal_IP.
-   */
-  if ((last_resolved_addr & 0xffffff00ul) == (ip & 0xffffff00ul))
-    return 1;
+  if (tor_addr_family(addr) == AF_INET) {
+    /*XXXX021 IP6 what corresponds to an /24? */
+    uint32_t ip = tor_addr_to_ipv4h(addr);
+
+    /* It's possible that this next check will hit before the first time
+     * resolve_my_address actually succeeds.  (For clients, it is likely that
+     * resolve_my_address will never be called at all).  In those cases,
+     * last_resolved_addr will be 0, and so checking to see whether ip is on
+     * the same /24 as last_resolved_addr will be the same as checking whether
+     * it was on net 0, which is already done by is_internal_IP.
+     */
+    if ((last_resolved_addr & 0xffffff00ul) == (ip & 0xffffff00ul))
+      return 1;
+  }
   return 0;
 }
 
@@ -4153,7 +4158,7 @@
     *msg = tor_strdup("Wrong number of elements in RedirectExit line");
     goto err;
   }
-  if (parse_addr_and_port_range(smartlist_get(elements,0),&r->addr,
+  if (tor_addr_parse_mask_ports(smartlist_get(elements,0),&r->addr,
                                 &r->maskbits,&r->port_min,&r->port_max)) {
     *msg = tor_strdup("Error parsing source address in RedirectExit line");
     goto err;
@@ -4161,8 +4166,8 @@
   if (0==strcasecmp(smartlist_get(elements,1), "pass")) {
     r->is_redirect = 0;
   } else {
-    if (parse_addr_port(LOG_WARN, smartlist_get(elements,1),NULL,
-                        &r->addr_dest, &r->port_dest)) {
+    if (tor_addr_port_parse(smartlist_get(elements,1),
+                            &r->addr_dest, &r->port_dest)) {
       *msg = tor_strdup("Error parsing dest address in RedirectExit line");
       goto err;
     }
@@ -4196,8 +4201,8 @@
 {
   smartlist_t *items = NULL;
   int r;
-  char *addrport=NULL, *address=NULL, *fingerprint=NULL;
-  uint32_t addr = 0;
+  char *addrport=NULL, *fingerprint=NULL;
+  tor_addr_t addr;
   uint16_t port = 0;
   char digest[DIGEST_LEN];
 
@@ -4210,7 +4215,7 @@
   }
   addrport = smartlist_get(items, 0);
   smartlist_del_keeporder(items, 0);
-  if (parse_addr_port(LOG_WARN, addrport, &address, &addr, &port)<0) {
+  if (tor_addr_port_parse(addrport, &addr, &port)<0) {
     log_warn(LD_CONFIG, "Error parsing Bridge address '%s'", addrport);
     goto err;
   }
@@ -4232,10 +4237,10 @@
   }
 
   if (!validate_only) {
-    log_debug(LD_DIR, "Bridge at %s:%d (%s)", address,
+    log_debug(LD_DIR, "Bridge at %s:%d (%s)", fmt_addr(&addr),
               (int)port,
               fingerprint ? fingerprint : "no key listed");
-    bridge_add_from_config(addr, port, fingerprint ? digest : NULL);
+    bridge_add_from_config(&addr, port, fingerprint ? digest : NULL);
   }
 
   r = 0;
@@ -4248,7 +4253,6 @@
   SMARTLIST_FOREACH(items, char*, s, tor_free(s));
   smartlist_free(items);
   tor_free(addrport);
-  tor_free(address);
   tor_free(fingerprint);
   return r;
 }

Modified: tor/trunk/src/or/connection.c
===================================================================
--- tor/trunk/src/or/connection.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/connection.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -907,26 +907,38 @@
 /** Do basic sanity checking on a newly received socket. Return 0
  * if it looks ok, else return -1. */
 static int
-check_sockaddr_in(struct sockaddr *sa, int len, int level)
+check_sockaddr(struct sockaddr *sa, int len, int level)
 {
   int ok = 1;
-  struct sockaddr_in *sin=(struct sockaddr_in*)sa;
 
-  if (len != sizeof(struct sockaddr_in)) {
-    log_fn(level, LD_NET, "Length of address not as expected: %d vs %d",
-           len,(int)sizeof(struct sockaddr_in));
+  if (sa->sa_family == AF_INET) {
+    struct sockaddr_in *sin=(struct sockaddr_in*)sa;
+    if (len != sizeof(struct sockaddr_in)) {
+      log_fn(level, LD_NET, "Length of address not as expected: %d vs %d",
+             len,(int)sizeof(struct sockaddr_in));
+      ok = 0;
+    }
+    if (sin->sin_addr.s_addr == 0 || sin->sin_port == 0) {
+      log_fn(level, LD_NET,
+             "Address for new connection has address/port equal to zero.");
+      ok = 0;
+    }
+  } else if (sa->sa_family == AF_INET6) {
+    struct sockaddr_in6 *sin6=(struct sockaddr_in6*)sa;
+    if (len != sizeof(struct sockaddr_in6)) {
+      log_fn(level, LD_NET, "Length of address not as expected: %d vs %d",
+             len,(int)sizeof(struct sockaddr_in6));
+      ok = 0;
+    }
+    if (tor_mem_is_zero((void*)sin6->sin6_addr.s6_addr, 16) ||
+        sin6->sin6_port == 0) {
+      log_fn(level, LD_NET,
+             "Address for new connection has address/port equal to zero.");
+      ok = 0;
+    }
+  } else {
     ok = 0;
   }
-  if (sa->sa_family != AF_INET) {
-    log_fn(level, LD_NET, "Family of address not as expected: %d vs %d",
-           sa->sa_family, AF_INET);
-    ok = 0;
-  }
-  if (sin->sin_addr.s_addr == 0 || sin->sin_port == 0) {
-    log_fn(level, LD_NET,
-           "Address for new connection has address/port equal to zero.");
-    ok = 0;
-  }
   return ok ? 0 : -1;
 }
 
@@ -939,17 +951,16 @@
   int news; /* the new socket */
   connection_t *newconn;
   /* information about the remote peer when connecting to other routers */
-  struct sockaddr_in remote;
   char addrbuf[256];
+  struct sockaddr *remote = (struct sockaddr*)addrbuf;
   /* length of the remote address. Must be whatever accept() needs. */
   socklen_t remotelen = (socklen_t)sizeof(addrbuf);
-  char tmpbuf[INET_NTOA_BUF_LEN];
   or_options_t *options = get_options();
 
   tor_assert((size_t)remotelen >= sizeof(struct sockaddr_in));
   memset(addrbuf, 0, sizeof(addrbuf));
 
-  news = tor_accept_socket(conn->s,(struct sockaddr *)&addrbuf,&remotelen);
+  news = tor_accept_socket(conn->s,remote,&remotelen);
   if (news < 0) { /* accept() error */
     int e = tor_socket_errno(conn->s);
     if (ERRNO_IS_ACCEPT_EAGAIN(e)) {
@@ -974,30 +985,32 @@
   if (options->ConstrainedSockets)
     set_constrained_socket_buffers(news, (int)options->ConstrainedSockSize);
 
-  if (((struct sockaddr*)addrbuf)->sa_family != conn->socket_family) {
+  if (remote->sa_family != conn->socket_family) {
     /* This is annoying, but can apparently happen on some Darwins. */
     log_info(LD_BUG, "A listener connection returned a socket with a "
              "mismatched family. %s for addr_family %d gave us a socket "
              "with address family %d.  Dropping.",
              conn_type_to_string(conn->type),
              (int)conn->socket_family,
-             (int)((struct sockaddr*)addrbuf)->sa_family);
+             (int)remote->sa_family);
     tor_close_socket(news);
     return 0;
   }
 
-  if (conn->socket_family == AF_INET) {
-    if (check_sockaddr_in((struct sockaddr*)addrbuf, remotelen, LOG_INFO)<0) {
+  if (conn->socket_family == AF_INET || conn->socket_family == AF_INET6) {
+    tor_addr_t addr;
+    uint16_t port;
+    if (check_sockaddr(remote, remotelen, LOG_INFO)<0) {
       log_info(LD_NET,
                "accept() returned a strange address; trying getsockname().");
-      remotelen=256;
+      remotelen=sizeof(addrbuf);
       memset(addrbuf, 0, sizeof(addrbuf));
-      if (getsockname(news, (struct sockaddr*)addrbuf, &remotelen)<0) {
+      if (getsockname(news, remote, &remotelen)<0) {
         int e = tor_socket_errno(news);
         log_warn(LD_NET, "getsockname() for new connection failed: %s",
                  tor_socket_strerror(e));
       } else {
-        if (check_sockaddr_in((struct sockaddr*)addrbuf, remotelen,
+        if (check_sockaddr((struct sockaddr*)addrbuf, remotelen,
                               LOG_WARN) < 0) {
           log_warn(LD_NET,"Something's wrong with this conn. Closing it.");
           tor_close_socket(news);
@@ -1005,26 +1018,43 @@
         }
       }
     }
-    memcpy(&remote, addrbuf, sizeof(struct sockaddr_in));
 
+    /* Duplicate code. XXXX021 */
+    if (remote->sa_family != conn->socket_family) {
+      /* This is annoying, but can apparently happen on some Darwins. */
+      log_info(LD_BUG, "A listener connection returned a socket with a "
+               "mismatched family. %s for addr_family %d gave us a socket "
+               "with address family %d.  Dropping.",
+               conn_type_to_string(conn->type),
+               (int)conn->socket_family,
+               (int)remote->sa_family);
+      tor_close_socket(news);
+      return 0;
+    }
+
+    tor_addr_from_sockaddr(&addr, remote);
+    if (remote->sa_family == AF_INET)
+      port = ((struct sockaddr_in *)remote)->sin_port;
+    else
+      port = ((struct sockaddr_in6 *)remote)->sin6_port;
+    port = ntohs(port);
+
     /* process entrance policies here, before we even create the connection */
     if (new_type == CONN_TYPE_AP) {
       /* check sockspolicy to see if we should accept it */
-      if (socks_policy_permits_address(ntohl(remote.sin_addr.s_addr)) == 0) {
-        tor_inet_ntoa(&remote.sin_addr, tmpbuf, sizeof(tmpbuf));
+      if (socks_policy_permits_address(&addr) == 0) {
         log_notice(LD_APP,
                    "Denying socks connection from untrusted address %s.",
-                   tmpbuf);
+                   fmt_addr(&addr));
         tor_close_socket(news);
         return 0;
       }
     }
     if (new_type == CONN_TYPE_DIR) {
       /* check dirpolicy to see if we should accept it */
-      if (dir_policy_permits_address(ntohl(remote.sin_addr.s_addr)) == 0) {
-        tor_inet_ntoa(&remote.sin_addr, tmpbuf, sizeof(tmpbuf));
+      if (dir_policy_permits_address(&addr) == 0) {
         log_notice(LD_DIRSERV,"Denying dir connection from address %s.",
-                   tmpbuf);
+                   fmt_addr(&addr));
         tor_close_socket(news);
         return 0;
       }
@@ -1034,9 +1064,9 @@
     newconn->s = news;
 
     /* remember the remote address */
-    newconn->addr = ntohl(remote.sin_addr.s_addr);
-    newconn->port = ntohs(remote.sin_port);
-    newconn->address = tor_dup_ip(newconn->addr);
+    tor_addr_copy(&newconn->addr, &addr);
+    newconn->port = port;
+    newconn->address = tor_dup_addr(&addr);
 
   } else if (conn->socket_family == AF_UNIX) {
     /* For now only control ports can be unix domain sockets
@@ -1047,7 +1077,7 @@
     newconn->s = news;
 
     /* remember the remote address -- do we have anything sane to put here? */
-    newconn->addr = 0;
+    tor_addr_make_unspec(&newconn->addr);
     newconn->port = 1;
     newconn->address = tor_strdup(conn->address);
   } else {
@@ -1115,11 +1145,14 @@
  */
 int
 connection_connect(connection_t *conn, const char *address,
-                   uint32_t addr, uint16_t port, int *socket_error)
+                   const tor_addr_t *addr, uint16_t port, int *socket_error)
 {
   int s, inprogress = 0;
-  struct sockaddr_in dest_addr;
+  char addrbuf[256];
+  struct sockaddr *dest_addr = (struct sockaddr*) addrbuf;
+  socklen_t dest_addr_len;
   or_options_t *options = get_options();
+  int protocol_family;
 
   if (get_n_open_sockets() >= get_options()->_ConnLimit-1) {
     int n_conns = get_n_open_sockets();
@@ -1130,7 +1163,12 @@
     return -1;
   }
 
-  s = tor_open_socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
+  if (tor_addr_family(addr) == AF_INET6)
+    protocol_family = PF_INET6;
+  else
+    protocol_family = PF_INET;
+
+  s = tor_open_socket(protocol_family,SOCK_STREAM,IPPROTO_TCP);
   if (s < 0) {
     *socket_error = tor_socket_errno(-1);
     log_warn(LD_NET,"Error creating network socket: %s",
@@ -1164,15 +1202,14 @@
   if (options->ConstrainedSockets)
     set_constrained_socket_buffers(s, (int)options->ConstrainedSockSize);
 
-  memset(&dest_addr,0,sizeof(dest_addr));
-  dest_addr.sin_family = AF_INET;
-  dest_addr.sin_port = htons(port);
-  dest_addr.sin_addr.s_addr = htonl(addr);
+  memset(addrbuf,0,sizeof(addrbuf));
+  dest_addr = (struct sockaddr*) addrbuf;
+  dest_addr_len = tor_addr_to_sockaddr(addr, port, dest_addr, sizeof(addrbuf));
+  tor_assert(dest_addr_len > 0);
 
   log_debug(LD_NET,"Connecting to %s:%u.",escaped_safe_str(address),port);
 
-  if (connect(s,(struct sockaddr *)&dest_addr,
-              (socklen_t)sizeof(dest_addr)) < 0) {
+  if (connect(s, dest_addr, dest_addr_len) < 0) {
     int e = tor_socket_errno(s);
     if (!ERRNO_IS_CONN_EINPROGRESS(e)) {
       /* yuck. kill it. */
@@ -1422,7 +1459,7 @@
 static int
 connection_is_rate_limited(connection_t *conn)
 {
-  if (conn->linked || is_internal_IP(conn->addr, 0))
+  if (conn->linked || tor_addr_is_internal(&conn->addr, 0))
     return 0;
   else
     return 1;
@@ -2165,7 +2202,8 @@
     if (e) {
       /* some sort of error, but maybe just inprogress still */
       if (!ERRNO_IS_CONN_EINPROGRESS(e)) {
-        log_info(LD_NET,"in-progress connect failed. Removing.");
+        log_info(LD_NET,"in-progress connect failed. Removing. (%s)",
+                 tor_socket_strerror(e));
         if (CONN_IS_EDGE(conn))
           connection_edge_end_errno(TO_EDGE_CONN(conn));
         if (conn->type == CONN_TYPE_OR)
@@ -2400,13 +2438,15 @@
 or_connection_t *
 connection_or_exact_get_by_addr_port(uint32_t addr, uint16_t port)
 {
+  /* XXXX021 IP6 make this take a tor_addr_t, or deprecate it. */
+
   or_connection_t *best=NULL;
   smartlist_t *conns = get_connection_array();
 
   SMARTLIST_FOREACH(conns, connection_t *, conn,
   {
     if (conn->type == CONN_TYPE_OR &&
-        conn->addr == addr &&
+        tor_addr_eq_ipv4h(&conn->addr, addr) &&
         conn->port == port &&
         !conn->marked_for_close &&
         (!best || best->_base.timestamp_created < conn->timestamp_created))
@@ -2419,14 +2459,14 @@
  * or NULL if no such connection exists. */
 connection_t *
 connection_get_by_type_addr_port_purpose(int type,
-                                         uint32_t addr, uint16_t port,
+                                         const tor_addr_t *addr, uint16_t port,
                                          int purpose)
 {
   smartlist_t *conns = get_connection_array();
   SMARTLIST_FOREACH(conns, connection_t *, conn,
   {
     if (conn->type == type &&
-        conn->addr == addr &&
+        tor_addr_eq(&conn->addr, addr) &&
         conn->port == port &&
         conn->purpose == purpose &&
         !conn->marked_for_close)

Modified: tor/trunk/src/or/connection_edge.c
===================================================================
--- tor/trunk/src/or/connection_edge.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/connection_edge.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -207,9 +207,16 @@
   payload[0] = reason;
   if (reason == END_STREAM_REASON_EXITPOLICY &&
       !connection_edge_is_rendezvous_stream(conn)) {
-    set_uint32(payload+1, htonl(conn->_base.addr));
-    set_uint32(payload+5, htonl(dns_clip_ttl(conn->address_ttl)));
-    payload_len += 8;
+    int addrlen;
+    if (tor_addr_family(&conn->_base.addr) == AF_INET) {
+      set_uint32(payload+1, tor_addr_to_ipv4n(&conn->_base.addr));
+      addrlen = 4;
+    } else {
+      memcpy(payload+1, tor_addr_to_in6_addr8(&conn->_base.addr), 16);
+      addrlen = 16;
+    }
+    set_uint32(payload+1+addrlen, htonl(dns_clip_ttl(conn->address_ttl)));
+    payload_len += 4+addrlen;
   }
 
   circ = circuit_get_by_edge_conn(conn);
@@ -285,15 +292,12 @@
 {
   char valbuf[INET_NTOA_BUF_LEN];
   connection_t *conn;
-  struct in_addr in;
 
   tor_assert(edge_conn);
   tor_assert(edge_conn->_base.type == CONN_TYPE_EXIT);
   conn = TO_CONN(edge_conn);
   tor_assert(conn->state == EXIT_CONN_STATE_CONNECTING);
 
-  in.s_addr = htonl(conn->addr);
-  tor_inet_ntoa(&in,valbuf,sizeof(valbuf));
   log_info(LD_EXIT,"Exit connection to %s:%u (%s) established.",
            escaped_safe_str(conn->address),conn->port,safe_str(valbuf));
 
@@ -308,13 +312,22 @@
                                      RELAY_COMMAND_CONNECTED, NULL, 0) < 0)
       return 0; /* circuit is closed, don't continue */
   } else {
-    char connected_payload[8];
-    set_uint32(connected_payload, htonl(conn->addr));
-    set_uint32(connected_payload+4,
-               htonl(dns_clip_ttl(edge_conn->address_ttl)));
+    char connected_payload[20];
+    int connected_payload_len;
+    if (tor_addr_family(&conn->addr) == AF_INET) {
+      set_uint32(connected_payload, tor_addr_to_ipv4n(&conn->addr));
+      set_uint32(connected_payload+4,
+                 htonl(dns_clip_ttl(edge_conn->address_ttl)));
+      connected_payload_len = 8;
+    } else {
+      memcpy(connected_payload, tor_addr_to_in6_addr8(&conn->addr), 16);
+      set_uint32(connected_payload+16,
+                 htonl(dns_clip_ttl(edge_conn->address_ttl)));
+      connected_payload_len = 20;
+    }
     if (connection_edge_send_command(edge_conn,
-                                     RELAY_COMMAND_CONNECTED,
-                                     connected_payload, 8) < 0)
+                                 RELAY_COMMAND_CONNECTED,
+                                 connected_payload, connected_payload_len) < 0)
       return 0; /* circuit is closed, don't continue */
   }
   tor_assert(edge_conn->package_window > 0);
@@ -356,13 +369,12 @@
   int seconds_idle;
   smartlist_t *conns = get_connection_array();
 
-  SMARTLIST_FOREACH(conns, connection_t *, c,
-  {
+  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, c) {
     if (c->type != CONN_TYPE_AP)
       continue;
     conn = TO_EDGE_CONN(c);
     /* if it's an internal linked connection, don't yell its status. */
-    severity = (!conn->_base.addr && !conn->_base.port)
+    severity = (tor_addr_is_null(&conn->_base.addr) && !conn->_base.port)
       ? LOG_INFO : LOG_NOTICE;
     seconds_idle = (int)( now - conn->_base.timestamp_lastread );
 
@@ -434,7 +446,7 @@
       if (!conn->_base.marked_for_close)
         connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
     }
-  }); /* end foreach */
+  } SMARTLIST_FOREACH_END(conn);
 }
 
 /** Tell any AP streams that are waiting for a new circuit to try again,
@@ -472,8 +484,7 @@
   edge_connection_t *edge_conn;
   char digest[DIGEST_LEN];
   smartlist_t *conns = get_connection_array();
-  SMARTLIST_FOREACH(conns, connection_t *, conn,
-  {
+  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
     if (conn->marked_for_close ||
         conn->type != CONN_TYPE_AP ||
         conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
@@ -486,11 +497,12 @@
       continue;
     if (tor_digest_is_zero(digest)) {
       /* we don't know the digest; have to compare addr:port */
-      struct in_addr in;
+      tor_addr_t addr;
       if (!build_state || !build_state->chosen_exit ||
-          !edge_conn->socks_request || !edge_conn->socks_request->address ||
-          !tor_inet_aton(edge_conn->socks_request->address, &in) ||
-          build_state->chosen_exit->addr != ntohl(in.s_addr) ||
+          !edge_conn->socks_request || !edge_conn->socks_request->address)
+        continue;
+      if (tor_addr_from_str(&addr, edge_conn->socks_request->address)<0 ||
+          !tor_addr_eq(&build_state->chosen_exit->addr, &addr) ||
           build_state->chosen_exit->port != edge_conn->socks_request->port)
         continue;
     }
@@ -498,7 +510,7 @@
                      "just failed.", edge_conn->chosen_exit_name,
                      edge_conn->socks_request->address);
     connection_mark_unattached_ap(edge_conn, END_STREAM_REASON_TIMEOUT);
-  });
+  } SMARTLIST_FOREACH_END(conn);
 }
 
 /** A circuit failed to finish on its last hop <b>info</b>. If there
@@ -2147,7 +2159,7 @@
   }
 
   conn->_base.address = tor_strdup("(Tor_internal)");
-  conn->_base.addr = 0;
+  tor_addr_make_unspec(&conn->_base.addr);
   conn->_base.port = 0;
 
   if (connection_add(TO_CONN(conn)) < 0) { /* no space, forget it */
@@ -2535,7 +2547,7 @@
 
   if (rh.command == RELAY_COMMAND_BEGIN_DIR) {
     tor_assert(or_circ);
-    if (or_circ->p_conn && or_circ->p_conn->_base.addr)
+    if (or_circ->p_conn && !tor_addr_is_null(&or_circ->p_conn->_base.addr))
       n_stream->_base.addr = or_circ->p_conn->_base.addr;
     return connection_exit_connect_dir(n_stream);
   }
@@ -2618,7 +2630,7 @@
 void
 connection_exit_connect(edge_connection_t *edge_conn)
 {
-  uint32_t addr;
+  const tor_addr_t *addr;
   uint16_t port;
   connection_t *conn = TO_CONN(edge_conn);
   int socket_error = 0;
@@ -2633,23 +2645,20 @@
     return;
   }
 
-  addr = conn->addr;
+  addr = &conn->addr;
   port = conn->port;
   if (redirect_exit_list) {
     SMARTLIST_FOREACH(redirect_exit_list, exit_redirect_t *, r,
     {
-      if (!addr_mask_cmp_bits(addr, r->addr, r->maskbits) &&
+      if (tor_addr_compare_masked(addr, &r->addr, r->maskbits, CMP_SEMANTIC) &&
           (r->port_min <= port) && (port <= r->port_max)) {
-        struct in_addr in;
         if (r->is_redirect) {
-          char tmpbuf[INET_NTOA_BUF_LEN];
-          addr = r->addr_dest;
-          port = r->port_dest;
-          in.s_addr = htonl(addr);
-          tor_inet_ntoa(&in, tmpbuf, sizeof(tmpbuf));
+          addr = &r->addr_dest;
+          if (r->port_dest)
+            port = r->port_dest;
           log_debug(LD_EXIT, "Redirecting connection from %s:%d to %s:%d",
                     escaped_safe_str(conn->address), conn->port,
-                    safe_str(tmpbuf), port);
+                    fmt_addr(addr), port);
         }
         break;
       }
@@ -2692,13 +2701,21 @@
                                  NULL, 0);
   } else { /* normal stream */
     /* This must be the original address, not the redirected address. */
-    char connected_payload[8];
-    set_uint32(connected_payload, htonl(conn->addr));
-    set_uint32(connected_payload+4,
+    char connected_payload[20];
+    int connected_payload_len;
+    if (tor_addr_family(&conn->addr) == AF_INET) {
+      set_uint32(connected_payload, tor_addr_to_ipv4n(&conn->addr));
+      connected_payload_len = 4;
+    } else {
+      memcpy(connected_payload, tor_addr_to_in6_addr8(&conn->addr), 16);
+      connected_payload_len = 16;
+    }
+    set_uint32(connected_payload+connected_payload_len,
                htonl(dns_clip_ttl(edge_conn->address_ttl)));
+    connected_payload_len += 4;
     connection_edge_send_command(edge_conn,
                                  RELAY_COMMAND_CONNECTED,
-                                 connected_payload, 8);
+                                 connected_payload, connected_payload_len);
   }
 }
 

Modified: tor/trunk/src/or/connection_or.c
===================================================================
--- tor/trunk/src/or/connection_or.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/connection_or.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -348,14 +348,9 @@
 
   if (get_options()->HttpsProxy) {
     char buf[1024];
-    char addrbuf[INET_NTOA_BUF_LEN];
-    struct in_addr in;
     char *base64_authenticator=NULL;
     const char *authenticator = get_options()->HttpsProxyAuthenticator;
 
-    in.s_addr = htonl(conn->addr);
-    tor_inet_ntoa(&in, addrbuf, sizeof(addrbuf));
-
     if (authenticator) {
       base64_authenticator = alloc_http_authenticator(authenticator);
       if (!base64_authenticator)
@@ -363,12 +358,13 @@
     }
     if (base64_authenticator) {
       tor_snprintf(buf, sizeof(buf), "CONNECT %s:%d HTTP/1.1\r\n"
-                   "Proxy-Authorization: Basic %s\r\n\r\n", addrbuf,
+                   "Proxy-Authorization: Basic %s\r\n\r\n",
+                   fmt_addr(&conn->addr),
                    conn->port, base64_authenticator);
       tor_free(base64_authenticator);
     } else {
       tor_snprintf(buf, sizeof(buf), "CONNECT %s:%d HTTP/1.0\r\n\r\n",
-                   addrbuf, conn->port);
+                   fmt_addr(&conn->addr), conn->port);
     }
     connection_write_to_buf(buf, strlen(buf), conn);
     conn->state = OR_CONN_STATE_PROXY_FLUSHING;
@@ -388,7 +384,7 @@
  * by checking to see if this describes a router we know. */
 static void
 connection_or_init_conn_from_address(or_connection_t *conn,
-                                     uint32_t addr, uint16_t port,
+                                     const tor_addr_t *addr, uint16_t port,
                                      const char *id_digest,
                                      int started_here)
 {
@@ -397,11 +393,13 @@
   conn->bandwidthrate = (int)options->BandwidthRate;
   conn->read_bucket = conn->bandwidthburst = (int)options->BandwidthBurst;
   connection_or_set_identity_digest(conn, id_digest);
-  conn->_base.addr = addr;
+
   conn->_base.port = port;
-  conn->real_addr = addr;
+  tor_addr_copy(&conn->_base.addr, addr);
+  tor_addr_copy(&conn->real_addr, addr);
   if (r) {
-    if (conn->_base.addr == r->addr)
+    /* XXXX021 proposal 118 will make this more complex. */
+    if (tor_addr_eq_ipv4h(&conn->_base.addr, r->addr))
       conn->is_canonical = 1;
     if (!started_here) {
       /* Override the addr/port, so our log messages will make sense.
@@ -413,8 +411,8 @@
        * we wanted to log what OR a connection was to, and if we logged the
        * right IP address and port 56244, that wouldn't be as helpful. now we
        * log the "right" port too, so we know if it's moria1 or moria2.
-      */
-      conn->_base.addr = r->addr;
+       */
+      tor_addr_from_ipv4h(&conn->_base.addr, r->addr);
       conn->_base.port = r->or_port;
     }
     conn->nickname = tor_strdup(r->nickname);
@@ -434,7 +432,7 @@
                     conn->identity_digest, DIGEST_LEN);
     }
     tor_free(conn->_base.address);
-    conn->_base.address = tor_dup_ip(addr);
+    conn->_base.address = tor_dup_addr(addr);
   }
 }
 
@@ -509,13 +507,17 @@
  * Return the launched conn, or NULL if it failed.
  */
 or_connection_t *
-connection_or_connect(uint32_t addr, uint16_t port, const char *id_digest)
+connection_or_connect(const tor_addr_t *_addr, uint16_t port,
+                      const char *id_digest)
 {
   or_connection_t *conn;
   or_options_t *options = get_options();
   int socket_error = 0;
+  tor_addr_t addr;
 
+  tor_assert(_addr);
   tor_assert(id_digest);
+  tor_addr_copy(&addr, _addr);
 
   if (server_mode(options) && router_digest_is_me(id_digest)) {
     log_info(LD_PROTOCOL,"Client asked me to connect to myself. Refusing.");
@@ -525,18 +527,18 @@
   conn = TO_OR_CONN(connection_new(CONN_TYPE_OR, AF_INET));
 
   /* set up conn so it's got all the data we need to remember */
-  connection_or_init_conn_from_address(conn, addr, port, id_digest, 1);
+  connection_or_init_conn_from_address(conn, &addr, port, id_digest, 1);
   conn->_base.state = OR_CONN_STATE_CONNECTING;
   control_event_or_conn_status(conn, OR_CONN_EVENT_LAUNCHED, 0);
 
   if (options->HttpsProxy) {
     /* we shouldn't connect directly. use the https proxy instead. */
-    addr = options->HttpsProxyAddr;
+    tor_addr_from_ipv4h(&addr, options->HttpsProxyAddr);
     port = options->HttpsProxyPort;
   }
 
   switch (connection_connect(TO_CONN(conn), conn->_base.address,
-                             addr, port, &socket_error)) {
+                             &addr, port, &socket_error)) {
     case -1:
       /* If the connection failed immediately, and we're using
        * an https proxy, our https proxy is down. Don't blame the
@@ -846,7 +848,7 @@
   if (tor_tls_used_v1_handshake(conn->tls)) {
     conn->link_proto = 1;
     if (!started_here) {
-      connection_or_init_conn_from_address(conn,conn->_base.addr,
+      connection_or_init_conn_from_address(conn, &conn->_base.addr,
                                            conn->_base.port, digest_rcvd, 0);
     }
     return connection_or_set_state_open(conn);
@@ -855,7 +857,7 @@
     if (connection_init_or_handshake_state(conn, started_here) < 0)
       return -1;
     if (!started_here) {
-      connection_or_init_conn_from_address(conn,conn->_base.addr,
+      connection_or_init_conn_from_address(conn, &conn->_base.addr,
                                            conn->_base.port, digest_rcvd, 0);
     }
     return connection_or_send_versions(conn);
@@ -910,8 +912,13 @@
     router_set_status(conn->identity_digest, 1);
   } else {
     /* only report it to the geoip module if it's not a known router */
-    if (!router_get_by_digest(conn->identity_digest))
-      geoip_note_client_seen(GEOIP_CLIENT_CONNECT, TO_CONN(conn)->addr, now);
+    if (!router_get_by_digest(conn->identity_digest)) {
+      if (tor_addr_family(&TO_CONN(conn)->addr) == AF_INET) {
+        /*XXXX021 IP6 support ipv6 geoip.*/
+        uint32_t a = tor_addr_to_ipv4h(&TO_CONN(conn)->addr);
+        geoip_note_client_seen(GEOIP_CLIENT_CONNECT, a, now);
+      }
+    }
   }
   if (conn->handshake_state) {
     or_handshake_state_free(conn->handshake_state);
@@ -1086,24 +1093,34 @@
   cell_t cell;
   time_t now = time(NULL);
   routerinfo_t *me;
+  int len;
+  char *out;
 
   memset(&cell, 0, sizeof(cell_t));
   cell.command = CELL_NETINFO;
 
-  /* Their address. */
+  /* Timestamp. */
   set_uint32(cell.payload, htonl((uint32_t)now));
-  cell.payload[4] = RESOLVED_TYPE_IPV4;
-  cell.payload[5] = 4;
-  set_uint32(cell.payload+6, htonl(conn->_base.addr));
 
+  /* Their address. */
+  out = cell.payload + 4;
+  len = append_address_to_payload(out, &conn->_base.addr);
+  if (len<0)
+    return -1;
+  out += len;
+
   /* My address. */
   if ((me = router_get_my_routerinfo())) {
-    cell.payload[10] = 1; /* only one address is supported. */
-    cell.payload[11] = RESOLVED_TYPE_IPV4;
-    cell.payload[12] = 4;
-    set_uint32(cell.payload+13, htonl(me->addr));
+    tor_addr_t my_addr;
+    *out++ = 1; /* only one address is supported. */
+
+    tor_addr_from_ipv4h(&my_addr, me->addr);
+    len = append_address_to_payload(out, &my_addr);
+    if (len < 0)
+      return -1;
+    out += len;
   } else {
-    cell.payload[10] = 0;
+    *out++ = 0;
   }
 
   connection_or_write_cell_to_buf(&cell, conn);

Modified: tor/trunk/src/or/cpuworker.c
===================================================================
--- tor/trunk/src/or/cpuworker.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/cpuworker.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -63,9 +63,10 @@
 /** Pack addr,port,and circ_id; set *tag to the result. (See note on
  * cpuworker_main for wire format.) */
 static void
-tag_pack(char *tag, uint32_t addr, uint16_t port, circid_t circ_id)
+tag_pack(char *tag, const tor_addr_t *addr, uint16_t port, circid_t circ_id)
 {
-  *(uint32_t *)tag     = addr;
+  /*XXXX RETHINK THIS WHOLE MESS !!!! !NM NM NM NM*/
+  *(uint32_t *)tag     = tor_addr_to_ipv4h(addr);
   *(uint16_t *)(tag+4) = port;
   *(uint16_t *)(tag+6) = circ_id;
 }
@@ -161,6 +162,8 @@
     /* (Here we use connection_or_exact_get_by_addr_port rather than
      * get_by_identity_digest: we want a specific port here in
      * case there are multiple connections.) */
+    /* XXXX021 This is dumb. We don't want just any connection with a matching
+     * IP and port: we want the exact one that sent us this CREATE cell. */
     p_conn = connection_or_exact_get_by_addr_port(addr,port);
     if (p_conn)
       circ = circuit_get_by_circid_orconn(circ_id, p_conn);
@@ -468,7 +471,7 @@
       tor_free(onionskin);
       return -1;
     }
-    tag_pack(tag, circ->p_conn->_base.addr, circ->p_conn->_base.port,
+    tag_pack(tag, &circ->p_conn->_base.addr, circ->p_conn->_base.port,
              circ->p_circ_id);
 
     cpuworker->state = CPUWORKER_STATE_BUSY_ONION;

Modified: tor/trunk/src/or/directory.c
===================================================================
--- tor/trunk/src/or/directory.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/directory.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -243,10 +243,10 @@
   /* This tries dirservers which we believe to be down, but ultimately, that's
    * harmless, and we may as well err on the side of getting things uploaded.
    */
-  SMARTLIST_FOREACH(dirservers, trusted_dir_server_t *, ds,
-    {
+  SMARTLIST_FOREACH_BEGIN(dirservers, trusted_dir_server_t *, ds) {
       routerstatus_t *rs = &(ds->fake_status);
       size_t upload_len = payload_len;
+      tor_addr_t ds_addr;
 
       if ((type & ds->type) == 0)
         continue;
@@ -260,13 +260,14 @@
         log_info(LD_DIR, "Uploading an extrainfo (length %d)",
                  (int) extrainfo_len);
       }
+      tor_addr_from_ipv4h(&ds_addr, ds->addr);
       post_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose) ||
-              !fascist_firewall_allows_address_dir(ds->addr, ds->dir_port);
+        !fascist_firewall_allows_address_dir(&ds_addr, ds->dir_port);
       directory_initiate_command_routerstatus(rs, dir_purpose,
                                               router_purpose,
                                               post_via_tor,
                                               NULL, payload, upload_len, 0);
-    });
+  } SMARTLIST_FOREACH_END(ds);
   if (!found) {
     char *s = authority_type_to_string(type);
     log_warn(LD_DIR, "Publishing server descriptor to directory authorities "
@@ -344,7 +345,9 @@
        * so, for now, never assume the server supports that. */
       routerinfo_t *ri = choose_random_entry(NULL);
       if (ri) {
-        directory_initiate_command(ri->address, ri->addr,
+        tor_addr_t addr;
+        tor_addr_from_ipv4h(&addr, ri->addr);
+        directory_initiate_command(ri->address, &addr,
                                    ri->or_port, 0,
                                    0, /* don't use conditional consensus url */
                                    1, ri->cache_info.identity_digest,
@@ -459,6 +462,7 @@
   char address_buf[INET_NTOA_BUF_LEN+1];
   struct in_addr in;
   const char *address;
+  tor_addr_t addr;
   if ((router = router_get_by_digest(status->identity_digest))) {
     address = router->address;
   } else {
@@ -466,7 +470,8 @@
     tor_inet_ntoa(&in, address_buf, sizeof(address_buf));
     address = address_buf;
   }
-  directory_initiate_command(address, status->addr,
+  tor_addr_from_ipv4h(&addr, status->addr);
+  directory_initiate_command(address, &addr,
                              status->or_port, status->dir_port,
                              status->version_supports_conditional_consensus,
                              status->version_supports_begindir,
@@ -487,7 +492,7 @@
     routerinfo_t *me = router_get_my_routerinfo();
     if (me &&
         router_digest_is_me(conn->identity_digest) &&
-        me->addr == conn->_base.addr &&
+        tor_addr_eq_ipv4h(&conn->_base.addr, me->addr) && /*XXXX021 prop 118*/
         me->dir_port == conn->_base.port)
       return 1;
   }
@@ -626,7 +631,8 @@
  * 3) Else yes.
  */
 static int
-directory_command_should_use_begindir(or_options_t *options, uint32_t addr,
+directory_command_should_use_begindir(or_options_t *options,
+                                      const tor_addr_t *addr,
                                       int or_port, uint8_t router_purpose,
                                       int anonymized_connection)
 {
@@ -648,7 +654,7 @@
  * <b>supports_begindir</b>, and whose identity key digest is
  * <b>digest</b>. */
 void
-directory_initiate_command(const char *address, uint32_t addr,
+directory_initiate_command(const char *address, const tor_addr_t *_addr,
                            uint16_t or_port, uint16_t dir_port,
                            int supports_conditional_consensus,
                            int supports_begindir, const char *digest,
@@ -661,14 +667,17 @@
   or_options_t *options = get_options();
   int socket_error = 0;
   int use_begindir = supports_begindir &&
-                     directory_command_should_use_begindir(options, addr,
+                     directory_command_should_use_begindir(options, _addr,
                        or_port, router_purpose, anonymized_connection);
+  tor_addr_t addr;
 
   tor_assert(address);
-  tor_assert(addr);
+  tor_assert(_addr);
   tor_assert(or_port || dir_port);
   tor_assert(digest);
 
+  tor_addr_copy(&addr, _addr);
+
   log_debug(LD_DIR, "anonymized %d, use_begindir %d.",
             anonymized_connection, use_begindir);
 
@@ -677,7 +686,7 @@
   conn = TO_DIR_CONN(connection_new(CONN_TYPE_DIR, AF_INET));
 
   /* set up conn so it's got all the data we need to remember */
-  conn->_base.addr = addr;
+  tor_addr_copy(&conn->_base.addr, &addr);
   conn->_base.port = use_begindir ? or_port : dir_port;
   conn->_base.address = tor_strdup(address);
   memcpy(conn->identity_digest, digest, DIGEST_LEN);
@@ -695,11 +704,11 @@
     /* then we want to connect to dirport directly */
 
     if (options->HttpProxy) {
-      addr = options->HttpProxyAddr;
+      tor_addr_from_ipv4h(&addr, options->HttpProxyAddr);
       dir_port = options->HttpProxyPort;
     }
 
-    switch (connection_connect(TO_CONN(conn), conn->_base.address, addr,
+    switch (connection_connect(TO_CONN(conn), conn->_base.address, &addr,
                                dir_port, &socket_error)) {
       case -1:
         connection_dir_request_failed(conn); /* retry if we want */
@@ -2092,7 +2101,7 @@
     tor_snprintf(cp, sizeof(tmp)-(cp-tmp), "Content-Type: %s\r\n", type);
     cp += strlen(cp);
   }
-  if (!is_local_IP(conn->_base.addr)) {
+  if (!is_local_addr(&conn->_base.addr)) {
     /* Don't report the source address for a nearby/private connection.
      * Otherwise we tend to mis-report in cases where incoming ports are
      * being forwarded to a Tor server running behind the firewall. */
@@ -2541,19 +2550,26 @@
     {
       geoip_client_action_t act =
         is_v3 ? GEOIP_CLIENT_NETWORKSTATUS : GEOIP_CLIENT_NETWORKSTATUS_V2;
-      uint32_t addr = conn->_base.addr;
 
-      if (conn->_base.linked_conn) {
-        connection_t *c = conn->_base.linked_conn;
-        if (c->type == CONN_TYPE_EXIT) {
-          circuit_t *circ = TO_EDGE_CONN(c)->on_circuit;
-          if (! CIRCUIT_IS_ORIGIN(circ)) {
-            or_connection_t *orconn = TO_OR_CIRCUIT(circ)->p_conn;
-            addr = orconn->_base.addr;
+      if (tor_addr_family(&conn->_base.addr) == AF_INET) {
+        uint32_t addr = tor_addr_to_ipv4h(&conn->_base.addr);
+
+        if (conn->_base.linked_conn) {
+          connection_t *c = conn->_base.linked_conn;
+          if (c->type == CONN_TYPE_EXIT) {
+            circuit_t *circ = TO_EDGE_CONN(c)->on_circuit;
+            if (! CIRCUIT_IS_ORIGIN(circ)) {
+              or_connection_t *orconn = TO_OR_CIRCUIT(circ)->p_conn;
+              if (tor_addr_family(&conn->_base.addr) == AF_INET)
+                addr = tor_addr_to_ipv4h(&orconn->_base.addr);
+              else
+                addr = 0;
+            }
           }
         }
+        if (addr)
+          geoip_note_client_seen(act, addr, time(NULL));
       }
-      geoip_note_client_seen(act, addr, time(NULL));
     }
 #endif
 

Modified: tor/trunk/src/or/dirserv.c
===================================================================
--- tor/trunk/src/or/dirserv.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/dirserv.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -2770,8 +2770,9 @@
   static char ctr = 0;
   int bridge_auth = authdir_mode_bridge(get_options());
 
-  SMARTLIST_FOREACH(rl->routers, routerinfo_t *, router, {
+  SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, router) {
     const char *id_digest = router->cache_info.identity_digest;
+    tor_addr_t router_addr;
     if (router_is_me(router))
       continue;
     if (bridge_auth && router->purpose != ROUTER_PURPOSE_BRIDGE)
@@ -2784,10 +2785,10 @@
       /* Remember when we started trying to determine reachability */
       if (!router->testing_since)
         router->testing_since = now;
-      connection_or_connect(router->addr, router->or_port,
-                            id_digest);
+      tor_addr_from_ipv4h(&router_addr, router->addr);
+      connection_or_connect(&router_addr, router->or_port, id_digest);
     }
-  });
+  } SMARTLIST_FOREACH_END(router);
   if (!try_all) /* increment ctr */
     ctr = (ctr + 1) % 128;
 }

Modified: tor/trunk/src/or/dns.c
===================================================================
--- tor/trunk/src/or/dns.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/dns.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -78,6 +78,7 @@
   uint32_t magic;
   char address[MAX_ADDRESSLEN]; /**< The hostname to be resolved. */
   union {
+    /*XXXX021 Make this use a tor_addr_t OP6 */
     uint32_t addr;  /**< IPv4 addr for <b>address</b>. */
     char *hostname; /**< Hostname for <b>address</b> (if a reverse lookup) */
   } result;
@@ -420,10 +421,11 @@
     {
     case RESOLVED_TYPE_IPV4:
       buf[1] = 4;
-      set_uint32(buf+2, htonl(conn->_base.addr));
+      set_uint32(buf+2, tor_addr_to_ipv4n(&conn->_base.addr));
       set_uint32(buf+6, htonl(ttl));
       buflen = 10;
       break;
+    /*XXXX021 IP6 need ipv6 implementation */
     case RESOLVED_TYPE_ERROR_TRANSIENT:
     case RESOLVED_TYPE_ERROR:
       {
@@ -644,7 +646,7 @@
   /* first check if exitconn->_base.address is an IP. If so, we already
    * know the answer. */
   if (tor_inet_aton(exitconn->_base.address, &in) != 0) {
-    exitconn->_base.addr = ntohl(in.s_addr);
+    tor_addr_from_ipv4n(&exitconn->_base.addr, in.s_addr);
     exitconn->address_ttl = DEFAULT_DNS_TTL;
     return 1;
   }
@@ -714,7 +716,7 @@
           tor_assert(is_resolve);
           *hostname_out = tor_strdup(resolve->result.hostname);
         } else {
-          exitconn->_base.addr = resolve->result.addr;
+          tor_addr_from_ipv4h(&exitconn->_base.addr, resolve->result.addr);
         }
         return 1;
       case CACHE_STATE_CACHED_FAILED:
@@ -1017,7 +1019,7 @@
     pendconn = pend->conn; /* don't pass complex things to the
                               connection_mark_for_close macro */
     assert_connection_ok(TO_CONN(pendconn),time(NULL));
-    pendconn->_base.addr = addr;
+    tor_addr_from_ipv4h(&pendconn->_base.addr, addr);
     pendconn->address_ttl = ttl;
 
     if (outcome != DNS_RESOLVE_SUCCEEDED) {

Modified: tor/trunk/src/or/dnsserv.c
===================================================================
--- tor/trunk/src/or/dnsserv.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/dnsserv.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -25,9 +25,9 @@
   struct evdns_server_question *q = NULL;
   struct sockaddr_storage addr;
   struct sockaddr *sa;
-  struct sockaddr_in *sin;
   int addrlen;
-  uint32_t ipaddr;
+  tor_addr_t tor_addr;
+  uint16_t port;
   int err = DNS_ERR_NONE;
   char *q_name;
 
@@ -46,22 +46,24 @@
   }
   (void) addrlen;
   sa = (struct sockaddr*) &addr;
-  if (sa->sa_family != AF_INET) {
-    /* XXXX_IP6 Handle IPV6 */
-    log_warn(LD_APP, "Requesting address wasn't ipv4.");
+  if (tor_addr_from_sockaddr(&tor_addr, sa)<0) {
+    log_warn(LD_APP, "Requesting address wasn't recognized.");
     evdns_server_request_respond(req, DNS_ERR_SERVERFAILED);
     return;
-  } else {
-    sin = (struct sockaddr_in*)&addr;
-    ipaddr = ntohl(sin->sin_addr.s_addr);
   }
 
-  if (!socks_policy_permits_address(ipaddr)) {
+  if (!socks_policy_permits_address(&tor_addr)) {
     log_warn(LD_APP, "Rejecting DNS request from disallowed IP.");
     evdns_server_request_respond(req, DNS_ERR_REFUSED);
     return;
   }
 
+  if (sa->sa_family == AF_INET)
+    port = ((struct sockaddr_in *)sa)->sin_port;
+  else
+    port = ((struct sockaddr_in6 *)sa)->sin6_port;
+  port = ntohs(port);
+
   /* Now, let's find the first actual question of a type we can answer in this
    * DNS request.  It makes us a little noncompliant to act like this; we
    * should fix that eventually if it turns out to make a difference for
@@ -116,9 +118,9 @@
   conn->_base.state = AP_CONN_STATE_RESOLVE_WAIT;
   conn->is_dns_request = 1;
 
-  TO_CONN(conn)->addr = ntohl(sin->sin_addr.s_addr);
-  TO_CONN(conn)->port = ntohs(sin->sin_port);
-  TO_CONN(conn)->address = tor_dup_ip(TO_CONN(conn)->addr);
+  tor_addr_copy(&TO_CONN(conn)->addr, &tor_addr);
+  TO_CONN(conn)->port = port;
+  TO_CONN(conn)->address = tor_dup_addr(&tor_addr);
 
   if (q->type == EVDNS_TYPE_A)
     conn->socks_request->command = SOCKS_COMMAND_RESOLVE;

Modified: tor/trunk/src/or/main.c
===================================================================
--- tor/trunk/src/or/main.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/main.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -1896,7 +1896,7 @@
   smartlist_free(closeable_connection_lst);
   smartlist_free(active_linked_connection_lst);
   tor_free(timeout_event);
-  /* Stuff in util.c */
+  /* Stuff in util.c and address.c*/
   if (!postfork) {
     escaped(NULL);
     esc_router_info(NULL);

Modified: tor/trunk/src/or/networkstatus.c
===================================================================
--- tor/trunk/src/or/networkstatus.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/networkstatus.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -1002,15 +1002,18 @@
 
   if (authority) {
     /* An authority launches a separate connection for everybody. */
-    SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
-       {
+    SMARTLIST_FOREACH_BEGIN(trusted_dir_servers, trusted_dir_server_t *, ds)
+      {
          char resource[HEX_DIGEST_LEN+6]; /* fp/hexdigit.z\0 */
+         tor_addr_t addr;
          if (!(ds->type & V2_AUTHORITY))
            continue;
          if (router_digest_is_me(ds->digest))
            continue;
+         tor_addr_from_ipv4h(&addr, ds->addr);
+         /* Is this quite sensible with IPv6 or multiple addresses? */
          if (connection_get_by_type_addr_port_purpose(
-                CONN_TYPE_DIR, ds->addr, ds->dir_port,
+                CONN_TYPE_DIR, &addr, ds->dir_port,
                 DIR_PURPOSE_FETCH_NETWORKSTATUS)) {
            /* XXX020 the above dir_port won't be accurate if we're
             * doing a tunneled conn. In that case it should be or_port.
@@ -1031,7 +1034,8 @@
                resource,
                NULL, 0 /* No payload. */,
                0 /* No I-M-S. */);
-       });
+      }
+    SMARTLIST_FOREACH_END(ds);
   } else {
     /* A non-authority cache launches one connection to a random authority. */
     /* (Check whether we're currently fetching network-status objects.) */

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/or.h	2008-08-05 20:08:19 UTC (rev 16435)
@@ -870,8 +870,8 @@
   int socket_family; /**< Address family of this connection's socket.  Usually
                       * AF_INET, but it can also be AF_UNIX, or in the future
                       * AF_INET6 */
-  uint32_t addr; /**< IP of the other side of the connection; used to identify
-                  * routers, along with port. */
+  tor_addr_t addr; /**< IP of the other side of the connection; used to
+                    * identify routers, along with port. */
   uint16_t port; /**< If non-zero, port  on the other end
                   * of the connection. */
   uint16_t marked_for_close; /**< Should we close this conn on the next
@@ -922,7 +922,7 @@
    * recent, we can rate limit it further. */
   time_t client_used;
 
-  uint32_t real_addr; /**< The actual address that this connection came from
+  tor_addr_t real_addr; /**< The actual address that this connection came from
                        * or went to.  The <b>addr</b> field is prone to
                        * getting overridden by the address from the router
                        * descriptor matching <b>identity_digest</b>. */
@@ -1629,7 +1629,7 @@
                                           * display. */
   char identity_digest[DIGEST_LEN]; /**< Hash of this router's identity key. */
   uint16_t port; /**< OR port. */
-  uint32_t addr; /**< IP address in host order. */
+  tor_addr_t addr; /**< IP address. */
   crypto_pk_env_t *onion_key; /**< Current onionskin key. */
 } extend_info_t;
 
@@ -1997,14 +1997,12 @@
 /** An entry specifying a set of addresses and ports that should be remapped
  * to another address and port before exiting this exit node. */
 typedef struct exit_redirect_t {
-  /* XXXX_IP6 make this whole mess ipv6-capable.  (Does anybody use it? */
-
-  uint32_t addr;
+  tor_addr_t addr;
   uint16_t port_min;
   uint16_t port_max;
   maskbits_t maskbits;
 
-  uint32_t addr_dest;
+  tor_addr_t addr_dest;
   uint16_t port_dest;
   unsigned int is_redirect:1;
 } exit_redirect_t;
@@ -2591,7 +2589,7 @@
 void onion_append_to_cpath(crypt_path_t **head_ptr, crypt_path_t *new_hop);
 extend_info_t *extend_info_alloc(const char *nickname, const char *digest,
                                  crypto_pk_env_t *onion_key,
-                                 uint32_t addr, uint16_t port);
+                                 const tor_addr_t *addr, uint16_t port);
 extend_info_t *extend_info_from_router(routerinfo_t *r);
 extend_info_t *extend_info_dup(extend_info_t *info);
 void extend_info_free(extend_info_t *info);
@@ -2611,8 +2609,9 @@
 
 void clear_bridge_list(void);
 int routerinfo_is_a_configured_bridge(routerinfo_t *ri);
-void bridge_add_from_config(uint32_t addr, uint16_t port, char *digest);
-void retry_bridge_descriptor_fetch_directly(char *digest);
+void bridge_add_from_config(const tor_addr_t *addr, uint16_t port,
+                            char *digest);
+void retry_bridge_descriptor_fetch_directly(const char *digest);
 void fetch_bridge_descriptors(time_t now);
 void learned_bridge_descriptor(routerinfo_t *ri, int from_cache);
 int any_bridge_descriptors_known(void);
@@ -2739,7 +2738,7 @@
                          int clear_first, char **msg);
 int resolve_my_address(int warn_severity, or_options_t *options,
                        uint32_t *addr, char **hostname_out);
-int is_local_IP(uint32_t ip) ATTR_PURE;
+int is_local_addr(const tor_addr_t *addr) ATTR_PURE;
 void options_init(or_options_t *options);
 int options_init_from_torrc(int argc, char **argv);
 setopt_err_t options_init_from_string(const char *cf,
@@ -2794,7 +2793,8 @@
 
 void connection_expire_held_open(void);
 
-int connection_connect(connection_t *conn, const char *address, uint32_t addr,
+int connection_connect(connection_t *conn, const char *address,
+                       const tor_addr_t *addr,
                        uint16_t port, int *socket_error);
 int retry_all_listeners(smartlist_t *replaced_conns,
                         smartlist_t *new_conns);
@@ -2835,7 +2835,8 @@
 
 connection_t *connection_get_by_type(int type);
 connection_t *connection_get_by_type_purpose(int type, int purpose);
-connection_t *connection_get_by_type_addr_port_purpose(int type, uint32_t addr,
+connection_t *connection_get_by_type_addr_port_purpose(int type,
+                                                   const tor_addr_t *addr,
                                                    uint16_t port, int purpose);
 connection_t *connection_get_by_type_state(int type, int state);
 connection_t *connection_get_by_type_state_rendquery(int type, int state,
@@ -2948,8 +2949,8 @@
 int connection_or_finished_flushing(or_connection_t *conn);
 int connection_or_finished_connecting(or_connection_t *conn);
 
-or_connection_t *connection_or_connect(uint32_t addr, uint16_t port,
-                                    const char *id_digest);
+or_connection_t *connection_or_connect(const tor_addr_t *addr, uint16_t port,
+                                       const char *id_digest);
 
 int connection_tls_start_handshake(or_connection_t *conn, int receiving);
 int connection_tls_continue_handshake(or_connection_t *conn);
@@ -3144,7 +3145,7 @@
 int connection_dir_finished_flushing(dir_connection_t *conn);
 int connection_dir_finished_connecting(dir_connection_t *conn);
 void connection_dir_request_failed(dir_connection_t *conn);
-void directory_initiate_command(const char *address, uint32_t addr,
+void directory_initiate_command(const char *address, const tor_addr_t *addr,
                                 uint16_t or_port, uint16_t dir_port,
                                 int supports_conditional_consensus,
                                 int supports_begindir, const char *digest,
@@ -3606,10 +3607,11 @@
 } addr_policy_result_t;
 
 int firewall_is_fascist_or(void);
-int fascist_firewall_allows_address_or(uint32_t addr, uint16_t port);
-int fascist_firewall_allows_address_dir(uint32_t addr, uint16_t port);
-int dir_policy_permits_address(uint32_t addr);
-int socks_policy_permits_address(uint32_t addr);
+int fascist_firewall_allows_address_or(const tor_addr_t *addr, uint16_t port);
+int fascist_firewall_allows_or(routerinfo_t *ri);
+int fascist_firewall_allows_address_dir(const tor_addr_t *addr, uint16_t port);
+int dir_policy_permits_address(const tor_addr_t *addr);
+int socks_policy_permits_address(const tor_addr_t *addr);
 int authdir_policy_permits_address(uint32_t addr, uint16_t port);
 int authdir_policy_valid_address(uint32_t addr, uint16_t port);
 int authdir_policy_baddir_address(uint32_t addr, uint16_t port);
@@ -3621,6 +3623,8 @@
 
 addr_policy_t *addr_policy_get_canonical_entry(addr_policy_t *ent);
 int cmp_addr_policies(smartlist_t *a, smartlist_t *b);
+addr_policy_result_t compare_tor_addr_to_addr_policy(const tor_addr_t *addr,
+                              uint16_t port, smartlist_t *policy);
 addr_policy_result_t compare_addr_to_addr_policy(uint32_t addr,
                               uint16_t port, smartlist_t *policy);
 int policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
@@ -3693,6 +3697,11 @@
 void make_circuit_inactive_on_conn(circuit_t *circ, or_connection_t *conn);
 void make_circuit_active_on_conn(circuit_t *circ, or_connection_t *conn);
 
+int append_address_to_payload(char *payload_out, const tor_addr_t *addr);
+const char *decode_address_from_payload(tor_addr_t *addr_out,
+                                        const char *payload,
+                                        int payload_len);
+
 /********************************* rephist.c ***************************/
 
 void rep_hist_init(void);

Modified: tor/trunk/src/or/policies.c
===================================================================
--- tor/trunk/src/or/policies.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/policies.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -197,11 +197,11 @@
  * connection to <b>addr</b>:<b>port</b>.
  */
 static int
-addr_policy_permits_address(uint32_t addr, uint16_t port,
+addr_policy_permits_tor_addr(const tor_addr_t *addr, uint16_t port,
                             smartlist_t *policy)
 {
   addr_policy_result_t p;
-  p = compare_addr_to_addr_policy(addr, port, policy);
+  p = compare_tor_addr_to_addr_policy(addr, port, policy);
   switch (p) {
     case ADDR_POLICY_PROBABLY_ACCEPTED:
     case ADDR_POLICY_ACCEPTED:
@@ -215,40 +215,60 @@
   }
 }
 
+/* DOCDOC XXXX021 deprecate? */
+static int
+addr_policy_permits_address(uint32_t addr, uint16_t port,
+                            smartlist_t *policy)
+{
+  tor_addr_t a;
+  tor_addr_from_ipv4h(&a, addr);
+  return addr_policy_permits_tor_addr(&a, port, policy);
+}
+
 /** Return true iff we think our firewall will let us make an OR connection to
  * addr:port. */
 int
-fascist_firewall_allows_address_or(uint32_t addr, uint16_t port)
+fascist_firewall_allows_address_or(const tor_addr_t *addr, uint16_t port)
 {
-  return addr_policy_permits_address(addr, port,
+  return addr_policy_permits_tor_addr(addr, port,
                                      reachable_or_addr_policy);
 }
 
+/** DOCDOC */
+int
+fascist_firewall_allows_or(routerinfo_t *ri)
+{
+  /* XXXX021 proposal 118 */
+  tor_addr_t addr;
+  tor_addr_from_ipv4h(&addr, ri->addr);
+  return fascist_firewall_allows_address_or(&addr, ri->or_port);
+}
+
 /** Return true iff we think our firewall will let us make a directory
  * connection to addr:port. */
 int
-fascist_firewall_allows_address_dir(uint32_t addr, uint16_t port)
+fascist_firewall_allows_address_dir(const tor_addr_t *addr, uint16_t port)
 {
-  return addr_policy_permits_address(addr, port,
-                                     reachable_dir_addr_policy);
+  return addr_policy_permits_tor_addr(addr, port,
+                                      reachable_dir_addr_policy);
 }
 
 /** Return 1 if <b>addr</b> is permitted to connect to our dir port,
  * based on <b>dir_policy</b>. Else return 0.
  */
 int
-dir_policy_permits_address(uint32_t addr)
+dir_policy_permits_address(const tor_addr_t *addr)
 {
-  return addr_policy_permits_address(addr, 1, dir_policy);
+  return addr_policy_permits_tor_addr(addr, 1, dir_policy);
 }
 
 /** Return 1 if <b>addr</b> is permitted to connect to our socks port,
  * based on <b>socks_policy</b>. Else return 0.
  */
 int
-socks_policy_permits_address(uint32_t addr)
+socks_policy_permits_address(const tor_addr_t *addr)
 {
-  return addr_policy_permits_address(addr, 1, socks_policy);
+  return addr_policy_permits_tor_addr(addr, 1, socks_policy);
 }
 
 /** Return 1 if <b>addr</b>:<b>port</b> is permitted to publish to our
@@ -505,6 +525,16 @@
   return found->policy;
 }
 
+/** DOCDOC */
+addr_policy_result_t
+compare_addr_to_addr_policy(uint32_t addr, uint16_t port, smartlist_t *policy)
+{
+  /*XXXX021 deprecate this function? */
+  tor_addr_t a;
+  tor_addr_from_ipv4h(&a, addr);
+  return compare_tor_addr_to_addr_policy(&a, port, policy);
+}
+
 /** Decide whether a given addr:port is definitely accepted,
  * definitely rejected, probably accepted, or probably rejected by a
  * given policy.  If <b>addr</b> is 0, we don't know the IP of the
@@ -523,8 +553,8 @@
  * 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,
-                            smartlist_t *policy)
+compare_tor_addr_to_addr_policy(const tor_addr_t *addr, uint16_t port,
+                                smartlist_t *policy)
 {
   int maybe_reject = 0;
   int maybe_accept = 0;
@@ -532,10 +562,7 @@
   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);
+  addr_is_unknown = tor_addr_is_null(addr);
 
   len = policy ? smartlist_len(policy) : 0;
 
@@ -558,7 +585,7 @@
       }
     } else {
       /* Address is known */
-      if (!tor_addr_compare_masked(&addr, &tmpe->addr, tmpe->maskbits,
+      if (!tor_addr_compare_masked(addr, &tmpe->addr, tmpe->maskbits,
                                    CMP_SEMANTIC)) {
         if (port >= tmpe->prt_min && port <= tmpe->prt_max) {
           /* Exact match for the policy */

Modified: tor/trunk/src/or/relay.c
===================================================================
--- tor/trunk/src/or/relay.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/relay.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -1839,6 +1839,57 @@
   }
 }
 
+/** DOCDOC */
+int
+append_address_to_payload(char *payload_out, const tor_addr_t *addr)
+{
+  uint32_t a;
+  switch (tor_addr_family(addr)) {
+  case AF_INET:
+    payload_out[0] = RESOLVED_TYPE_IPV4;
+    payload_out[1] = 4;
+    a = tor_addr_to_ipv4n(addr);
+    memcpy(payload_out+2, &a, 4);
+    return 6;
+  case AF_INET6:
+    payload_out[0] = RESOLVED_TYPE_IPV6;
+    payload_out[1] = 16;
+    memcpy(payload_out+2, tor_addr_to_in6_addr8(addr), 16);
+    return 18;
+  case AF_UNSPEC:
+  default:
+    return -1;
+  }
+}
+
+/** DODOC */
+const char *
+decode_address_from_payload(tor_addr_t *addr_out, const char *payload,
+                            int payload_len)
+{
+  if (payload_len < 2)
+    return NULL;
+  if (payload_len < 2+(uint8_t)payload[1])
+    return NULL;
+
+  switch (payload[0]) {
+  case RESOLVED_TYPE_IPV4:
+    if (payload[1] != 4)
+      return NULL;
+    tor_addr_from_ipv4n(addr_out, get_uint32(payload+2));
+    break;
+  case RESOLVED_TYPE_IPV6:
+    if (payload[1] != 16)
+      return NULL;
+    tor_addr_from_ipv6_bytes(addr_out, payload+2);
+    break;
+  default:
+    tor_addr_make_unspec(addr_out);
+    break;
+  }
+  return payload + 2 + (uint8_t)payload[1];
+}
+
 /** Fail with an assert if the active circuits ring on <b>orconn</b> is
  * corrupt.  */
 void

Modified: tor/trunk/src/or/rendclient.c
===================================================================
--- tor/trunk/src/or/rendclient.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/rendclient.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -124,7 +124,7 @@
     int klen;
     tmp[0] = 2; /* version 2 of the cell format */
     /* nul pads */
-    set_uint32(tmp+1, htonl(extend_info->addr));
+    set_uint32(tmp+1, tor_addr_to_ipv4h(&extend_info->addr));
     set_uint16(tmp+5, htons(extend_info->port));
     memcpy(tmp+7, extend_info->identity_digest, DIGEST_LEN);
     klen = crypto_pk_asn1_encode(extend_info->onion_key, tmp+7+DIGEST_LEN+2,

Modified: tor/trunk/src/or/rendcommon.c
===================================================================
--- tor/trunk/src/or/rendcommon.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/rendcommon.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -200,7 +200,7 @@
       goto done;
     }
     /* Assemble everything for this introduction point. */
-    address = tor_dup_ip(info->addr);
+    address = tor_dup_addr(&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/rendservice.c
===================================================================
--- tor/trunk/src/or/rendservice.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/rendservice.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -22,7 +22,7 @@
 typedef struct rend_service_port_config_t {
   uint16_t virtual_port;
   uint16_t real_port;
-  uint32_t real_addr;
+  tor_addr_t real_addr;
 } rend_service_port_config_t;
 
 /** Try to maintain this many intro points per service if possible. */
@@ -121,7 +121,6 @@
 {
   int i;
   rend_service_port_config_t *p;
-  struct in_addr addr;
 
   service->intro_nodes = smartlist_create();
 
@@ -152,12 +151,9 @@
     log_debug(LD_REND,"Configuring service with directory \"%s\"",
               service->directory);
     for (i = 0; i < smartlist_len(service->ports); ++i) {
-      char addrbuf[INET_NTOA_BUF_LEN];
       p = smartlist_get(service->ports, i);
-      addr.s_addr = htonl(p->real_addr);
-      tor_inet_ntoa(&addr, addrbuf, sizeof(addrbuf));
       log_debug(LD_REND,"Service maps port %d to %s:%d",
-                p->virtual_port, addrbuf, p->real_port);
+                p->virtual_port, fmt_addr(&p->real_addr), p->real_port);
     }
   }
 }
@@ -176,7 +172,7 @@
   int virtport;
   int realport;
   uint16_t p;
-  uint32_t addr;
+  tor_addr_t addr;
   const char *addrport;
   rend_service_port_config_t *result = NULL;
 
@@ -198,11 +194,11 @@
   if (smartlist_len(sl) == 1) {
     /* No addr:port part; use default. */
     realport = virtport;
-    addr = 0x7F000001u; /* 127.0.0.1 */
+    tor_addr_from_ipv4h(&addr, 0x7F000001u); /* 127.0.0.1 */
   } else {
     addrport = smartlist_get(sl,1);
     if (strchr(addrport, ':') || strchr(addrport, '.')) {
-      if (parse_addr_port(LOG_WARN, addrport, NULL, &addr, &p)<0) {
+      if (tor_addr_port_parse(addrport, &addr, &p)<0) {
         log_warn(LD_CONFIG,"Unparseable address in hidden service port "
                  "configuration.");
         goto err;
@@ -216,14 +212,14 @@
                  "service port configuration.", escaped(addrport));
         goto err;
       }
-      addr = 0x7F000001u; /* Default to 127.0.0.1 */
+      tor_addr_from_ipv4h(&addr, 0x7F000001u); /* Default to 127.0.0.1 */
     }
   }
 
   result = tor_malloc(sizeof(rend_service_port_config_t));
   result->virtual_port = virtport;
   result->real_port = realport;
-  result->real_addr = addr;
+  tor_addr_copy(&result->real_addr, &addr);
  err:
   SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
   smartlist_free(sl);
@@ -538,7 +534,7 @@
     /* Version 2 INTRODUCE2 cell. */
     int klen;
     extend_info = tor_malloc_zero(sizeof(extend_info_t));
-    extend_info->addr = ntohl(get_uint32(buf+1));
+    tor_addr_from_ipv4n(&extend_info->addr, get_uint32(buf+1));
     extend_info->port = ntohs(get_uint16(buf+5));
     memcpy(extend_info->identity_digest, buf+7, DIGEST_LEN);
     extend_info->nickname[0] = '$';
@@ -1415,7 +1411,7 @@
   chosen_port = smartlist_choose(matching_ports);
   smartlist_free(matching_ports);
   if (chosen_port) {
-    conn->_base.addr = chosen_port->real_addr;
+    tor_addr_copy(&conn->_base.addr, &chosen_port->real_addr);
     conn->_base.port = chosen_port->real_port;
     return 0;
   }

Modified: tor/trunk/src/or/router.c
===================================================================
--- tor/trunk/src/or/router.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/router.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -736,6 +736,7 @@
 {
   routerinfo_t *me = router_get_my_routerinfo();
   int orport_reachable = check_whether_orport_reachable();
+  tor_addr_t addr;
   if (!me)
     return;
 
@@ -750,12 +751,13 @@
                                 me->address, me->or_port);
   }
 
+  tor_addr_from_ipv4h(&addr, me->addr);
   if (test_dir && !check_whether_dirport_reachable() &&
       !connection_get_by_type_addr_port_purpose(
-                CONN_TYPE_DIR, me->addr, me->dir_port,
+                CONN_TYPE_DIR, &addr, me->dir_port,
                 DIR_PURPOSE_FETCH_SERVERDESC)) {
     /* ask myself, via tor, for my server descriptor. */
-    directory_initiate_command(me->address, me->addr,
+    directory_initiate_command(me->address, &addr,
                                me->or_port, me->dir_port,
                                0, /* does not matter */
                                0, me->cache_info.identity_digest,
@@ -1111,10 +1113,10 @@
 
   /* make sure it's resolved to something. this way we can't get a
      'maybe' below. */
-  if (!conn->_base.addr)
+  if (tor_addr_is_null(&conn->_base.addr))
     return -1;
 
-  return compare_addr_to_addr_policy(conn->_base.addr, conn->_base.port,
+  return compare_tor_addr_to_addr_policy(&conn->_base.addr, conn->_base.port,
                    desc_routerinfo->exit_policy) != ADDR_POLICY_ACCEPTED;
 }
 
@@ -1543,7 +1545,7 @@
     /* Don't believe anybody who says our IP is, say, 127.0.0.1. */
     return;
   }
-  if (addr == d_conn->_base.addr) {
+  if (tor_addr_eq_ipv4h(&d_conn->_base.addr, addr)) {
     /* Don't believe anybody who says our IP is their IP. */
     log_debug(LD_DIR, "A directory server told us our IP address is %s, "
               "but he's just reporting his own IP address. Ignoring.",

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/routerlist.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -994,10 +994,11 @@
   overloaded_tunnel = smartlist_create();
 
   /* Find all the running dirservers we know about. */
-  SMARTLIST_FOREACH(consensus->routerstatus_list, routerstatus_t *, status,
-  {
+  SMARTLIST_FOREACH_BEGIN(consensus->routerstatus_list, routerstatus_t *,
+                          status) {
     int is_trusted;
     int is_overloaded = status->last_dir_503_at + DIR_503_TIMEOUT > now;
+    tor_addr_t addr;
     if (!status->is_running || !status->dir_port || !status->is_valid)
       continue;
     if (status->is_bad_directory)
@@ -1016,18 +1017,21 @@
     if ((type & EXTRAINFO_CACHE) &&
         !router_supports_extrainfo(status->identity_digest, 0))
       continue;
+
+    /* XXXX021 IP6 proposal 118 */
+    tor_addr_from_ipv4h(&addr, status->addr);
+
     if (prefer_tunnel &&
         status->version_supports_begindir &&
         (!fascistfirewall ||
-         fascist_firewall_allows_address_or(status->addr, status->or_port)))
+         fascist_firewall_allows_address_or(&addr, status->or_port)))
       smartlist_add(is_trusted ? trusted_tunnel :
                       is_overloaded ? overloaded_tunnel : tunnel, status);
     else if (!fascistfirewall ||
-             fascist_firewall_allows_address_dir(status->addr,
-                                                 status->dir_port))
+             fascist_firewall_allows_address_dir(&addr, status->dir_port))
       smartlist_add(is_trusted ? trusted_direct :
                       is_overloaded ? overloaded_direct : direct, status);
-  });
+  } SMARTLIST_FOREACH_END(status);
 
   if (smartlist_len(tunnel)) {
     result = routerstatus_sl_choose_by_bandwidth(tunnel);
@@ -1078,10 +1082,11 @@
   overloaded_direct = smartlist_create();
   overloaded_tunnel = smartlist_create();
 
-  SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, d,
+  SMARTLIST_FOREACH_BEGIN(trusted_dir_servers, trusted_dir_server_t *, d)
     {
       int is_overloaded =
           d->fake_status.last_dir_503_at + DIR_503_TIMEOUT > now;
+      tor_addr_t addr;
       if (!d->is_running) continue;
       if ((type & d->type) == 0)
         continue;
@@ -1090,17 +1095,22 @@
         continue;
       if (requireother && me && router_digest_is_me(d->digest))
           continue;
+
+      /* XXXX021 IP6 proposal 118 */
+      tor_addr_from_ipv4h(&addr, d->addr);
+
       if (prefer_tunnel &&
           d->or_port &&
           (!fascistfirewall ||
-           fascist_firewall_allows_address_or(d->addr, d->or_port)))
+           fascist_firewall_allows_address_or(&addr, d->or_port)))
         smartlist_add(is_overloaded ? overloaded_tunnel : tunnel,
                       &d->fake_status);
       else if (!fascistfirewall ||
-               fascist_firewall_allows_address_dir(d->addr, d->dir_port))
+               fascist_firewall_allows_address_dir(&addr, d->dir_port))
         smartlist_add(is_overloaded ? overloaded_direct : direct,
                       &d->fake_status);
-    });
+    }
+  SMARTLIST_FOREACH_END(d);
 
   if (smartlist_len(tunnel)) {
     result = smartlist_choose(tunnel);

Modified: tor/trunk/src/or/routerparse.c
===================================================================
--- tor/trunk/src/or/routerparse.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/routerparse.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -3548,7 +3548,6 @@
   directory_token_t *tok;
   rend_intro_point_t *intro;
   extend_info_t *info;
-  struct in_addr ip;
   int result, num_ok=1;
   memarea_t *area = NULL;
   tor_assert(parsed);
@@ -3621,12 +3620,17 @@
                   info->identity_digest, DIGEST_LEN);
     /* Parse IP address. */
     tok = find_first_by_keyword(tokens, R_IPO_IP_ADDRESS);
-    if (tor_inet_aton(tok->args[0], &ip) == 0) {
-      log_warn(LD_REND, "Could not parse IP address.");
+    if (tor_addr_from_str(&info->addr, tok->args[0])<0) {
+      log_warn(LD_REND, "Could not parse introduction point address.");
       rend_intro_point_free(intro);
       goto err;
     }
-    info->addr = ntohl(ip.s_addr);
+    if (tor_addr_family(&info->addr) != AF_INET) {
+      log_warn(LD_REND, "Introduction point address was not ipv4.");
+      rend_intro_point_free(intro);
+      goto err;
+    }
+
     /* Parse onion port. */
     tok = find_first_by_keyword(tokens, R_IPO_ONION_PORT);
     info->port = (uint16_t) tor_parse_long(tok->args[0],10,1,65535,

Modified: tor/trunk/src/or/test.c
===================================================================
--- tor/trunk/src/or/test.c	2008-08-05 19:17:17 UTC (rev 16434)
+++ tor/trunk/src/or/test.c	2008-08-05 20:08:19 UTC (rev 16435)
@@ -1336,13 +1336,13 @@
   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(1234, ntohs(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_port = htons(7070);
   sin6->sin6_addr.s6_addr[0] = 128;
   tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6);
   test_eq(tor_addr_family(&t1), AF_INET6);
@@ -1354,7 +1354,7 @@
           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(9999, ntohs(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
@@ -3901,8 +3901,8 @@
     base16_encode(intro->extend_info->nickname + 1,
                   sizeof(intro->extend_info->nickname) - 1,
                   intro->extend_info->identity_digest, DIGEST_LEN);
-    intro->extend_info->addr = crypto_rand_int(65536); /* Does not cover all
-                                                        * IP addresses. */
+    /* Does not cover all IP addresses. */
+    tor_addr_from_ipv4h(&intro->extend_info->addr, crypto_rand_int(65536));
     intro->extend_info->port = crypto_rand_int(65536);
     intro->intro_key = crypto_pk_dup_key(pk2);
     smartlist_add(generated->intro_nodes, intro);
@@ -3940,7 +3940,7 @@
     test_memeq(gen_info->identity_digest, par_info->identity_digest,
                DIGEST_LEN);
     test_streq(gen_info->nickname, par_info->nickname);
-    test_eq(gen_info->addr, par_info->addr);
+    test_assert(tor_addr_eq(&gen_info->addr, &par_info->addr));
     test_eq(gen_info->port, par_info->port);
   }
   tor_free(intro_points_encrypted);



More information about the tor-commits mailing list