mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
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
This commit is contained in:
@@ -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
|
||||
|
||||
+13
-7
@@ -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.)
|
||||
|
||||
+111
-54
@@ -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.
|
||||
|
||||
+18
-3
@@ -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);
|
||||
|
||||
|
||||
+51
-49
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
+11
-9
@@ -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),
|
||||
|
||||
+9
-12
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+26
-22
@@ -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;
|
||||
}
|
||||
|
||||
+90
-50
@@ -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)
|
||||
|
||||
+56
-39
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+48
-31
@@ -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);
|
||||
|
||||
+6
-3
@@ -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;
|
||||
|
||||
+40
-24
@@ -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
|
||||
|
||||
|
||||
+5
-4
@@ -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;
|
||||
}
|
||||
|
||||
+6
-4
@@ -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) {
|
||||
|
||||
+14
-12
@@ -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;
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
@@ -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.) */
|
||||
|
||||
+30
-21
@@ -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);
|
||||
|
||||
+45
-18
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
+1
-1
@@ -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"
|
||||
|
||||
+9
-13
@@ -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;
|
||||
}
|
||||
|
||||
+7
-5
@@ -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.",
|
||||
|
||||
+20
-10
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
+6
-6
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user