aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2008-08-05 20:08:19 +0000
committerNick Mathewson <nickm@torproject.org>2008-08-05 20:08:19 +0000
commit960a0f0a994ba23480e14ffe5179160194fd9616 (patch)
tree250494775699fda2f0f543a350b02e89c5a77a03
parent750bb795ac1fcb5b76b6488690400c77fbff0a3f (diff)
downloadtor-960a0f0a994ba23480e14ffe5179160194fd9616.tar
tor-960a0f0a994ba23480e14ffe5179160194fd9616.tar.gz
r17641@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. svn:r16435
-rw-r--r--ChangeLog7
-rw-r--r--doc/TODO.02120
-rw-r--r--src/common/address.c165
-rw-r--r--src/common/address.h21
-rw-r--r--src/or/circuitbuild.c100
-rw-r--r--src/or/circuitlist.c9
-rw-r--r--src/or/circuituse.c20
-rw-r--r--src/or/command.c21
-rw-r--r--src/or/config.c48
-rw-r--r--src/or/connection.c140
-rw-r--r--src/or/connection_edge.c95
-rw-r--r--src/or/connection_or.c79
-rw-r--r--src/or/cpuworker.c9
-rw-r--r--src/or/directory.c66
-rw-r--r--src/or/dirserv.c9
-rw-r--r--src/or/dns.c10
-rw-r--r--src/or/dnsserv.c26
-rw-r--r--src/or/main.c2
-rw-r--r--src/or/networkstatus.c12
-rw-r--r--src/or/or.h51
-rw-r--r--src/or/policies.c63
-rw-r--r--src/or/relay.c51
-rw-r--r--src/or/rendclient.c2
-rw-r--r--src/or/rendcommon.c2
-rw-r--r--src/or/rendservice.c22
-rw-r--r--src/or/router.c12
-rw-r--r--src/or/routerlist.c30
-rw-r--r--src/or/routerparse.c12
-rw-r--r--src/or/test.c12
29 files changed, 703 insertions, 413 deletions
diff --git a/ChangeLog b/ChangeLog
index 5bf5bcaa0..e5c7ed4a3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/doc/TODO.021 b/doc/TODO.021
index 82521e0f8..fbc3c1dea 100644
--- a/doc/TODO.021
+++ b/doc/TODO.021
@@ -180,14 +180,20 @@ R d Do we want to maintain our own set of entryguards that we use as
- 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.)
diff --git a/src/common/address.c b/src/common/address.c
index 3328f41f1..711dc16c3 100644
--- a/src/common/address.c
+++ b/src/common/address.c
@@ -8,7 +8,7 @@ const char address_c_id[] =
/**
* \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 @@ const char address_c_id[] =
#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 @@ const char address_c_id[] =
#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 @@ const char address_c_id[] =
#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 @@ tor_addr_to_sockaddr(const tor_addr_t *a,
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 @@ tor_addr_to_sockaddr(const tor_addr_t *a,
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 @@ tor_addr_to_sockaddr(const tor_addr_t *a,
/** 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,7 +111,18 @@ tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa)
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
@@ -178,10 +150,14 @@ tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr)
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,18 +609,27 @@ tor_addr_is_loopback(const tor_addr_t *addr)
}
}
-/** 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>.
@@ -652,7 +637,8 @@ tor_addr_from_ipv4h(tor_addr_t *dest, uint32_t v4addr)
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 @@ tor_dup_addr(const tor_addr_t *addr)
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 @@ tor_addr_from_str(tor_addr_t *addr, const char *src)
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.
diff --git a/src/common/address.h b/src/common/address.h
index b079f6945..133a9b192 100644
--- a/src/common/address.h
+++ b/src/common/address.h
@@ -40,7 +40,8 @@ static INLINE const struct in6_addr *tor_addr_to_in6(const tor_addr_t *a);
static INLINE int tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u);
socklen_t tor_addr_to_sockaddr(const tor_addr_t *a, uint16_t port,
struct sockaddr *sa_out, 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 @@ tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u)
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 @@ int tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2,
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 @@ const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, int len,
int decorate);
int tor_addr_from_str(tor_addr_t *addr, const char *src);
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src);
-void tor_addr_from_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);
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index aac8b2a78..842ecbd1d 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -343,8 +343,6 @@ circuit_handle_first_hop(origin_circuit_t *circ)
{
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 @@ circuit_handle_first_hop(origin_circuit_t *circ)
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 @@ circuit_handle_first_hop(origin_circuit_t *circ)
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 @@ circuit_n_conn_done(or_connection_t *or_conn, int status)
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 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
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 @@ circuit_extend(cell_t *cell, circuit_t *circ)
* 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 @@ circuit_extend(cell_t *cell, circuit_t *circ)
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 @@ onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload,
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 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state)
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 @@ onion_append_hop(crypt_path_t **head_ptr, extend_info_t *choice)
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 @@ extend_info_alloc(const char *nickname, const char *digest,
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_alloc(const char *nickname, const char *digest,
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 @@ entry_is_live(entry_guard_t *e, int need_uptime, int need_capacity,
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 @@ getinfo_helper_entry_guards(control_connection_t *conn,
* 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 @@ routerinfo_get_configured_bridge(routerinfo_t *ri)
{
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 @@ routerinfo_is_a_configured_bridge(routerinfo_t *ri)
/** 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 @@ bridge_fetch_status_arrived(bridge_info_t *bridge, time_t now)
/** 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 @@ find_bridge_by_digest(char *digest)
/** 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 @@ retry_bridge_descriptor_fetch_directly(char *digest)
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 @@ fetch_bridge_descriptors(time_t now)
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 @@ fetch_bridge_descriptors(time_t now)
/* 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 @@ fetch_bridge_descriptors(time_t now)
!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 @@ fetch_bridge_descriptors(time_t now)
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 @@ fetch_bridge_descriptors(time_t now)
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
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 8fedfca8e..2f19bbf2c 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -231,8 +231,7 @@ circuit_get_all_pending_on_or_conn(smartlist_t *out, or_connection_t *or_conn)
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 @@ circuit_get_all_pending_on_or_conn(smartlist_t *out, or_connection_t *or_conn)
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 @@ circuit_get_all_pending_on_or_conn(smartlist_t *out, or_connection_t *or_conn)
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 @@ circuit_dump_by_conn(connection_t *conn, int severity)
}
}
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,
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index ebba1cdfa..8dfc607c1 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -102,9 +102,10 @@ circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn,
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 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
* 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 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn)
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),
diff --git a/src/or/command.c b/src/or/command.c
index 89bc72ef1..476501ffc 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -576,22 +576,19 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn)
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;
}
diff --git a/src/or/config.c b/src/or/config.c
index 1594c922b..201a621e6 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -2365,26 +2365,31 @@ resolve_my_address(int warn_severity, or_options_t *options,
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 @@ parse_redirect_line(smartlist_t *result, config_line_t *line, char **msg)
*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 @@ parse_redirect_line(smartlist_t *result, config_line_t *line, char **msg)
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 @@ parse_bridge_line(const char *line, int validate_only)
{
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 @@ parse_bridge_line(const char *line, int validate_only)
}
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 @@ parse_bridge_line(const char *line, int validate_only)
}
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 @@ parse_bridge_line(const char *line, int validate_only)
SMARTLIST_FOREACH(items, char*, s, tor_free(s));
smartlist_free(items);
tor_free(addrport);
- tor_free(address);
tor_free(fingerprint);
return r;
}
diff --git a/src/or/connection.c b/src/or/connection.c
index 8c7cca1ba..c415af898 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -907,24 +907,36 @@ connection_create_listener(struct sockaddr *listensockaddr, int type,
/** 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));
- 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.");
+ 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;
}
return ok ? 0 : -1;
@@ -939,17 +951,16 @@ connection_handle_listener_read(connection_t *conn, int new_type)
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 @@ connection_handle_listener_read(connection_t *conn, int new_type)
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 @@ connection_handle_listener_read(connection_t *conn, int new_type)
}
}
}
- 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 @@ connection_handle_listener_read(connection_t *conn, int new_type)
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 @@ connection_handle_listener_read(connection_t *conn, int new_type)
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 @@ connection_init_accepted_conn(connection_t *conn, uint8_t listener_type)
*/
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 @@ connection_connect(connection_t *conn, const char *address,
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 @@ connection_connect(connection_t *conn, const char *address,
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 @@ retry_all_listeners(smartlist_t *replaced_conns,
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 @@ connection_handle_write(connection_t *conn, int force)
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 @@ _connection_write_to_buf_impl(const char *string, size_t len,
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 @@ connection_or_exact_get_by_addr_port(uint32_t addr, uint16_t port)
* 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)
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 5b1b5b824..123c011ff 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -207,9 +207,16 @@ connection_edge_end(edge_connection_t *conn, char reason)
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 @@ connection_edge_finished_connecting(edge_connection_t *edge_conn)
{
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 @@ connection_edge_finished_connecting(edge_connection_t *edge_conn)
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 @@ connection_ap_expire_beginning(void)
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 @@ connection_ap_expire_beginning(void)
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 @@ connection_ap_fail_onehop(const char *failed_digest,
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 @@ connection_ap_fail_onehop(const char *failed_digest,
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 @@ connection_ap_fail_onehop(const char *failed_digest,
"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 @@ connection_ap_make_link(char *address, uint16_t port,
}
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 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
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 @@ connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ)
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 @@ connection_exit_connect(edge_connection_t *edge_conn)
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 @@ connection_exit_connect(edge_connection_t *edge_conn)
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);
}
}
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 1c6c85bd1..6c08a4e77 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -348,14 +348,9 @@ connection_or_finished_connecting(or_connection_t *or_conn)
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 @@ connection_or_finished_connecting(or_connection_t *or_conn)
}
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 @@ connection_or_finished_connecting(or_connection_t *or_conn)
* 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 @@ connection_or_init_conn_from_address(or_connection_t *conn,
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 @@ connection_or_init_conn_from_address(or_connection_t *conn,
* 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 @@ connection_or_init_conn_from_address(or_connection_t *conn,
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 @@ connection_or_get_by_identity_digest(const char *digest)
* 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 @@ connection_or_connect(uint32_t addr, uint16_t port, const char *id_digest)
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 @@ connection_tls_finish_handshake(or_connection_t *conn)
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 @@ connection_tls_finish_handshake(or_connection_t *conn)
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 @@ connection_or_set_state_open(or_connection_t *conn)
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 @@ connection_or_send_netinfo(or_connection_t *conn)
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);
diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c
index e56d2787f..77e15c748 100644
--- a/src/or/cpuworker.c
+++ b/src/or/cpuworker.c
@@ -63,9 +63,10 @@ connection_cpu_finished_flushing(connection_t *conn)
/** 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 @@ connection_cpu_process_inbuf(connection_t *conn)
/* (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 @@ assign_onionskin_to_cpuworker(connection_t *cpuworker,
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;
diff --git a/src/or/directory.c b/src/or/directory.c
index febdced84..8dacc9c71 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -243,10 +243,10 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
/* 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 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
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 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
* 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 @@ directory_initiate_command_routerstatus(routerstatus_t *status,
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 @@ directory_initiate_command_routerstatus(routerstatus_t *status,
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 @@ directory_conn_is_self_reachability_test(dir_connection_t *conn)
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 @@ connection_dir_download_cert_failed(dir_connection_t *conn, int status)
* 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 @@ directory_command_should_use_begindir(or_options_t *options, uint32_t addr,
* <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 @@ directory_initiate_command(const char *address, uint32_t addr,
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 @@ directory_initiate_command(const char *address, uint32_t addr,
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 @@ directory_initiate_command(const char *address, uint32_t addr,
/* 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 @@ write_http_response_header_impl(dir_connection_t *conn, ssize_t length,
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 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
{
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
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index e43c57029..e59b84d90 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -2770,8 +2770,9 @@ dirserv_test_reachability(time_t now, int try_all)
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 @@ dirserv_test_reachability(time_t now, int try_all)
/* 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;
}
diff --git a/src/or/dns.c b/src/or/dns.c
index 5af868b27..16673e2d2 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -78,6 +78,7 @@ typedef struct cached_resolve_t {
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 @@ send_resolved_cell(edge_connection_t *conn, uint8_t answer_type)
{
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 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
/* 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 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
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 @@ dns_found_answer(const char *address, uint8_t is_reverse, uint32_t addr,
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) {
diff --git a/src/or/dnsserv.c b/src/or/dnsserv.c
index 18623f6a4..5a1c02383 100644
--- a/src/or/dnsserv.c
+++ b/src/or/dnsserv.c
@@ -25,9 +25,9 @@ evdns_server_callback(struct evdns_server_request *req, void *_data)
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 @@ evdns_server_callback(struct evdns_server_request *req, void *_data)
}
(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 @@ evdns_server_callback(struct evdns_server_request *req, void *_data)
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;
diff --git a/src/or/main.c b/src/or/main.c
index f2457c420..8e054f277 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1896,7 +1896,7 @@ tor_free_all(int postfork)
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);
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 1c685b64c..35b65cf10 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -1002,15 +1002,18 @@ update_v2_networkstatus_cache_downloads(time_t now)
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 @@ update_v2_networkstatus_cache_downloads(time_t now)
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.) */
diff --git a/src/or/or.h b/src/or/or.h
index 61c98a7df..40b9efae9 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -870,8 +870,8 @@ typedef struct connection_t {
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 @@ typedef struct or_connection_t {
* 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 @@ typedef struct extend_info_t {
* 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 @@ static INLINE origin_circuit_t *TO_ORIGIN_CIRCUIT(circuit_t *x)
/** 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 @@ int circuit_extend_to_new_exit(origin_circuit_t *circ, extend_info_t *info);
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 @@ int getinfo_helper_entry_guards(control_connection_t *conn,
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 options_trial_assign(config_line_t *list, int use_defaults,
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_mark_for_close(connection_t *conn,int line, const char *file);
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 @@ edge_connection_t *connection_get_by_global_id(uint32_t id);
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_flushed_some(or_connection_t *conn);
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_process_inbuf(dir_connection_t *conn);
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 @@ typedef enum {
} 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 @@ int policies_parse_from_options(or_options_t *options);
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 assert_active_circuits_ok(or_connection_t *orconn);
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);
diff --git a/src/or/policies.c b/src/or/policies.c
index 60320a6b5..e7acdbba5 100644
--- a/src/or/policies.c
+++ b/src/or/policies.c
@@ -197,11 +197,11 @@ firewall_is_fascist_or(void)
* 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 @@ addr_policy_permits_address(uint32_t addr, uint16_t port,
}
}
+/* 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 @@ addr_policy_get_canonical_entry(addr_policy_t *e)
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 @@ addr_policy_get_canonical_entry(addr_policy_t *e)
* 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 @@ compare_addr_to_addr_policy(uint32_t _addr, uint16_t port,
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 @@ compare_addr_to_addr_policy(uint32_t _addr, uint16_t port,
}
} 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 */
diff --git a/src/or/relay.c b/src/or/relay.c
index 155f06669..8b68c8cf7 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -1839,6 +1839,57 @@ append_cell_to_circuit_queue(circuit_t *circ, or_connection_t *orconn,
}
}
+/** 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
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index 394e0eca8..e05fef90e 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -124,7 +124,7 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
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,
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
index b9e2e81f0..7361903ac 100644
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@ -200,7 +200,7 @@ rend_encode_v2_intro_points(char **ipos_base64,
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"
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index 6cf4d591a..431d87224 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -22,7 +22,7 @@ static origin_circuit_t *find_intro_circuit(rend_intro_point_t *intro,
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 @@ rend_add_service(rend_service_t *service)
{
int i;
rend_service_port_config_t *p;
- struct in_addr addr;
service->intro_nodes = smartlist_create();
@@ -152,12 +151,9 @@ rend_add_service(rend_service_t *service)
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 @@ parse_port_config(const char *string)
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 @@ parse_port_config(const char *string)
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 @@ parse_port_config(const char *string)
"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 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request,
/* 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 @@ rend_service_set_connection_addr_port(edge_connection_t *conn,
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;
}
diff --git a/src/or/router.c b/src/or/router.c
index bd8cb8351..842cb7b52 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -736,6 +736,7 @@ consider_testing_reachability(int test_or, int test_dir)
{
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 @@ consider_testing_reachability(int test_or, int test_dir)
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 @@ router_compare_to_my_exit_policy(edge_connection_t *conn)
/* 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 @@ router_new_address_suggestion(const char *suggestion,
/* 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.",
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 66e80f2dc..bce675ce0 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -994,10 +994,11 @@ router_pick_directory_server_impl(authority_type_t type, int flags)
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 @@ router_pick_directory_server_impl(authority_type_t type, int flags)
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 @@ router_pick_trusteddirserver_impl(authority_type_t type, int flags)
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 @@ router_pick_trusteddirserver_impl(authority_type_t type, int flags)
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);
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 811e276a7..d86c6f05a 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -3548,7 +3548,6 @@ rend_decrypt_introduction_points(rend_service_descriptor_t *parsed,
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 @@ rend_decrypt_introduction_points(rend_service_descriptor_t *parsed,
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,
diff --git a/src/or/test.c b/src/or/test.c
index a3aa9906f..0f19e5b01 100644
--- a/src/or/test.c
+++ b/src/or/test.c
@@ -1336,13 +1336,13 @@ test_util_ip6_helpers(void)
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 @@ test_util_ip6_helpers(void)
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 @@ test_rend_fns_v2(void)
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_rend_fns_v2(void)
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);