diff options
author | teor <teor2345@gmail.com> | 2015-01-10 17:20:06 +1100 |
---|---|---|
committer | teor <teor2345@gmail.com> | 2015-01-10 17:20:06 +1100 |
commit | f8ffb57bc4430ff9bbd7560eecdda4284b2799ba (patch) | |
tree | 7b73b0bf39d756c31bb62dbcd3c239864a6a46c8 /src | |
parent | debd7862bb6d641c13fe4ee019da633c683d740e (diff) | |
parent | 33df3e37ffecfed309a1a0f210a96620c0ebb837 (diff) | |
download | tor-f8ffb57bc4430ff9bbd7560eecdda4284b2799ba.tar.gz tor-f8ffb57bc4430ff9bbd7560eecdda4284b2799ba.zip |
Merge branch 'master' of https://git.torproject.org/tor into bug13111-empty-key-files-fn-empty
Conflicts:
src/or/connection_edge.c
Merged in favour of origin.
Diffstat (limited to 'src')
216 files changed, 2512 insertions, 637 deletions
diff --git a/src/common/address.c b/src/common/address.c index 0b475fc9fd..a80926049a 100644 --- a/src/common/address.c +++ b/src/common/address.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -89,13 +89,14 @@ tor_addr_to_sockaddr(const tor_addr_t *a, struct sockaddr *sa_out, socklen_t len) { + memset(sa_out, 0, len); + sa_family_t family = tor_addr_family(a); if (family == AF_INET) { struct sockaddr_in *sin; if (len < (int)sizeof(struct sockaddr_in)) return 0; sin = (struct sockaddr_in *)sa_out; - memset(sin, 0, sizeof(struct sockaddr_in)); #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN sin->sin_len = sizeof(struct sockaddr_in); #endif @@ -108,7 +109,6 @@ tor_addr_to_sockaddr(const tor_addr_t *a, if (len < (int)sizeof(struct sockaddr_in6)) return 0; sin6 = (struct sockaddr_in6 *)sa_out; - memset(sin6, 0, sizeof(struct sockaddr_in6)); #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN sin6->sin6_len = sizeof(struct sockaddr_in6); #endif @@ -129,6 +129,9 @@ tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa, { tor_assert(a); tor_assert(sa); + + memset(a, 0, sizeof(*a)); + if (sa->sa_family == AF_INET) { struct sockaddr_in *sin = (struct sockaddr_in *) sa; tor_addr_from_ipv4n(a, sin->sin_addr.s_addr); @@ -1023,7 +1026,6 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2, } else { a2 = tor_addr_to_ipv4h(addr2); } - if (mbits <= 0) return 0; if (mbits > 32) mbits = 32; a1 >>= (32-mbits); a2 >>= (32-mbits); @@ -1369,8 +1371,8 @@ tor_addr_is_multicast(const tor_addr_t *a) * connects to the Internet. This address should only be used in checking * whether our address has changed. Return 0 on success, -1 on failure. */ -int -get_interface_address6(int severity, sa_family_t family, tor_addr_t *addr) +MOCK_IMPL(int, +get_interface_address6,(int severity, sa_family_t family, tor_addr_t *addr)) { /* XXX really, this function should yield a smartlist of addresses. */ smartlist_t *addrs; @@ -1699,8 +1701,8 @@ tor_dup_ip(uint32_t addr) * checking whether our address has changed. Return 0 on success, -1 on * failure. */ -int -get_interface_address(int severity, uint32_t *addr) +MOCK_IMPL(int, +get_interface_address,(int severity, uint32_t *addr)) { tor_addr_t local_addr; int r; diff --git a/src/common/address.h b/src/common/address.h index e8bab223a7..d70bb9c508 100644 --- a/src/common/address.h +++ b/src/common/address.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -159,7 +159,8 @@ char *tor_dup_addr(const tor_addr_t *addr) ATTR_MALLOC; const char *fmt_addr_impl(const tor_addr_t *addr, int decorate); const char *fmt_addrport(const tor_addr_t *addr, uint16_t port); const char * fmt_addr32(uint32_t addr); -int get_interface_address6(int severity, sa_family_t family, tor_addr_t *addr); +MOCK_DECL(int,get_interface_address6,(int severity, sa_family_t family, +tor_addr_t *addr)); /** 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 @@ -236,7 +237,7 @@ int addr_mask_get_bits(uint32_t mask); #define INET_NTOA_BUF_LEN 16 int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len); char *tor_dup_ip(uint32_t addr) ATTR_MALLOC; -int get_interface_address(int severity, uint32_t *addr); +MOCK_DECL(int,get_interface_address,(int severity, uint32_t *addr)); tor_addr_port_t *tor_addr_port_new(const tor_addr_t *addr, uint16_t port); diff --git a/src/common/aes.c b/src/common/aes.c index 877dce625c..7651f1d93a 100644 --- a/src/common/aes.c +++ b/src/common/aes.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/common/aes.h b/src/common/aes.h index f014e3a424..df2f3aa65d 100644 --- a/src/common/aes.h +++ b/src/common/aes.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* Implements a minimal interface to counter-mode AES. */ diff --git a/src/common/backtrace.c b/src/common/backtrace.c index e6fb8938ac..1033c7e5de 100644 --- a/src/common/backtrace.c +++ b/src/common/backtrace.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Tor Project, Inc. */ +/* Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define __USE_GNU diff --git a/src/common/backtrace.h b/src/common/backtrace.h index 4938745b3d..a9151d7956 100644 --- a/src/common/backtrace.h +++ b/src/common/backtrace.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Tor Project, Inc. */ +/* Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_BACKTRACE_H diff --git a/src/common/compat.c b/src/common/compat.c index 404f4f189f..6d36321193 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -2198,9 +2198,20 @@ get_environment(void) #endif } -/** Set *addr to the IP address (in dotted-quad notation) stored in c. - * Return 1 on success, 0 if c is badly formatted. (Like inet_aton(c,addr), - * but works on Windows and Solaris.) +/** Get name of current host and write it to <b>name</b> array, whose + * length is specified by <b>namelen</b> argument. Return 0 upon + * successfull completion; otherwise return return -1. (Currently, + * this function is merely a mockable wrapper for POSIX gethostname().) + */ +MOCK_IMPL(int, +tor_gethostname,(char *name, size_t namelen)) +{ + return gethostname(name,namelen); +} + +/** Set *addr to the IP address (in dotted-quad notation) stored in *str. + * Return 1 on success, 0 if *str is badly formatted. + * (Like inet_aton(str,addr), but works on Windows and Solaris.) */ int tor_inet_aton(const char *str, struct in_addr* addr) @@ -2420,8 +2431,9 @@ tor_inet_pton(int af, const char *src, void *dst) * (This function exists because standard windows gethostbyname * doesn't treat raw IP addresses properly.) */ -int -tor_lookup_hostname(const char *name, uint32_t *addr) + +MOCK_IMPL(int, +tor_lookup_hostname,(const char *name, uint32_t *addr)) { tor_addr_t myaddr; int ret; diff --git a/src/common/compat.h b/src/common/compat.h index 7001361af3..04e8cb267c 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_COMPAT_H @@ -532,10 +532,11 @@ struct sockaddr_in6 { }; #endif +MOCK_DECL(int,tor_gethostname,(char *name, size_t namelen)); int tor_inet_aton(const char *cp, struct in_addr *addr) ATTR_NONNULL((1,2)); const char *tor_inet_ntop(int af, const void *src, char *dst, size_t len); int tor_inet_pton(int af, const char *src, void *dst); -int tor_lookup_hostname(const char *name, uint32_t *addr) ATTR_NONNULL((1,2)); +MOCK_DECL(int,tor_lookup_hostname,(const char *name, uint32_t *addr)); int set_socket_nonblocking(tor_socket_t socket); int tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2]); int network_init(void); diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c index 85ed58456e..15308dd4cb 100644 --- a/src/common/compat_libevent.c +++ b/src/common/compat_libevent.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2014, The Tor Project, Inc. */ +/* Copyright (c) 2009-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -146,13 +146,25 @@ tor_evsignal_new(struct event_base * base, int sig, { return tor_event_new(base, sig, EV_SIGNAL|EV_PERSIST, cb, arg); } -/** Work-alike replacement for event_free() on pre-Libevent-2.0 systems. */ +/** Work-alike replacement for event_free() on pre-Libevent-2.0 systems, + * except tolerate tor_event_free(NULL). */ void tor_event_free(struct event *ev) { + if (ev == NULL) + return; event_del(ev); tor_free(ev); } +#else +/* Wrapper for event_free() that tolerates tor_event_free(NULL) */ +void +tor_event_free(struct event *ev) +{ + if (ev == NULL) + return; + event_free(ev); +} #endif /** Global event base for use by the main thread. */ diff --git a/src/common/compat_libevent.h b/src/common/compat_libevent.h index 57d0c4da1b..69259e7ed6 100644 --- a/src/common/compat_libevent.h +++ b/src/common/compat_libevent.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2014, The Tor Project, Inc. */ +/* Copyright (c) 2009-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_COMPAT_LIBEVENT_H @@ -28,11 +28,9 @@ void suppress_libevent_log_msg(const char *msg); #define tor_event_new event_new #define tor_evtimer_new evtimer_new #define tor_evsignal_new evsignal_new -#define tor_event_free event_free #define tor_evdns_add_server_port(sock, tcp, cb, data) \ evdns_add_server_port_with_base(tor_libevent_get_base(), \ (sock),(tcp),(cb),(data)); - #else struct event *tor_event_new(struct event_base * base, evutil_socket_t sock, short what, void (*cb)(evutil_socket_t, short, void *), void *arg); @@ -40,10 +38,11 @@ struct event *tor_evtimer_new(struct event_base * base, void (*cb)(evutil_socket_t, short, void *), void *arg); struct event *tor_evsignal_new(struct event_base * base, int sig, void (*cb)(evutil_socket_t, short, void *), void *arg); -void tor_event_free(struct event *ev); #define tor_evdns_add_server_port evdns_add_server_port #endif +void tor_event_free(struct event *ev); + typedef struct periodic_timer_t periodic_timer_t; periodic_timer_t *periodic_timer_new(struct event_base *base, diff --git a/src/common/container.c b/src/common/container.c index ab4e22de52..37e28004ae 100644 --- a/src/common/container.c +++ b/src/common/container.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/common/container.h b/src/common/container.h index d3d20af5b2..377cdf5dba 100644 --- a/src/common/container.h +++ b/src/common/container.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_CONTAINER_H diff --git a/src/common/crypto.c b/src/common/crypto.c index 7138ba003e..370c04a315 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -1293,7 +1293,7 @@ crypto_pk_asn1_decode(const char *str, size_t len) * Return 0 on success, -1 on failure. */ int -crypto_pk_get_digest(crypto_pk_t *pk, char *digest_out) +crypto_pk_get_digest(const crypto_pk_t *pk, char *digest_out) { unsigned char *buf = NULL; int len; @@ -2752,6 +2752,8 @@ base64_decode(char *dest, size_t destlen, const char *src, size_t srclen) if (destlen > SIZE_T_CEILING) return -1; + memset(dest, 0, destlen); + EVP_DecodeInit(&ctx); EVP_DecodeUpdate(&ctx, (unsigned char*)dest, &len, (unsigned char*)src, srclen); @@ -2773,6 +2775,8 @@ base64_decode(char *dest, size_t destlen, const char *src, size_t srclen) if (destlen > SIZE_T_CEILING) return -1; + memset(dest, 0, destlen); + /* Iterate over all the bytes in src. Each one will add 0 or 6 bits to the * value we're decoding. Accumulate bits in <b>n</b>, and whenever we have * 24 bits, batch them into 3 bytes and flush those bytes to dest. @@ -2952,6 +2956,8 @@ base32_decode(char *dest, size_t destlen, const char *src, size_t srclen) tor_assert((nbits/8) <= destlen); /* We need enough space. */ tor_assert(destlen < SIZE_T_CEILING); + memset(dest, 0, destlen); + /* Convert base32 encoded chars to the 5-bit values that they represent. */ tmp = tor_malloc_zero(srclen); for (j = 0; j < srclen; ++j) { diff --git a/src/common/crypto.h b/src/common/crypto.h index d496521849..d305bc17a0 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -180,7 +180,7 @@ int crypto_pk_private_hybrid_decrypt(crypto_pk_t *env, char *to, int crypto_pk_asn1_encode(crypto_pk_t *pk, char *dest, size_t dest_len); crypto_pk_t *crypto_pk_asn1_decode(const char *str, size_t len); -int crypto_pk_get_digest(crypto_pk_t *pk, char *digest_out); +int crypto_pk_get_digest(const crypto_pk_t *pk, char *digest_out); int crypto_pk_get_all_digests(crypto_pk_t *pk, digests_t *digests_out); int crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out,int add_space); int crypto_pk_get_hashed_fingerprint(crypto_pk_t *pk, char *fp_out); diff --git a/src/common/crypto_curve25519.c b/src/common/crypto_curve25519.c index c04b715abd..5bb14b0d95 100644 --- a/src/common/crypto_curve25519.c +++ b/src/common/crypto_curve25519.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* Wrapper code for a curve25519 implementation. */ diff --git a/src/common/crypto_curve25519.h b/src/common/crypto_curve25519.h index e8f885227e..48e8a6d962 100644 --- a/src/common/crypto_curve25519.h +++ b/src/common/crypto_curve25519.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_CRYPTO_CURVE25519_H diff --git a/src/common/crypto_ed25519.c b/src/common/crypto_ed25519.c index 340fb4956f..f2e6945ac8 100644 --- a/src/common/crypto_ed25519.c +++ b/src/common/crypto_ed25519.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Tor Project, Inc. */ +/* Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* Wrapper code for an ed25519 implementation. */ diff --git a/src/common/crypto_ed25519.h b/src/common/crypto_ed25519.h index 8c3663e0dd..7efa74bff5 100644 --- a/src/common/crypto_ed25519.h +++ b/src/common/crypto_ed25519.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_CRYPTO_ED25519_H diff --git a/src/common/crypto_format.c b/src/common/crypto_format.c index 63dd391914..00e0e9ea85 100644 --- a/src/common/crypto_format.c +++ b/src/common/crypto_format.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* Formatting and parsing code for crypto-related data structures. */ diff --git a/src/common/crypto_s2k.c b/src/common/crypto_s2k.c index 6d9ee497ab..99f3b2ebbc 100644 --- a/src/common/crypto_s2k.c +++ b/src/common/crypto_s2k.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CRYPTO_S2K_PRIVATE diff --git a/src/common/crypto_s2k.h b/src/common/crypto_s2k.h index a33dc96e46..66df24c3c4 100644 --- a/src/common/crypto_s2k.h +++ b/src/common/crypto_s2k.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_CRYPTO_S2K_H_INCLUDED diff --git a/src/common/di_ops.c b/src/common/di_ops.c index 0dcd6924e7..c9d1350880 100644 --- a/src/common/di_ops.c +++ b/src/common/di_ops.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Tor Project, Inc. */ +/* Copyright (c) 2011-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/common/di_ops.h b/src/common/di_ops.h index 935f93fc1a..bbb1caa00c 100644 --- a/src/common/di_ops.h +++ b/src/common/di_ops.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/common/log.c b/src/common/log.c index 0a21ffbd44..2e7c711413 100644 --- a/src/common/log.c +++ b/src/common/log.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/common/memarea.c b/src/common/memarea.c index 40c09bd0e6..6841ba54e7 100644 --- a/src/common/memarea.c +++ b/src/common/memarea.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2014, The Tor Project, Inc. */ +/* Copyright (c) 2008-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** \file memarea.c diff --git a/src/common/memarea.h b/src/common/memarea.h index fb261d11fa..d14f3a2bae 100644 --- a/src/common/memarea.h +++ b/src/common/memarea.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2014, The Tor Project, Inc. */ +/* Copyright (c) 2008-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* Tor dependencies */ diff --git a/src/common/mempool.c b/src/common/mempool.c index 695a110d3d..55a34070d7 100644 --- a/src/common/mempool.c +++ b/src/common/mempool.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2014, The Tor Project, Inc. */ +/* Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #if 1 /* Tor dependencies */ diff --git a/src/common/mempool.h b/src/common/mempool.h index 1e7a3121de..5cbeb8f482 100644 --- a/src/common/mempool.h +++ b/src/common/mempool.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2014, The Tor Project, Inc. */ +/* Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/common/procmon.c b/src/common/procmon.c index ee27e97f79..2d0f021724 100644 --- a/src/common/procmon.c +++ b/src/common/procmon.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Tor Project, Inc. */ +/* Copyright (c) 2011-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/common/procmon.h b/src/common/procmon.h index 6c487648bb..ccee6bfac6 100644 --- a/src/common/procmon.h +++ b/src/common/procmon.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Tor Project, Inc. */ +/* Copyright (c) 2011-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/common/sandbox.c b/src/common/sandbox.c index ece56df81f..450b04a6f7 100644 --- a/src/common/sandbox.c +++ b/src/common/sandbox.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -58,6 +58,16 @@ #include <time.h> #include <poll.h> +#ifdef HAVE_LINUX_NETFILTER_IPV4_H +#include <linux/netfilter_ipv4.h> +#endif +#ifdef HAVE_LINUX_IF_H +#include <linux/if.h> +#endif +#ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H +#include <linux/netfilter_ipv6/ip6_tables.h> +#endif + #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \ defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION) #define USE_BACKTRACE @@ -634,6 +644,22 @@ sb_getsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) if (rc) return rc; +#ifdef HAVE_LINUX_NETFILTER_IPV4_H + rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), + SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP), + SCMP_CMP(2, SCMP_CMP_EQ, SO_ORIGINAL_DST)); + if (rc) + return rc; +#endif + +#ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H + rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), + SCMP_CMP(1, SCMP_CMP_EQ, SOL_IPV6), + SCMP_CMP(2, SCMP_CMP_EQ, IP6T_SO_ORIGINAL_DST)); + if (rc) + return rc; +#endif + return 0; } @@ -1309,6 +1335,13 @@ sandbox_disable_getaddrinfo_cache(void) sandbox_getaddrinfo_cache_disabled = 1; } +void +sandbox_freeaddrinfo(struct addrinfo *ai) +{ + if (sandbox_getaddrinfo_cache_disabled) + freeaddrinfo(ai); +} + int sandbox_getaddrinfo(const char *name, const char *servname, const struct addrinfo *hints, diff --git a/src/common/sandbox.h b/src/common/sandbox.h index ad001865a7..36d25d6516 100644 --- a/src/common/sandbox.h +++ b/src/common/sandbox.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -115,7 +115,7 @@ struct addrinfo; int sandbox_getaddrinfo(const char *name, const char *servname, const struct addrinfo *hints, struct addrinfo **res); -#define sandbox_freeaddrinfo(addrinfo) ((void)0) +void sandbox_freeaddrinfo(struct addrinfo *addrinfo); void sandbox_free_getaddrinfo_cache(void); #else #define sandbox_getaddrinfo(name, servname, hints, res) \ diff --git a/src/common/testsupport.h b/src/common/testsupport.h index 2610086700..db7700aeb0 100644 --- a/src/common/testsupport.h +++ b/src/common/testsupport.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Tor Project, Inc. */ +/* Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_TESTSUPPORT_H @@ -20,8 +20,8 @@ * * and implement it as: * - * MOCK_IMPL(void - * writebuf,(size_t n, char *buf) + * MOCK_IMPL(void, + * writebuf,(size_t n, char *buf)) * { * ... * } diff --git a/src/common/torgzip.c b/src/common/torgzip.c index 4480e4b747..4f23407e23 100644 --- a/src/common/torgzip.c +++ b/src/common/torgzip.c @@ -1,6 +1,6 @@ /* Copyright (c) 2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -92,10 +92,27 @@ tor_zlib_get_header_version_str(void) /** Return the 'bits' value to tell zlib to use <b>method</b>.*/ static INLINE int -method_bits(compress_method_t method) +method_bits(compress_method_t method, zlib_compression_level_t level) { /* Bits+16 means "use gzip" in zlib >= 1.2 */ - return method == GZIP_METHOD ? 15+16 : 15; + const int flag = method == GZIP_METHOD ? 16 : 0; + switch (level) { + default: + case HIGH_COMPRESSION: return flag + 15; + case MEDIUM_COMPRESSION: return flag + 13; + case LOW_COMPRESSION: return flag + 11; + } +} + +static INLINE int +get_memlevel(zlib_compression_level_t level) +{ + switch (level) { + default: + case HIGH_COMPRESSION: return 8; + case MEDIUM_COMPRESSION: return 7; + case LOW_COMPRESSION: return 6; + } } /** @{ */ @@ -162,8 +179,9 @@ tor_gzip_compress(char **out, size_t *out_len, stream->avail_in = (unsigned int)in_len; if (deflateInit2(stream, Z_BEST_COMPRESSION, Z_DEFLATED, - method_bits(method), - 8, Z_DEFAULT_STRATEGY) != Z_OK) { + method_bits(method, HIGH_COMPRESSION), + get_memlevel(HIGH_COMPRESSION), + Z_DEFAULT_STRATEGY) != Z_OK) { log_warn(LD_GENERAL, "Error from deflateInit2: %s", stream->msg?stream->msg:"<no message>"); goto err; @@ -289,7 +307,7 @@ tor_gzip_uncompress(char **out, size_t *out_len, stream->avail_in = (unsigned int)in_len; if (inflateInit2(stream, - method_bits(method)) != Z_OK) { + method_bits(method, HIGH_COMPRESSION)) != Z_OK) { log_warn(LD_GENERAL, "Error from inflateInit2: %s", stream->msg?stream->msg:"<no message>"); goto err; @@ -315,7 +333,8 @@ tor_gzip_uncompress(char **out, size_t *out_len, log_warn(LD_BUG, "Error freeing gzip structures"); goto err; } - if (inflateInit2(stream, method_bits(method)) != Z_OK) { + if (inflateInit2(stream, + method_bits(method,HIGH_COMPRESSION)) != Z_OK) { log_warn(LD_GENERAL, "Error from second inflateInit2: %s", stream->msg?stream->msg:"<no message>"); goto err; @@ -426,10 +445,11 @@ struct tor_zlib_state_t { * <b>compress</b>, it's for compression; otherwise it's for * decompression. */ tor_zlib_state_t * -tor_zlib_new(int compress, compress_method_t method) +tor_zlib_new(int compress, compress_method_t method, + zlib_compression_level_t compression_level) { tor_zlib_state_t *out; - int bits; + int bits, memlevel; if (method == GZIP_METHOD && !is_gzip_supported()) { /* Old zlib version don't support gzip in inflateInit2 */ @@ -437,21 +457,29 @@ tor_zlib_new(int compress, compress_method_t method) return NULL; } + if (! compress) { + /* use this setting for decompression, since we might have the + * max number of window bits */ + compression_level = HIGH_COMPRESSION; + } + out = tor_malloc_zero(sizeof(tor_zlib_state_t)); out->stream.zalloc = Z_NULL; out->stream.zfree = Z_NULL; out->stream.opaque = NULL; out->compress = compress; - bits = method_bits(method); + bits = method_bits(method, compression_level); + memlevel = get_memlevel(compression_level); if (compress) { if (deflateInit2(&out->stream, Z_BEST_COMPRESSION, Z_DEFLATED, - bits, 8, Z_DEFAULT_STRATEGY) != Z_OK) + bits, memlevel, + Z_DEFAULT_STRATEGY) != Z_OK) goto err; } else { if (inflateInit2(&out->stream, bits) != Z_OK) goto err; } - out->allocation = tor_zlib_state_size_precalc(!compress, bits, 8); + out->allocation = tor_zlib_state_size_precalc(!compress, bits, memlevel); total_zlib_allocation += out->allocation; diff --git a/src/common/torgzip.h b/src/common/torgzip.h index 1378d55b76..0fc2deb6c4 100644 --- a/src/common/torgzip.h +++ b/src/common/torgzip.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -19,6 +19,15 @@ typedef enum { NO_METHOD=0, GZIP_METHOD=1, ZLIB_METHOD=2, UNKNOWN_METHOD=3 } compress_method_t; +/** + * Enumeration to define tradeoffs between memory usage and compression level. + * HIGH_COMPRESSION saves the most bandwidth; LOW_COMPRESSION saves the most + * memory. + **/ +typedef enum { + HIGH_COMPRESSION, MEDIUM_COMPRESSION, LOW_COMPRESSION +} zlib_compression_level_t; + int tor_gzip_compress(char **out, size_t *out_len, const char *in, size_t in_len, @@ -47,7 +56,8 @@ typedef enum { } tor_zlib_output_t; /** Internal state for an incremental zlib compression/decompression. */ typedef struct tor_zlib_state_t tor_zlib_state_t; -tor_zlib_state_t *tor_zlib_new(int compress, compress_method_t method); +tor_zlib_state_t *tor_zlib_new(int compress, compress_method_t method, + zlib_compression_level_t level); tor_zlib_output_t tor_zlib_process(tor_zlib_state_t *state, char **out, size_t *out_len, diff --git a/src/common/torint.h b/src/common/torint.h index d0b0ac14a0..6171700898 100644 --- a/src/common/torint.h +++ b/src/common/torint.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -191,6 +191,10 @@ typedef unsigned __int64 uint64_t; #endif #endif +#ifndef INT64_MIN +#define INT64_MIN ((- INT64_MAX) - 1) +#endif + #ifndef SIZE_MAX #if SIZEOF_SIZE_T == 8 #define SIZE_MAX UINT64_MAX diff --git a/src/common/torlog.h b/src/common/torlog.h index 483a97935f..8923a9e213 100644 --- a/src/common/torlog.h +++ b/src/common/torlog.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/common/tortls.c b/src/common/tortls.c index cca2d420b6..dd33b330dc 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/common/tortls.h b/src/common/tortls.h index 235d801202..f8c6d5913b 100644 --- a/src/common/tortls.h +++ b/src/common/tortls.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_TORTLS_H diff --git a/src/common/util.c b/src/common/util.c index 2f01a83974..5e9dd18f02 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -513,6 +513,51 @@ round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor) return number; } +/** Return the lowest x in [INT64_MIN, INT64_MAX] such that x is at least + * <b>number</b>, and x modulo <b>divisor</b> == 0. */ +int64_t +round_int64_to_next_multiple_of(int64_t number, int64_t divisor) +{ + tor_assert(divisor > 0); + if (number >= 0 && INT64_MAX - divisor + 1 >= number) + number += divisor - 1; + number -= number % divisor; + return number; +} + +/** Transform a random value <b>p</b> from the uniform distribution in + * [0.0, 1.0[ into a Laplace distributed value with location parameter + * <b>mu</b> and scale parameter <b>b</b> in [-Inf, Inf[. */ +double +sample_laplace_distribution(double mu, double b, double p) +{ + tor_assert(p >= 0.0 && p < 1.0); + /* This is the "inverse cumulative distribution function" from: + * http://en.wikipedia.org/wiki/Laplace_distribution */ + return mu - b * (p > 0.5 ? 1.0 : -1.0) + * tor_mathlog(1.0 - 2.0 * fabs(p - 0.5)); +} + +/** Add random noise between INT64_MIN and INT64_MAX coming from a + * Laplace distribution with mu = 0 and b = <b>delta_f</b>/<b>epsilon</b> + * to <b>signal</b> based on the provided <b>random</b> value in + * [0.0, 1.0[. */ +int64_t +add_laplace_noise(int64_t signal, double random, double delta_f, + double epsilon) +{ + /* cast to int64_t intended */ + int64_t noise = sample_laplace_distribution( + 0.0, /* just add noise, no further signal */ + delta_f / epsilon, random); + if (noise > 0 && INT64_MAX - noise < signal) + return INT64_MAX; + else if (noise < 0 && INT64_MIN - noise > signal) + return INT64_MIN; + else + return signal + noise; +} + /** Return the number of bits set in <b>v</b>. */ int n_bits_set_u8(uint8_t v) @@ -1223,6 +1268,9 @@ base16_decode(char *dest, size_t destlen, const char *src, size_t srclen) return -1; if (destlen < srclen/2 || destlen > SIZE_T_CEILING) return -1; + + memset(dest, 0, destlen); + end = src+srclen; while (src<end) { v1 = hex_decode_digit_(*src); @@ -1656,15 +1704,18 @@ format_iso_time_nospace_usec(char *buf, const struct timeval *tv) /** Given an ISO-formatted UTC time value (after the epoch) in <b>cp</b>, * parse it and store its value in *<b>t</b>. Return 0 on success, -1 on - * failure. Ignore extraneous stuff in <b>cp</b> separated by whitespace from - * the end of the time string. */ + * failure. Ignore extraneous stuff in <b>cp</b> after the end of the time + * string, unless <b>strict</b> is set. */ int -parse_iso_time(const char *cp, time_t *t) +parse_iso_time_(const char *cp, time_t *t, int strict) { struct tm st_tm; unsigned int year=0, month=0, day=0, hour=0, minute=0, second=0; - if (tor_sscanf(cp, "%u-%2u-%2u %2u:%2u:%2u", &year, &month, - &day, &hour, &minute, &second) < 6) { + int n_fields; + char extra_char; + n_fields = tor_sscanf(cp, "%u-%2u-%2u %2u:%2u:%2u%c", &year, &month, + &day, &hour, &minute, &second, &extra_char); + if (strict ? (n_fields != 6) : (n_fields < 6)) { char *esc = esc_for_log(cp); log_warn(LD_GENERAL, "ISO time %s was unparseable", esc); tor_free(esc); @@ -1693,6 +1744,16 @@ parse_iso_time(const char *cp, time_t *t) return tor_timegm(&st_tm, t); } +/** Given an ISO-formatted UTC time value (after the epoch) in <b>cp</b>, + * parse it and store its value in *<b>t</b>. Return 0 on success, -1 on + * failure. Reject the string if any characters are present after the time. + */ +int +parse_iso_time(const char *cp, time_t *t) +{ + return parse_iso_time_(cp, t, 1); +} + /** Given a <b>date</b> in one of the three formats allowed by HTTP (ugh), * parse it into <b>tm</b>. Return 0 on success, negative on failure. */ int diff --git a/src/common/util.h b/src/common/util.h index d45dd06741..1b8fc74db5 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -172,6 +172,10 @@ uint64_t round_to_power_of_2(uint64_t u64); unsigned round_to_next_multiple_of(unsigned number, unsigned divisor); uint32_t round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor); uint64_t round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor); +int64_t round_int64_to_next_multiple_of(int64_t number, int64_t divisor); +double sample_laplace_distribution(double mu, double b, double p); +int64_t add_laplace_noise(int64_t signal, double random, double delta_f, + double epsilon); int n_bits_set_u8(uint8_t v); /* Compute the CEIL of <b>a</b> divided by <b>b</b>, for nonnegative <b>a</b> @@ -270,6 +274,7 @@ void format_local_iso_time(char *buf, time_t t); void format_iso_time(char *buf, time_t t); void format_iso_time_nospace(char *buf, time_t t); void format_iso_time_nospace_usec(char *buf, const struct timeval *tv); +int parse_iso_time_(const char *cp, time_t *t, int strict); int parse_iso_time(const char *buf, time_t *t); int parse_http_time(const char *buf, struct tm *tm); int format_time_interval(char *out, size_t out_len, long interval); diff --git a/src/common/util_process.c b/src/common/util_process.c index 1924c19509..849a5c0b63 100644 --- a/src/common/util_process.c +++ b/src/common/util_process.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/common/util_process.h b/src/common/util_process.h index e7c55ed33d..c55cd8c5fa 100644 --- a/src/common/util_process.h +++ b/src/common/util_process.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Tor Project, Inc. */ +/* Copyright (c) 2011-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/ext/ht.h b/src/ext/ht.h index 09f5dcccd5..e7a76196f5 100644 --- a/src/ext/ht.h +++ b/src/ext/ht.h @@ -1,6 +1,6 @@ /* Copyright (c) 2002, Christopher Clark. * Copyright (c) 2005-2006, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See license at end. */ /* Based on ideas by Christopher Clark and interfaces from Niels Provos. */ diff --git a/src/ext/trunnel/trunnel-impl.h b/src/ext/trunnel/trunnel-impl.h index c88ee3988e..8714fded9f 100644 --- a/src/ext/trunnel/trunnel-impl.h +++ b/src/ext/trunnel/trunnel-impl.h @@ -5,7 +5,7 @@ /* trunnel-impl.h -- Implementation helpers for trunnel, included by * generated trunnel files * - * Copyright 2014, The Tor Project, Inc. + * Copyright 2014-2015, The Tor Project, Inc. * See license at the end of this file for copying information. */ diff --git a/src/ext/trunnel/trunnel.c b/src/ext/trunnel/trunnel.c index a18d67584e..735323798f 100644 --- a/src/ext/trunnel/trunnel.c +++ b/src/ext/trunnel/trunnel.c @@ -4,7 +4,7 @@ */ /* trunnel.c -- Helper functions to implement trunnel. * - * Copyright 2014, The Tor Project, Inc. + * Copyright 2014-2015, The Tor Project, Inc. * See license at the end of this file for copying information. * * See trunnel-impl.h for documentation of these functions. diff --git a/src/ext/trunnel/trunnel.h b/src/ext/trunnel/trunnel.h index f51cade03f..22c1ed80c9 100644 --- a/src/ext/trunnel/trunnel.h +++ b/src/ext/trunnel/trunnel.h @@ -5,7 +5,7 @@ /* trunnel.h -- Public declarations for trunnel, to be included * in trunnel header files. - * Copyright 2014, The Tor Project, Inc. + * Copyright 2014-2015, The Tor Project, Inc. * See license at the end of this file for copying information. */ diff --git a/src/or/addressmap.c b/src/or/addressmap.c index d7ac7c8ec7..8ad24323b5 100644 --- a/src/or/addressmap.c +++ b/src/or/addressmap.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define ADDRESSMAP_PRIVATE @@ -94,7 +94,7 @@ addressmap_ent_free(void *_ent) tor_free(ent); } -/** Free storage held by a virtaddress_entry_t* entry in <b>ent</b>. */ +/** Free storage held by a virtaddress_entry_t* entry in <b>_ent</b>. */ static void addressmap_virtaddress_ent_free(void *_ent) { @@ -104,11 +104,13 @@ addressmap_virtaddress_ent_free(void *_ent) ent = _ent; tor_free(ent->ipv4_address); + tor_free(ent->ipv6_address); tor_free(ent->hostname_address); tor_free(ent); } -/** Free storage held by a virtaddress_entry_t* entry in <b>ent</b>. */ +/** Remove <b>address</b> (which must map to <b>ent</b>) from the + * virtual address map. */ static void addressmap_virtaddress_remove(const char *address, addressmap_entry_t *ent) { @@ -120,9 +122,11 @@ addressmap_virtaddress_remove(const char *address, addressmap_entry_t *ent) if (ve) { if (!strcmp(address, ve->ipv4_address)) tor_free(ve->ipv4_address); + if (!strcmp(address, ve->ipv6_address)) + tor_free(ve->ipv6_address); if (!strcmp(address, ve->hostname_address)) tor_free(ve->hostname_address); - if (!ve->ipv4_address && !ve->hostname_address) { + if (!ve->ipv4_address && !ve->ipv6_address && !ve->hostname_address) { tor_free(ve); strmap_remove(virtaddress_reversemap, ent->new_address); } @@ -131,7 +135,7 @@ addressmap_virtaddress_remove(const char *address, addressmap_entry_t *ent) } /** Remove <b>ent</b> (which must be mapped to by <b>address</b>) from the - * client address maps. */ + * client address maps, and then free it. */ static void addressmap_ent_remove(const char *address, addressmap_entry_t *ent) { @@ -226,6 +230,8 @@ addressmap_address_should_automap(const char *address, return 0; SMARTLIST_FOREACH_BEGIN(suffix_list, const char *, suffix) { + if (!strcmp(suffix, ".")) + return 1; if (!strcasecmpend(address, suffix)) return 1; } SMARTLIST_FOREACH_END(suffix); @@ -496,7 +502,7 @@ addressmap_have_mapping(const char *address, int update_expiry) * equal to <b>address</b>, or any address ending with a period followed by * <b>address</b>. If <b>wildcard_addr</b> and <b>wildcard_new_addr</b> are * both true, the mapping will rewrite addresses that end with - * ".<b>address</b>" into ones that end with ".<b>new_address</b>." + * ".<b>address</b>" into ones that end with ".<b>new_address</b>". * * If <b>new_address</b> is NULL, or <b>new_address</b> is equal to * <b>address</b> and <b>wildcard_addr</b> is equal to @@ -535,9 +541,9 @@ addressmap_register(const char *address, char *new_address, time_t expires, if (expires > 1) { log_info(LD_APP,"Temporary addressmap ('%s' to '%s') not performed, " "since it's already mapped to '%s'", - safe_str_client(address), - safe_str_client(new_address), - safe_str_client(ent->new_address)); + safe_str_client(address), + safe_str_client(new_address), + safe_str_client(ent->new_address)); tor_free(new_address); return; } @@ -839,8 +845,8 @@ get_random_virtual_addr(const virtual_addr_conf_t *conf, tor_addr_t *addr_out) } /** Return a newly allocated string holding an address of <b>type</b> - * (one of RESOLVED_TYPE_{IPV4|HOSTNAME}) that has not yet been mapped, - * and that is very unlikely to be the address of any real host. + * (one of RESOLVED_TYPE_{IPV4|IPV6|HOSTNAME}) that has not yet been + * mapped, and that is very unlikely to be the address of any real host. * * May return NULL if we have run out of virtual addresses. */ @@ -888,7 +894,7 @@ addressmap_get_virtual_address(int type) /* XXXX This code is to make sure I didn't add an undecorated version * by mistake. I hope it's needless. */ char tmp[TOR_ADDR_BUF_LEN]; - tor_addr_to_str(buf, &addr, sizeof(tmp), 0); + tor_addr_to_str(tmp, &addr, sizeof(tmp), 0); if (strmap_get(addressmap, tmp)) { log_warn(LD_BUG, "%s wasn't in the addressmap, but %s was.", buf, tmp); diff --git a/src/or/addressmap.h b/src/or/addressmap.h index 598f7b0e3e..bb737e47f4 100644 --- a/src/or/addressmap.h +++ b/src/or/addressmap.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_ADDRESSMAP_H diff --git a/src/or/buffers.c b/src/or/buffers.c index 4cdc03bc03..ca0e815e33 100644 --- a/src/or/buffers.c +++ b/src/or/buffers.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -2063,9 +2063,7 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req, socks_request_set_socks5_error(req, SOCKS5_NOT_ALLOWED); return -1; } - } - - if (!string_is_valid_hostname(req->address)) { + } else if (!string_is_valid_hostname(req->address)) { socks_request_set_socks5_error(req, SOCKS5_GENERAL_ERROR); log_warn(LD_PROTOCOL, diff --git a/src/or/buffers.h b/src/or/buffers.h index 4687fbefd7..6dd3d1762b 100644 --- a/src/or/buffers.h +++ b/src/or/buffers.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/channel.c b/src/or/channel.c index 5ee0748802..062ae3370e 100644 --- a/src/or/channel.c +++ b/src/or/channel.c @@ -1,4 +1,4 @@ -/* * Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -147,7 +147,6 @@ HT_GENERATE2(channel_idmap, channel_idmap_entry_s, node, channel_idmap_hash, channel_idmap_eq, 0.5, tor_reallocarray_, tor_free_); static cell_queue_entry_t * cell_queue_entry_dup(cell_queue_entry_t *q); -static void cell_queue_entry_free(cell_queue_entry_t *q, int handed_off); #if 0 static int cell_queue_entry_is_padding(cell_queue_entry_t *q); #endif @@ -417,8 +416,7 @@ channel_register(channel_t *chan) smartlist_add(all_channels, chan); /* Is it finished? */ - if (chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR) { + if (CHANNEL_FINISHED(chan)) { /* Put it in the finished list, creating it if necessary */ if (!finished_channels) finished_channels = smartlist_new(); smartlist_add(finished_channels, chan); @@ -427,7 +425,7 @@ channel_register(channel_t *chan) if (!active_channels) active_channels = smartlist_new(); smartlist_add(active_channels, chan); - if (chan->state != CHANNEL_STATE_CLOSING) { + if (!CHANNEL_IS_CLOSING(chan)) { /* It should have a digest set */ if (!tor_digest_is_zero(chan->identity_digest)) { /* Yeah, we're good, add it to the map */ @@ -462,8 +460,7 @@ channel_unregister(channel_t *chan) if (!(chan->registered)) return; /* Is it finished? */ - if (chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR) { + if (CHANNEL_FINISHED(chan)) { /* Get it out of the finished list */ if (finished_channels) smartlist_remove(finished_channels, chan); } else { @@ -479,9 +476,7 @@ channel_unregister(channel_t *chan) /* Should it be in the digest map? */ if (!tor_digest_is_zero(chan->identity_digest) && - !(chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR)) { + !(CHANNEL_CONDEMNED(chan))) { /* Remove it */ channel_remove_from_digest_map(chan); } @@ -581,9 +576,7 @@ channel_add_to_digest_map(channel_t *chan) tor_assert(chan); /* Assert that the state makes sense */ - tor_assert(!(chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR)); + tor_assert(!CHANNEL_CONDEMNED(chan)); /* Assert that there is a digest */ tor_assert(!tor_digest_is_zero(chan->identity_digest)); @@ -821,8 +814,8 @@ channel_free(channel_t *chan) if (!chan) return; /* It must be closed or errored */ - tor_assert(chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR); + tor_assert(CHANNEL_FINISHED(chan)); + /* It must be deregistered */ tor_assert(!(chan->registered)); @@ -1036,9 +1029,7 @@ channel_get_cell_handler(channel_t *chan) { tor_assert(chan); - if (chan->state == CHANNEL_STATE_OPENING || - chan->state == CHANNEL_STATE_OPEN || - chan->state == CHANNEL_STATE_MAINT) + if (CHANNEL_CAN_HANDLE_CELLS(chan)) return chan->cell_handler; return NULL; @@ -1056,9 +1047,7 @@ channel_get_var_cell_handler(channel_t *chan) { tor_assert(chan); - if (chan->state == CHANNEL_STATE_OPENING || - chan->state == CHANNEL_STATE_OPEN || - chan->state == CHANNEL_STATE_MAINT) + if (CHANNEL_CAN_HANDLE_CELLS(chan)) return chan->var_cell_handler; return NULL; @@ -1081,9 +1070,7 @@ channel_set_cell_handlers(channel_t *chan, int try_again = 0; tor_assert(chan); - tor_assert(chan->state == CHANNEL_STATE_OPENING || - chan->state == CHANNEL_STATE_OPEN || - chan->state == CHANNEL_STATE_MAINT); + tor_assert(CHANNEL_CAN_HANDLE_CELLS(chan)); log_debug(LD_CHANNEL, "Setting cell_handler callback for channel %p to %p", @@ -1137,9 +1124,8 @@ channel_mark_for_close(channel_t *chan) tor_assert(chan->close != NULL); /* If it's already in CLOSING, CLOSED or ERROR, this is a no-op */ - if (chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR) return; + if (CHANNEL_CONDEMNED(chan)) + return; log_debug(LD_CHANNEL, "Closing channel %p (global ID " U64_FORMAT ") " @@ -1218,9 +1204,8 @@ channel_close_from_lower_layer(channel_t *chan) tor_assert(chan != NULL); /* If it's already in CLOSING, CLOSED or ERROR, this is a no-op */ - if (chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR) return; + if (CHANNEL_CONDEMNED(chan)) + return; log_debug(LD_CHANNEL, "Closing channel %p (global ID " U64_FORMAT ") " @@ -1278,9 +1263,8 @@ channel_close_for_error(channel_t *chan) tor_assert(chan != NULL); /* If it's already in CLOSING, CLOSED or ERROR, this is a no-op */ - if (chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR) return; + if (CHANNEL_CONDEMNED(chan)) + return; log_debug(LD_CHANNEL, "Closing channel %p due to lower-layer error", @@ -1336,13 +1320,11 @@ void channel_closed(channel_t *chan) { tor_assert(chan); - tor_assert(chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR); + tor_assert(CHANNEL_CONDEMNED(chan)); /* No-op if already inactive */ - if (chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR) return; + if (CHANNEL_FINISHED(chan)) + return; /* Inform any pending (not attached) circs that they should * give up. */ @@ -1405,10 +1387,7 @@ channel_clear_identity_digest(channel_t *chan) "global ID " U64_FORMAT, chan, U64_PRINTF_ARG(chan->global_identifier)); - state_not_in_map = - (chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR); + state_not_in_map = CHANNEL_CONDEMNED(chan); if (!state_not_in_map && chan->registered && !tor_digest_is_zero(chan->identity_digest)) @@ -1441,10 +1420,8 @@ channel_set_identity_digest(channel_t *chan, identity_digest ? hex_str(identity_digest, DIGEST_LEN) : "(null)"); - state_not_in_map = - (chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR); + state_not_in_map = CHANNEL_CONDEMNED(chan); + was_in_digest_map = !state_not_in_map && chan->registered && @@ -1494,10 +1471,7 @@ channel_clear_remote_end(channel_t *chan) "global ID " U64_FORMAT, chan, U64_PRINTF_ARG(chan->global_identifier)); - state_not_in_map = - (chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR); + state_not_in_map = CHANNEL_CONDEMNED(chan); if (!state_not_in_map && chan->registered && !tor_digest_is_zero(chan->identity_digest)) @@ -1533,10 +1507,8 @@ channel_set_remote_end(channel_t *chan, identity_digest ? hex_str(identity_digest, DIGEST_LEN) : "(null)"); - state_not_in_map = - (chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR); + state_not_in_map = CHANNEL_CONDEMNED(chan); + was_in_digest_map = !state_not_in_map && chan->registered && @@ -1596,7 +1568,7 @@ cell_queue_entry_dup(cell_queue_entry_t *q) * them) or not (we should free). */ -static void +STATIC void cell_queue_entry_free(cell_queue_entry_t *q, int handed_off) { if (!q) return; @@ -1761,9 +1733,7 @@ channel_write_cell_queue_entry(channel_t *chan, cell_queue_entry_t *q) tor_assert(q); /* Assert that the state makes sense for a cell write */ - tor_assert(chan->state == CHANNEL_STATE_OPENING || - chan->state == CHANNEL_STATE_OPEN || - chan->state == CHANNEL_STATE_MAINT); + tor_assert(CHANNEL_CAN_HANDLE_CELLS(chan)); { circid_t circ_id; @@ -1777,7 +1747,7 @@ channel_write_cell_queue_entry(channel_t *chan, cell_queue_entry_t *q) /* Can we send it right out? If so, try */ if (TOR_SIMPLEQ_EMPTY(&chan->outgoing_queue) && - chan->state == CHANNEL_STATE_OPEN) { + CHANNEL_IS_OPEN(chan)) { /* Pick the right write function for this cell type and save the result */ switch (q->type) { case CELL_QUEUE_FIXED: @@ -1835,7 +1805,7 @@ channel_write_cell_queue_entry(channel_t *chan, cell_queue_entry_t *q) /* Update channel queue size */ chan->bytes_in_queue += cell_bytes; /* Try to process the queue? */ - if (chan->state == CHANNEL_STATE_OPEN) channel_flush_cells(chan); + if (CHANNEL_IS_OPEN(chan)) channel_flush_cells(chan); } } @@ -1856,7 +1826,7 @@ channel_write_cell(channel_t *chan, cell_t *cell) tor_assert(chan); tor_assert(cell); - if (chan->state == CHANNEL_STATE_CLOSING) { + if (CHANNEL_IS_CLOSING(chan)) { log_debug(LD_CHANNEL, "Discarding cell_t %p on closing channel %p with " "global ID "U64_FORMAT, cell, chan, U64_PRINTF_ARG(chan->global_identifier)); @@ -1893,7 +1863,7 @@ channel_write_packed_cell(channel_t *chan, packed_cell_t *packed_cell) tor_assert(chan); tor_assert(packed_cell); - if (chan->state == CHANNEL_STATE_CLOSING) { + if (CHANNEL_IS_CLOSING(chan)) { log_debug(LD_CHANNEL, "Discarding packed_cell_t %p on closing channel %p " "with global ID "U64_FORMAT, packed_cell, chan, U64_PRINTF_ARG(chan->global_identifier)); @@ -1932,7 +1902,7 @@ channel_write_var_cell(channel_t *chan, var_cell_t *var_cell) tor_assert(chan); tor_assert(var_cell); - if (chan->state == CHANNEL_STATE_CLOSING) { + if (CHANNEL_IS_CLOSING(chan)) { log_debug(LD_CHANNEL, "Discarding var_cell_t %p on closing channel %p " "with global ID "U64_FORMAT, var_cell, chan, U64_PRINTF_ARG(chan->global_identifier)); @@ -2211,7 +2181,7 @@ channel_flush_some_cells, (channel_t *chan, ssize_t num_cells)) if (!unlimited && num_cells <= flushed) goto done; /* If we aren't in CHANNEL_STATE_OPEN, nothing goes through */ - if (chan->state == CHANNEL_STATE_OPEN) { + if (CHANNEL_IS_OPEN(chan)) { /* Try to flush as much as we can that's already queued */ flushed += channel_flush_some_cells_from_outgoing_queue(chan, (unlimited ? -1 : num_cells - flushed)); @@ -2302,7 +2272,7 @@ channel_flush_some_cells_from_outgoing_queue(channel_t *chan, if (!unlimited && num_cells <= flushed) return 0; /* If we aren't in CHANNEL_STATE_OPEN, nothing goes through */ - if (chan->state == CHANNEL_STATE_OPEN) { + if (CHANNEL_IS_OPEN(chan)) { while ((unlimited || num_cells > flushed) && NULL != (q = TOR_SIMPLEQ_FIRST(&chan->outgoing_queue))) { free_q = 0; @@ -2667,9 +2637,8 @@ channel_process_cells(channel_t *chan) { cell_queue_entry_t *q; tor_assert(chan); - tor_assert(chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_MAINT || - chan->state == CHANNEL_STATE_OPEN); + tor_assert(CHANNEL_IS_CLOSING(chan) || CHANNEL_IS_MAINT(chan) || + CHANNEL_IS_OPEN(chan)); log_debug(LD_CHANNEL, "Processing as many incoming cells as we can for channel %p", @@ -2736,7 +2705,7 @@ channel_queue_cell(channel_t *chan, cell_t *cell) tor_assert(chan); tor_assert(cell); - tor_assert(chan->state == CHANNEL_STATE_OPEN); + tor_assert(CHANNEL_IS_OPEN(chan)); /* Do we need to queue it, or can we just call the handler right away? */ if (!(chan->cell_handler)) need_to_queue = 1; @@ -2790,7 +2759,7 @@ channel_queue_var_cell(channel_t *chan, var_cell_t *var_cell) tor_assert(chan); tor_assert(var_cell); - tor_assert(chan->state == CHANNEL_STATE_OPEN); + tor_assert(CHANNEL_IS_OPEN(chan)); /* Do we need to queue it, or can we just call the handler right away? */ if (!(chan->var_cell_handler)) need_to_queue = 1; @@ -2913,10 +2882,7 @@ channel_send_destroy(circid_t circ_id, channel_t *chan, int reason) } /* Check to make sure we can send on this channel first */ - if (!(chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR) && - chan->cmux) { + if (!CHANNEL_CONDEMNED(chan) && chan->cmux) { channel_note_destroy_pending(chan, circ_id); circuitmux_append_destroy_cell(chan, chan->cmux, circ_id, reason); log_debug(LD_OR, @@ -3106,9 +3072,7 @@ channel_free_list(smartlist_t *channels, int mark_for_close) } channel_unregister(curr); if (mark_for_close) { - if (!(curr->state == CHANNEL_STATE_CLOSING || - curr->state == CHANNEL_STATE_CLOSED || - curr->state == CHANNEL_STATE_ERROR)) { + if (!CHANNEL_CONDEMNED(curr)) { channel_mark_for_close(curr); } channel_force_free(curr); @@ -3322,9 +3286,7 @@ channel_get_for_extend(const char *digest, tor_assert(tor_memeq(chan->identity_digest, digest, DIGEST_LEN)); - if (chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR) + if (CHANNEL_CONDEMNED(chan)) continue; /* Never return a channel on which the other end appears to be @@ -3334,7 +3296,7 @@ channel_get_for_extend(const char *digest, } /* Never return a non-open connection. */ - if (chan->state != CHANNEL_STATE_OPEN) { + if (!CHANNEL_IS_OPEN(chan)) { /* If the address matches, don't launch a new connection for this * circuit. */ if (channel_matches_target_addr_for_extend(chan, target_addr)) diff --git a/src/or/channel.h b/src/or/channel.h index 5c2a1a35e2..ecc2a092e4 100644 --- a/src/or/channel.h +++ b/src/or/channel.h @@ -1,4 +1,4 @@ -/* * Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -380,6 +380,8 @@ struct cell_queue_entry_s { /* Cell queue functions for benefit of test suite */ STATIC int chan_cell_queue_len(const chan_cell_queue_t *queue); + +STATIC void cell_queue_entry_free(cell_queue_entry_t *q, int handed_off); #endif /* Channel operations for subclasses and internal use only */ @@ -503,6 +505,39 @@ channel_t * channel_find_by_remote_digest(const char *identity_digest); channel_t * channel_next_with_digest(channel_t *chan); /* + * Helper macros to lookup state of given channel. + */ + +#define CHANNEL_IS_CLOSED(chan) (channel_is_in_state((chan), \ + CHANNEL_STATE_CLOSED)) +#define CHANNEL_IS_OPENING(chan) (channel_is_in_state((chan), \ + CHANNEL_STATE_OPENING)) +#define CHANNEL_IS_OPEN(chan) (channel_is_in_state((chan), \ + CHANNEL_STATE_OPEN)) +#define CHANNEL_IS_MAINT(chan) (channel_is_in_state((chan), \ + CHANNEL_STATE_MAINT)) +#define CHANNEL_IS_CLOSING(chan) (channel_is_in_state((chan), \ + CHANNEL_STATE_CLOSING)) +#define CHANNEL_IS_ERROR(chan) (channel_is_in_state((chan), \ + CHANNEL_STATE_ERROR)) + +#define CHANNEL_FINISHED(chan) (CHANNEL_IS_CLOSED(chan) || \ + CHANNEL_IS_ERROR(chan)) + +#define CHANNEL_CONDEMNED(chan) (CHANNEL_IS_CLOSING(chan) || \ + CHANNEL_FINISHED(chan)) + +#define CHANNEL_CAN_HANDLE_CELLS(chan) (CHANNEL_IS_OPENING(chan) || \ + CHANNEL_IS_OPEN(chan) || \ + CHANNEL_IS_MAINT(chan)) + +static INLINE int +channel_is_in_state(channel_t *chan, channel_state_t state) +{ + return chan->state == state; +} + +/* * Metadata queries/updates */ diff --git a/src/or/channeltls.c b/src/or/channeltls.c index 90ad1e679f..e194c1c4df 100644 --- a/src/or/channeltls.c +++ b/src/or/channeltls.c @@ -1,4 +1,4 @@ -/* * Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -940,13 +940,13 @@ channel_tls_handle_state_change_on_orconn(channel_tls_t *chan, base_chan = TLS_CHAN_TO_BASE(chan); - /* Make sure the base connection state makes sense - shouldn't be error, - * closed or listening. */ + /* Make sure the base connection state makes sense - shouldn't be error + * or closed. */ - tor_assert(base_chan->state == CHANNEL_STATE_OPENING || - base_chan->state == CHANNEL_STATE_OPEN || - base_chan->state == CHANNEL_STATE_MAINT || - base_chan->state == CHANNEL_STATE_CLOSING); + tor_assert(CHANNEL_IS_OPENING(base_chan) || + CHANNEL_IS_OPEN(base_chan) || + CHANNEL_IS_MAINT(base_chan) || + CHANNEL_IS_CLOSING(base_chan)); /* Did we just go to state open? */ if (state == OR_CONN_STATE_OPEN) { @@ -964,7 +964,7 @@ channel_tls_handle_state_change_on_orconn(channel_tls_t *chan, * Not open, so from CHANNEL_STATE_OPEN we go to CHANNEL_STATE_MAINT, * otherwise no change. */ - if (base_chan->state == CHANNEL_STATE_OPEN) { + if (CHANNEL_IS_OPEN(base_chan)) { channel_change_state(base_chan, CHANNEL_STATE_MAINT); } } diff --git a/src/or/channeltls.h b/src/or/channeltls.h index 133ad43bb4..507429420b 100644 --- a/src/or/channeltls.h +++ b/src/or/channeltls.h @@ -1,4 +1,4 @@ -/* * Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/circpathbias.c b/src/or/circpathbias.c index a6858a3460..a0115cc6ec 100644 --- a/src/or/circpathbias.c +++ b/src/or/circpathbias.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "or.h" @@ -768,8 +768,8 @@ pathbias_send_usable_probe(circuit_t *circ) /* Can't probe if the channel isn't open */ if (circ->n_chan == NULL || - (circ->n_chan->state != CHANNEL_STATE_OPEN - && circ->n_chan->state != CHANNEL_STATE_MAINT)) { + (!CHANNEL_IS_OPEN(circ->n_chan) + && !CHANNEL_IS_MAINT(circ->n_chan))) { log_info(LD_CIRC, "Skipping pathbias probe for circuit %d: Channel is not open.", ocirc->global_identifier); diff --git a/src/or/circpathbias.h b/src/or/circpathbias.h index bb8846353c..9e973850d5 100644 --- a/src/or/circpathbias.h +++ b/src/or/circpathbias.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index ddb186bea4..9620a23655 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -672,7 +672,7 @@ circuit_deliver_create_cell(circuit_t *circ, const create_cell_t *create_cell, if (CIRCUIT_IS_ORIGIN(circ)) { /* Update began timestamp for circuits starting their first hop */ if (TO_ORIGIN_CIRCUIT(circ)->cpath->state == CPATH_STATE_CLOSED) { - if (circ->n_chan->state != CHANNEL_STATE_OPEN) { + if (!CHANNEL_IS_OPEN(circ->n_chan)) { log_warn(LD_CIRC, "Got first hop for a circuit without an opened channel. " "State: %s.", channel_state_to_string(circ->n_chan->state)); @@ -1378,8 +1378,10 @@ onionskin_answer(or_circuit_t *circ, log_debug(LD_CIRC,"Finished sending '%s' cell.", circ->is_first_hop ? "created_fast" : "created"); - if (!channel_is_local(circ->p_chan) && - !channel_is_outgoing(circ->p_chan)) { + /* Ignore the local bit when testing - many test networks run on local + * addresses */ + if ((!channel_is_local(circ->p_chan) || get_options()->TestingTorNetwork) + && !channel_is_outgoing(circ->p_chan)) { /* record that we could process create cells from a non-local conn * that we didn't initiate; presumably this means that create cells * can reach us too. */ @@ -1863,7 +1865,7 @@ onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit) choose_good_exit_server(circ->base_.purpose, state->need_uptime, state->need_capacity, state->is_internal); if (!node) { - log_warn(LD_CIRC,"failed to choose an exit server"); + log_warn(LD_CIRC,"Failed to choose an exit server"); return -1; } exit = extend_info_from_node(node, 0); @@ -1990,7 +1992,8 @@ choose_good_middle_server(uint8_t purpose, tor_assert(CIRCUIT_PURPOSE_MIN_ <= purpose && purpose <= CIRCUIT_PURPOSE_MAX_); - log_debug(LD_CIRC, "Contemplating intermediate hop: random choice."); + log_debug(LD_CIRC, "Contemplating intermediate hop %d: random choice.", + cur_len); excluded = smartlist_new(); if ((r = build_state_get_exit_node(state))) { nodelist_add_node_and_family(excluded, r); @@ -2052,9 +2055,18 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state) smartlist_add(excluded, (void*)node); }); } - /* and exclude current entry guards and their families, if applicable */ + /* and exclude current entry guards and their families, + * unless we're in a test network, and excluding guards + * would exclude all nodes (i.e. we're in an incredibly small tor network, + * or we're using TestingAuthVoteGuard *). + * This is an incomplete fix, but is no worse than the previous behaviour, + * and only applies to minimal, testing tor networks + * (so it's no less secure) */ /*XXXX025 use the using_as_guard flag to accomplish this.*/ - if (options->UseEntryGuards) { + if (options->UseEntryGuards + && (!options->TestingTorNetwork || + smartlist_len(nodelist_get_list()) > smartlist_len(get_entry_guards()) + )) { SMARTLIST_FOREACH(get_entry_guards(), const entry_guard_t *, entry, { if ((node = node_get_by_id(entry->identity))) { diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index e70cdc5825..442afe8451 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index 0e88b47676..36ba3bffb7 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -1,7 +1,7 @@ /* Copyright 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -1752,9 +1752,7 @@ circuit_mark_for_close_, (circuit_t *circ, int reason, int line, if (circ->n_chan) { circuit_clear_cell_queue(circ, circ->n_chan); /* Only send destroy if the channel isn't closing anyway */ - if (!(circ->n_chan->state == CHANNEL_STATE_CLOSING || - circ->n_chan->state == CHANNEL_STATE_CLOSED || - circ->n_chan->state == CHANNEL_STATE_ERROR)) { + if (!CHANNEL_CONDEMNED(circ->n_chan)) { channel_send_destroy(circ->n_circ_id, circ->n_chan, reason); } circuitmux_detach_circuit(circ->n_chan->cmux, circ); @@ -1786,9 +1784,7 @@ circuit_mark_for_close_, (circuit_t *circ, int reason, int line, if (or_circ->p_chan) { circuit_clear_cell_queue(circ, or_circ->p_chan); /* Only send destroy if the channel isn't closing anyway */ - if (!(or_circ->p_chan->state == CHANNEL_STATE_CLOSING || - or_circ->p_chan->state == CHANNEL_STATE_CLOSED || - or_circ->p_chan->state == CHANNEL_STATE_ERROR)) { + if (!CHANNEL_CONDEMNED(or_circ->p_chan)) { channel_send_destroy(or_circ->p_circ_id, or_circ->p_chan, reason); } circuitmux_detach_circuit(or_circ->p_chan->cmux, circ); diff --git a/src/or/circuitlist.h b/src/or/circuitlist.h index ea1076d53f..4e600da57d 100644 --- a/src/or/circuitlist.h +++ b/src/or/circuitlist.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/circuitmux.c b/src/or/circuitmux.c index 443dad0a54..a77bffac90 100644 --- a/src/or/circuitmux.c +++ b/src/or/circuitmux.c @@ -1,4 +1,4 @@ -/* * Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/circuitmux.h b/src/or/circuitmux.h index 53092cd66c..837e3961bf 100644 --- a/src/or/circuitmux.h +++ b/src/or/circuitmux.h @@ -1,4 +1,4 @@ -/* * Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/circuitmux_ewma.c b/src/or/circuitmux_ewma.c index 0d7d6ef197..1c0318de06 100644 --- a/src/or/circuitmux_ewma.c +++ b/src/or/circuitmux_ewma.c @@ -1,4 +1,4 @@ -/* * Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/circuitmux_ewma.h b/src/or/circuitmux_ewma.h index ce78a8ef0d..3feef834dd 100644 --- a/src/or/circuitmux_ewma.h +++ b/src/or/circuitmux_ewma.h @@ -1,4 +1,4 @@ -/* * Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/circuitstats.c b/src/or/circuitstats.c index a136278e58..18cb1c8484 100644 --- a/src/or/circuitstats.c +++ b/src/or/circuitstats.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CIRCUITSTATS_PRIVATE diff --git a/src/or/circuitstats.h b/src/or/circuitstats.h index 7cef4f7fb1..fe05a24e97 100644 --- a/src/or/circuitstats.h +++ b/src/or/circuitstats.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/circuituse.c b/src/or/circuituse.c index ad4a3a546d..612b536bad 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -1024,9 +1024,11 @@ circuit_predict_and_launch_new(void) /* Second, see if we need any more exit circuits. */ /* check if we know of a port that's been requested recently - * and no circuit is currently available that can handle it. */ + * and no circuit is currently available that can handle it. + * Exits (obviously) require an exit circuit. */ if (!circuit_all_predicted_ports_handled(now, &port_needs_uptime, - &port_needs_capacity)) { + &port_needs_capacity) + && router_have_consensus_path() == CONSENSUS_PATH_EXIT) { if (port_needs_uptime) flags |= CIRCLAUNCH_NEED_UPTIME; if (port_needs_capacity) @@ -1038,8 +1040,10 @@ circuit_predict_and_launch_new(void) return; } - /* Third, see if we need any more hidden service (server) circuits. */ - if (num_rend_services() && num_uptime_internal < 3) { + /* Third, see if we need any more hidden service (server) circuits. + * HS servers only need an internal circuit. */ + if (num_rend_services() && num_uptime_internal < 3 + && router_have_consensus_path() != CONSENSUS_PATH_UNKNOWN) { flags = (CIRCLAUNCH_NEED_CAPACITY | CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL); log_info(LD_CIRC, @@ -1050,11 +1054,13 @@ circuit_predict_and_launch_new(void) return; } - /* Fourth, see if we need any more hidden service (client) circuits. */ + /* Fourth, see if we need any more hidden service (client) circuits. + * HS clients only need an internal circuit. */ if (rep_hist_get_predicted_internal(now, &hidserv_needs_uptime, &hidserv_needs_capacity) && ((num_uptime_internal<2 && hidserv_needs_uptime) || - num_internal<2)) { + num_internal<2) + && router_have_consensus_path() != CONSENSUS_PATH_UNKNOWN) { if (hidserv_needs_uptime) flags |= CIRCLAUNCH_NEED_UPTIME; if (hidserv_needs_capacity) @@ -1071,15 +1077,23 @@ circuit_predict_and_launch_new(void) /* Finally, check to see if we still need more circuits to learn * a good build timeout. But if we're close to our max number we * want, don't do another -- we want to leave a few slots open so - * we can still build circuits preemptively as needed. */ - if (num < MAX_UNUSED_OPEN_CIRCUITS-2 && - ! circuit_build_times_disabled() && - circuit_build_times_needs_circuits_now(get_circuit_build_times())) { - flags = CIRCLAUNCH_NEED_CAPACITY; - log_info(LD_CIRC, - "Have %d clean circs need another buildtime test circ.", num); - circuit_launch(CIRCUIT_PURPOSE_C_GENERAL, flags); - return; + * we can still build circuits preemptively as needed. + * XXXX make the assumption that build timeout streams should be + * created whenever we can build internal circuits. */ + if (router_have_consensus_path() != CONSENSUS_PATH_UNKNOWN) { + if (num < MAX_UNUSED_OPEN_CIRCUITS-2 && + ! circuit_build_times_disabled() && + circuit_build_times_needs_circuits_now(get_circuit_build_times())) { + flags = CIRCLAUNCH_NEED_CAPACITY; + /* if there are no exits in the consensus, make timeout + * circuits internal */ + if (router_have_consensus_path() == CONSENSUS_PATH_INTERNAL) + flags |= CIRCLAUNCH_IS_INTERNAL; + log_info(LD_CIRC, + "Have %d clean circs need another buildtime test circ.", num); + circuit_launch(CIRCUIT_PURPOSE_C_GENERAL, flags); + return; + } } } @@ -1096,11 +1110,17 @@ circuit_build_needed_circs(time_t now) { const or_options_t *options = get_options(); - /* launch a new circ for any pending streams that need one */ - connection_ap_attach_pending(); + /* launch a new circ for any pending streams that need one + * XXXX make the assumption that (some) AP streams (i.e. HS clients) + * don't require an exit circuit, review in #13814. + * This allows HSs to function in a consensus without exits. */ + if (router_have_consensus_path() != CONSENSUS_PATH_UNKNOWN) + connection_ap_attach_pending(); - /* make sure any hidden services have enough intro points */ - rend_services_introduce(); + /* make sure any hidden services have enough intro points + * HS intro point streams only require an internal circuit */ + if (router_have_consensus_path() != CONSENSUS_PATH_UNKNOWN) + rend_services_introduce(); circuit_expire_old_circs_as_needed(now); @@ -1632,6 +1652,16 @@ circuit_launch(uint8_t purpose, int flags) return circuit_launch_by_extend_info(purpose, NULL, flags); } +/** DOCDOC */ +static int +have_enough_path_info(int need_exit) +{ + if (need_exit) + return router_have_consensus_path() == CONSENSUS_PATH_EXIT; + else + return router_have_consensus_path() != CONSENSUS_PATH_UNKNOWN; +} + /** Launch a new circuit with purpose <b>purpose</b> and exit node * <b>extend_info</b> (or NULL to select a random exit node). If flags * contains CIRCLAUNCH_NEED_UPTIME, choose among routers with high uptime. If @@ -1646,10 +1676,14 @@ circuit_launch_by_extend_info(uint8_t purpose, { origin_circuit_t *circ; int onehop_tunnel = (flags & CIRCLAUNCH_ONEHOP_TUNNEL) != 0; - - if (!onehop_tunnel && !router_have_minimum_dir_info()) { - log_debug(LD_CIRC,"Haven't fetched enough directory info yet; canceling " - "circuit launch."); + int have_path = have_enough_path_info(! (flags & CIRCLAUNCH_IS_INTERNAL) ); + + if (!onehop_tunnel && (!router_have_minimum_dir_info() || !have_path)) { + log_debug(LD_CIRC,"Haven't %s yet; canceling " + "circuit launch.", + !router_have_minimum_dir_info() ? + "fetched enough directory info" : + "received a consensus with exits"); return NULL; } @@ -1806,7 +1840,9 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn, return 1; /* we're happy */ } - if (!want_onehop && !router_have_minimum_dir_info()) { + int have_path = have_enough_path_info(!need_internal); + + if (!want_onehop && (!router_have_minimum_dir_info() || !have_path)) { if (!connection_get_by_type(CONN_TYPE_DIR)) { int severity = LOG_NOTICE; /* FFFF if this is a tunneled directory fetch, don't yell @@ -1814,14 +1850,20 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn, if (entry_list_is_constrained(options) && entries_known_but_down(options)) { log_fn(severity, LD_APP|LD_DIR, - "Application request when we haven't used client functionality " - "lately. Optimistically trying known %s again.", + "Application request when we haven't %s. " + "Optimistically trying known %s again.", + !router_have_minimum_dir_info() ? + "used client functionality lately" : + "received a consensus with exits", options->UseBridges ? "bridges" : "entrynodes"); entries_retry_all(options); } else if (!options->UseBridges || any_bridge_descriptors_known()) { log_fn(severity, LD_APP|LD_DIR, - "Application request when we haven't used client functionality " - "lately. Optimistically trying directory fetches again."); + "Application request when we haven't %s. " + "Optimistically trying directory fetches again.", + !router_have_minimum_dir_info() ? + "used client functionality lately" : + "received a consensus with exits"); routerlist_retry_directory_downloads(time(NULL)); } } @@ -2012,7 +2054,7 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn, circ->rend_data = rend_data_dup(ENTRY_TO_EDGE_CONN(conn)->rend_data); if (circ->base_.purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND && circ->base_.state == CIRCUIT_STATE_OPEN) - rend_client_rendcirc_has_opened(circ); + circuit_has_opened(circ); } } } /* endif (!circ) */ diff --git a/src/or/circuituse.h b/src/or/circuituse.h index ce044d30dc..a59f478ac8 100644 --- a/src/or/circuituse.h +++ b/src/or/circuituse.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/command.c b/src/or/command.c index 268c495371..6dde2a9b7e 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -438,6 +438,7 @@ command_process_created_cell(cell_t *cell, channel_t *chan) static void command_process_relay_cell(cell_t *cell, channel_t *chan) { + const or_options_t *options = get_options(); circuit_t *circ; int reason, direction; @@ -511,6 +512,14 @@ command_process_relay_cell(cell_t *cell, channel_t *chan) direction==CELL_DIRECTION_OUT?"forward":"backward"); circuit_mark_for_close(circ, -reason); } + + /* If this is a cell in an RP circuit, count it as part of the + hidden service stats */ + if (options->HiddenServiceStatistics && + !CIRCUIT_IS_ORIGIN(circ) && + TO_OR_CIRCUIT(circ)->circuit_carries_hs_traffic_stats) { + rep_hist_seen_new_rp_cell(); + } } /** Process a 'destroy' <b>cell</b> that just arrived from diff --git a/src/or/command.h b/src/or/command.h index 509b4a0e9f..bea96261bb 100644 --- a/src/or/command.h +++ b/src/or/command.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/config.c b/src/or/config.c index a413aa4a40..2aeb73eeba 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -11,6 +11,7 @@ #define CONFIG_PRIVATE #include "or.h" +#include "compat.h" #include "addressmap.h" #include "channel.h" #include "circuitbuild.h" @@ -64,7 +65,6 @@ static config_abbrev_t option_abbrevs_[] = { PLURAL(AuthDirBadExitCC), PLURAL(AuthDirInvalidCC), PLURAL(AuthDirRejectCC), - PLURAL(ExitNode), PLURAL(EntryNode), PLURAL(ExcludeNode), PLURAL(FirewallPort), @@ -228,6 +228,7 @@ static config_var_t option_vars_[] = { V(ExitPolicyRejectPrivate, BOOL, "1"), V(ExitPortStatistics, BOOL, "0"), V(ExtendAllowPrivateAddresses, BOOL, "0"), + V(ExitRelay, AUTOBOOL, "auto"), VPORT(ExtORPort, LINELIST, NULL), V(ExtORPortCookieAuthFile, STRING, NULL), V(ExtORPortCookieAuthFileGroupReadable, BOOL, "0"), @@ -268,6 +269,7 @@ static config_var_t option_vars_[] = { VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL), VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines, NULL), VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL), + V(HiddenServiceStatistics, BOOL, "0"), V(HidServAuth, LINELIST, NULL), V(CloseHSClientCircuitsImmediatelyOnTimeout, BOOL, "0"), V(CloseHSServiceRendCircuitsImmediatelyOnTimeout, BOOL, "0"), @@ -468,7 +470,7 @@ static const config_var_t testing_tor_network_defaults[] = { V(V3AuthVotingInterval, INTERVAL, "5 minutes"), V(V3AuthVoteDelay, INTERVAL, "20 seconds"), V(V3AuthDistDelay, INTERVAL, "20 seconds"), - V(TestingV3AuthInitialVotingInterval, INTERVAL, "5 minutes"), + V(TestingV3AuthInitialVotingInterval, INTERVAL, "150 seconds"), V(TestingV3AuthInitialVoteDelay, INTERVAL, "20 seconds"), V(TestingV3AuthInitialDistDelay, INTERVAL, "20 seconds"), V(TestingV3AuthVotingStartOffset, INTERVAL, "0"), @@ -1714,6 +1716,7 @@ options_act(const or_options_t *old_options) if (options->CellStatistics || options->DirReqStatistics || options->EntryStatistics || options->ExitPortStatistics || options->ConnDirectionStatistics || + options->HiddenServiceStatistics || options->BridgeAuthoritativeDir) { time_t now = time(NULL); int print_notice = 0; @@ -1722,6 +1725,7 @@ options_act(const or_options_t *old_options) if (!public_server_mode(options)) { options->CellStatistics = 0; options->EntryStatistics = 0; + options->HiddenServiceStatistics = 0; options->ExitPortStatistics = 0; } @@ -1767,6 +1771,11 @@ options_act(const or_options_t *old_options) options->ConnDirectionStatistics) { rep_hist_conn_stats_init(now); } + if ((!old_options || !old_options->HiddenServiceStatistics) && + options->HiddenServiceStatistics) { + log_info(LD_CONFIG, "Configured to measure hidden service statistics."); + rep_hist_hs_stats_init(now); + } if ((!old_options || !old_options->BridgeAuthoritativeDir) && options->BridgeAuthoritativeDir) { rep_hist_desc_stats_init(now); @@ -1778,6 +1787,8 @@ options_act(const or_options_t *old_options) "data directory in 24 hours from now."); } + /* If we used to have statistics enabled but we just disabled them, + stop gathering them. */ if (old_options && old_options->CellStatistics && !options->CellStatistics) rep_hist_buffer_stats_term(); @@ -1787,6 +1798,9 @@ options_act(const or_options_t *old_options) if (old_options && old_options->EntryStatistics && !options->EntryStatistics) geoip_entry_stats_term(); + if (old_options && old_options->HiddenServiceStatistics && + !options->HiddenServiceStatistics) + rep_hist_hs_stats_term(); if (old_options && old_options->ExitPortStatistics && !options->ExitPortStatistics) rep_hist_exit_stats_term(); @@ -1819,7 +1833,7 @@ options_act(const or_options_t *old_options) directory_fetches_dir_info_early(old_options)) || !bool_eq(directory_fetches_dir_info_later(options), directory_fetches_dir_info_later(old_options))) { - /* Make sure update_router_have_min_dir_info gets called. */ + /* Make sure update_router_have_minimum_dir_info() gets called. */ router_dir_info_changed(); /* We might need to download a new consensus status later or sooner than * we had expected. */ @@ -2033,7 +2047,7 @@ print_usage(void) printf( "Copyright (c) 2001-2004, Roger Dingledine\n" "Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson\n" -"Copyright (c) 2007-2014, The Tor Project, Inc.\n\n" +"Copyright (c) 2007-2015, The Tor Project, Inc.\n\n" "tor -f <torrc> [args]\n" "See man page for options, or https://www.torproject.org/ for " "documentation.\n"); @@ -2073,7 +2087,33 @@ reset_last_resolved_addr(void) } /** - * Use <b>options-\>Address</b> to guess our public IP address. + * Attempt getting our non-local (as judged by tor_addr_is_internal() + * function) IP address using following techniques, listed in + * order from best (most desirable, try first) to worst (least + * desirable, try if everything else fails). + * + * First, attempt using <b>options-\>Address</b> to get our + * non-local IP address. + * + * If <b>options-\>Address</b> represents a non-local IP address, + * consider it ours. + * + * If <b>options-\>Address</b> is a DNS name that resolves to + * a non-local IP address, consider this IP address ours. + * + * If <b>options-\>Address</b> is NULL, fall back to getting local + * hostname and using it in above-described ways to try and + * get our IP address. + * + * In case local hostname cannot be resolved to a non-local IP + * address, try getting an IP address of network interface + * in hopes it will be non-local one. + * + * Fail if one or more of the following is true: + * - DNS name in <b>options-\>Address</b> cannot be resolved. + * - <b>options-\>Address</b> is a local host address. + * - Attempt to getting local hostname fails. + * - Attempt to getting network interface address fails. * * Return 0 if all is well, or -1 if we can't find a suitable * public IP address. @@ -2082,6 +2122,11 @@ reset_last_resolved_addr(void) * - Put our public IP address (in host order) into *<b>addr_out</b>. * - If <b>method_out</b> is non-NULL, set *<b>method_out</b> to a static * string describing how we arrived at our answer. + * - "CONFIGURED" - parsed from IP address string in + * <b>options-\>Address</b> + * - "RESOLVED" - resolved from DNS name in <b>options-\>Address</b> + * - "GETHOSTNAME" - resolved from a local hostname. + * - "INTERFACE" - retrieved from a network interface. * - If <b>hostname_out</b> is non-NULL, and we resolved a hostname to * get our address, set *<b>hostname_out</b> to a newly allocated string * holding that hostname. (If we didn't get our address by resolving a @@ -2120,7 +2165,7 @@ resolve_my_address(int warn_severity, const or_options_t *options, explicit_ip = 0; /* it's implicit */ explicit_hostname = 0; /* it's implicit */ - if (gethostname(hostname, sizeof(hostname)) < 0) { + if (tor_gethostname(hostname, sizeof(hostname)) < 0) { log_fn(warn_severity, LD_NET,"Error obtaining local hostname"); return -1; } @@ -2597,20 +2642,24 @@ options_validate(or_options_t *old_options, or_options_t *options, if (!strcasecmp(options->TransProxyType, "default")) { options->TransProxyType_parsed = TPT_DEFAULT; } else if (!strcasecmp(options->TransProxyType, "pf-divert")) { -#ifndef __OpenBSD__ - REJECT("pf-divert is a OpenBSD-specific feature."); +#if !defined(__OpenBSD__) && !defined( DARWIN ) + /* Later versions of OS X have pf */ + REJECT("pf-divert is a OpenBSD-specific " + "and OS X/Darwin-specific feature."); #else options->TransProxyType_parsed = TPT_PF_DIVERT; #endif } else if (!strcasecmp(options->TransProxyType, "tproxy")) { -#ifndef __linux__ +#if !defined(__linux__) REJECT("TPROXY is a Linux-specific feature."); #else options->TransProxyType_parsed = TPT_TPROXY; #endif } else if (!strcasecmp(options->TransProxyType, "ipfw")) { -#ifndef __FreeBSD__ - REJECT("ipfw is a FreeBSD-specific feature."); +#if !defined(__FreeBSD__) && !defined( DARWIN ) + /* Earlier versions of OS X have ipfw */ + REJECT("ipfw is a FreeBSD-specific" + "and OS X/Darwin-specific feature."); #else options->TransProxyType_parsed = TPT_IPFW; #endif @@ -2862,6 +2911,7 @@ options_validate(or_options_t *old_options, or_options_t *options, options->MaxMemInQueues = compute_real_max_mem_in_queues(options->MaxMemInQueues_raw, server_mode(options)); + options->MaxMemInQueues_low_threshold = (options->MaxMemInQueues / 4) * 3; options->AllowInvalid_ = 0; @@ -3397,19 +3447,68 @@ options_validate(or_options_t *old_options, or_options_t *options, if (options->V3AuthVoteDelay + options->V3AuthDistDelay >= options->V3AuthVotingInterval/2) { - REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than half " - "V3AuthVotingInterval"); + /* + This doesn't work, but it seems like it should: + what code is preventing the interval being less than twice the lead-up? + if (options->TestingTorNetwork) { + if (options->V3AuthVoteDelay + options->V3AuthDistDelay >= + options->V3AuthVotingInterval) { + REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than " + "V3AuthVotingInterval"); + } else { + COMPLAIN("V3AuthVoteDelay plus V3AuthDistDelay is more than half " + "V3AuthVotingInterval. This may lead to " + "consensus instability, particularly if clocks drift."); + } + } else { + */ + REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than half " + "V3AuthVotingInterval"); + /* + } + */ + } + + if (options->V3AuthVoteDelay < MIN_VOTE_SECONDS) { + if (options->TestingTorNetwork) { + if (options->V3AuthVoteDelay < MIN_VOTE_SECONDS_TESTING) { + REJECT("V3AuthVoteDelay is way too low."); + } else { + COMPLAIN("V3AuthVoteDelay is very low. " + "This may lead to failure to vote for a consensus."); + } + } else { + REJECT("V3AuthVoteDelay is way too low."); + } + } + + if (options->V3AuthDistDelay < MIN_DIST_SECONDS) { + if (options->TestingTorNetwork) { + if (options->V3AuthDistDelay < MIN_DIST_SECONDS_TESTING) { + REJECT("V3AuthDistDelay is way too low."); + } else { + COMPLAIN("V3AuthDistDelay is very low. " + "This may lead to missing votes in a consensus."); + } + } else { + REJECT("V3AuthDistDelay is way too low."); + } } - if (options->V3AuthVoteDelay < MIN_VOTE_SECONDS) - REJECT("V3AuthVoteDelay is way too low."); - if (options->V3AuthDistDelay < MIN_DIST_SECONDS) - REJECT("V3AuthDistDelay is way too low."); if (options->V3AuthNIntervalsValid < 2) REJECT("V3AuthNIntervalsValid must be at least 2."); if (options->V3AuthVotingInterval < MIN_VOTE_INTERVAL) { - REJECT("V3AuthVotingInterval is insanely low."); + if (options->TestingTorNetwork) { + if (options->V3AuthVotingInterval < MIN_VOTE_INTERVAL_TESTING) { + REJECT("V3AuthVotingInterval is insanely low."); + } else { + COMPLAIN("V3AuthVotingInterval is very low. " + "This may lead to failure to synchronise for a consensus."); + } + } else { + REJECT("V3AuthVotingInterval is insanely low."); + } } else if (options->V3AuthVotingInterval > 24*60*60) { REJECT("V3AuthVotingInterval is insanely high."); } else if (((24*60*60) % options->V3AuthVotingInterval) != 0) { @@ -3431,15 +3530,6 @@ options_validate(or_options_t *old_options, or_options_t *options, AF_INET6, 1, msg)<0) return -1; - if (options->AutomapHostsSuffixes) { - SMARTLIST_FOREACH(options->AutomapHostsSuffixes, char *, suf, - { - size_t len = strlen(suf); - if (len && suf[len-1] == '.') - suf[len-1] = '\0'; - }); - } - if (options->TestingTorNetwork && !(options->DirAuthorities || (options->AlternateDirAuthority && @@ -3484,26 +3574,27 @@ options_validate(or_options_t *old_options, or_options_t *options, CHECK_DEFAULT(TestingCertMaxDownloadTries); #undef CHECK_DEFAULT - if (options->TestingV3AuthInitialVotingInterval < MIN_VOTE_INTERVAL) { + if (options->TestingV3AuthInitialVotingInterval + < MIN_VOTE_INTERVAL_TESTING_INITIAL) { REJECT("TestingV3AuthInitialVotingInterval is insanely low."); } else if (((30*60) % options->TestingV3AuthInitialVotingInterval) != 0) { REJECT("TestingV3AuthInitialVotingInterval does not divide evenly into " "30 minutes."); } - if (options->TestingV3AuthInitialVoteDelay < MIN_VOTE_SECONDS) { + if (options->TestingV3AuthInitialVoteDelay < MIN_VOTE_SECONDS_TESTING) { REJECT("TestingV3AuthInitialVoteDelay is way too low."); } - if (options->TestingV3AuthInitialDistDelay < MIN_DIST_SECONDS) { + if (options->TestingV3AuthInitialDistDelay < MIN_DIST_SECONDS_TESTING) { REJECT("TestingV3AuthInitialDistDelay is way too low."); } if (options->TestingV3AuthInitialVoteDelay + options->TestingV3AuthInitialDistDelay >= - options->TestingV3AuthInitialVotingInterval/2) { + options->TestingV3AuthInitialVotingInterval) { REJECT("TestingV3AuthInitialVoteDelay plus TestingV3AuthInitialDistDelay " - "must be less than half TestingV3AuthInitialVotingInterval"); + "must be less than TestingV3AuthInitialVotingInterval"); } if (options->TestingV3AuthVotingStartOffset > @@ -3511,6 +3602,8 @@ options_validate(or_options_t *old_options, or_options_t *options, options->V3AuthVotingInterval)) { REJECT("TestingV3AuthVotingStartOffset is higher than the voting " "interval."); + } else if (options->TestingV3AuthVotingStartOffset < 0) { + REJECT("TestingV3AuthVotingStartOffset must be non-negative."); } if (options->TestingAuthDirTimeToLearnReachability < 0) { @@ -3831,6 +3924,7 @@ options_transition_affects_descriptor(const or_options_t *old_options, !opt_streq(old_options->Nickname,new_options->Nickname) || !opt_streq(old_options->Address,new_options->Address) || !config_lines_eq(old_options->ExitPolicy,new_options->ExitPolicy) || + old_options->ExitRelay != new_options->ExitRelay || old_options->ExitPolicyRejectPrivate != new_options->ExitPolicyRejectPrivate || old_options->IPv6Exit != new_options->IPv6Exit || diff --git a/src/or/config.h b/src/or/config.h index 133b472eb2..6bd3eb5734 100644 --- a/src/or/config.h +++ b/src/or/config.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/confparse.c b/src/or/confparse.c index 8ee985c92a..ac21df25cb 100644 --- a/src/or/confparse.c +++ b/src/or/confparse.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "or.h" diff --git a/src/or/confparse.h b/src/or/confparse.h index 3712924ac7..83c0f75b52 100644 --- a/src/or/confparse.h +++ b/src/or/confparse.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_CONFPARSE_H diff --git a/src/or/connection.c b/src/or/connection.c index ce3fda89c1..c67cc3c111 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -544,8 +544,7 @@ connection_free_(connection_t *conn) or_conn, TLS_CHAN_TO_BASE(or_conn->chan), U64_PRINTF_ARG( TLS_CHAN_TO_BASE(or_conn->chan)->global_identifier)); - if (!(TLS_CHAN_TO_BASE(or_conn->chan)->state == CHANNEL_STATE_CLOSED || - TLS_CHAN_TO_BASE(or_conn->chan)->state == CHANNEL_STATE_ERROR)) { + if (!CHANNEL_FINISHED(TLS_CHAN_TO_BASE(or_conn->chan))) { channel_close_for_error(TLS_CHAN_TO_BASE(or_conn->chan)); } @@ -575,8 +574,10 @@ connection_free_(connection_t *conn) tor_free(control_conn->incoming_cmd); } - tor_free(conn->read_event); /* Probably already freed by connection_free. */ - tor_free(conn->write_event); /* Probably already freed by connection_free. */ + /* Probably already freed by connection_free. */ + tor_event_free(conn->read_event); + tor_event_free(conn->write_event); + conn->read_event = conn->write_event = NULL; IF_HAS_BUFFEREVENT(conn, { /* This was a workaround to handle bugs in some old versions of libevent * where callbacks can occur after calling bufferevent_free(). Setting diff --git a/src/or/connection.h b/src/or/connection.h index 7cdfd3e253..ce6ed284c1 100644 --- a/src/or/connection.h +++ b/src/or/connection.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 9859cc26ea..d8f397bd90 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -46,6 +46,19 @@ #ifdef HAVE_LINUX_NETFILTER_IPV4_H #include <linux/netfilter_ipv4.h> #define TRANS_NETFILTER +#define TRANS_NETFILTER_IPV4 +#endif + +#ifdef HAVE_LINUX_IF_H +#include <linux/if.h> +#endif + +#ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H +#include <linux/netfilter_ipv6/ip6_tables.h> +#if defined(IP6T_SO_ORIGINAL_DST) +#define TRANS_NETFILTER +#define TRANS_NETFILTER_IPV6 +#endif #endif #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H) @@ -745,14 +758,6 @@ connection_ap_fail_onehop(const char *failed_digest, tor_addr_t addr; if (!build_state || !build_state->chosen_exit || !entry_conn->socks_request) { - /* clang thinks that an array midway through a structure - * will never have a NULL address, under either: - * -Wpointer-bool-conversion if using !, or - * -Wtautological-pointer-compare if using == or != - * It's probably right (unless pointers overflow and wrap), - * so we just skip this check - || !entry_conn->socks_request->address - */ continue; } if (tor_addr_parse(&addr, entry_conn->socks_request->address)<0 || @@ -1409,10 +1414,29 @@ destination_from_socket(entry_connection_t *conn, socks_request_t *req) struct sockaddr_storage orig_dst; socklen_t orig_dst_len = sizeof(orig_dst); tor_addr_t addr; + int rv; #ifdef TRANS_NETFILTER - if (getsockopt(ENTRY_TO_CONN(conn)->s, SOL_IP, SO_ORIGINAL_DST, - (struct sockaddr*)&orig_dst, &orig_dst_len) < 0) { + switch (ENTRY_TO_CONN(conn)->socket_family) { +#ifdef TRANS_NETFILTER_IPV4 + case AF_INET: + rv = getsockopt(ENTRY_TO_CONN(conn)->s, SOL_IP, SO_ORIGINAL_DST, + (struct sockaddr*)&orig_dst, &orig_dst_len); + break; +#endif +#ifdef TRANS_NETFILTER_IPV6 + case AF_INET6: + rv = getsockopt(ENTRY_TO_CONN(conn)->s, SOL_IPV6, IP6T_SO_ORIGINAL_DST, + (struct sockaddr*)&orig_dst, &orig_dst_len); + break; +#endif + default: + log_warn(LD_BUG, + "Received transparent data from an unsuported socket family %d", + ENTRY_TO_CONN(conn)->socket_family); + return -1; + } + if (rv < 0) { int e = tor_socket_errno(ENTRY_TO_CONN(conn)->s); log_warn(LD_NET, "getsockopt() failed: %s", tor_socket_strerror(e)); return -1; @@ -2589,12 +2613,23 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ) if (rend_service_set_connection_addr_port(n_stream, origin_circ) < 0) { log_info(LD_REND,"Didn't find rendezvous service (port %d)", n_stream->base_.port); + /* Send back reason DONE because we want to make hidden service port + * scanning harder thus instead of returning that the exit policy + * didn't match, which makes it obvious that the port is closed, + * return DONE and kill the circuit. That way, a user (malicious or + * not) needs one circuit per bad port unless it matches the policy of + * the hidden service. */ relay_send_end_cell_from_edge(rh.stream_id, circ, - END_STREAM_REASON_EXITPOLICY, + END_STREAM_REASON_DONE, origin_circ->cpath->prev); connection_free(TO_CONN(n_stream)); tor_free(address); - return 0; + + /* Drop the circuit here since it might be someone deliberately + * scanning the hidden service ports. Note that this mitigates port + * scanning by adding more work on the attacker side to successfully + * scan but does not fully solve it. */ + return END_CIRC_AT_ORIGIN; } assert_circuit_ok(circ); log_debug(LD_REND,"Finished assigning addr/port"); diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h index 5071086a41..e6adad91d8 100644 --- a/src/or/connection_edge.h +++ b/src/or/connection_edge.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/connection_or.c b/src/or/connection_or.c index f228450723..85462d899d 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -1149,9 +1149,7 @@ connection_or_notify_error(or_connection_t *conn, if (conn->chan) { chan = TLS_CHAN_TO_BASE(conn->chan); /* Don't transition if we're already in closing, closed or error */ - if (!(chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR)) { + if (!CHANNEL_CONDEMNED(chan)) { channel_close_for_error(chan); } } @@ -1310,9 +1308,7 @@ connection_or_close_normally(or_connection_t *orconn, int flush) if (orconn->chan) { chan = TLS_CHAN_TO_BASE(orconn->chan); /* Don't transition if we're already in closing, closed or error */ - if (!(chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR)) { + if (!CHANNEL_CONDEMNED(chan)) { channel_close_from_lower_layer(chan); } } @@ -1333,9 +1329,7 @@ connection_or_close_for_error(or_connection_t *orconn, int flush) if (orconn->chan) { chan = TLS_CHAN_TO_BASE(orconn->chan); /* Don't transition if we're already in closing, closed or error */ - if (!(chan->state == CHANNEL_STATE_CLOSING || - chan->state == CHANNEL_STATE_CLOSED || - chan->state == CHANNEL_STATE_ERROR)) { + if (!CHANNEL_CONDEMNED(chan)) { channel_close_for_error(chan); } } diff --git a/src/or/connection_or.h b/src/or/connection_or.h index b82896e26d..fc261c6bac 100644 --- a/src/or/connection_or.h +++ b/src/or/connection_or.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/control.c b/src/or/control.c index dc67588d6a..9ff71c9541 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -1438,6 +1438,8 @@ getinfo_helper_misc(control_connection_t *conn, const char *question, (void) conn; if (!strcmp(question, "version")) { *answer = tor_strdup(get_version()); + } else if (!strcmp(question, "bw-event-cache")) { + *answer = get_bw_samples(); } else if (!strcmp(question, "config-file")) { *answer = tor_strdup(get_torrc_fname(0)); } else if (!strcmp(question, "config-defaults-file")) { @@ -2113,6 +2115,7 @@ typedef struct getinfo_item_t { * to answer them. */ static const getinfo_item_t getinfo_items[] = { ITEM("version", misc, "The current version of Tor."), + ITEM("bw-event-cache", misc, "Cached BW events for a short interval."), ITEM("config-file", misc, "Current location of the \"torrc\" file."), ITEM("config-defaults-file", misc, "Current location of the defaults file."), ITEM("config-text", misc, @@ -2465,6 +2468,14 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len, goto done; } + if (smartlist_len(args) < 2) { + connection_printf_to_buf(conn, + "512 syntax error: not enough arguments.\r\n"); + SMARTLIST_FOREACH(args, char *, cp, tor_free(cp)); + smartlist_free(args); + goto done; + } + smartlist_split_string(router_nicknames, smartlist_get(args,1), ",", 0, 0); SMARTLIST_FOREACH(args, char *, cp, tor_free(cp)); @@ -4147,11 +4158,29 @@ control_event_tb_empty(const char *bucket, uint32_t read_empty_time, return 0; } +/* about 5 minutes worth. */ +#define N_BW_EVENTS_TO_CACHE 300 +/* Index into cached_bw_events to next write. */ +static int next_measurement_idx = 0; +/* number of entries set in n_measurements */ +static int n_measurements = 0; +static struct cached_bw_event_s { + uint32_t n_read; + uint32_t n_written; +} cached_bw_events[N_BW_EVENTS_TO_CACHE]; + /** A second or more has elapsed: tell any interested control * connections how much bandwidth we used. */ int control_event_bandwidth_used(uint32_t n_read, uint32_t n_written) { + cached_bw_events[next_measurement_idx].n_read = n_read; + cached_bw_events[next_measurement_idx].n_written = n_written; + if (++next_measurement_idx == N_BW_EVENTS_TO_CACHE) + next_measurement_idx = 0; + if (n_measurements < N_BW_EVENTS_TO_CACHE) + ++n_measurements; + if (EVENT_IS_INTERESTING(EVENT_BANDWIDTH_USED)) { send_control_event(EVENT_BANDWIDTH_USED, ALL_FORMATS, "650 BW %lu %lu\r\n", @@ -4162,6 +4191,35 @@ control_event_bandwidth_used(uint32_t n_read, uint32_t n_written) return 0; } +STATIC char * +get_bw_samples(void) +{ + int i; + int idx = (next_measurement_idx + N_BW_EVENTS_TO_CACHE - n_measurements) + % N_BW_EVENTS_TO_CACHE; + tor_assert(0 <= idx && idx < N_BW_EVENTS_TO_CACHE); + + smartlist_t *elements = smartlist_new(); + + for (i = 0; i < n_measurements; ++i) { + tor_assert(0 <= idx && idx < N_BW_EVENTS_TO_CACHE); + const struct cached_bw_event_s *bwe = &cached_bw_events[idx]; + + smartlist_add_asprintf(elements, "%u,%u", + (unsigned)bwe->n_read, + (unsigned)bwe->n_written); + + idx = (idx + 1) % N_BW_EVENTS_TO_CACHE; + } + + char *result = smartlist_join_strings(elements, " ", 0, NULL); + + SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp)); + smartlist_free(elements); + + return result; +} + /** Called when we are sending a log message to the controllers: suspend * sending further log messages to the controllers until we're done. Used by * CONN_LOG_PROTECT. */ @@ -4807,23 +4865,43 @@ bootstrap_status_to_string(bootstrap_status_t s, const char **tag, break; case BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS: *tag = "requesting_descriptors"; - *summary = "Asking for relay descriptors"; + /* XXXX this appears to incorrectly report internal on most loads */ + *summary = router_have_consensus_path() == CONSENSUS_PATH_INTERNAL ? + "Asking for relay descriptors for internal paths" : + "Asking for relay descriptors"; break; + /* If we're sure there are no exits in the consensus, + * inform the controller by adding "internal" + * to the status summaries. + * (We only check this while loading descriptors, + * so we may not know in the earlier stages.) + * But if there are exits, we can't be sure whether + * we're creating internal or exit paths/circuits. + * XXXX Or should be use different tags or statuses + * for internal and exit/all? */ case BOOTSTRAP_STATUS_LOADING_DESCRIPTORS: *tag = "loading_descriptors"; - *summary = "Loading relay descriptors"; + *summary = router_have_consensus_path() == CONSENSUS_PATH_INTERNAL ? + "Loading relay descriptors for internal paths" : + "Loading relay descriptors"; break; case BOOTSTRAP_STATUS_CONN_OR: *tag = "conn_or"; - *summary = "Connecting to the Tor network"; + *summary = router_have_consensus_path() == CONSENSUS_PATH_INTERNAL ? + "Connecting to the Tor network internally" : + "Connecting to the Tor network"; break; case BOOTSTRAP_STATUS_HANDSHAKE_OR: *tag = "handshake_or"; - *summary = "Finishing handshake with first hop"; + *summary = router_have_consensus_path() == CONSENSUS_PATH_INTERNAL ? + "Finishing handshake with first hop of internal circuit" : + "Finishing handshake with first hop"; break; case BOOTSTRAP_STATUS_CIRCUIT_CREATE: *tag = "circuit_create"; - *summary = "Establishing a Tor circuit"; + *summary = router_have_consensus_path() == CONSENSUS_PATH_INTERNAL ? + "Establishing an internal Tor circuit" : + "Establishing a Tor circuit"; break; case BOOTSTRAP_STATUS_DONE: *tag = "done"; diff --git a/src/or/control.h b/src/or/control.h index f62084b931..8c9f7bbdc9 100644 --- a/src/or/control.h +++ b/src/or/control.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -203,6 +203,7 @@ void append_cell_stats_by_command(smartlist_t *event_parts, const uint64_t *number_to_include); void format_cell_stats(char **event_string, circuit_t *circ, cell_stats_t *cell_stats); +STATIC char *get_bw_samples(void); #endif #endif diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c index 568d9e42d8..340fbec620 100644 --- a/src/or/cpuworker.c +++ b/src/or/cpuworker.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/cpuworker.h b/src/or/cpuworker.h index f7f1d8346b..2a2b37a975 100644 --- a/src/or/cpuworker.h +++ b/src/or/cpuworker.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/directory.c b/src/or/directory.c index cca4b54e24..7b4020080c 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "or.h" @@ -20,6 +20,7 @@ #include "networkstatus.h" #include "nodelist.h" #include "policies.h" +#include "relay.h" #include "rendclient.h" #include "rendcommon.h" #include "rephist.h" @@ -433,18 +434,33 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose, if (resource) flav = networkstatus_parse_flavor_name(resource); + /* DEFAULT_IF_MODIFIED_SINCE_DELAY is 1/20 of the default consensus + * period of 1 hour. + */ +#define DEFAULT_IF_MODIFIED_SINCE_DELAY (180) if (flav != -1) { /* IF we have a parsed consensus of this type, we can do an * if-modified-time based on it. */ v = networkstatus_get_latest_consensus_by_flavor(flav); - if (v) - if_modified_since = v->valid_after + 180; + if (v) { + /* In networks with particularly short V3AuthVotingIntervals, + * ask for the consensus if it's been modified since half the + * V3AuthVotingInterval of the most recent consensus. */ + time_t ims_delay = DEFAULT_IF_MODIFIED_SINCE_DELAY; + if (v->fresh_until > v->valid_after + && ims_delay > (v->fresh_until - v->valid_after)/2) { + ims_delay = (v->fresh_until - v->valid_after)/2; + } + if_modified_since = v->valid_after + ims_delay; + } } else { /* Otherwise it might be a consensus we don't parse, but which we * do cache. Look at the cached copy, perhaps. */ cached_dir_t *cd = dirserv_get_consensus(resource); + /* We have no method of determining the voting interval from an + * unparsed consensus, so we use the default. */ if (cd) - if_modified_since = cd->published + 180; + if_modified_since = cd->published + DEFAULT_IF_MODIFIED_SINCE_DELAY; } } @@ -2258,6 +2274,7 @@ write_http_status_line(dir_connection_t *conn, int status, log_warn(LD_BUG,"status line too long."); return; } + log_debug(LD_DIRSERV,"Wrote status 'HTTP/1.0 %d %s'", status, reason_phrase); connection_write_to_buf(buf, strlen(buf), TO_CONN(conn)); } @@ -2523,6 +2540,24 @@ client_likes_consensus(networkstatus_t *v, const char *want_url) return (have >= need_at_least); } +/** Return the compression level we should use for sending a compressed + * response of size <b>n_bytes</b>. */ +static zlib_compression_level_t +choose_compression_level(ssize_t n_bytes) +{ + if (! have_been_under_memory_pressure()) { + return HIGH_COMPRESSION; /* we have plenty of RAM. */ + } else if (n_bytes < 0) { + return HIGH_COMPRESSION; /* unknown; might be big. */ + } else if (n_bytes < 1024) { + return LOW_COMPRESSION; + } else if (n_bytes < 2048) { + return MEDIUM_COMPRESSION; + } else { + return HIGH_COMPRESSION; + } +} + /** Helper function: called when a dirserver gets a complete HTTP GET * request. Look for a request for a directory or for a rendezvous * service descriptor. On finding one, write a response into @@ -2554,8 +2589,11 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, if ((header = http_get_header(headers, "If-Modified-Since: "))) { struct tm tm; if (parse_http_time(header, &tm) == 0) { - if (tor_timegm(&tm, &if_modified_since)<0) + if (tor_timegm(&tm, &if_modified_since)<0) { if_modified_since = 0; + } else { + log_debug(LD_DIRSERV, "If-Modified-Since is '%s'.", escaped(header)); + } } /* The correct behavior on a malformed If-Modified-Since header is to * act as if no If-Modified-Since header had been given. */ @@ -2705,7 +2743,7 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, smartlist_len(dir_fps) == 1 ? lifetime : 0); conn->fingerprint_stack = dir_fps; if (! compressed) - conn->zlib_state = tor_zlib_new(0, ZLIB_METHOD); + conn->zlib_state = tor_zlib_new(0, ZLIB_METHOD, HIGH_COMPRESSION); /* Prime the connection with some data. */ conn->dir_spool_src = DIR_SPOOL_NETWORKSTATUS; @@ -2793,7 +2831,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, if (smartlist_len(items)) { if (compressed) { - conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD); + conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD, + choose_compression_level(estimated_len)); SMARTLIST_FOREACH(items, const char *, c, connection_write_to_buf_zlib(c, strlen(c), conn, 0)); connection_write_to_buf_zlib("", 0, conn, 1); @@ -2842,7 +2881,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, conn->fingerprint_stack = fps; if (compressed) - conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD); + conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD, + choose_compression_level(dlen)); connection_dirserv_flushed_some(conn); goto done; @@ -2910,7 +2950,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, } write_http_response_header(conn, -1, compressed, cache_lifetime); if (compressed) - conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD); + conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD, + choose_compression_level(dlen)); /* Prime the connection with some data. */ connection_dirserv_flushed_some(conn); } @@ -2985,7 +3026,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, write_http_response_header(conn, compressed?-1:len, compressed, 60*60); if (compressed) { - conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD); + conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD, + choose_compression_level(len)); SMARTLIST_FOREACH(certs, authority_cert_t *, c, connection_write_to_buf_zlib(c->cache_info.signed_descriptor_body, c->cache_info.signed_descriptor_len, diff --git a/src/or/directory.h b/src/or/directory.h index d78046912c..1458ad2cc7 100644 --- a/src/or/directory.h +++ b/src/or/directory.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/dirserv.c b/src/or/dirserv.c index d31bb72361..d668749c5b 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define DIRSERV_PRIVATE @@ -733,7 +733,7 @@ running_long_enough_to_decide_unreachable(void) } /** Each server needs to have passed a reachability test no more - * than this number of seconds ago, or he is listed as down in + * than this number of seconds ago, or it is listed as down in * the directory. */ #define REACHABLE_TIMEOUT (45*60) @@ -887,12 +887,26 @@ static int router_is_active(const routerinfo_t *ri, const node_t *node, time_t now) { time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH; - if (ri->cache_info.published_on < cutoff) + if (ri->cache_info.published_on < cutoff) { return 0; - if (!node->is_running || !node->is_valid || ri->is_hibernating) + } + if (!node->is_running || !node->is_valid || ri->is_hibernating) { return 0; - if (!ri->bandwidthcapacity) + } + /* Only require bandwith capacity in non-test networks, or + * if TestingTorNetwork, and TestingMinExitFlagThreshold is non-zero */ + if (!ri->bandwidthcapacity) { + if (get_options()->TestingTorNetwork) { + if (get_options()->TestingMinExitFlagThreshold > 0) { + /* If we're in a TestingTorNetwork, and TestingMinExitFlagThreshold is, + * then require bandwidthcapacity */ + return 0; + } + } else { + /* If we're not in a TestingTorNetwork, then require bandwidthcapacity */ return 0; + } + } return 1; } @@ -1037,7 +1051,7 @@ directory_fetches_dir_info_later(const or_options_t *options) } /** Return true iff we want to fetch and keep certificates for authorities - * that we don't acknowledge as aurthorities ourself. + * that we don't acknowledge as authorities ourself. */ int directory_caches_unknown_auth_certs(const or_options_t *options) @@ -1498,7 +1512,7 @@ dirserv_compute_performance_thresholds(routerlist_t *rl, (unsigned long)guard_tk, (unsigned long)guard_bandwidth_including_exits_kb, (unsigned long)guard_bandwidth_excluding_exits_kb, - enough_mtbf_info ? "" : " don't "); + enough_mtbf_info ? "" : " don't"); tor_free(uptimes); tor_free(mtbfs); @@ -2246,7 +2260,7 @@ int dirserv_read_measured_bandwidths(const char *from_file, smartlist_t *routerstatuses) { - char line[256]; + char line[512]; FILE *fp = tor_fopen_cloexec(from_file, "r"); int applied_lines = 0; time_t file_time, now; @@ -3182,7 +3196,7 @@ connection_dirserv_add_networkstatus_bytes_to_outbuf(dir_connection_t *conn) if (uncompressing && ! conn->zlib_state && conn->fingerprint_stack && smartlist_len(conn->fingerprint_stack)) { - conn->zlib_state = tor_zlib_new(0, ZLIB_METHOD); + conn->zlib_state = tor_zlib_new(0, ZLIB_METHOD, HIGH_COMPRESSION); } } if (r) return r; diff --git a/src/or/dirserv.h b/src/or/dirserv.h index 57cec3401f..d4ce54260c 100644 --- a/src/or/dirserv.h +++ b/src/or/dirserv.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/dirvote.c b/src/or/dirvote.c index 39505a4f9e..f0dcc88070 100644 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define DIRVOTE_PRIVATE @@ -1107,8 +1107,12 @@ networkstatus_compute_consensus(smartlist_t *votes, vote_seconds = median_int(votesec_list, n_votes); dist_seconds = median_int(distsec_list, n_votes); - tor_assert(valid_after+MIN_VOTE_INTERVAL <= fresh_until); - tor_assert(fresh_until+MIN_VOTE_INTERVAL <= valid_until); + tor_assert(valid_after + + (get_options()->TestingTorNetwork ? + MIN_VOTE_INTERVAL_TESTING : MIN_VOTE_INTERVAL) <= fresh_until); + tor_assert(fresh_until + + (get_options()->TestingTorNetwork ? + MIN_VOTE_INTERVAL_TESTING : MIN_VOTE_INTERVAL) <= valid_until); tor_assert(vote_seconds >= MIN_VOTE_SECONDS); tor_assert(dist_seconds >= MIN_DIST_SECONDS); @@ -2706,7 +2710,7 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out) goto discard; } else if (v->vote->published < vote->published) { log_notice(LD_DIR, "Replacing an older pending vote from this " - "directory."); + "directory (%s)", vi->address); cached_dir_decref(v->vote_body); networkstatus_vote_free(v->vote); v->vote_body = new_cached_dir(tor_strndup(vote_body, diff --git a/src/or/dirvote.h b/src/or/dirvote.h index 5d44ba4320..8908336fa1 100644 --- a/src/or/dirvote.h +++ b/src/or/dirvote.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -14,12 +14,42 @@ #include "testsupport.h" +/* + * Ideally, assuming synced clocks, we should only need 1 second for each of: + * - Vote + * - Distribute + * - Consensus Publication + * As we can gather descriptors continuously. + * (Could we even go as far as publishing the previous consensus, + * in the same second that we vote for the next one?) + * But we're not there yet: these are the lowest working values at this time. + */ + /** Lowest allowable value for VoteSeconds. */ #define MIN_VOTE_SECONDS 2 +/** Lowest allowable value for VoteSeconds when TestingTorNetwork is 1 */ +#define MIN_VOTE_SECONDS_TESTING 2 + /** Lowest allowable value for DistSeconds. */ #define MIN_DIST_SECONDS 2 -/** Smallest allowable voting interval. */ +/** Lowest allowable value for DistSeconds when TestingTorNetwork is 1 */ +#define MIN_DIST_SECONDS_TESTING 2 + +/** Lowest allowable voting interval. */ #define MIN_VOTE_INTERVAL 300 +/** Lowest allowable voting interval when TestingTorNetwork is 1: + * Voting Interval can be: + * 10, 12, 15, 18, 20, 24, 25, 30, 36, 40, 45, 50, 60, ... + * Testing Initial Voting Interval can be: + * 5, 6, 8, 9, or any of the possible values for Voting Interval, + * as they both need to evenly divide 30 minutes. + * If clock desynchronisation is an issue, use an interval of at least: + * 18 * drift in seconds, to allow for a clock slop factor */ +#define MIN_VOTE_INTERVAL_TESTING \ + (((MIN_VOTE_SECONDS_TESTING)+(MIN_DIST_SECONDS_TESTING)+1)*2) + +#define MIN_VOTE_INTERVAL_TESTING_INITIAL \ + ((MIN_VOTE_SECONDS_TESTING)+(MIN_DIST_SECONDS_TESTING)+1) /** The lowest consensus method that we currently support. */ #define MIN_SUPPORTED_CONSENSUS_METHOD 13 diff --git a/src/or/dns.c b/src/or/dns.c index 7bf64dc4ff..129ca395b6 100644 --- a/src/or/dns.c +++ b/src/or/dns.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/dns.h b/src/or/dns.h index cabbb9ba09..b13ab0f890 100644 --- a/src/or/dns.h +++ b/src/or/dns.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/dnsserv.c b/src/or/dnsserv.c index 3d63874a65..7b5068199b 100644 --- a/src/or/dnsserv.c +++ b/src/or/dnsserv.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2014, The Tor Project, Inc. */ +/* Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/dnsserv.h b/src/or/dnsserv.h index c8074dfaa0..09ad5d7759 100644 --- a/src/or/dnsserv.h +++ b/src/or/dnsserv.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index b18aabe1f4..968a993999 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -1319,7 +1319,7 @@ entry_guards_parse_state(or_state_t *state, int set, char **msg) "EntryGuardDownSince/UnlistedSince without EntryGuard"); break; } - if (parse_iso_time(line->value, &when)<0) { + if (parse_iso_time_(line->value, &when, 0)<0) { *msg = tor_strdup("Unable to parse entry nodes: " "Bad time in EntryGuardDownSince/UnlistedSince"); break; diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h index 5416398430..7f3a4fb29c 100644 --- a/src/or/entrynodes.h +++ b/src/or/entrynodes.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/eventdns_tor.h b/src/or/eventdns_tor.h index b135a534fc..9d51f0960e 100644 --- a/src/or/eventdns_tor.h +++ b/src/or/eventdns_tor.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2014, The Tor Project, Inc. */ +/* Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_EVENTDNS_TOR_H diff --git a/src/or/ext_orport.c b/src/or/ext_orport.c index 9b550ee90e..e8c8aa60a4 100644 --- a/src/or/ext_orport.c +++ b/src/or/ext_orport.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012, The Tor Project, Inc. */ +/* Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/ext_orport.h b/src/or/ext_orport.h index 277bbfdbcf..8b2542f937 100644 --- a/src/or/ext_orport.h +++ b/src/or/ext_orport.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef EXT_ORPORT_H diff --git a/src/or/fp_pair.c b/src/or/fp_pair.c index fc7d107ba7..42bebcd847 100644 --- a/src/or/fp_pair.c +++ b/src/or/fp_pair.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Tor Project, Inc. */ +/* Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "or.h" diff --git a/src/or/fp_pair.h b/src/or/fp_pair.h index 67b94fb6b4..0830ab1f36 100644 --- a/src/or/fp_pair.h +++ b/src/or/fp_pair.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Tor Project, Inc. */ +/* Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/geoip.c b/src/or/geoip.c index c02343d489..5564b72a04 100644 --- a/src/or/geoip.c +++ b/src/or/geoip.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2014, The Tor Project, Inc. */ +/* Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/geoip.h b/src/or/geoip.h index cec19ea564..683ec073b2 100644 --- a/src/or/geoip.h +++ b/src/or/geoip.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/hibernate.c b/src/or/hibernate.c index 4f0660c2dc..356e11f6ec 100644 --- a/src/or/hibernate.c +++ b/src/or/hibernate.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/hibernate.h b/src/or/hibernate.h index 0616e11c57..b9e619c5ad 100644 --- a/src/or/hibernate.h +++ b/src/or/hibernate.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/include.am b/src/or/include.am index 643f7ce001..b44e1099dc 100644 --- a/src/or/include.am +++ b/src/or/include.am @@ -111,7 +111,7 @@ src_or_tor_LDADD = src/or/libtor.a src/common/libor.a \ src/common/libor-crypto.a $(LIBDONNA) \ src/common/libor-event.a \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \ - @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ + @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ @TOR_SYSTEMD_LIBS@ if COVERAGE_ENABLED src_or_tor_cov_SOURCES = src/or/tor_main.c @@ -122,7 +122,10 @@ src_or_tor_cov_LDADD = src/or/libtor-testing.a src/common/libor-testing.a \ src/common/libor-crypto-testing.a $(LIBDONNA) \ src/common/libor-event-testing.a \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \ - @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ + @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ @TOR_SYSTEMD_LIBS@ +TESTING_TOR_BINARY = ./src/or/tor-cov +else +TESTING_TOR_BINARY = ./src/or/tor endif ORHEADERS = \ diff --git a/src/or/main.c b/src/or/main.c index e78e9bf6a6..9e5a916b16 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -75,6 +75,16 @@ #include <event2/bufferevent.h> #endif +#ifdef HAVE_SYSTEMD +# if defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) +/* Systemd's use of gcc's __INCLUDE_LEVEL__ extension macro appears to confuse + * Coverity. Here's a kludge to unconfuse it. + */ +# define __INCLUDE_LEVEL__ 2 +# endif +#include <systemd/sd-daemon.h> +#endif + void evdns_shutdown(int); /********* PROTOTYPES **********/ @@ -1384,6 +1394,11 @@ run_scheduled_events(time_t now) if (next_write && next_write < next_time_to_write_stats_files) next_time_to_write_stats_files = next_write; } + if (options->HiddenServiceStatistics) { + time_t next_write = rep_hist_hs_stats_write(time_to_write_stats_files); + if (next_write && next_write < next_time_to_write_stats_files) + next_time_to_write_stats_files = next_write; + } if (options->ExitPortStatistics) { time_t next_write = rep_hist_exit_stats_write(time_to_write_stats_files); if (next_write && next_write < next_time_to_write_stats_files) @@ -1754,6 +1769,17 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg) current_second = now; /* remember which second it is, for next time */ } +#ifdef HAVE_SYSTEMD_209 +static periodic_timer_t *systemd_watchdog_timer = NULL; + +/** Libevent callback: invoked to reset systemd watchdog. */ +static void +systemd_watchdog_callback(periodic_timer_t *timer, void *arg) +{ + sd_notify(1, "WATCHDOG=1"); +} +#endif + #ifndef USE_BUFFEREVENTS /** Timer: used to invoke refill_callback(). */ static periodic_timer_t *refill_timer = NULL; @@ -2022,6 +2048,28 @@ do_main_loop(void) tor_assert(second_timer); } +#ifdef HAVE_SYSTEMD_209 + uint64_t watchdog_delay; + /* set up systemd watchdog notification. */ + if (sd_watchdog_enabled(1, &watchdog_delay) > 0) { + if (! systemd_watchdog_timer) { + struct timeval watchdog; + /* The manager will "act on" us if we don't send them a notification + * every 'watchdog_delay' microseconds. So, send notifications twice + * that often. */ + watchdog_delay /= 2; + watchdog.tv_sec = watchdog_delay / 1000000; + watchdog.tv_usec = watchdog_delay % 1000000; + + systemd_watchdog_timer = periodic_timer_new(tor_libevent_get_base(), + &watchdog, + systemd_watchdog_callback, + NULL); + tor_assert(systemd_watchdog_timer); + } + } +#endif + #ifndef USE_BUFFEREVENTS if (!refill_timer) { struct timeval refill_interval; @@ -2038,6 +2086,11 @@ do_main_loop(void) } #endif +#ifdef HAVE_SYSTEMD + log_notice(LD_GENERAL, "Signaling readiness to systemd"); + sd_notify(0, "READY=1"); +#endif + for (;;) { if (nt_service_is_stopping()) return 0; diff --git a/src/or/main.h b/src/or/main.h index 7d98983100..f77b4711c5 100644 --- a/src/or/main.h +++ b/src/or/main.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/microdesc.c b/src/or/microdesc.c index 7b826008b5..0511e870d1 100644 --- a/src/or/microdesc.c +++ b/src/or/microdesc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2014, The Tor Project, Inc. */ +/* Copyright (c) 2009-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "or.h" diff --git a/src/or/microdesc.h b/src/or/microdesc.h index fdfe8922ab..08571e4bd5 100644 --- a/src/or/microdesc.h +++ b/src/or/microdesc.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index 21efdd129d..59ba1e6cb7 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -832,6 +832,10 @@ update_consensus_networkstatus_fetch_time_impl(time_t now, int flav) a crazy-fast voting interval, though, 2 minutes may be too much. */ min_sec_before_caching = interval/16; + /* make sure we always delay by at least a second before caching */ + if (min_sec_before_caching == 0) { + min_sec_before_caching = 1; + } } if (directory_fetches_dir_info_early(options)) { @@ -863,8 +867,17 @@ update_consensus_networkstatus_fetch_time_impl(time_t now, int flav) dl_interval = (c->valid_until - start) - min_sec_before_caching; } } + /* catch low dl_interval in crazy-fast networks */ if (dl_interval < 1) dl_interval = 1; + /* catch late start in crazy-fast networks */ + if (start+dl_interval >= c->valid_until) + start = c->valid_until - dl_interval - 1; + log_debug(LD_DIR, + "fresh_until: %ld start: %ld " + "dl_interval: %ld valid_until: %ld ", + (long)c->fresh_until, (long)start, dl_interval, + (long)c->valid_until); /* We must not try to replace c while it's still fresh: */ tor_assert(c->fresh_until < start); /* We must download the next one before c is invalid: */ diff --git a/src/or/networkstatus.h b/src/or/networkstatus.h index a087a79ac3..d6e9e37013 100644 --- a/src/or/networkstatus.h +++ b/src/or/networkstatus.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/nodelist.c b/src/or/nodelist.c index e0e01ec190..249c198214 100644 --- a/src/or/nodelist.c +++ b/src/or/nodelist.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "or.h" @@ -24,6 +24,23 @@ static void nodelist_drop_node(node_t *node, int remove_from_ht); static void node_free(node_t *node); + +/** count_usable_descriptors counts descriptors with these flag(s) + */ +typedef enum { + /* All descriptors regardless of flags */ + USABLE_DESCRIPTOR_ALL = 0, + /* Only descriptors with the Exit flag */ + USABLE_DESCRIPTOR_EXIT_ONLY = 1 +} usable_descriptor_t; +static void count_usable_descriptors(int *num_present, + int *num_usable, + smartlist_t *descs_out, + const networkstatus_t *consensus, + const or_options_t *options, + time_t now, + routerset_t *in_set, + usable_descriptor_t exit_only); static void update_router_have_minimum_dir_info(void); static double get_frac_paths_needed_for_circs(const or_options_t *options, const networkstatus_t *ns); @@ -1256,20 +1273,28 @@ router_set_status(const char *digest, int up) } /** True iff, the last time we checked whether we had enough directory info - * to build circuits, the answer was "yes". */ + * to build circuits, the answer was "yes". If there are no exits in the + * consensus, we act as if we have 100% of the exit directory info. */ static int have_min_dir_info = 0; + +/** Does the consensus contain nodes that can exit? */ +static consensus_path_type_t have_consensus_path = CONSENSUS_PATH_UNKNOWN; + /** True iff enough has changed since the last time we checked whether we had * enough directory info to build circuits that our old answer can no longer * be trusted. */ static int need_to_update_have_min_dir_info = 1; /** String describing what we're missing before we have enough directory * info. */ -static char dir_info_status[256] = ""; - -/** Return true iff we have enough networkstatus and router information to - * start building circuits. Right now, this means "more than half the - * networkstatus documents, and at least 1/4 of expected routers." */ -//XXX should consider whether we have enough exiting nodes here. +static char dir_info_status[512] = ""; + +/** Return true iff we have enough consensus information to + * start building circuits. Right now, this means "a consensus that's + * less than a day old, and at least 60% of router descriptors (configurable), + * weighted by bandwidth. Treat the exit fraction as 100% if there are + * no exits in the consensus." + * To obtain the final weighted bandwidth, we multiply the + * weighted bandwidth fraction for each position (guard, middle, exit). */ int router_have_minimum_dir_info(void) { @@ -1291,6 +1316,24 @@ router_have_minimum_dir_info(void) return have_min_dir_info; } +/** Set to CONSENSUS_PATH_EXIT if there is at least one exit node + * in the consensus. We update this flag in compute_frac_paths_available if + * there is at least one relay that has an Exit flag in the consensus. + * Used to avoid building exit circuits when they will almost certainly fail. + * Set to CONSENSUS_PATH_INTERNAL if there are no exits in the consensus. + * (This situation typically occurs during bootstrap of a test network.) + * Set to CONSENSUS_PATH_UNKNOWN if we have never checked, or have + * reason to believe our last known value was invalid or has expired. + * If we're in a network with TestingDirAuthVoteExit set, + * this can cause router_have_consensus_path() to be set to + * CONSENSUS_PATH_EXIT, even if there are no nodes with accept exit policies. + */ +consensus_path_type_t +router_have_consensus_path(void) +{ + return have_consensus_path; +} + /** Called when our internal view of the directory has changed. This can be * when the authorities change, networkstatuses change, the list of routerdescs * changes, or number of running routers changes. @@ -1313,20 +1356,23 @@ get_dir_info_status_string(void) /** Iterate over the servers listed in <b>consensus</b>, and count how many of * them seem like ones we'd use, and how many of <em>those</em> we have * descriptors for. Store the former in *<b>num_usable</b> and the latter in - * *<b>num_present</b>. If <b>in_set</b> is non-NULL, only consider those - * routers in <b>in_set</b>. If <b>exit_only</b> is true, only consider nodes - * with the Exit flag. If *descs_out is present, add a node_t for each - * usable descriptor to it. + * *<b>num_present</b>. + * If <b>in_set</b> is non-NULL, only consider those routers in <b>in_set</b>. + * If <b>exit_only</b> is USABLE_DESCRIPTOR_EXIT_ONLY, only consider nodes + * with the Exit flag. + * If *<b>descs_out</b> is present, add a node_t for each usable descriptor + * to it. */ static void count_usable_descriptors(int *num_present, int *num_usable, smartlist_t *descs_out, const networkstatus_t *consensus, const or_options_t *options, time_t now, - routerset_t *in_set, int exit_only) + routerset_t *in_set, + usable_descriptor_t exit_only) { const int md = (consensus->flavor == FLAV_MICRODESC); - *num_present = 0, *num_usable=0; + *num_present = 0, *num_usable = 0; SMARTLIST_FOREACH_BEGIN(consensus->routerstatus_list, routerstatus_t *, rs) { @@ -1334,7 +1380,7 @@ count_usable_descriptors(int *num_present, int *num_usable, if (!node) continue; /* This would be a bug: every entry in the consensus is * supposed to have a node. */ - if (exit_only && ! rs->is_exit) + if (exit_only == USABLE_DESCRIPTOR_EXIT_ONLY && ! rs->is_exit) continue; if (in_set && ! routerset_contains_routerstatus(in_set, rs, -1)) continue; @@ -1358,11 +1404,21 @@ count_usable_descriptors(int *num_present, int *num_usable, log_debug(LD_DIR, "%d usable, %d present (%s%s).", *num_usable, *num_present, - md ? "microdesc" : "desc", exit_only ? " exits" : "s"); + md ? "microdesc" : "desc", + exit_only == USABLE_DESCRIPTOR_EXIT_ONLY ? " exits" : "s"); } /** Return an estimate of which fraction of usable paths through the Tor - * network we have available for use. */ + * network we have available for use. + * Count how many routers seem like ones we'd use, and how many of + * <em>those</em> we have descriptors for. Store the former in + * *<b>num_usable_out</b> and the latter in *<b>num_present_out</b>. + * If **<b>status_out</b> is present, allocate a new string and print the + * available percentages of guard, middle, and exit nodes to it, noting + * whether there are exits in the consensus. + * If there are no guards in the consensus, + * we treat the exit fraction as 100%. + */ static double compute_frac_paths_available(const networkstatus_t *consensus, const or_options_t *options, time_t now, @@ -1375,14 +1431,19 @@ compute_frac_paths_available(const networkstatus_t *consensus, smartlist_t *myexits= smartlist_new(); smartlist_t *myexits_unflagged = smartlist_new(); double f_guard, f_mid, f_exit, f_myexit, f_myexit_unflagged; - int np, nu; /* Ignored */ + double f_path = 0.0; + /* Used to determine whether there are any exits in the consensus */ + int np = 0; + /* Used to determine whether there are any exits with descriptors */ + int nu = 0; const int authdir = authdir_mode_v3(options); count_usable_descriptors(num_present_out, num_usable_out, - mid, consensus, options, now, NULL, 0); + mid, consensus, options, now, NULL, + USABLE_DESCRIPTOR_ALL); if (options->EntryNodes) { count_usable_descriptors(&np, &nu, guards, consensus, options, now, - options->EntryNodes, 0); + options->EntryNodes, USABLE_DESCRIPTOR_ALL); } else { SMARTLIST_FOREACH(mid, const node_t *, node, { if (authdir) { @@ -1395,22 +1456,78 @@ compute_frac_paths_available(const networkstatus_t *consensus, }); } - /* All nodes with exit flag */ + /* All nodes with exit flag + * If we're in a network with TestingDirAuthVoteExit set, + * this can cause false positives on have_consensus_path, + * incorrectly setting it to CONSENSUS_PATH_EXIT. This is + * an unavoidable feature of forcing authorities to declare + * certain nodes as exits. + */ count_usable_descriptors(&np, &nu, exits, consensus, options, now, - NULL, 1); + NULL, USABLE_DESCRIPTOR_EXIT_ONLY); + log_debug(LD_NET, + "%s: %d present, %d usable", + "exits", + np, + nu); + + /* We need at least 1 exit present in the consensus to consider + * building exit paths */ + /* Update our understanding of whether the consensus has exits */ + consensus_path_type_t old_have_consensus_path = have_consensus_path; + have_consensus_path = ((np > 0) ? + CONSENSUS_PATH_EXIT : + CONSENSUS_PATH_INTERNAL); + + if (have_consensus_path == CONSENSUS_PATH_INTERNAL + && old_have_consensus_path != have_consensus_path) { + log_notice(LD_NET, + "The current consensus has no exit nodes. " + "Tor can only build internal paths, " + "such as paths to hidden services."); + + /* However, exit nodes can reachability self-test using this consensus, + * join the network, and appear in a later consensus. This will allow + * the network to build exit paths, such as paths for world wide web + * browsing (as distinct from hidden service web browsing). */ + } + /* All nodes with exit flag in ExitNodes option */ count_usable_descriptors(&np, &nu, myexits, consensus, options, now, - options->ExitNodes, 1); + options->ExitNodes, USABLE_DESCRIPTOR_EXIT_ONLY); + log_debug(LD_NET, + "%s: %d present, %d usable", + "myexits", + np, + nu); + /* Now compute the nodes in the ExitNodes option where which we don't know * what their exit policy is, or we know it permits something. */ count_usable_descriptors(&np, &nu, myexits_unflagged, consensus, options, now, - options->ExitNodes, 0); + options->ExitNodes, USABLE_DESCRIPTOR_ALL); + log_debug(LD_NET, + "%s: %d present, %d usable", + "myexits_unflagged (initial)", + np, + nu); + SMARTLIST_FOREACH_BEGIN(myexits_unflagged, const node_t *, node) { - if (node_has_descriptor(node) && node_exit_policy_rejects_all(node)) + if (node_has_descriptor(node) && node_exit_policy_rejects_all(node)) { SMARTLIST_DEL_CURRENT(myexits_unflagged, node); + /* this node is not actually an exit */ + np--; + /* this node is unusable as an exit */ + nu--; + } } SMARTLIST_FOREACH_END(node); + log_debug(LD_NET, + "%s: %d present, %d usable", + "myexits_unflagged (final)", + np, + nu); + f_guard = frac_nodes_with_descriptors(guards, WEIGHT_FOR_GUARD); f_mid = frac_nodes_with_descriptors(mid, WEIGHT_FOR_MID); f_exit = frac_nodes_with_descriptors(exits, WEIGHT_FOR_EXIT); @@ -1418,6 +1535,12 @@ compute_frac_paths_available(const networkstatus_t *consensus, f_myexit_unflagged= frac_nodes_with_descriptors(myexits_unflagged,WEIGHT_FOR_EXIT); + log_debug(LD_NET, + "f_exit: %.2f, f_myexit: %.2f, f_myexit_unflagged: %.2f", + f_exit, + f_myexit, + f_myexit_unflagged); + /* If our ExitNodes list has eliminated every possible Exit node, and there * were some possible Exit nodes, then instead consider nodes that permit * exiting to some ports. */ @@ -1439,16 +1562,28 @@ compute_frac_paths_available(const networkstatus_t *consensus, if (f_myexit < f_exit) f_exit = f_myexit; + /* if the consensus has no exits, treat the exit fraction as 100% */ + if (router_have_consensus_path() != CONSENSUS_PATH_EXIT) { + f_exit = 1.0; + } + + f_path = f_guard * f_mid * f_exit; + if (status_out) tor_asprintf(status_out, "%d%% of guards bw, " "%d%% of midpoint bw, and " - "%d%% of exit bw", + "%d%% of exit bw%s = " + "%d%% of path bw", (int)(f_guard*100), (int)(f_mid*100), - (int)(f_exit*100)); + (int)(f_exit*100), + (router_have_consensus_path() == CONSENSUS_PATH_EXIT ? + "" : + " (no exits in consensus)"), + (int)(f_path*100)); - return f_guard * f_mid * f_exit; + return f_path; } /** We just fetched a new set of descriptors. Compute how far through @@ -1521,6 +1656,9 @@ update_router_have_minimum_dir_info(void) using_md = consensus->flavor == FLAV_MICRODESC; +#define NOTICE_DIR_INFO_STATUS_INTERVAL (60) + + /* Check fraction of available paths */ { char *status = NULL; int num_present=0, num_usable=0; @@ -1529,16 +1667,37 @@ update_router_have_minimum_dir_info(void) &status); if (paths < get_frac_paths_needed_for_circs(options,consensus)) { - tor_snprintf(dir_info_status, sizeof(dir_info_status), - "We need more %sdescriptors: we have %d/%d, and " - "can only build %d%% of likely paths. (We have %s.)", - using_md?"micro":"", num_present, num_usable, - (int)(paths*100), status); - /* log_notice(LD_NET, "%s", dir_info_status); */ + /* these messages can be excessive in testing networks */ + static ratelim_t last_warned = + RATELIM_INIT(NOTICE_DIR_INFO_STATUS_INTERVAL); + char *suppression_msg = NULL; + if ((suppression_msg = rate_limit_log(&last_warned, time(NULL)))) { + tor_snprintf(dir_info_status, sizeof(dir_info_status), + "We need more %sdescriptors: we have %d/%d, and " + "can only build %d%% of likely paths. (We have %s.)", + using_md?"micro":"", num_present, num_usable, + (int)(paths*100), status); + log_warn(LD_NET, "%s%s", dir_info_status, suppression_msg); + tor_free(suppression_msg); + } tor_free(status); res = 0; control_event_bootstrap(BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS, 0); goto done; + } else { + /* these messages can be excessive in testing networks */ + static ratelim_t last_warned = + RATELIM_INIT(NOTICE_DIR_INFO_STATUS_INTERVAL); + char *suppression_msg = NULL; + if ((suppression_msg = rate_limit_log(&last_warned, time(NULL)))) { + tor_snprintf(dir_info_status, sizeof(dir_info_status), + "We have enough %sdescriptors: we have %d/%d, and " + "can build %d%% of likely paths. (We have %s.)", + using_md?"micro":"", num_present, num_usable, + (int)(paths*100), status); + log_info(LD_NET, "%s%s", dir_info_status, suppression_msg); + tor_free(suppression_msg); + } } tor_free(status); @@ -1546,12 +1705,16 @@ update_router_have_minimum_dir_info(void) } done: + + /* If paths have just become available in this update. */ if (res && !have_min_dir_info) { log_notice(LD_DIR, "We now have enough directory information to build circuits."); control_event_client_status(LOG_NOTICE, "ENOUGH_DIR_INFO"); control_event_bootstrap(BOOTSTRAP_STATUS_CONN_OR, 0); } + + /* If paths have just become unavailable in this update. */ if (!res && have_min_dir_info) { int quiet = directory_too_idle_to_fetch_descriptors(options, now); tor_log(quiet ? LOG_INFO : LOG_NOTICE, LD_DIR, @@ -1563,7 +1726,7 @@ update_router_have_minimum_dir_info(void) * should only do while circuits are working, like reachability tests * and fetching bridge descriptors only over circuits. */ note_that_we_maybe_cant_complete_circuits(); - + have_consensus_path = CONSENSUS_PATH_UNKNOWN; control_event_client_status(LOG_NOTICE, "NOT_ENOUGH_DIR_INFO"); } have_min_dir_info = res; diff --git a/src/or/nodelist.h b/src/or/nodelist.h index 48b0e94be0..a131e0dd4e 100644 --- a/src/or/nodelist.h +++ b/src/or/nodelist.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -79,7 +79,37 @@ int node_is_unreliable(const node_t *router, int need_uptime, int router_exit_policy_all_nodes_reject(const tor_addr_t *addr, uint16_t port, int need_uptime); void router_set_status(const char *digest, int up); + +/** router_have_minimum_dir_info tests to see if we have enough + * descriptor information to create circuits. + * If there are exits in the consensus, we wait until we have enough + * info to create exit paths before creating any circuits. If there are + * no exits in the consensus, we wait for enough info to create internal + * paths, and should avoid creating exit paths, as they will simply fail. + * We make sure we create all available circuit types at the same time. */ int router_have_minimum_dir_info(void); + +/** Set to CONSENSUS_PATH_EXIT if there is at least one exit node + * in the consensus. We update this flag in compute_frac_paths_available if + * there is at least one relay that has an Exit flag in the consensus. + * Used to avoid building exit circuits when they will almost certainly fail. + * Set to CONSENSUS_PATH_INTERNAL if there are no exits in the consensus. + * (This situation typically occurs during bootstrap of a test network.) + * Set to CONSENSUS_PATH_UNKNOWN if we have never checked, or have + * reason to believe our last known value was invalid or has expired. + */ +typedef enum { + /* we haven't checked yet, or we have invalidated our previous check */ + CONSENSUS_PATH_UNKNOWN = -1, + /* The consensus only has internal relays, and we should only + * create internal paths, circuits, streams, ... */ + CONSENSUS_PATH_INTERNAL = 0, + /* The consensus has at least one exit, and can therefore (potentially) + * create exit and internal paths, circuits, streams, ... */ + CONSENSUS_PATH_EXIT = 1 +} consensus_path_type_t; +consensus_path_type_t router_have_consensus_path(void); + void router_dir_info_changed(void); const char *get_dir_info_status_string(void); int count_loading_descriptors_progress(void); diff --git a/src/or/ntmain.c b/src/or/ntmain.c index ea6ec3b03e..833d870041 100644 --- a/src/or/ntmain.c +++ b/src/or/ntmain.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "or.h" diff --git a/src/or/ntmain.h b/src/or/ntmain.h index 68565e17ca..eb55a296f6 100644 --- a/src/or/ntmain.h +++ b/src/or/ntmain.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/onion.c b/src/or/onion.c index b8f85f9194..3723a3e11e 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/onion.h b/src/or/onion.h index 2fd86206e4..35619879e4 100644 --- a/src/or/onion.h +++ b/src/or/onion.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/onion_fast.c b/src/or/onion_fast.c index 0ca3e3a5a0..a52a11357c 100644 --- a/src/or/onion_fast.c +++ b/src/or/onion_fast.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/onion_fast.h b/src/or/onion_fast.h index 2fc605fc42..da3c217ae9 100644 --- a/src/or/onion_fast.h +++ b/src/or/onion_fast.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/onion_ntor.c b/src/or/onion_ntor.c index c028ed0ff9..7f58f4d758 100644 --- a/src/or/onion_ntor.c +++ b/src/or/onion_ntor.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/or/onion_ntor.h b/src/or/onion_ntor.h index 29178e942d..230941c3c5 100644 --- a/src/or/onion_ntor.h +++ b/src/or/onion_ntor.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_ONION_NTOR_H diff --git a/src/or/onion_tap.c b/src/or/onion_tap.c index b3b2a008bc..8879a22ca2 100644 --- a/src/or/onion_tap.c +++ b/src/or/onion_tap.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/onion_tap.h b/src/or/onion_tap.h index 36fb649d60..f02a4f6f51 100644 --- a/src/or/onion_tap.h +++ b/src/or/onion_tap.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/or.h b/src/or/or.h index 0de37452bd..58e2164665 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -3204,6 +3204,10 @@ typedef struct or_circuit_t { /** True iff this circuit was made with a CREATE_FAST cell. */ unsigned int is_first_hop : 1; + /** If set, this circuit carries HS traffic. Consider it in any HS + * statistics. */ + unsigned int circuit_carries_hs_traffic_stats : 1; + /** Number of cells that were removed from circuit queue; reset every * time when writing buffer stats to disk. */ uint32_t processed_cells; @@ -3533,6 +3537,8 @@ typedef struct { uint64_t MaxMemInQueues_raw; uint64_t MaxMemInQueues;/**< If we have more memory than this allocated * for queues and buffers, run the OOM handler */ + /** Above this value, consider ourselves low on RAM. */ + uint64_t MaxMemInQueues_low_threshold; /** @name port booleans * @@ -3669,8 +3675,9 @@ typedef struct { * hostname ending with one of the suffixes in * <b>AutomapHostsSuffixes</b>, map it to a * virtual address. */ - smartlist_t *AutomapHostsSuffixes; /**< List of suffixes for - * <b>AutomapHostsOnResolve</b>. */ + /** List of suffixes for <b>AutomapHostsOnResolve</b>. The special value + * "." means "match everything." */ + smartlist_t *AutomapHostsSuffixes; int RendPostPeriod; /**< How often do we post each rendezvous service * descriptor? Remember to publish them independently. */ int KeepalivePeriod; /**< How often do we send padding cells to keep @@ -3961,6 +3968,10 @@ typedef struct { /** If true, the user wants us to collect statistics as entry node. */ int EntryStatistics; + /** If true, the user wants us to collect statistics as hidden service + * directory, introduction point, or rendezvous point. */ + int HiddenServiceStatistics; + /** If true, include statistics file contents in extra-info documents. */ int ExtraInfoStatistics; @@ -4260,6 +4271,14 @@ typedef struct { * when sending. */ int SchedulerMaxFlushCells__; + + /** Is this an exit node? This is a tristate, where "1" means "yes, and use + * the default exit policy if none is given" and "0" means "no; exit policy + * is 'reject *'" and "auto" (-1) means "same as 1, but warn the user." + * + * XXXX Eventually, the default will be 0. */ + int ExitRelay; + } or_options_t; /** Persistent state for an onion router, as saved to disk. */ diff --git a/src/or/policies.c b/src/or/policies.c index d10bebd79a..560b8cb4c3 100644 --- a/src/or/policies.c +++ b/src/or/policies.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -434,6 +434,33 @@ validate_addr_policies(const or_options_t *options, char **msg) REJECT("Error in ExitPolicy entry."); } + static int warned_about_exitrelay = 0; + + const int exitrelay_setting_is_auto = options->ExitRelay == -1; + const int policy_accepts_something = + ! (policy_is_reject_star(addr_policy, AF_INET) && + policy_is_reject_star(addr_policy, AF_INET6)); + + if (server_mode(options) && + ! warned_about_exitrelay && + exitrelay_setting_is_auto && + policy_accepts_something) { + /* Policy accepts something */ + warned_about_exitrelay = 1; + log_warn(LD_CONFIG, + "Tor is running as an exit relay%s. If you did not want this " + "behavior, please set the ExitRelay option to 0. If you do " + "want to run an exit Relay, please set the ExitRelay option " + "to 1 to disable this warning, and for forward compatibility.", + options->ExitPolicy == NULL ? + " with the default exit policy" : ""); + if (options->ExitPolicy == NULL) { + log_warn(LD_CONFIG, + "In a future version of Tor, ExitRelay 0 may become the " + "default when no ExitPolicy is given."); + } + } + /* The rest of these calls *append* to addr_policy. So don't actually * use the results for anything other than checking if they parse! */ if (parse_addr_policy(options->DirPolicy, &addr_policy, -1)) @@ -1022,6 +1049,9 @@ policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest, * * If <b>or_options->BridgeRelay</b> is false, add entries of default * Tor exit policy into <b>result</b> smartlist. + * + * If or_options->ExitRelay is false, then make our exit policy into + * "reject *:*" regardless. */ int policies_parse_exit_policy_from_options(const or_options_t *or_options, @@ -1030,6 +1060,12 @@ policies_parse_exit_policy_from_options(const or_options_t *or_options, { exit_policy_parser_cfg_t parser_cfg = 0; + if (or_options->ExitRelay == 0) { + append_exit_policy_string(result, "reject *4:*"); + append_exit_policy_string(result, "reject *6:*"); + return 0; + } + if (or_options->IPv6Exit) { parser_cfg |= EXIT_POLICY_IPV6_ENABLED; } diff --git a/src/or/policies.h b/src/or/policies.h index 90d94190dd..0225b57a2c 100644 --- a/src/or/policies.h +++ b/src/or/policies.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/reasons.c b/src/or/reasons.c index b0f1b65131..c65acb54ae 100644 --- a/src/or/reasons.c +++ b/src/or/reasons.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/reasons.h b/src/or/reasons.h index 8b3694b05a..00a099061b 100644 --- a/src/or/reasons.h +++ b/src/or/reasons.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/relay.c b/src/or/relay.c index b95e5841e7..2d11096309 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -2433,6 +2433,12 @@ cell_queues_get_total_allocation(void) return total_cells_allocated * packed_cell_mem_cost(); } +/** How long after we've been low on memory should we try to conserve it? */ +#define MEMORY_PRESSURE_INTERVAL (30*60) + +/** The time at which we were last low on memory. */ +static time_t last_time_under_memory_pressure = 0; + /** Check whether we've got too much space used for cells. If so, * call the OOM handler and return 1. Otherwise, return 0. */ STATIC int @@ -2441,13 +2447,25 @@ cell_queues_check_size(void) size_t alloc = cell_queues_get_total_allocation(); alloc += buf_get_total_allocation(); alloc += tor_zlib_get_total_allocation(); - if (alloc >= get_options()->MaxMemInQueues) { - circuits_handle_oom(alloc); - return 1; + if (alloc >= get_options()->MaxMemInQueues_low_threshold) { + last_time_under_memory_pressure = approx_time(); + if (alloc >= get_options()->MaxMemInQueues) { + circuits_handle_oom(alloc); + return 1; + } } return 0; } +/** Return true if we've been under memory pressure in the last + * MEMORY_PRESSURE_INTERVAL seconds. */ +int +have_been_under_memory_pressure(void) +{ + return last_time_under_memory_pressure + MEMORY_PRESSURE_INTERVAL + < approx_time(); +} + /** * Update the number of cells available on the circuit's n_chan or p_chan's * circuit mux. diff --git a/src/or/relay.h b/src/or/relay.h index 351516aada..cdc2a9ae19 100644 --- a/src/or/relay.h +++ b/src/or/relay.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -50,6 +50,8 @@ void clean_cell_pool(void); void dump_cell_pool_usage(int severity); size_t packed_cell_mem_cost(void); +int have_been_under_memory_pressure(void); + /* For channeltls.c */ void packed_cell_free(packed_cell_t *cell); diff --git a/src/or/rendclient.c b/src/or/rendclient.c index f351ae7161..8cace92b2c 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/rendclient.h b/src/or/rendclient.h index 40d388c489..098c61d0a1 100644 --- a/src/or/rendclient.h +++ b/src/or/rendclient.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index df74b745a2..0f75118be2 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -411,7 +411,7 @@ rend_desc_v2_is_parsable(rend_encoded_v2_service_descriptor_t *desc) &test_intro_content, &test_intro_size, &test_encoded_size, - &test_next, desc->desc_str); + &test_next, desc->desc_str, 1); rend_service_descriptor_free(test_parsed); tor_free(test_intro_content); return (res >= 0); @@ -924,6 +924,7 @@ rend_cache_lookup_v2_desc_as_dir(const char *desc_id, const char **desc) rend_cache_store_status_t rend_cache_store_v2_desc_as_dir(const char *desc) { + const or_options_t *options = get_options(); rend_service_descriptor_t *parsed; char desc_id[DIGEST_LEN]; char *intro_content; @@ -945,7 +946,7 @@ rend_cache_store_v2_desc_as_dir(const char *desc) } while (rend_parse_v2_service_descriptor(&parsed, desc_id, &intro_content, &intro_size, &encoded_size, - &next_desc, current_desc) >= 0) { + &next_desc, current_desc, 1) >= 0) { number_parsed++; /* We don't care about the introduction points. */ tor_free(intro_content); @@ -1003,6 +1004,12 @@ rend_cache_store_v2_desc_as_dir(const char *desc) log_info(LD_REND, "Successfully stored service descriptor with desc ID " "'%s' and len %d.", safe_str(desc_id_base32), (int)encoded_size); + + /* Statistics: Note down this potentially new HS. */ + if (options->HiddenServiceStatistics) { + rep_hist_stored_maybe_new_hs(e->parsed->pk); + } + number_stored++; goto advance; skip: @@ -1084,7 +1091,7 @@ rend_cache_store_v2_desc_as_client(const char *desc, /* Parse the descriptor. */ if (rend_parse_v2_service_descriptor(&parsed, desc_id, &intro_content, &intro_size, &encoded_size, - &next_desc, desc) < 0) { + &next_desc, desc, 0) < 0) { log_warn(LD_REND, "Could not parse descriptor."); goto err; } diff --git a/src/or/rendcommon.h b/src/or/rendcommon.h index 186326a0c1..4b910d2729 100644 --- a/src/or/rendcommon.h +++ b/src/or/rendcommon.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/rendmid.c b/src/or/rendmid.c index 6a701e7a77..9f6ff86c47 100644 --- a/src/or/rendmid.c +++ b/src/or/rendmid.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -281,6 +281,7 @@ int rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request, size_t request_len) { + const or_options_t *options = get_options(); or_circuit_t *rend_circ; char hexid[9]; int reason = END_CIRC_REASON_INTERNAL; @@ -316,6 +317,12 @@ rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request, goto err; } + /* Statistics: Mark this circuit as an RP circuit so that we collect + stats from it. */ + if (options->HiddenServiceStatistics) { + circ->circuit_carries_hs_traffic_stats = 1; + } + /* Send the RENDEZVOUS2 cell to Alice. */ if (relay_send_command_from_edge(0, TO_CIRCUIT(rend_circ), RELAY_COMMAND_RENDEZVOUS2, diff --git a/src/or/rendmid.h b/src/or/rendmid.h index 25c711fa7b..6bd691a740 100644 --- a/src/or/rendmid.h +++ b/src/or/rendmid.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 196145e210..3b73674691 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -531,7 +531,7 @@ rend_config_services(const or_options_t *options, int validate_only) } } if (service) { - cpd_check_t check_opts = CPD_CHECK_MODE_ONLY; + cpd_check_t check_opts = CPD_CHECK_MODE_ONLY|CPD_CHECK; if (service->dir_group_readable) { check_opts |= CPD_GROUP_READ; } @@ -1527,8 +1527,7 @@ find_rp_for_intro(const rend_intro_cell_t *intro, } if (intro->version == 0 || intro->version == 1) { - if (intro->version == 1) rp_nickname = (const char *)(intro->u.v1.rp); - else rp_nickname = (const char *)(intro->u.v0.rp); + rp_nickname = (const char *)(intro->u.v0_v1.rp); node = node_get_by_nickname(rp_nickname, 0); if (!node) { @@ -1777,11 +1776,7 @@ rend_service_parse_intro_for_v0_or_v1( goto err; } - if (intro->version == 1) { - memcpy(intro->u.v1.rp, rp_nickname, endptr - rp_nickname + 1); - } else { - memcpy(intro->u.v0.rp, rp_nickname, endptr - rp_nickname + 1); - } + memcpy(intro->u.v0_v1.rp, rp_nickname, endptr - rp_nickname + 1); return ver_specific_len; diff --git a/src/or/rendservice.h b/src/or/rendservice.h index c2342ef573..754f7c358c 100644 --- a/src/or/rendservice.h +++ b/src/or/rendservice.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -38,13 +38,9 @@ struct rend_intro_cell_s { /* Version-specific parts */ union { struct { - /* Rendezvous point nickname */ - uint8_t rp[20]; - } v0; - struct { /* Rendezvous point nickname or hex-encoded key digest */ uint8_t rp[42]; - } v1; + } v0_v1; struct { /* The extend_info_t struct has everything v2 uses */ extend_info_t *extend_info; diff --git a/src/or/rephist.c b/src/or/rephist.c index f1e882729b..34908828a5 100644 --- a/src/or/rephist.c +++ b/src/or/rephist.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -1131,9 +1131,7 @@ rep_hist_load_mtbf_data(time_t now) * totals? */ #define NUM_SECS_ROLLING_MEASURE 10 /** How large are the intervals for which we track and report bandwidth use? */ -/* XXXX Watch out! Before Tor 0.2.2.21-alpha, using any other value here would - * generate an unparseable state file. */ -#define NUM_SECS_BW_SUM_INTERVAL (15*60) +#define NUM_SECS_BW_SUM_INTERVAL (4*60*60) /** How far in the past do we remember and publish bandwidth use? */ #define NUM_SECS_BW_SUM_IS_VALID (24*60*60) /** How many bandwidth usage intervals do we remember? (derived) */ @@ -2908,11 +2906,227 @@ rep_hist_log_circuit_handshake_stats(time_t now) memset(onion_handshakes_requested, 0, sizeof(onion_handshakes_requested)); } +/* Hidden service statistics section */ + +/** Start of the current hidden service stats interval or 0 if we're + * not collecting hidden service statistics. */ +static time_t start_of_hs_stats_interval; + +/** Carries the various hidden service statistics, and any other + * information needed. */ +typedef struct hs_stats_t { + /** How many relay cells have we seen as rendezvous points? */ + int64_t rp_relay_cells_seen; + + /** Set of unique public key digests we've seen this stat period + * (could also be implemented as sorted smartlist). */ + digestmap_t *onions_seen_this_period; +} hs_stats_t; + +/** Our statistics structure singleton. */ +static hs_stats_t *hs_stats = NULL; + +/** Allocate, initialize and return an hs_stats_t structure. */ +static hs_stats_t * +hs_stats_new(void) +{ + hs_stats_t * hs_stats = tor_malloc_zero(sizeof(hs_stats_t)); + hs_stats->onions_seen_this_period = digestmap_new(); + + return hs_stats; +} + +/** Free an hs_stats_t structure. */ +static void +hs_stats_free(hs_stats_t *hs_stats) +{ + if (!hs_stats) { + return; + } + + digestmap_free(hs_stats->onions_seen_this_period, NULL); + tor_free(hs_stats); +} + +/** Initialize hidden service statistics. */ +void +rep_hist_hs_stats_init(time_t now) +{ + if (!hs_stats) { + hs_stats = hs_stats_new(); + } + + start_of_hs_stats_interval = now; +} + +/** Clear history of hidden service statistics and set the measurement + * interval start to <b>now</b>. */ +static void +rep_hist_reset_hs_stats(time_t now) +{ + if (!hs_stats) { + hs_stats = hs_stats_new(); + } + + hs_stats->rp_relay_cells_seen = 0; + + digestmap_free(hs_stats->onions_seen_this_period, NULL); + hs_stats->onions_seen_this_period = digestmap_new(); + + start_of_hs_stats_interval = now; +} + +/** Stop collecting hidden service stats in a way that we can re-start + * doing so in rep_hist_buffer_stats_init(). */ +void +rep_hist_hs_stats_term(void) +{ + rep_hist_reset_hs_stats(0); +} + +/** We saw a new HS relay cell, Count it! */ +void +rep_hist_seen_new_rp_cell(void) +{ + if (!hs_stats) { + return; // We're not collecting stats + } + + hs_stats->rp_relay_cells_seen++; +} + +/** As HSDirs, we saw another hidden service with public key + * <b>pubkey</b>. Check whether we have counted it before, if not + * count it now! */ +void +rep_hist_stored_maybe_new_hs(const crypto_pk_t *pubkey) +{ + char pubkey_hash[DIGEST_LEN]; + + if (!hs_stats) { + return; // We're not collecting stats + } + + /* Get the digest of the pubkey which will be used to detect whether + we've seen this hidden service before or not. */ + if (crypto_pk_get_digest(pubkey, pubkey_hash) < 0) { + /* This fail should not happen; key has been validated by + descriptor parsing code first. */ + return; + } + + /* Check if this is the first time we've seen this hidden + service. If it is, count it as new. */ + if (!digestmap_get(hs_stats->onions_seen_this_period, + pubkey_hash)) { + digestmap_set(hs_stats->onions_seen_this_period, + pubkey_hash, (void*)(uintptr_t)1); + } +} + +/* The number of cells that are supposed to be hidden from the adversary + * by adding noise from the Laplace distribution. This value, divided by + * EPSILON, is Laplace parameter b. */ +#define REND_CELLS_DELTA_F 2048 +/* Security parameter for obfuscating number of cells with a value between + * 0 and 1. Smaller values obfuscate observations more, but at the same + * time make statistics less usable. */ +#define REND_CELLS_EPSILON 0.3 +/* The number of cells that are supposed to be hidden from the adversary + * by rounding up to the next multiple of this number. */ +#define REND_CELLS_BIN_SIZE 1024 +/* The number of service identities that are supposed to be hidden from + * the adversary by adding noise from the Laplace distribution. This + * value, divided by EPSILON, is Laplace parameter b. */ +#define ONIONS_SEEN_DELTA_F 8 +/* Security parameter for obfuscating number of service identities with a + * value between 0 and 1. Smaller values obfuscate observations more, but + * at the same time make statistics less usable. */ +#define ONIONS_SEEN_EPSILON 0.3 +/* The number of service identities that are supposed to be hidden from + * the adversary by rounding up to the next multiple of this number. */ +#define ONIONS_SEEN_BIN_SIZE 8 + +/** Allocate and return a string containing hidden service stats that + * are meant to be placed in the extra-info descriptor. */ +static char * +rep_hist_format_hs_stats(time_t now) +{ + char t[ISO_TIME_LEN+1]; + char *hs_stats_string; + int64_t obfuscated_cells_seen; + int64_t obfuscated_onions_seen; + + obfuscated_cells_seen = round_int64_to_next_multiple_of( + hs_stats->rp_relay_cells_seen, + REND_CELLS_BIN_SIZE); + obfuscated_cells_seen = add_laplace_noise(obfuscated_cells_seen, + crypto_rand_double(), + REND_CELLS_DELTA_F, REND_CELLS_EPSILON); + obfuscated_onions_seen = round_int64_to_next_multiple_of(digestmap_size( + hs_stats->onions_seen_this_period), + ONIONS_SEEN_BIN_SIZE); + obfuscated_onions_seen = add_laplace_noise(obfuscated_onions_seen, + crypto_rand_double(), ONIONS_SEEN_DELTA_F, + ONIONS_SEEN_EPSILON); + + format_iso_time(t, now); + tor_asprintf(&hs_stats_string, "hidserv-stats-end %s (%d s)\n" + "hidserv-rend-relayed-cells "I64_FORMAT" delta_f=%d " + "epsilon=%.2f bin_size=%d\n" + "hidserv-dir-onions-seen "I64_FORMAT" delta_f=%d " + "epsilon=%.2f bin_size=%d\n", + t, (unsigned) (now - start_of_hs_stats_interval), + I64_PRINTF_ARG(obfuscated_cells_seen), REND_CELLS_DELTA_F, + REND_CELLS_EPSILON, REND_CELLS_BIN_SIZE, + I64_PRINTF_ARG(obfuscated_onions_seen), + ONIONS_SEEN_DELTA_F, + ONIONS_SEEN_EPSILON, ONIONS_SEEN_BIN_SIZE); + + return hs_stats_string; +} + +/** If 24 hours have passed since the beginning of the current HS + * stats period, write buffer stats to $DATADIR/stats/hidserv-stats + * (possibly overwriting an existing file) and reset counters. Return + * when we would next want to write buffer stats or 0 if we never want to + * write. */ +time_t +rep_hist_hs_stats_write(time_t now) +{ + char *str = NULL; + + if (!start_of_hs_stats_interval) { + return 0; /* Not initialized. */ + } + + if (start_of_hs_stats_interval + WRITE_STATS_INTERVAL > now) { + goto done; /* Not ready to write */ + } + + /* Generate history string. */ + str = rep_hist_format_hs_stats(now); + + /* Reset HS history. */ + rep_hist_reset_hs_stats(now); + + /* Try to write to disk. */ + if (!check_or_create_data_subdir("stats")) { + write_to_data_subdir("stats", "hidserv-stats", str, + "hidden service stats"); + } + + done: + tor_free(str); + return start_of_hs_stats_interval + WRITE_STATS_INTERVAL; +} + /** Free all storage held by the OR/link history caches, by the * bandwidth history arrays, by the port history, or by statistics . */ void rep_hist_free_all(void) { + hs_stats_free(hs_stats); digestmap_free(history_map, free_or_history); tor_free(read_array); tor_free(write_array); diff --git a/src/or/rephist.h b/src/or/rephist.h index d853fe2e00..42710c4ed6 100644 --- a/src/or/rephist.h +++ b/src/or/rephist.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -99,6 +99,13 @@ void rep_hist_note_circuit_handshake_requested(uint16_t type); void rep_hist_note_circuit_handshake_assigned(uint16_t type); void rep_hist_log_circuit_handshake_stats(time_t now); +void rep_hist_hs_stats_init(time_t now); +void rep_hist_hs_stats_term(void); +time_t rep_hist_hs_stats_write(time_t now); +char *rep_hist_get_hs_stats_string(void); +void rep_hist_seen_new_rp_cell(void); +void rep_hist_stored_maybe_new_hs(const crypto_pk_t *pubkey); + void rep_hist_free_all(void); #endif diff --git a/src/or/replaycache.c b/src/or/replaycache.c index 6d1b59101d..569e0736cb 100644 --- a/src/or/replaycache.c +++ b/src/or/replaycache.c @@ -1,4 +1,4 @@ - /* Copyright (c) 2012-2014, The Tor Project, Inc. */ + /* Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* diff --git a/src/or/replaycache.h b/src/or/replaycache.h index 904fd45ff1..9b9daf3831 100644 --- a/src/or/replaycache.h +++ b/src/or/replaycache.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/router.c b/src/or/router.c index f0317aa549..a1feda3497 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define ROUTER_PRIVATE @@ -1236,6 +1236,11 @@ router_orport_found_reachable(void) " Publishing server descriptor." : ""); can_reach_or_port = 1; mark_my_descriptor_dirty("ORPort found reachable"); + /* This is a significant enough change to upload immediately, + * at least in a test network */ + if (get_options()->TestingTorNetwork == 1) { + reschedule_descriptor_update_check(); + } control_event_server_status(LOG_NOTICE, "REACHABILITY_SUCCEEDED ORADDRESS=%s:%d", address, me->or_port); @@ -1253,8 +1258,14 @@ router_dirport_found_reachable(void) log_notice(LD_DIRSERV,"Self-testing indicates your DirPort is reachable " "from the outside. Excellent."); can_reach_dir_port = 1; - if (decide_to_advertise_dirport(get_options(), me->dir_port)) + if (decide_to_advertise_dirport(get_options(), me->dir_port)) { mark_my_descriptor_dirty("DirPort found reachable"); + /* This is a significant enough change to upload immediately, + * at least in a test network */ + if (get_options()->TestingTorNetwork == 1) { + reschedule_descriptor_update_check(); + } + } control_event_server_status(LOG_NOTICE, "REACHABILITY_SUCCEEDED DIRADDRESS=%s:%d", address, me->dir_port); @@ -2674,6 +2685,11 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo, "dirreq-stats-end", now, &contents) > 0) { smartlist_add(chunks, contents); } + if (options->HiddenServiceStatistics && + load_stats_file("stats"PATH_SEPARATOR"hidserv-stats", + "hidserv-stats-end", now, &contents) > 0) { + smartlist_add(chunks, contents); + } if (options->EntryStatistics && load_stats_file("stats"PATH_SEPARATOR"entry-stats", "entry-stats-end", now, &contents) > 0) { diff --git a/src/or/router.h b/src/or/router.h index b5d7f11053..8108ffb22f 100644 --- a/src/or/router.h +++ b/src/or/router.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/routerlist.c b/src/or/routerlist.c index c9d2f8ad28..d3734238eb 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -2211,11 +2211,29 @@ router_choose_random_node(smartlist_t *excludedsmartlist, router_add_running_nodes_to_smartlist(sl, allow_invalid, need_uptime, need_capacity, need_guard, need_desc); + log_debug(LD_CIRC, + "We found %d running nodes.", + smartlist_len(sl)); + smartlist_subtract(sl,excludednodes); - if (excludedsmartlist) + log_debug(LD_CIRC, + "We removed %d excludednodes, leaving %d nodes.", + smartlist_len(excludednodes), + smartlist_len(sl)); + + if (excludedsmartlist) { smartlist_subtract(sl,excludedsmartlist); - if (excludedset) + log_debug(LD_CIRC, + "We removed %d excludedsmartlist, leaving %d nodes.", + smartlist_len(excludedsmartlist), + smartlist_len(sl)); + } + if (excludedset) { routerset_subtract_nodes(sl,excludedset); + log_debug(LD_CIRC, + "We removed excludedset, leaving %d nodes.", + smartlist_len(sl)); + } // Always weight by bandwidth choice = node_sl_choose_by_bandwidth(sl, rule); diff --git a/src/or/routerlist.h b/src/or/routerlist.h index e73e69b63a..d7e15db87e 100644 --- a/src/or/routerlist.h +++ b/src/or/routerlist.h @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/routerparse.c b/src/or/routerparse.c index bc3b00226a..a2bc8fbb93 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -2598,11 +2598,15 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out, (int) tor_parse_long(tok->args[1], 10, 0, INT_MAX, &ok, NULL); if (!ok) goto err; - if (ns->valid_after + MIN_VOTE_INTERVAL > ns->fresh_until) { + if (ns->valid_after + + (get_options()->TestingTorNetwork ? + MIN_VOTE_INTERVAL_TESTING : MIN_VOTE_INTERVAL) > ns->fresh_until) { log_warn(LD_DIR, "Vote/consensus freshness interval is too short"); goto err; } - if (ns->valid_after + MIN_VOTE_INTERVAL*2 > ns->valid_until) { + if (ns->valid_after + + (get_options()->TestingTorNetwork ? + MIN_VOTE_INTERVAL_TESTING : MIN_VOTE_INTERVAL)*2 > ns->valid_until) { log_warn(LD_DIR, "Vote/consensus liveness interval is too short"); goto err; } @@ -4246,40 +4250,50 @@ tor_version_parse(const char *s, tor_version_t *out) char *eos=NULL; const char *cp=NULL; /* Format is: - * "Tor " ? NUM dot NUM dot NUM [ ( pre | rc | dot ) NUM [ - tag ] ] + * "Tor " ? NUM dot NUM [ dot NUM [ ( pre | rc | dot ) NUM ] ] [ - tag ] */ tor_assert(s); tor_assert(out); memset(out, 0, sizeof(tor_version_t)); - + out->status = VER_RELEASE; if (!strcasecmpstart(s, "Tor ")) s += 4; - /* Get major. */ - out->major = (int)strtol(s,&eos,10); - if (!eos || eos==s || *eos != '.') return -1; - cp = eos+1; - - /* Get minor */ - out->minor = (int) strtol(cp,&eos,10); - if (!eos || eos==cp || *eos != '.') return -1; - cp = eos+1; - - /* Get micro */ - out->micro = (int) strtol(cp,&eos,10); - if (!eos || eos==cp) return -1; - if (!*eos) { - out->status = VER_RELEASE; - out->patchlevel = 0; + cp = s; + +#define NUMBER(m) \ + do { \ + out->m = (int)strtol(cp, &eos, 10); \ + if (!eos || eos == cp) \ + return -1; \ + cp = eos; \ + } while (0) + +#define DOT() \ + do { \ + if (*cp != '.') \ + return -1; \ + ++cp; \ + } while (0) + + NUMBER(major); + DOT(); + NUMBER(minor); + if (*cp == 0) return 0; - } - cp = eos; + else if (*cp == '-') + goto status_tag; + DOT(); + NUMBER(micro); /* Get status */ - if (*cp == '.') { - out->status = VER_RELEASE; + if (*cp == 0) { + return 0; + } else if (*cp == '.') { ++cp; + } else if (*cp == '-') { + goto status_tag; } else if (0==strncmp(cp, "pre", 3)) { out->status = VER_PRE; cp += 3; @@ -4290,11 +4304,9 @@ tor_version_parse(const char *s, tor_version_t *out) return -1; } - /* Get patchlevel */ - out->patchlevel = (int) strtol(cp,&eos,10); - if (!eos || eos==cp) return -1; - cp = eos; + NUMBER(patchlevel); + status_tag: /* Get status tag. */ if (*cp == '-' || *cp == '.') ++cp; @@ -4330,6 +4342,8 @@ tor_version_parse(const char *s, tor_version_t *out) } return 0; +#undef NUMBER +#undef DOT } /** Compare two tor versions; Return <0 if a < b; 0 if a ==b, >0 if a > @@ -4417,6 +4431,9 @@ sort_version_list(smartlist_t *versions, int remove_duplicates) * to *<b>encoded_size_out</b>, and a pointer to the possibly next * descriptor to *<b>next_out</b>; return 0 for success (including validation) * and -1 for failure. + * + * If <b>as_hsdir</b> is 1, we're parsing this as an HSDir, and we should + * be strict about time formats. */ int rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out, @@ -4424,7 +4441,8 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out, char **intro_points_encrypted_out, size_t *intro_points_encrypted_size_out, size_t *encoded_size_out, - const char **next_out, const char *desc) + const char **next_out, const char *desc, + int as_hsdir) { rend_service_descriptor_t *result = tor_malloc_zero(sizeof(rend_service_descriptor_t)); @@ -4438,6 +4456,8 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out, char public_key_hash[DIGEST_LEN]; char test_desc_id[DIGEST_LEN]; memarea_t *area = NULL; + const int strict_time_fmt = as_hsdir; + tor_assert(desc); /* Check if desc starts correctly. */ if (strncmp(desc, "rendezvous-service-descriptor ", @@ -4532,7 +4552,7 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out, * descriptor. */ tok = find_by_keyword(tokens, R_PUBLICATION_TIME); tor_assert(tok->n_args == 1); - if (parse_iso_time(tok->args[0], &result->timestamp) < 0) { + if (parse_iso_time_(tok->args[0], &result->timestamp, strict_time_fmt) < 0) { log_warn(LD_REND, "Invalid publication time: '%s'", tok->args[0]); goto err; } diff --git a/src/or/routerparse.h b/src/or/routerparse.h index e950548f8c..18a7d2563c 100644 --- a/src/or/routerparse.h +++ b/src/or/routerparse.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -73,7 +73,8 @@ int rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out, char **intro_points_encrypted_out, size_t *intro_points_encrypted_size_out, size_t *encoded_size_out, - const char **next_out, const char *desc); + const char **next_out, const char *desc, + int as_hsdir); int rend_decrypt_introduction_points(char **ipos_decrypted, size_t *ipos_decrypted_size, const char *descriptor_cookie, diff --git a/src/or/routerset.c b/src/or/routerset.c index 38aed77ee9..99de11ed5e 100644 --- a/src/or/routerset.c +++ b/src/or/routerset.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define ROUTERSET_PRIVATE diff --git a/src/or/routerset.h b/src/or/routerset.h index a741eb5fda..8d41de8b6b 100644 --- a/src/or/routerset.h +++ b/src/or/routerset.h @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/scheduler.c b/src/or/scheduler.c index d1a15aacb2..f3fbc4ad4e 100644 --- a/src/or/scheduler.c +++ b/src/or/scheduler.c @@ -1,4 +1,4 @@ -/* * Copyright (c) 2013, The Tor Project, Inc. */ +/* * Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -156,7 +156,9 @@ scheduler_free_all(void) log_debug(LD_SCHED, "Shutting down scheduler"); if (run_sched_ev) { - event_del(run_sched_ev); + if (event_del(run_sched_ev) < 0) { + log_warn(LD_BUG, "Problem deleting run_sched_ev"); + } tor_event_free(run_sched_ev); run_sched_ev = NULL; } diff --git a/src/or/scheduler.h b/src/or/scheduler.h index 404776b18b..70f6a39d4c 100644 --- a/src/or/scheduler.h +++ b/src/or/scheduler.h @@ -1,4 +1,4 @@ -/* * Copyright (c) 2013, The Tor Project, Inc. */ +/* * Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/statefile.c b/src/or/statefile.c index 6640aed7d0..dd1894beb7 100644 --- a/src/or/statefile.c +++ b/src/or/statefile.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define STATEFILE_PRIVATE diff --git a/src/or/statefile.h b/src/or/statefile.h index 1f3aebee4f..8c790ea206 100644 --- a/src/or/statefile.h +++ b/src/or/statefile.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_STATEFILE_H diff --git a/src/or/status.c b/src/or/status.c index c11d99ba7f..0717070a05 100644 --- a/src/or/status.c +++ b/src/or/status.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Tor Project, Inc. */ +/* Copyright (c) 2010-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/status.h b/src/or/status.h index 451f343963..3dd8206e0f 100644 --- a/src/or/status.h +++ b/src/or/status.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Tor Project, Inc. */ +/* Copyright (c) 2010-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_STATUS_H diff --git a/src/or/tor_main.c b/src/or/tor_main.c index 9489cdca7f..af03b8c06a 100644 --- a/src/or/tor_main.c +++ b/src/or/tor_main.c @@ -1,6 +1,6 @@ /* Copyright 2001-2004 Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** String describing which Tor Git repository version the source was diff --git a/src/or/transports.c b/src/or/transports.c index 2623f807d0..6f07054ea8 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Tor Project, Inc. */ +/* Copyright (c) 2011-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -112,8 +112,6 @@ static void parse_method_error(const char *line, int is_server_method); #define parse_server_method_error(l) parse_method_error(l, 1) #define parse_client_method_error(l) parse_method_error(l, 0) -static INLINE void free_execve_args(char **arg); - /** Managed proxy protocol strings */ #define PROTO_ENV_ERROR "ENV-ERROR" #define PROTO_NEG_SUCCESS "VERSION" @@ -1502,7 +1500,7 @@ pt_kickstart_proxy, (const smartlist_t *transport_list, /** Frees the array of pointers in <b>arg</b> used as arguments to execve(2). */ -static INLINE void +STATIC void free_execve_args(char **arg) { char **tmp = arg; diff --git a/src/or/transports.h b/src/or/transports.h index 2958d5e187..7c69941496 100644 --- a/src/or/transports.h +++ b/src/or/transports.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -131,6 +131,8 @@ STATIC int configure_proxy(managed_proxy_t *mp); STATIC char* get_pt_proxy_uri(void); +STATIC void free_execve_args(char **arg); + #endif #endif diff --git a/src/test/bench.c b/src/test/bench.c index 74af06c6e6..68870f8657 100644 --- a/src/test/bench.c +++ b/src/test/bench.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* Ordinarily defined in tor_main.c; this bit is just here to provide one diff --git a/src/test/bt_test.py b/src/test/bt_test.py index 8290509fa7..0afe797a6d 100755 --- a/src/test/bt_test.py +++ b/src/test/bt_test.py @@ -1,4 +1,4 @@ -# Copyright 2013, The Tor Project, Inc +# Copyright 2013-2015, The Tor Project, Inc # See LICENSE for licensing information """ diff --git a/src/test/ed25519_exts_ref.py b/src/test/ed25519_exts_ref.py index 93dc49ee93..d5a3a79910 100644 --- a/src/test/ed25519_exts_ref.py +++ b/src/test/ed25519_exts_ref.py @@ -1,5 +1,5 @@ #!/usr/bin/python -# Copyright 2014, The Tor Project, Inc +# Copyright 2014-2015, The Tor Project, Inc # See LICENSE for licensing information """ diff --git a/src/test/fakechans.h b/src/test/fakechans.h index b129ab49a5..8fb8f420a8 100644 --- a/src/test/fakechans.h +++ b/src/test/fakechans.h @@ -1,4 +1,4 @@ - /* Copyright (c) 2014, The Tor Project, Inc. */ + /* Copyright (c) 2014-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_FAKECHANS_H @@ -12,6 +12,7 @@ void make_fake_cell(cell_t *c); void make_fake_var_cell(var_cell_t *c); channel_t * new_fake_channel(void); +void free_fake_channel(channel_t *c); /* Also exposes some a mock used by both test_channel.c and test_relay.c */ void scheduler_channel_has_waiting_cells_mock(channel_t *ch); diff --git a/src/test/include.am b/src/test/include.am index 4518f8fb8f..71425ea440 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -68,7 +68,8 @@ src_test_test_LDADD = src/or/libtor-testing.a src/common/libor-testing.a \ src/common/libor-crypto-testing.a $(LIBDONNA) \ src/common/libor-event-testing.a src/trunnel/libor-trunnel-testing.a \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \ - @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ + @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ \ + @TOR_SYSTEMD_LIBS@ src_test_bench_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \ @TOR_LDFLAGS_libevent@ @@ -76,7 +77,8 @@ src_test_bench_LDADD = src/or/libtor.a src/common/libor.a \ src/common/libor-crypto.a $(LIBDONNA) \ src/common/libor-event.a \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \ - @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ + @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ \ + @TOR_SYSTEMD_LIBS@ noinst_HEADERS+= \ src/test/fakechans.h \ diff --git a/src/test/ntor_ref.py b/src/test/ntor_ref.py index 7d6e43e716..e37637d92a 100755 --- a/src/test/ntor_ref.py +++ b/src/test/ntor_ref.py @@ -1,5 +1,5 @@ #!/usr/bin/python -# Copyright 2012-2013, The Tor Project, Inc +# Copyright 2012-2015, The Tor Project, Inc # See LICENSE for licensing information """ diff --git a/src/test/test-child.c b/src/test/test-child.c index 91ae5a66a5..2ce01ea9bb 100644 --- a/src/test/test-child.c +++ b/src/test/test-child.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Tor Project, Inc. */ +/* Copyright (c) 2011-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include <stdio.h> diff --git a/src/test/test.c b/src/test/test.c index fbe5625300..de6efaf873 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* Ordinarily defined in tor_main.c; this bit is just here to provide one @@ -696,12 +696,12 @@ test_rend_fns(void *arg) smartlist_get(descs, 0))->desc_id, OP_EQ, computed_desc_id, DIGEST_LEN); tt_assert(rend_parse_v2_service_descriptor(&parsed, parsed_desc_id, - &intro_points_encrypted, - &intro_points_size, - &encoded_size, - &next_desc, - ((rend_encoded_v2_service_descriptor_t *) - smartlist_get(descs, 0))->desc_str) == 0); + &intro_points_encrypted, + &intro_points_size, + &encoded_size, + &next_desc, + ((rend_encoded_v2_service_descriptor_t *) + smartlist_get(descs, 0))->desc_str, 1) == 0); tt_assert(parsed); tt_mem_op(((rend_encoded_v2_service_descriptor_t *) smartlist_get(descs, 0))->desc_id,OP_EQ, parsed_desc_id, DIGEST_LEN); diff --git a/src/test/test.h b/src/test/test.h index 5518ca3f60..48037a5ba3 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2003, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_TEST_H diff --git a/src/test/test_addr.c b/src/test/test_addr.c index c9c47bdaee..2c25c1ef7d 100644 --- a/src/test/test_addr.c +++ b/src/test/test_addr.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define ADDRESSMAP_PRIVATE diff --git a/src/test/test_bt_cl.c b/src/test/test_bt_cl.c index c0c334656d..0fa0cd5c0a 100644 --- a/src/test/test_bt_cl.c +++ b/src/test/test_bt_cl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_buffers.c b/src/test/test_buffers.c index cb29ab0a9e..101f448472 100644 --- a/src/test/test_buffers.c +++ b/src/test/test_buffers.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define BUFFERS_PRIVATE @@ -611,7 +611,7 @@ test_buffers_zlib_impl(int finalize_with_nil) int done; buf = buf_new_with_capacity(128); /* will round up */ - zlib_state = tor_zlib_new(1, ZLIB_METHOD); + zlib_state = tor_zlib_new(1, ZLIB_METHOD, HIGH_COMPRESSION); msg = tor_malloc(512); crypto_rand(msg, 512); @@ -688,7 +688,7 @@ test_buffers_zlib_fin_at_chunk_end(void *arg) tt_uint_op(buf->head->datalen, OP_EQ, headerjunk); tt_uint_op(buf_datalen(buf), OP_EQ, headerjunk); /* Write an empty string, with finalization on. */ - zlib_state = tor_zlib_new(1, ZLIB_METHOD); + zlib_state = tor_zlib_new(1, ZLIB_METHOD, HIGH_COMPRESSION); tt_int_op(write_to_buf_zlib(buf, zlib_state, "", 0, 1), OP_EQ, 0); in_len = buf_datalen(buf); diff --git a/src/test/test_cell_formats.c b/src/test/test_cell_formats.c index e1f6bd71f7..e86dc0934f 100644 --- a/src/test/test_cell_formats.c +++ b/src/test/test_cell_formats.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_cell_queue.c b/src/test/test_cell_queue.c index e2fc95ccd6..effd316f34 100644 --- a/src/test/test_cell_queue.c +++ b/src/test/test_cell_queue.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Tor Project, Inc. */ +/* Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CIRCUITLIST_PRIVATE diff --git a/src/test/test_channel.c b/src/test/test_channel.c index f882b99906..99633a4026 100644 --- a/src/test/test_channel.c +++ b/src/test/test_channel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013, The Tor Project, Inc. */ +/* Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define TOR_CHANNEL_INTERNAL_ @@ -430,6 +430,27 @@ new_fake_channel(void) return chan; } +void +free_fake_channel(channel_t *chan) +{ + cell_queue_entry_t *cell, *cell_tmp; + + if (! chan) + return; + + if (chan->cmux) + circuitmux_free(chan->cmux); + + TOR_SIMPLEQ_FOREACH_SAFE(cell, &chan->incoming_queue, next, cell_tmp) { + cell_queue_entry_free(cell, 0); + } + TOR_SIMPLEQ_FOREACH_SAFE(cell, &chan->outgoing_queue, next, cell_tmp) { + cell_queue_entry_free(cell, 0); + } + + tor_free(chan); +} + /** * Counter query for scheduler_channel_has_waiting_cells_mock() */ @@ -610,7 +631,7 @@ test_channel_dumpstats(void *arg) done: tor_free(cell); - tor_free(ch); + free_fake_channel(ch); UNMOCK(scheduler_channel_doesnt_want_writes); UNMOCK(scheduler_release_channel); @@ -748,6 +769,8 @@ test_channel_flushmux(void *arg) test_cmux_cells = 0; done: + if (ch) + circuitmux_free(ch->cmux); tor_free(ch); UNMOCK(channel_flush_from_first_active_circuit); @@ -831,7 +854,7 @@ test_channel_incoming(void *arg) ch = NULL; done: - tor_free(ch); + free_fake_channel(ch); tor_free(cell); tor_free(var_cell); @@ -944,8 +967,8 @@ test_channel_lifecycle(void *arg) tt_int_op(test_releases_count, ==, init_releases_count + 4); done: - tor_free(ch1); - tor_free(ch2); + free_fake_channel(ch1); + free_fake_channel(ch2); UNMOCK(scheduler_channel_doesnt_want_writes); UNMOCK(scheduler_release_channel); @@ -1214,6 +1237,7 @@ test_channel_multi(void *arg) cell = tor_malloc_zero(sizeof(cell_t)); make_fake_cell(cell); channel_write_cell(ch2, cell); + cell = NULL; /* Check the estimates */ channel_update_xmit_queue_size(ch1); @@ -1248,8 +1272,8 @@ test_channel_multi(void *arg) UNMOCK(scheduler_release_channel); done: - tor_free(ch1); - tor_free(ch2); + free_fake_channel(ch1); + free_fake_channel(ch2); return; } @@ -1269,6 +1293,7 @@ test_channel_queue_impossible(void *arg) int old_count; cell_queue_entry_t *q = NULL; uint64_t global_queue_estimate; + uintptr_t cellintptr; /* Cache the global queue size (see below) */ global_queue_estimate = channel_get_global_queue_estimate(); @@ -1279,9 +1304,6 @@ test_channel_queue_impossible(void *arg) init_cell_pool(); #endif /* ENABLE_MEMPOOLS */ - packed_cell = packed_cell_new(); - tt_assert(packed_cell); - ch = new_fake_channel(); tt_assert(ch); @@ -1299,6 +1321,7 @@ test_channel_queue_impossible(void *arg) /* Get a fresh cell and write it to the channel*/ cell = tor_malloc_zero(sizeof(cell_t)); make_fake_cell(cell); + cellintptr = (uintptr_t)(void*)cell; channel_write_cell(ch, cell); /* Now it should be queued */ @@ -1307,7 +1330,7 @@ test_channel_queue_impossible(void *arg) tt_assert(q); if (q) { tt_int_op(q->type, ==, CELL_QUEUE_FIXED); - tt_ptr_op(q->u.fixed.cell, ==, cell); + tt_assert((uintptr_t)q->u.fixed.cell == cellintptr); } /* Do perverse things to it */ tor_free(q->u.fixed.cell); @@ -1328,6 +1351,7 @@ test_channel_queue_impossible(void *arg) ch->state = CHANNEL_STATE_MAINT; var_cell = tor_malloc_zero(sizeof(var_cell_t) + CELL_PAYLOAD_SIZE); make_fake_var_cell(var_cell); + cellintptr = (uintptr_t)(void*)var_cell; channel_write_var_cell(ch, var_cell); /* Check that it's queued */ @@ -1336,7 +1360,7 @@ test_channel_queue_impossible(void *arg) tt_assert(q); if (q) { tt_int_op(q->type, ==, CELL_QUEUE_VAR); - tt_ptr_op(q->u.var.var_cell, ==, var_cell); + tt_assert((uintptr_t)q->u.var.var_cell == cellintptr); } /* Remove the cell from the queue entry */ @@ -1355,6 +1379,7 @@ test_channel_queue_impossible(void *arg) ch->state = CHANNEL_STATE_MAINT; packed_cell = packed_cell_new(); tt_assert(packed_cell); + cellintptr = (uintptr_t)(void*)packed_cell; channel_write_packed_cell(ch, packed_cell); /* Check that it's queued */ @@ -1363,7 +1388,7 @@ test_channel_queue_impossible(void *arg) tt_assert(q); if (q) { tt_int_op(q->type, ==, CELL_QUEUE_PACKED); - tt_ptr_op(q->u.packed.packed_cell, ==, packed_cell); + tt_assert((uintptr_t)q->u.packed.packed_cell == cellintptr); } /* Remove the cell from the queue entry */ @@ -1381,6 +1406,7 @@ test_channel_queue_impossible(void *arg) ch->state = CHANNEL_STATE_MAINT; cell = tor_malloc_zero(sizeof(cell_t)); make_fake_cell(cell); + cellintptr = (uintptr_t)(void*)cell; channel_write_cell(ch, cell); /* Check that it's queued */ @@ -1389,7 +1415,7 @@ test_channel_queue_impossible(void *arg) tt_assert(q); if (q) { tt_int_op(q->type, ==, CELL_QUEUE_FIXED); - tt_ptr_op(q->u.fixed.cell, ==, cell); + tt_assert((uintptr_t)q->u.fixed.cell == cellintptr); } /* Clobber it, including the queue entry type */ tor_free(q->u.fixed.cell); @@ -1403,7 +1429,7 @@ test_channel_queue_impossible(void *arg) tt_int_op(chan_cell_queue_len(&(ch->outgoing_queue)), ==, 0); done: - tor_free(ch); + free_fake_channel(ch); #ifdef ENABLE_MEMPOOLS free_cell_pool(); #endif /* ENABLE_MEMPOOLS */ @@ -1532,7 +1558,7 @@ test_channel_queue_size(void *arg) UNMOCK(scheduler_release_channel); done: - tor_free(ch); + free_fake_channel(ch); return; } @@ -1566,12 +1592,15 @@ test_channel_write(void *arg) old_count = test_cells_written; channel_write_cell(ch, cell); + cell = NULL; tt_assert(test_cells_written == old_count + 1); channel_write_var_cell(ch, var_cell); + var_cell = NULL; tt_assert(test_cells_written == old_count + 2); channel_write_packed_cell(ch, packed_cell); + packed_cell = NULL; tt_assert(test_cells_written == old_count + 3); /* Now we test queueing; tell it not to accept cells */ @@ -1632,15 +1661,18 @@ test_channel_write(void *arg) cell = tor_malloc_zero(sizeof(cell_t)); make_fake_cell(cell); channel_write_cell(ch, cell); + cell = NULL; tt_assert(test_cells_written == old_count); var_cell = tor_malloc_zero(sizeof(var_cell_t) + CELL_PAYLOAD_SIZE); make_fake_var_cell(var_cell); channel_write_var_cell(ch, var_cell); + var_cell = NULL; tt_assert(test_cells_written == old_count); packed_cell = packed_cell_new(); channel_write_packed_cell(ch, packed_cell); + packed_cell = NULL; tt_assert(test_cells_written == old_count); #ifdef ENABLE_MEMPOOLS @@ -1648,8 +1680,10 @@ test_channel_write(void *arg) #endif /* ENABLE_MEMPOOLS */ done: - tor_free(ch); - + free_fake_channel(ch); + tor_free(var_cell); + tor_free(cell); + packed_cell_free(packed_cell); return; } diff --git a/src/test/test_channeltls.c b/src/test/test_channeltls.c index 45e24dfbec..016e504ab3 100644 --- a/src/test/test_channeltls.c +++ b/src/test/test_channeltls.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Tor Project, Inc. */ +/* Copyright (c) 2014-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include <math.h> @@ -80,7 +80,7 @@ test_channeltls_create(void *arg) */ ch->close = tlschan_fake_close_method; channel_mark_for_close(ch); - tor_free(ch); + free_fake_channel(ch); UNMOCK(scheduler_release_channel); } @@ -167,7 +167,7 @@ test_channeltls_num_bytes_queued(void *arg) */ ch->close = tlschan_fake_close_method; channel_mark_for_close(ch); - tor_free(ch); + free_fake_channel(ch); UNMOCK(scheduler_release_channel); } @@ -241,7 +241,7 @@ test_channeltls_overhead_estimate(void *arg) */ ch->close = tlschan_fake_close_method; channel_mark_for_close(ch); - tor_free(ch); + free_fake_channel(ch); UNMOCK(scheduler_release_channel); } @@ -304,6 +304,7 @@ tlschan_fake_close_method(channel_t *chan) tt_assert(tlschan != NULL); /* Just free the fake orconn */ + tor_free(tlschan->conn->base_.address); tor_free(tlschan->conn); channel_closed(chan); diff --git a/src/test/test_checkdir.c b/src/test/test_checkdir.c index 6c520656e0..882e3b3a61 100644 --- a/src/test/test_checkdir.c +++ b/src/test/test_checkdir.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Tor Project, Inc. */ +/* Copyright (c) 2014-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_circuitlist.c b/src/test/test_circuitlist.c index 181aec20a9..0760accfc1 100644 --- a/src/test/test_circuitlist.c +++ b/src/test/test_circuitlist.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Tor Project, Inc. */ +/* Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define TOR_CHANNEL_INTERNAL_ diff --git a/src/test/test_circuitmux.c b/src/test/test_circuitmux.c index 20c106ab9d..2a2a7ba145 100644 --- a/src/test/test_circuitmux.c +++ b/src/test/test_circuitmux.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Tor Project, Inc. */ +/* Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define TOR_CHANNEL_INTERNAL_ diff --git a/src/test/test_cmdline_args.py b/src/test/test_cmdline_args.py index 55d1cdb805..c8e68e8240 100755 --- a/src/test/test_cmdline_args.py +++ b/src/test/test_cmdline_args.py @@ -57,14 +57,14 @@ def run_tor(args, failure=False): raise UnexpectedFailure() elif not result and failure: raise UnexpectedSuccess() - return b2s(output) + return b2s(output.replace('\r\n','\n')) def spaceify_fp(fp): for i in range(0, len(fp), 4): yield fp[i:i+4] def lines(s): - out = s.split("\n") + out = s.splitlines() if out and out[-1] == '': del out[-1] return out @@ -151,7 +151,7 @@ class CmdlineTests(unittest.TestCase): if os.stat(TOR).st_mtime < os.stat(main_c).st_mtime: self.skipTest(TOR+" not up to date") out = run_tor(["--digests"]) - main_line = [ l for l in lines(out) if l.endswith("/main.c") ] + main_line = [ l for l in lines(out) if l.endswith("/main.c") or l.endswith(" main.c") ] digest, name = main_line[0].split() f = open(main_c, 'rb') actual = hashlib.sha1(f.read()).hexdigest() diff --git a/src/test/test_config.c b/src/test/test_config.c index dcb4e92c56..fb8e4020dc 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -1,11 +1,12 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" #define CONFIG_PRIVATE +#define PT_PRIVATE #include "or.h" #include "addressmap.h" #include "config.h" @@ -578,6 +579,8 @@ pt_kickstart_proxy_mock(const smartlist_t *transport_list, /* XXXX check that args are as expected. */ ++pt_kickstart_proxy_mock_call_count; + + free_execve_args(proxy_argv); } static int @@ -853,10 +856,598 @@ test_config_fix_my_family(void *arg) or_options_free(defaults); } +static int n_hostname_01010101 = 0; + +/** This mock function is meant to replace tor_lookup_hostname(). + * It answers with 1.1.1.1 as IP adddress that resulted from lookup. + * This function increments <b>n_hostname_01010101</b> counter by one + * every time it is called. + */ +static int +tor_lookup_hostname_01010101(const char *name, uint32_t *addr) +{ + n_hostname_01010101++; + + if (name && addr) { + *addr = ntohl(0x01010101); + } + + return 0; +} + +static int n_hostname_localhost = 0; + +/** This mock function is meant to replace tor_lookup_hostname(). + * It answers with 127.0.0.1 as IP adddress that resulted from lookup. + * This function increments <b>n_hostname_localhost</b> counter by one + * every time it is called. + */ +static int +tor_lookup_hostname_localhost(const char *name, uint32_t *addr) +{ + n_hostname_localhost++; + + if (name && addr) { + *addr = 0x7f000001; + } + + return 0; +} + +static int n_hostname_failure = 0; + +/** This mock function is meant to replace tor_lookup_hostname(). + * It pretends to fail by returning -1 to caller. Also, this function + * increments <b>n_hostname_failure</b> every time it is called. + */ +static int +tor_lookup_hostname_failure(const char *name, uint32_t *addr) +{ + (void)name; + (void)addr; + + n_hostname_failure++; + + return -1; +} + +static int n_gethostname_replacement = 0; + +/** This mock function is meant to replace tor_gethostname(). It + * responds with string "onionrouter!" as hostname. This function + * increments <b>n_gethostname_replacement</b> by one every time + * it is called. + */ +static int +tor_gethostname_replacement(char *name, size_t namelen) +{ + n_gethostname_replacement++; + + if (name && namelen) { + strlcpy(name,"onionrouter!",namelen); + } + + return 0; +} + +static int n_gethostname_localhost = 0; + +/** This mock function is meant to replace tor_gethostname(). It + * responds with string "127.0.0.1" as hostname. This function + * increments <b>n_gethostname_localhost</b> by one every time + * it is called. + */ +static int +tor_gethostname_localhost(char *name, size_t namelen) +{ + n_gethostname_localhost++; + + if (name && namelen) { + strlcpy(name,"127.0.0.1",namelen); + } + + return 0; +} + +static int n_gethostname_failure = 0; + +/** This mock function is meant to replace tor_gethostname. + * It pretends to fail by returning -1. This function increments + * <b>n_gethostname_failure</b> by one every time it is called. + */ +static int +tor_gethostname_failure(char *name, size_t namelen) +{ + (void)name; + (void)namelen; + n_gethostname_failure++; + + return -1; +} + +static int n_get_interface_address = 0; + +/** This mock function is meant to replace get_interface_address(). + * It answers with address 8.8.8.8. This function increments + * <b>n_get_interface_address</b> by one every time it is called. + */ +static int +get_interface_address_08080808(int severity, uint32_t *addr) +{ + (void)severity; + + n_get_interface_address++; + + if (addr) { + *addr = ntohl(0x08080808); + } + + return 0; +} + +static int n_get_interface_address6 = 0; +static sa_family_t last_address6_family; + +/** This mock function is meant to replace get_interface_address6(). + * It answers with IP address 9.9.9.9 iff both of the following are true: + * - <b>family</b> is AF_INET + * - <b>addr</b> pointer is not NULL. + * This function increments <b>n_get_interface_address6</b> by one every + * time it is called. + */ +static int +get_interface_address6_replacement(int severity, sa_family_t family, + tor_addr_t *addr) +{ + (void)severity; + + last_address6_family = family; + n_get_interface_address6++; + + if ((family != AF_INET) || !addr) { + return -1; + } + + tor_addr_from_ipv4h(addr,0x09090909); + + return 0; +} + +static int n_get_interface_address_failure = 0; + +/** + * This mock function is meant to replace get_interface_address(). + * It pretends to fail getting interface address by returning -1. + * <b>n_get_interface_address_failure</b> is incremented by one + * every time this function is called. + */ +static int +get_interface_address_failure(int severity, uint32_t *addr) +{ + (void)severity; + (void)addr; + + n_get_interface_address_failure++; + + return -1; +} + +static int n_get_interface_address6_failure = 0; + +/** + * This mock function is meant to replace get_interface_addres6(). + * It will pretent to fail by return -1. + * <b>n_get_interface_address6_failure</b> is incremented by one + * every time this function is called and <b>last_address6_family</b> + * is assigned the value of <b>family</b> argument. + */ +static int +get_interface_address6_failure(int severity, sa_family_t family, + tor_addr_t *addr) +{ + (void)severity; + (void)addr; + n_get_interface_address6_failure++; + last_address6_family = family; + + return -1; +} + +static void +test_config_resolve_my_address(void *arg) +{ + or_options_t *options; + uint32_t resolved_addr; + const char *method_used; + char *hostname_out = NULL; + int retval; + int prev_n_hostname_01010101; + int prev_n_hostname_localhost; + int prev_n_hostname_failure; + int prev_n_gethostname_replacement; + int prev_n_gethostname_failure; + int prev_n_gethostname_localhost; + int prev_n_get_interface_address; + int prev_n_get_interface_address_failure; + int prev_n_get_interface_address6; + int prev_n_get_interface_address6_failure; + + (void)arg; + + options = options_new(); + + options_init(options); + + /* + * CASE 1: + * If options->Address is a valid IPv4 address string, we want + * the corresponding address to be parsed and returned. + */ + + options->Address = tor_strdup("128.52.128.105"); + + retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + &method_used,&hostname_out); + + tt_want(retval == 0); + tt_want_str_op(method_used,==,"CONFIGURED"); + tt_want(hostname_out == NULL); + tt_assert(htonl(resolved_addr) == 0x69803480); + + tor_free(options->Address); + +/* + * CASE 2: + * If options->Address is a valid DNS address, we want resolve_my_address() + * function to ask tor_lookup_hostname() for help with resolving it + * and return the address that was resolved (in host order). + */ + + MOCK(tor_lookup_hostname,tor_lookup_hostname_01010101); + + tor_free(options->Address); + options->Address = tor_strdup("www.torproject.org"); + + prev_n_hostname_01010101 = n_hostname_01010101; + + retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + &method_used,&hostname_out); + + tt_want(retval == 0); + tt_want(n_hostname_01010101 == prev_n_hostname_01010101 + 1); + tt_want_str_op(method_used,==,"RESOLVED"); + tt_want_str_op(hostname_out,==,"www.torproject.org"); + tt_assert(htonl(resolved_addr) == 0x01010101); + + UNMOCK(tor_lookup_hostname); + + tor_free(options->Address); + tor_free(hostname_out); + +/* + * CASE 3: + * Given that options->Address is NULL, we want resolve_my_address() + * to try and use tor_gethostname() to get hostname AND use + * tor_lookup_hostname() to get IP address. + */ + + resolved_addr = 0; + tor_free(options->Address); + options->Address = NULL; + + MOCK(tor_gethostname,tor_gethostname_replacement); + MOCK(tor_lookup_hostname,tor_lookup_hostname_01010101); + + prev_n_gethostname_replacement = n_gethostname_replacement; + prev_n_hostname_01010101 = n_hostname_01010101; + + retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + &method_used,&hostname_out); + + tt_want(retval == 0); + tt_want(n_gethostname_replacement == prev_n_gethostname_replacement + 1); + tt_want(n_hostname_01010101 == prev_n_hostname_01010101 + 1); + tt_want_str_op(method_used,==,"GETHOSTNAME"); + tt_want_str_op(hostname_out,==,"onionrouter!"); + tt_assert(htonl(resolved_addr) == 0x01010101); + + UNMOCK(tor_gethostname); + UNMOCK(tor_lookup_hostname); + + tor_free(hostname_out); + +/* + * CASE 4: + * Given that options->Address is a local host address, we want + * resolve_my_address() function to fail. + */ + + resolved_addr = 0; + tor_free(options->Address); + options->Address = tor_strdup("127.0.0.1"); + + retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + &method_used,&hostname_out); + + tt_want(resolved_addr == 0); + tt_assert(retval == -1); + + tor_free(options->Address); + tor_free(hostname_out); + +/* + * CASE 5: + * We want resolve_my_address() to fail if DNS address in options->Address + * cannot be resolved. + */ + + MOCK(tor_lookup_hostname,tor_lookup_hostname_failure); + + prev_n_hostname_failure = n_hostname_failure; + + tor_free(options->Address); + options->Address = tor_strdup("www.tor-project.org"); + + retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + &method_used,&hostname_out); + + tt_want(n_hostname_failure == prev_n_hostname_failure + 1); + tt_assert(retval == -1); + + UNMOCK(tor_lookup_hostname); + + tor_free(options->Address); + tor_free(hostname_out); + +/* + * CASE 6: + * If options->Address is NULL AND gettting local hostname fails, we want + * resolve_my_address() to fail as well. + */ + + MOCK(tor_gethostname,tor_gethostname_failure); + + prev_n_gethostname_failure = n_gethostname_failure; + + retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + &method_used,&hostname_out); + + tt_want(n_gethostname_failure == prev_n_gethostname_failure + 1); + tt_assert(retval == -1); + + UNMOCK(tor_gethostname); + tor_free(hostname_out); + +/* + * CASE 7: + * We want resolve_my_address() to try and get network interface address via + * get_interface_address() if hostname returned by tor_gethostname() cannot be + * resolved into IP address. + */ + + MOCK(tor_gethostname,tor_gethostname_replacement); + MOCK(tor_lookup_hostname,tor_lookup_hostname_failure); + MOCK(get_interface_address,get_interface_address_08080808); + + prev_n_gethostname_replacement = n_gethostname_replacement; + prev_n_get_interface_address = n_get_interface_address; + + retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + &method_used,&hostname_out); + + tt_want(retval == 0); + tt_want_int_op(n_gethostname_replacement, ==, + prev_n_gethostname_replacement + 1); + tt_want_int_op(n_get_interface_address, ==, + prev_n_get_interface_address + 1); + tt_want_str_op(method_used,==,"INTERFACE"); + tt_want(hostname_out == NULL); + tt_assert(resolved_addr == ntohl(0x08080808)); + + UNMOCK(get_interface_address); + tor_free(hostname_out); + +/* + * CASE 8: + * Suppose options->Address is NULL AND hostname returned by tor_gethostname() + * is unresolvable. We want resolve_my_address to fail if + * get_interface_address() fails. + */ + + MOCK(get_interface_address,get_interface_address_failure); + + prev_n_get_interface_address_failure = n_get_interface_address_failure; + prev_n_gethostname_replacement = n_gethostname_replacement; + + retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + &method_used,&hostname_out); + + tt_want(n_get_interface_address_failure == + prev_n_get_interface_address_failure + 1); + tt_want(n_gethostname_replacement == + prev_n_gethostname_replacement + 1); + tt_assert(retval == -1); + + UNMOCK(get_interface_address); + tor_free(hostname_out); + +/* + * CASE 9: + * Given that options->Address is NULL AND tor_lookup_hostname() + * fails AND hostname returned by gethostname() resolves + * to local IP address, we want resolve_my_address() function to + * call get_interface_address6(.,AF_INET,.) and return IP address + * the latter function has found. + */ + + MOCK(tor_lookup_hostname,tor_lookup_hostname_failure); + MOCK(tor_gethostname,tor_gethostname_replacement); + MOCK(get_interface_address6,get_interface_address6_replacement); + + prev_n_gethostname_replacement = n_gethostname_replacement; + prev_n_hostname_failure = n_hostname_failure; + prev_n_get_interface_address6 = n_get_interface_address6; + + retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + &method_used,&hostname_out); + + tt_want(last_address6_family == AF_INET); + tt_want(n_get_interface_address6 == prev_n_get_interface_address6 + 1); + tt_want(n_hostname_failure == prev_n_hostname_failure + 1); + tt_want(n_gethostname_replacement == prev_n_gethostname_replacement + 1); + tt_want(retval == 0); + tt_want_str_op(method_used,==,"INTERFACE"); + tt_assert(htonl(resolved_addr) == 0x09090909); + + UNMOCK(tor_lookup_hostname); + UNMOCK(tor_gethostname); + UNMOCK(get_interface_address6); + + tor_free(hostname_out); + + /* + * CASE 10: We want resolve_my_address() to fail if all of the following + * are true: + * 1. options->Address is not NULL + * 2. ... but it cannot be converted to struct in_addr by + * tor_inet_aton() + * 3. ... and tor_lookup_hostname() fails to resolve the + * options->Address + */ + + MOCK(tor_lookup_hostname,tor_lookup_hostname_failure); + + prev_n_hostname_failure = n_hostname_failure; + + tor_free(options->Address); + options->Address = tor_strdup("some_hostname"); + + retval = resolve_my_address(LOG_NOTICE, options, &resolved_addr, + &method_used,&hostname_out); + + tt_want(n_hostname_failure == prev_n_hostname_failure + 1); + tt_assert(retval == -1); + + UNMOCK(tor_gethostname); + UNMOCK(tor_lookup_hostname); + + tor_free(hostname_out); + + /* + * CASE 11: + * Suppose the following sequence of events: + * 1. options->Address is NULL + * 2. tor_gethostname() succeeds to get hostname of machine Tor + * if running on. + * 3. Hostname from previous step cannot be converted to + * address by using tor_inet_aton() function. + * 4. However, tor_lookup_hostname() succeds in resolving the + * hostname from step 2. + * 5. Unfortunately, tor_addr_is_internal() deems this address + * to be internal. + * 6. get_interface_address6(.,AF_INET,.) returns non-internal + * IPv4 + * + * We want resolve_my_addr() to succeed with method "INTERFACE" + * and address from step 6. + */ + + tor_free(options->Address); + options->Address = NULL; + + MOCK(tor_gethostname,tor_gethostname_replacement); + MOCK(tor_lookup_hostname,tor_lookup_hostname_localhost); + MOCK(get_interface_address6,get_interface_address6_replacement); + + prev_n_gethostname_replacement = n_gethostname_replacement; + prev_n_hostname_localhost = n_hostname_localhost; + prev_n_get_interface_address6 = n_get_interface_address6; + + retval = resolve_my_address(LOG_DEBUG, options, &resolved_addr, + &method_used,&hostname_out); + + tt_want(n_gethostname_replacement == prev_n_gethostname_replacement + 1); + tt_want(n_hostname_localhost == prev_n_hostname_localhost + 1); + tt_want(n_get_interface_address6 == prev_n_get_interface_address6 + 1); + + tt_str_op(method_used,==,"INTERFACE"); + tt_assert(!hostname_out); + tt_assert(retval == 0); + + /* + * CASE 11b: + * 1-5 as above. + * 6. get_interface_address6() fails. + * + * In this subcase, we want resolve_my_address() to fail. + */ + + UNMOCK(get_interface_address6); + MOCK(get_interface_address6,get_interface_address6_failure); + + prev_n_gethostname_replacement = n_gethostname_replacement; + prev_n_hostname_localhost = n_hostname_localhost; + prev_n_get_interface_address6_failure = n_get_interface_address6_failure; + + retval = resolve_my_address(LOG_DEBUG, options, &resolved_addr, + &method_used,&hostname_out); + + tt_want(n_gethostname_replacement == prev_n_gethostname_replacement + 1); + tt_want(n_hostname_localhost == prev_n_hostname_localhost + 1); + tt_want(n_get_interface_address6_failure == + prev_n_get_interface_address6_failure + 1); + + tt_assert(retval == -1); + + UNMOCK(tor_gethostname); + UNMOCK(tor_lookup_hostname); + UNMOCK(get_interface_address6); + + /* CASE 12: + * Suppose the following happens: + * 1. options->Address is NULL AND options->DirAuthorities is 1. + * 2. tor_gethostname() succeeds in getting hostname of a machine ... + * 3. ... which is successfully parsed by tor_inet_aton() ... + * 4. into IPv4 address that tor_addr_is_inernal() considers to be + * internal. + * + * In this case, we want resolve_my_address() to fail. + */ + + tor_free(options->Address); + options->Address = NULL; + options->DirAuthorities = tor_malloc_zero(sizeof(config_line_t)); + + MOCK(tor_gethostname,tor_gethostname_localhost); + + prev_n_gethostname_localhost = n_gethostname_localhost; + + retval = resolve_my_address(LOG_DEBUG, options, &resolved_addr, + &method_used,&hostname_out); + + tt_want(n_gethostname_localhost == prev_n_gethostname_localhost + 1); + tt_assert(retval == -1); + + UNMOCK(tor_gethostname); + + done: + tor_free(options->Address); + tor_free(options->DirAuthorities); + or_options_free(options); + tor_free(hostname_out); + + UNMOCK(tor_gethostname); + UNMOCK(tor_lookup_hostname); + UNMOCK(get_interface_address); + UNMOCK(get_interface_address6); + UNMOCK(tor_gethostname); +} + #define CONFIG_TEST(name, flags) \ { #name, test_config_ ## name, flags, NULL, NULL } struct testcase_t config_tests[] = { + CONFIG_TEST(resolve_my_address, TT_FORK), CONFIG_TEST(addressmap, 0), CONFIG_TEST(parse_bridge_line, 0), CONFIG_TEST(parse_transport_options_line, 0), diff --git a/src/test/test_containers.c b/src/test/test_containers.c index 1eb8c15fd5..79085a748e 100644 --- a/src/test/test_containers.c +++ b/src/test/test_containers.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_controller_events.c b/src/test/test_controller_events.c index dd9d590ec7..e36314da45 100644 --- a/src/test/test_controller_events.c +++ b/src/test/test_controller_events.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Tor Project, Inc. */ +/* Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CONNECTION_PRIVATE diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c index 5352b9fdb4..4a5a12c50a 100644 --- a/src/test/test_crypto.c +++ b/src/test/test_crypto.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_data.c b/src/test/test_data.c index 0e6f79f33c..6afba65757 100644 --- a/src/test/test_data.c +++ b/src/test/test_data.c @@ -1,6 +1,6 @@ /* Copyright 2001-2004 Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* Our unit test expect that the AUTHORITY_CERT_* public keys will sort diff --git a/src/test/test_dir.c b/src/test/test_dir.c index e5328fed56..c6594f8359 100644 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -388,6 +388,12 @@ test_dir_routerparse_bad(void *arg) #include "example_extrainfo.inc" static void +routerinfo_free_wrapper_(void *arg) +{ + routerinfo_free(arg); +} + +static void test_dir_extrainfo_parsing(void *arg) { (void) arg; @@ -455,9 +461,9 @@ test_dir_extrainfo_parsing(void *arg) #undef CHECK_FAIL done: + extrainfo_free(ei); routerinfo_free(ri); - /* XXXX elements should get freed too */ - digestmap_free((digestmap_t*)map, NULL); + digestmap_free((digestmap_t*)map, routerinfo_free_wrapper_); } static void @@ -552,9 +558,8 @@ test_dir_parse_router_list(void *arg) SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); smartlist_free(chunks); routerinfo_free(ri); - /* XXXX this leaks: */ if (map) { - digestmap_free((digestmap_t*)map, NULL); + digestmap_free((digestmap_t*)map, routerinfo_free_wrapper_); router_get_routerlist()->identity_map = (struct digest_ri_map_t*)digestmap_new(); } @@ -605,6 +610,7 @@ test_dir_load_routers(void *arg) smartlist_t *wanted = smartlist_new(); char buf[DIGEST_LEN]; char *mem_op_hex_tmp = NULL; + char *list = NULL; #define ADD(str) \ do { \ @@ -630,7 +636,7 @@ test_dir_load_routers(void *arg) /* Not ADDing BAD_PORTS */ ADD(EX_RI_BAD_TOKENS); - char *list = smartlist_join_strings(chunks, "", 0, NULL); + list = smartlist_join_strings(chunks, "", 0, NULL); tt_int_op(1, OP_EQ, router_load_routers_from_string(list, NULL, SAVED_IN_JOURNAL, wanted, 1, NULL)); @@ -670,6 +676,7 @@ test_dir_load_routers(void *arg) smartlist_free(chunks); SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp)); smartlist_free(wanted); + tor_free(list); } static int mock_get_by_ei_dd_calls = 0; @@ -722,6 +729,7 @@ test_dir_load_extrainfo(void *arg) smartlist_t *wanted = smartlist_new(); char buf[DIGEST_LEN]; char *mem_op_hex_tmp = NULL; + char *list = NULL; #define ADD(str) \ do { \ @@ -746,7 +754,7 @@ test_dir_load_extrainfo(void *arg) ADD(EX_EI_BAD_TOKENS); ADD(EX_EI_BAD_SIG2); - char *list = smartlist_join_strings(chunks, "", 0, NULL); + list = smartlist_join_strings(chunks, "", 0, NULL); router_load_extrainfo_from_string(list, NULL, SAVED_IN_JOURNAL, wanted, 1); /* The "maximal" router was added. */ @@ -788,6 +796,7 @@ test_dir_load_extrainfo(void *arg) smartlist_free(chunks); SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp)); smartlist_free(wanted); + tor_free(list); } static void @@ -836,6 +845,42 @@ test_dir_versions(void *arg) tt_int_op(VER_RELEASE,OP_EQ, ver1.status); tt_str_op("",OP_EQ, ver1.status_tag); + tt_int_op(0, OP_EQ, tor_version_parse("10.1", &ver1)); + tt_int_op(10, OP_EQ, ver1.major); + tt_int_op(1, OP_EQ, ver1.minor); + tt_int_op(0, OP_EQ, ver1.micro); + tt_int_op(0, OP_EQ, ver1.patchlevel); + tt_int_op(VER_RELEASE, OP_EQ, ver1.status); + tt_str_op("", OP_EQ, ver1.status_tag); + tt_int_op(0, OP_EQ, tor_version_parse("5.99.999", &ver1)); + tt_int_op(5, OP_EQ, ver1.major); + tt_int_op(99, OP_EQ, ver1.minor); + tt_int_op(999, OP_EQ, ver1.micro); + tt_int_op(0, OP_EQ, ver1.patchlevel); + tt_int_op(VER_RELEASE, OP_EQ, ver1.status); + tt_str_op("", OP_EQ, ver1.status_tag); + tt_int_op(0, OP_EQ, tor_version_parse("10.1-alpha", &ver1)); + tt_int_op(10, OP_EQ, ver1.major); + tt_int_op(1, OP_EQ, ver1.minor); + tt_int_op(0, OP_EQ, ver1.micro); + tt_int_op(0, OP_EQ, ver1.patchlevel); + tt_int_op(VER_RELEASE, OP_EQ, ver1.status); + tt_str_op("alpha", OP_EQ, ver1.status_tag); + tt_int_op(0, OP_EQ, tor_version_parse("2.1.700-alpha", &ver1)); + tt_int_op(2, OP_EQ, ver1.major); + tt_int_op(1, OP_EQ, ver1.minor); + tt_int_op(700, OP_EQ, ver1.micro); + tt_int_op(0, OP_EQ, ver1.patchlevel); + tt_int_op(VER_RELEASE, OP_EQ, ver1.status); + tt_str_op("alpha", OP_EQ, ver1.status_tag); + tt_int_op(0, OP_EQ, tor_version_parse("1.6.8-alpha-dev", &ver1)); + tt_int_op(1, OP_EQ, ver1.major); + tt_int_op(6, OP_EQ, ver1.minor); + tt_int_op(8, OP_EQ, ver1.micro); + tt_int_op(0, OP_EQ, ver1.patchlevel); + tt_int_op(VER_RELEASE, OP_EQ, ver1.status); + tt_str_op("alpha-dev", OP_EQ, ver1.status_tag); + #define tt_versionstatus_op(vs1, op, vs2) \ tt_assert_test_type(vs1,vs2,#vs1" "#op" "#vs2,version_status_t, \ (val1_ op val2_),"%d",TT_EXIT_TEST_FUNCTION) diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c index 5bf2985d2f..19071a1550 100644 --- a/src/test/test_entrynodes.c +++ b/src/test/test_entrynodes.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Tor Project, Inc. */ +/* Copyright (c) 2014-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_extorport.c b/src/test/test_extorport.c index d99961dd4a..2e5a32eef3 100644 --- a/src/test/test_extorport.c +++ b/src/test/test_extorport.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Tor Project, Inc. */ +/* Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CONNECTION_PRIVATE diff --git a/src/test/test_hs.c b/src/test/test_hs.c index a5cd841a55..0246eaf648 100644 --- a/src/test/test_hs.c +++ b/src/test/test_hs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2014, The Tor Project, Inc. */ +/* Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_introduce.c b/src/test/test_introduce.c index fe8ffbfa4b..0cab8ef4cc 100644 --- a/src/test/test_introduce.c +++ b/src/test/test_introduce.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_logging.c b/src/test/test_logging.c index 17f1ed566c..6205b3bdc5 100644 --- a/src/test/test_logging.c +++ b/src/test/test_logging.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Tor Project, Inc. */ +/* Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c index 4a7c29b747..fb3df77edc 100644 --- a/src/test/test_microdesc.c +++ b/src/test/test_microdesc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Tor Project, Inc. */ +/* Copyright (c) 2010-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -703,8 +703,7 @@ test_md_reject_cache(void *arg) done: UNMOCK(networkstatus_get_latest_consensus_by_flavor); UNMOCK(router_get_mutable_consensus_status_by_descriptor_digest); - if (options) - tor_free(options->DataDirectory); + tor_free(options->DataDirectory); microdesc_free_all(); smartlist_free(added); SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp)); diff --git a/src/test/test_nodelist.c b/src/test/test_nodelist.c index 2fba3da7e0..9bd8b4a7ea 100644 --- a/src/test/test_nodelist.c +++ b/src/test/test_nodelist.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2014, The Tor Project, Inc. */ +/* Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_ntor_cl.c b/src/test/test_ntor_cl.c index 2899ad6710..955b508ef0 100644 --- a/src/test/test_ntor_cl.c +++ b/src/test/test_ntor_cl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_oom.c b/src/test/test_oom.c index 1f21f65c60..28b4c0435a 100644 --- a/src/test/test_oom.c +++ b/src/test/test_oom.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Tor Project, Inc. */ +/* Copyright (c) 2014-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* Unit tests for OOM handling logic */ diff --git a/src/test/test_options.c b/src/test/test_options.c index 44349b3800..a8ebadb14b 100644 --- a/src/test/test_options.c +++ b/src/test/test_options.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CONFIG_PRIVATE diff --git a/src/test/test_policy.c b/src/test/test_policy.c index e77e16c99e..33f90c7da5 100644 --- a/src/test/test_policy.c +++ b/src/test/test_policy.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Tor Project, Inc. */ +/* Copyright (c) 2013-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "or.h" diff --git a/src/test/test_pt.c b/src/test/test_pt.c index dba880ee19..996ef8666b 100644 --- a/src/test/test_pt.c +++ b/src/test/test_pt.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_relay.c b/src/test/test_relay.c index 6907597705..2144ef335e 100644 --- a/src/test/test_relay.c +++ b/src/test/test_relay.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Tor Project, Inc. */ +/* Copyright (c) 2014-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "or.h" @@ -111,14 +111,14 @@ test_relay_append_cell_to_circuit_queue(void *arg) /* Shut down channels */ channel_free_all(); - nchan = pchan = NULL; done: + tor_free(cell); + cell_queue_clear(&orcirc->base_.n_chan_cells); + cell_queue_clear(&orcirc->p_chan_cells); tor_free(orcirc); - if (nchan && nchan->cmux) circuitmux_free(nchan->cmux); - tor_free(nchan); - if (pchan && pchan->cmux) circuitmux_free(pchan->cmux); - tor_free(pchan); + free_fake_channel(nchan); + free_fake_channel(pchan); #ifdef ENABLE_MEMPOOLS free_cell_pool(); #endif /* ENABLE_MEMPOOLS */ diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c index 834dfeface..28c8f4e8ef 100644 --- a/src/test/test_relaycell.c +++ b/src/test/test_relaycell.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Tor Project, Inc. */ +/* Copyright (c) 2014-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* Unit tests for handling different kinds of relay cell */ @@ -104,7 +104,7 @@ test_relaycell_resolved(void *arg) tt_int_op(srm_answer_is_set, OP_EQ, 0); \ } \ tt_int_op(srm_ttl, OP_EQ, ttl); \ - tt_int_op(srm_expires, OP_EQ, expires); \ + tt_i64_op(srm_expires, OP_EQ, expires); \ } while (0) (void)arg; diff --git a/src/test/test_replay.c b/src/test/test_replay.c index b1f637a43b..a02c160365 100644 --- a/src/test/test_replay.c +++ b/src/test/test_replay.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Tor Project, Inc. */ +/* Copyright (c) 2012-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define REPLAYCACHE_PRIVATE diff --git a/src/test/test_routerkeys.c b/src/test/test_routerkeys.c index d8ad59a58b..60b6bb5a72 100644 --- a/src/test/test_routerkeys.c +++ b/src/test/test_routerkeys.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_scheduler.c b/src/test/test_scheduler.c index a7a1acc83e..73a422088f 100644 --- a/src/test/test_scheduler.c +++ b/src/test/test_scheduler.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Tor Project, Inc. */ +/* Copyright (c) 2014-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include <math.h> diff --git a/src/test/test_socks.c b/src/test/test_socks.c index fbb8b25980..465e427930 100644 --- a/src/test/test_socks.c +++ b/src/test/test_socks.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "or.h" diff --git a/src/test/test_util.c b/src/test/test_util.c index b952bb2596..15470e8efa 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2014, The Tor Project, Inc. */ + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -589,15 +589,17 @@ test_util_time(void *arg) i = parse_iso_time("2004-8-4 0:48:22", &t_res); tt_int_op(0,OP_EQ, i); tt_int_op(t_res,OP_EQ, (time_t)1091580502UL); - tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-zz 99-99x99 GMT", &t_res)); - tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-32 00:00:00 GMT", &t_res)); - tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 24:00:00 GMT", &t_res)); - tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:60:00 GMT", &t_res)); - tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:59:62 GMT", &t_res)); - tt_int_op(-1,OP_EQ, parse_iso_time("1969-03-30 23:59:59 GMT", &t_res)); - tt_int_op(-1,OP_EQ, parse_iso_time("2011-00-30 23:59:59 GMT", &t_res)); + tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-zz 99-99x99", &t_res)); + tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-32 00:00:00", &t_res)); + tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 24:00:00", &t_res)); + tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:60:00", &t_res)); + tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:59:62", &t_res)); + tt_int_op(-1,OP_EQ, parse_iso_time("1969-03-30 23:59:59", &t_res)); + tt_int_op(-1,OP_EQ, parse_iso_time("2011-00-30 23:59:59", &t_res)); tt_int_op(-1,OP_EQ, parse_iso_time("2147483647-08-29 14:00:00", &t_res)); tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:59", &t_res)); + tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04 00:48:22.100", &t_res)); + tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04 00:48:22XYZ", &t_res)); /* Test tor_gettimeofday */ @@ -1820,7 +1822,7 @@ test_util_gzip(void *arg) tor_free(buf1); tor_free(buf2); tor_free(buf3); - state = tor_zlib_new(1, ZLIB_METHOD); + state = tor_zlib_new(1, ZLIB_METHOD, HIGH_COMPRESSION); tt_assert(state); cp1 = buf1 = tor_malloc(1024); len1 = 1024; @@ -4619,6 +4621,58 @@ test_util_round_to_next_multiple_of(void *arg) tt_assert(round_uint64_to_next_multiple_of(99,7) == 105); tt_assert(round_uint64_to_next_multiple_of(99,9) == 99); + tt_assert(round_int64_to_next_multiple_of(0,1) == 0); + tt_assert(round_int64_to_next_multiple_of(0,7) == 0); + + tt_assert(round_int64_to_next_multiple_of(99,1) == 99); + tt_assert(round_int64_to_next_multiple_of(99,7) == 105); + tt_assert(round_int64_to_next_multiple_of(99,9) == 99); + + tt_assert(round_int64_to_next_multiple_of(-99,1) == -99); + tt_assert(round_int64_to_next_multiple_of(-99,7) == -98); + tt_assert(round_int64_to_next_multiple_of(-99,9) == -99); + + tt_assert(round_int64_to_next_multiple_of(INT64_MIN,2) == INT64_MIN); + tt_assert(round_int64_to_next_multiple_of(INT64_MAX,2) == + INT64_MAX-INT64_MAX%2); + done: + ; +} + +static void +test_util_laplace(void *arg) +{ + /* Sample values produced using Python's SciPy: + * + * >>> from scipy.stats import laplace + * >>> laplace.ppf([-0.01, 0.0, 0.01, 0.5, 0.51, 0.99, 1.0, 1.01], + ... loc = 24, scale = 24) + * array([ nan, -inf, -69.88855213, 24. , + * 24.48486498, 117.88855213, inf, nan]) + */ + const double mu = 24.0, b = 24.0; + const double delta_f = 15.0, epsilon = 0.3; /* b = 15.0 / 0.3 = 50.0 */ + (void)arg; + + tt_assert(isinf(sample_laplace_distribution(mu, b, 0.0))); + test_feq(-69.88855213, sample_laplace_distribution(mu, b, 0.01)); + test_feq(24.0, sample_laplace_distribution(mu, b, 0.5)); + test_feq(24.48486498, sample_laplace_distribution(mu, b, 0.51)); + test_feq(117.88855213, sample_laplace_distribution(mu, b, 0.99)); + + /* >>> laplace.ppf([0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99], + * ... loc = 0, scale = 50) + * array([ -inf, -80.47189562, -34.65735903, 0. , + * 34.65735903, 80.47189562, 195.60115027]) + */ + tt_assert(INT64_MIN + 20 == + add_laplace_noise(20, 0.0, delta_f, epsilon)); + tt_assert(-60 == add_laplace_noise(20, 0.1, delta_f, epsilon)); + tt_assert(-14 == add_laplace_noise(20, 0.25, delta_f, epsilon)); + tt_assert(20 == add_laplace_noise(20, 0.5, delta_f, epsilon)); + tt_assert(54 == add_laplace_noise(20, 0.75, delta_f, epsilon)); + tt_assert(100 == add_laplace_noise(20, 0.9, delta_f, epsilon)); + tt_assert(215 == add_laplace_noise(20, 0.99, delta_f, epsilon)); done: ; } @@ -4797,7 +4851,7 @@ test_util_max_mem(void *arg) } else { /* You do not have a petabyte. */ #if SIZEOF_SIZE_T == SIZEOF_UINT64_T - tt_uint_op(memory1, OP_LT, (U64_LITERAL(1)<<50)); + tt_u64_op(memory1, OP_LT, (U64_LITERAL(1)<<50)); #endif } @@ -4880,6 +4934,7 @@ struct testcase_t util_tests[] = { UTIL_LEGACY(strtok), UTIL_LEGACY(di_ops), UTIL_TEST(round_to_next_multiple_of, 0), + UTIL_TEST(laplace, 0), UTIL_TEST(strclear, 0), UTIL_TEST(find_str_at_start_of_line, 0), UTIL_TEST(string_is_C_identifier, 0), diff --git a/src/tools/tor-checkkey.c b/src/tools/tor-checkkey.c index f6c6508c33..e404b682cf 100644 --- a/src/tools/tor-checkkey.c +++ b/src/tools/tor-checkkey.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2014, The Tor Project, Inc. */ +/* Copyright (c) 2008-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/tools/tor-fw-helper/tor-fw-helper-natpmp.c b/src/tools/tor-fw-helper/tor-fw-helper-natpmp.c index 74485f9803..6369966869 100644 --- a/src/tools/tor-fw-helper/tor-fw-helper-natpmp.c +++ b/src/tools/tor-fw-helper/tor-fw-helper-natpmp.c @@ -1,5 +1,5 @@ /* Copyright (c) 2010, Jacob Appelbaum, Steven J. Murdoch. - * Copyright (c) 2010-2014, The Tor Project, Inc. */ + * Copyright (c) 2010-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/tools/tor-fw-helper/tor-fw-helper-natpmp.h b/src/tools/tor-fw-helper/tor-fw-helper-natpmp.h index 1bfebd91f9..abc5e11857 100644 --- a/src/tools/tor-fw-helper/tor-fw-helper-natpmp.h +++ b/src/tools/tor-fw-helper/tor-fw-helper-natpmp.h @@ -1,5 +1,5 @@ /* Copyright (c) 2010, Jacob Appelbaum, Steven J. Murdoch. - * Copyright (c) 2010-2014, The Tor Project, Inc. */ + * Copyright (c) 2010-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/tools/tor-fw-helper/tor-fw-helper-upnp.c b/src/tools/tor-fw-helper/tor-fw-helper-upnp.c index 59bc232dd3..e5495c906e 100644 --- a/src/tools/tor-fw-helper/tor-fw-helper-upnp.c +++ b/src/tools/tor-fw-helper/tor-fw-helper-upnp.c @@ -1,5 +1,5 @@ /* Copyright (c) 2010, Jacob Appelbaum, Steven J. Murdoch. - * Copyright (c) 2010-2014, The Tor Project, Inc. */ + * Copyright (c) 2010-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/tools/tor-fw-helper/tor-fw-helper-upnp.h b/src/tools/tor-fw-helper/tor-fw-helper-upnp.h index 9a5123e09f..bc9476eb98 100644 --- a/src/tools/tor-fw-helper/tor-fw-helper-upnp.h +++ b/src/tools/tor-fw-helper/tor-fw-helper-upnp.h @@ -1,5 +1,5 @@ /* Copyright (c) 2010, Jacob Appelbaum, Steven J. Murdoch. - * Copyright (c) 2010-2014, The Tor Project, Inc. */ + * Copyright (c) 2010-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/tools/tor-fw-helper/tor-fw-helper.c b/src/tools/tor-fw-helper/tor-fw-helper.c index 9a32b0cbe2..fdc0e1adea 100644 --- a/src/tools/tor-fw-helper/tor-fw-helper.c +++ b/src/tools/tor-fw-helper/tor-fw-helper.c @@ -1,5 +1,5 @@ /* Copyright (c) 2010, Jacob Appelbaum, Steven J. Murdoch. - * Copyright (c) 2010-2014, The Tor Project, Inc. */ + * Copyright (c) 2010-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/tools/tor-fw-helper/tor-fw-helper.h b/src/tools/tor-fw-helper/tor-fw-helper.h index 71bc11e168..4ebc75d8f7 100644 --- a/src/tools/tor-fw-helper/tor-fw-helper.h +++ b/src/tools/tor-fw-helper/tor-fw-helper.h @@ -1,5 +1,5 @@ /* Copyright (c) 2010, Jacob Appelbaum, Steven J. Murdoch. - * Copyright (c) 2010-2014, The Tor Project, Inc. */ + * Copyright (c) 2010-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/tools/tor-gencert.c b/src/tools/tor-gencert.c index f6805c1193..c599822e07 100644 --- a/src/tools/tor-gencert.c +++ b/src/tools/tor-gencert.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2014, The Tor Project, Inc. */ +/* Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/tools/tor-resolve.c b/src/tools/tor-resolve.c index 6ee155ade5..e6eadf1dd3 100644 --- a/src/tools/tor-resolve.c +++ b/src/tools/tor-resolve.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson - * Copyright (c) 2007-2014, The Tor Project, Inc. + * Copyright (c) 2007-2015, The Tor Project, Inc. */ /* See LICENSE for licensing information */ diff --git a/src/win32/orconfig.h b/src/win32/orconfig.h index cee81b31eb..d1a5b4b3e2 100644 --- a/src/win32/orconfig.h +++ b/src/win32/orconfig.h @@ -232,7 +232,7 @@ #define USING_TWOS_COMPLEMENT /* Version number of package */ -#define VERSION "0.2.6.1-alpha-dev" +#define VERSION "0.2.6.2-alpha-dev" |