summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/common/Makefile.am22
-rw-r--r--src/common/address.c13
-rw-r--r--src/common/address.h1
-rw-r--r--src/common/aes.c5
-rw-r--r--src/common/compat.c339
-rw-r--r--src/common/compat.h59
-rw-r--r--src/common/compat_libevent.c553
-rw-r--r--src/common/compat_libevent.h65
-rw-r--r--src/common/container.c187
-rw-r--r--src/common/container.h26
-rw-r--r--src/common/crypto.c357
-rw-r--r--src/common/crypto.h53
-rw-r--r--src/common/ht.h4
-rw-r--r--src/common/log.c75
-rw-r--r--src/common/memarea.c45
-rw-r--r--src/common/mempool.c2
-rw-r--r--src/common/sha256.c331
-rw-r--r--src/common/test.h184
-rw-r--r--src/common/torgzip.c41
-rw-r--r--src/common/torint.h3
-rw-r--r--src/common/torlog.h (renamed from src/common/log.h)11
-rw-r--r--src/common/tortls.c301
-rw-r--r--src/common/tortls.h5
-rw-r--r--src/common/tortls_states.h414
-rw-r--r--src/common/util.c403
-rw-r--r--src/common/util.h54
-rw-r--r--src/common/util_codedigest.c11
-rw-r--r--src/config/geoip14078
-rw-r--r--src/config/torrc.bridge.in171
-rw-r--r--src/config/torrc.complete.in533
-rw-r--r--src/config/torrc.sample.in26
-rw-r--r--src/or/Makefile.am121
-rw-r--r--src/or/buffers.c254
-rw-r--r--src/or/buffers.h58
-rw-r--r--src/or/circuitbuild.c1781
-rw-r--r--src/or/circuitbuild.h125
-rw-r--r--src/or/circuitlist.c124
-rw-r--r--src/or/circuitlist.h60
-rw-r--r--src/or/circuituse.c230
-rw-r--r--src/or/circuituse.h53
-rw-r--r--src/or/command.c38
-rw-r--r--src/or/command.h25
-rw-r--r--src/or/config.c1458
-rw-r--r--src/or/config.h78
-rw-r--r--src/or/config_codedigest.c11
-rw-r--r--src/or/connection.c622
-rw-r--r--src/or/connection.h100
-rw-r--r--src/or/connection_edge.c339
-rw-r--r--src/or/connection_edge.h100
-rw-r--r--src/or/connection_or.c372
-rw-r--r--src/or/connection_or.h57
-rw-r--r--src/or/control.c668
-rw-r--r--src/or/control.h85
-rw-r--r--src/or/cpuworker.c13
-rw-r--r--src/or/cpuworker.h25
-rw-r--r--src/or/directory.c448
-rw-r--r--src/or/directory.h110
-rw-r--r--src/or/dirserv.c800
-rw-r--r--src/or/dirserv.h134
-rw-r--r--src/or/dirvote.c1981
-rw-r--r--src/or/dirvote.h93
-rw-r--r--src/or/dns.c248
-rw-r--r--src/or/dns.h31
-rw-r--r--src/or/dnsserv.c55
-rw-r--r--src/or/dnsserv.h26
-rw-r--r--src/or/eventdns.c143
-rw-r--r--src/or/geoip.c1116
-rw-r--r--src/or/geoip.h57
-rw-r--r--src/or/hibernate.c192
-rw-r--r--src/or/hibernate.h29
-rw-r--r--src/or/main.c351
-rw-r--r--src/or/main.h67
-rw-r--r--src/or/microdesc.c414
-rw-r--r--src/or/microdesc.h37
-rw-r--r--src/or/networkstatus.c720
-rw-r--r--src/or/networkstatus.h100
-rw-r--r--src/or/ntmain.c127
-rw-r--r--src/or/ntmain.h30
-rw-r--r--src/or/onion.c31
-rw-r--r--src/or/onion.h48
-rw-r--r--src/or/or.h2304
-rw-r--r--src/or/policies.c116
-rw-r--r--src/or/policies.h60
-rw-r--r--src/or/reasons.c71
-rw-r--r--src/or/reasons.h31
-rw-r--r--src/or/relay.c751
-rw-r--r--src/or/relay.h68
-rw-r--r--src/or/rendclient.c187
-rw-r--r--src/or/rendclient.h43
-rw-r--r--src/or/rendcommon.c160
-rw-r--r--src/or/rendcommon.h65
-rw-r--r--src/or/rendmid.c5
-rw-r--r--src/or/rendmid.h25
-rw-r--r--src/or/rendservice.c298
-rw-r--r--src/or/rendservice.h37
-rw-r--r--src/or/rephist.c1134
-rw-r--r--src/or/rephist.h80
-rw-r--r--src/or/router.c551
-rw-r--r--src/or/router.h101
-rw-r--r--src/or/routerlist.c870
-rw-r--r--src/or/routerlist.h196
-rw-r--r--src/or/routerparse.c1402
-rw-r--r--src/or/routerparse.h88
-rw-r--r--src/or/test.c4911
-rw-r--r--src/or/tor_main.c2
-rw-r--r--src/test/Makefile.am30
-rw-r--r--src/test/test.c1286
-rw-r--r--src/test/test.h75
-rw-r--r--src/test/test_addr.c497
-rw-r--r--src/test/test_containers.c765
-rw-r--r--src/test/test_crypto.c788
-rw-r--r--src/test/test_data.c (renamed from src/or/test_data.c)0
-rw-r--r--src/test/test_dir.c1317
-rw-r--r--src/test/test_util.c1239
-rw-r--r--src/test/tinytest.c380
-rw-r--r--src/test/tinytest.h87
-rw-r--r--src/test/tinytest_demo.c215
-rw-r--r--src/test/tinytest_macros.h167
-rw-r--r--src/tools/Makefile.am6
-rw-r--r--src/tools/tor-checkkey.c14
-rw-r--r--src/tools/tor-gencert.c28
-rw-r--r--src/tools/tor-resolve.c8
-rw-r--r--src/win32/orconfig.h12
124 files changed, 34679 insertions, 18352 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index ae647b2d61..fa2dd560a6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,5 @@
# leave in dependency order, since common must be built first
-SUBDIRS = common or tools win32 config
-DIST_SUBDIRS = common or tools win32 config
+SUBDIRS = common or test tools win32 config
+DIST_SUBDIRS = common or test tools win32 config
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 105c413343..b1e03cd710 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -1,5 +1,7 @@
-noinst_LIBRARIES = libor.a libor-crypto.a
+noinst_LIBRARIES = libor.a libor-crypto.a libor-event.a
+
+EXTRA_DIST = common_sha1.i sha256.c
#CFLAGS = -Wall -Wpointer-arith -O2
@@ -10,7 +12,21 @@ libor_extra_source=
endif
libor_a_SOURCES = address.c log.c util.c compat.c container.c mempool.c \
- memarea.c $(libor_extra_source)
+ memarea.c util_codedigest.c $(libor_extra_source)
libor_crypto_a_SOURCES = crypto.c aes.c tortls.c torgzip.c
+libor_event_a_SOURCES = compat_libevent.c
+
+noinst_HEADERS = address.h torlog.h crypto.h util.h compat.h aes.h torint.h tortls.h strlcpy.c strlcat.c torgzip.h container.h ht.h mempool.h memarea.h ciphers.inc compat_libevent.h tortls_states.h
+
+common_sha1.i: $(libor_SOURCES) $(libor_crypto_a_SOURCES) $(noinst_HEADERS)
+ if test "@SHA1SUM@" != none; then \
+ @SHA1SUM@ $(libor_SOURCES) $(libor_crypto_a_SOURCES) $(noinst_HEADERS) | @SED@ -n 's/^\(.*\)$$/"\1\\n"/p' > common_sha1.i; \
+ elif test "@OPENSSL@" != none; then \
+ @OPENSSL@ sha1 $(libor_SOURCES) $(libor_crypto_a_SOURCES) $(noinst_HEADERS) | @SED@ -n 's/SHA1(\(.*\))= \(.*\)/"\2 \1\\n"/p' > common_sha1.i; \
+ else \
+ rm common_sha1.i; \
+ touch common_sha1.i; \
+ fi
-noinst_HEADERS = address.h log.h crypto.h test.h util.h compat.h aes.h torint.h tortls.h strlcpy.c strlcat.c torgzip.h container.h ht.h mempool.h memarea.h ciphers.inc
+util_codedigest.o: common_sha1.i
+crypto.o: sha256.c
diff --git a/src/common/address.c b/src/common/address.c
index 58ead3075a..c35f04c18b 100644
--- a/src/common/address.c
+++ b/src/common/address.c
@@ -12,7 +12,7 @@
#include "compat.h"
#include "util.h"
#include "address.h"
-#include "log.h"
+#include "torlog.h"
#ifdef MS_WINDOWS
#include <process.h>
@@ -726,7 +726,7 @@ tor_addr_is_loopback(const tor_addr_t *addr)
}
/** Set <b>dest</b> to equal the IPv4 address in <b>v4addr</b> (given in
- * network order. */
+ * network order). */
void
tor_addr_from_ipv4n(tor_addr_t *dest, uint32_t v4addr)
{
@@ -760,6 +760,8 @@ tor_addr_from_in6(tor_addr_t *dest, const struct in6_addr *in6)
void
tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src)
{
+ if (src == dest)
+ return;
tor_assert(src);
tor_assert(dest);
memcpy(dest, src, sizeof(tor_addr_t));
@@ -912,13 +914,6 @@ tor_dup_addr(const tor_addr_t *addr)
return tor_strdup(buf);
}
-/** Copy the address in <b>src</b> to <b>dest</b> */
-void
-tor_addr_assign(tor_addr_t *dest, const tor_addr_t *src)
-{
- memcpy(dest, src, sizeof(tor_addr_t));
-}
-
/** Return a string representing the address <b>addr</b>. This string is
* statically allocated, and must not be freed. Each call to
* <b>fmt_addr</b> invalidates the last result of the function. This
diff --git a/src/common/address.h b/src/common/address.h
index 352e0d7237..6116bb4b1c 100644
--- a/src/common/address.h
+++ b/src/common/address.h
@@ -107,7 +107,6 @@ tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u)
int tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr_out);
char *tor_dup_addr(const tor_addr_t *addr) ATTR_MALLOC;
-void tor_addr_assign(tor_addr_t *dest, const tor_addr_t *src);
const char *fmt_addr(const tor_addr_t *addr);
int get_interface_address6(int severity, sa_family_t family, tor_addr_t *addr);
diff --git a/src/common/aes.c b/src/common/aes.c
index 5a6bab242d..a17328317e 100644
--- a/src/common/aes.c
+++ b/src/common/aes.c
@@ -21,7 +21,7 @@
#include "compat.h"
#include "aes.h"
#include "util.h"
-#include "log.h"
+#include "torlog.h"
/* We have 3 strategies for getting AES: Via OpenSSL's AES_encrypt function,
* via OpenSSL's EVP_EncryptUpdate function, or via the built-in AES
@@ -263,7 +263,8 @@ aes_set_key(aes_cnt_cipher_t *cipher, const char *key, int key_bits)
void
aes_free_cipher(aes_cnt_cipher_t *cipher)
{
- tor_assert(cipher);
+ if (!cipher)
+ return;
#ifdef USE_OPENSSL_EVP
EVP_CIPHER_CTX_cleanup(&cipher->key);
#endif
diff --git a/src/common/compat.c b/src/common/compat.c
index 4cc8d99794..8ec4221b22 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -88,7 +88,7 @@
#include <sys/prctl.h>
#endif
-#include "log.h"
+#include "torlog.h"
#include "util.h"
#include "container.h"
#include "address.h"
@@ -170,12 +170,17 @@ tor_munmap_file(tor_mmap_t *handle)
tor_mmap_t *
tor_mmap_file(const char *filename)
{
+ TCHAR tfilename[MAX_PATH]= {0};
tor_mmap_t *res = tor_malloc_zero(sizeof(tor_mmap_t));
int empty = 0;
res->file_handle = INVALID_HANDLE_VALUE;
res->mmap_handle = NULL;
-
- res->file_handle = CreateFile(filename,
+#ifdef UNICODE
+ mbstowcs(tfilename,filename,MAX_PATH);
+#else
+ strlcpy(tfilename,filename,MAX_PATH);
+#endif
+ res->file_handle = CreateFile(tfilename,
GENERIC_READ, FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
@@ -308,6 +313,100 @@ tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
return r;
}
+/**
+ * Portable asprintf implementation. Does a printf() into a newly malloc'd
+ * string. Sets *<b>strp</b> to this string, and returns its length (not
+ * including the terminating NUL character).
+ *
+ * You can treat this function as if its implementation were something like
+ <pre>
+ char buf[_INFINITY_];
+ tor_snprintf(buf, sizeof(buf), fmt, args);
+ *strp = tor_strdup(buf);
+ return strlen(*strp):
+ </pre>
+ * Where _INFINITY_ is an imaginary constant so big that any string can fit
+ * into it.
+ */
+int
+tor_asprintf(char **strp, const char *fmt, ...)
+{
+ int r;
+ va_list args;
+ va_start(args, fmt);
+ r = tor_vasprintf(strp, fmt, args);
+ va_end(args);
+ if (!*strp || r < 0) {
+ log_err(LD_BUG, "Internal error in asprintf");
+ tor_assert(0);
+ }
+ return r;
+}
+
+/**
+ * Portable vasprintf implementation. Does a printf() into a newly malloc'd
+ * string. Differs from regular vasprintf in the same ways that
+ * tor_asprintf() differs from regular asprintf.
+ */
+int
+tor_vasprintf(char **strp, const char *fmt, va_list args)
+{
+ /* use a temporary variable in case *strp is in args. */
+ char *strp_tmp=NULL;
+#ifdef HAVE_VASPRINTF
+ /* If the platform gives us one, use it. */
+ int r = vasprintf(&strp_tmp, fmt, args);
+ if (r < 0)
+ *strp = NULL;
+ else
+ *strp = strp_tmp;
+ return r;
+#elif defined(_MSC_VER)
+ /* On Windows, _vsnprintf won't tell us the length of the string if it
+ * overflows, so we need to use _vcsprintf to tell how much to allocate */
+ int len, r;
+ char *res;
+ len = _vscprintf(fmt, args);
+ if (len < 0) {
+ *strp = NULL;
+ return -1;
+ }
+ strp_tmp = tor_malloc(len + 1);
+ r = _vsnprintf(strp_tmp, len+1, fmt, args);
+ if (r != len) {
+ tor_free(strp_tmp);
+ *strp = NULL;
+ return -1;
+ }
+ *strp = strp_tmp;
+ return len;
+#else
+ /* Everywhere else, we have a decent vsnprintf that tells us how many
+ * characters we need. We give it a try on a short buffer first, since
+ * it might be nice to avoid the second vsnprintf call.
+ */
+ char buf[128];
+ int len, r;
+ va_list tmp_args;
+ va_copy(tmp_args, args);
+ len = vsnprintf(buf, sizeof(buf), fmt, tmp_args);
+ va_end(tmp_args);
+ if (len < (int)sizeof(buf)) {
+ *strp = tor_strdup(buf);
+ return len;
+ }
+ strp_tmp = tor_malloc(len+1);
+ r = vsnprintf(strp_tmp, len+1, fmt, args);
+ if (r != len) {
+ tor_free(strp_tmp);
+ *strp = NULL;
+ return -1;
+ }
+ *strp = strp_tmp;
+ return len;
+#endif
+}
+
/** Given <b>hlen</b> bytes at <b>haystack</b> and <b>nlen</b> bytes at
* <b>needle</b>, return a pointer to the first occurrence of the needle
* within the haystack, or NULL if there is no such occurrence.
@@ -399,6 +498,37 @@ const char TOR_TOLOWER_TABLE[256] = {
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
};
+/** Implementation of strtok_r for platforms whose coders haven't figured out
+ * how to write one. Hey guys! You can use this code here for free! */
+char *
+tor_strtok_r_impl(char *str, const char *sep, char **lasts)
+{
+ char *cp, *start;
+ if (str)
+ start = cp = *lasts = str;
+ else if (!*lasts)
+ return NULL;
+ else
+ start = cp = *lasts;
+
+ tor_assert(*sep);
+ if (sep[1]) {
+ while (*cp && !strchr(sep, *cp))
+ ++cp;
+ } else {
+ tor_assert(strlen(sep) == 1);
+ cp = strchr(cp, *sep);
+ }
+
+ if (!cp || !*cp) {
+ *lasts = NULL;
+ } else {
+ *cp++ = '\0';
+ *lasts = cp;
+ }
+ return start;
+}
+
#ifdef MS_WINDOWS
/** Take a filename and return a pointer to its final element. This
* function is called on __FILE__ to fix a MSVC nit where __FILE__
@@ -450,8 +580,8 @@ get_uint32(const void *cp)
return v;
}
/**
- * Read a 32-bit value beginning at <b>cp</b>. Equivalent to
- * *(uint32_t*)(cp), but will not cause segfaults on platforms that forbid
+ * Read a 64-bit value beginning at <b>cp</b>. Equivalent to
+ * *(uint64_t*)(cp), but will not cause segfaults on platforms that forbid
* unaligned memory access.
*/
uint64_t
@@ -979,9 +1109,6 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
#if defined(CYGWIN) || defined(__CYGWIN__)
const char *platform = "Cygwin";
const unsigned long MAX_CONNECTIONS = 3200;
-#elif defined(IPHONE)
- const char *platform = "iPhone";
- const unsigned long MAX_CONNECTIONS = 9999;
#elif defined(MS_WINDOWS)
const char *platform = "Windows";
const unsigned long MAX_CONNECTIONS = 15000;
@@ -1553,6 +1680,30 @@ tor_lookup_hostname(const char *name, uint32_t *addr)
return -1;
}
+/** Initialize the insecure libc RNG. */
+void
+tor_init_weak_random(unsigned seed)
+{
+#ifdef MS_WINDOWS
+ srand(seed);
+#else
+ srandom(seed);
+#endif
+}
+
+/** Return a randomly chosen value in the range 0..TOR_RAND_MAX. This
+ * entropy will not be cryptographically strong; do not rely on it
+ * for anything an adversary should not be able to predict. */
+long
+tor_weak_random(void)
+{
+#ifdef MS_WINDOWS
+ return rand();
+#else
+ return random();
+#endif
+}
+
/** Hold the result of our call to <b>uname</b>. */
static char uname_result[256];
/** True iff uname_result is set. */
@@ -1578,13 +1729,14 @@ get_uname(void)
#ifdef MS_WINDOWS
OSVERSIONINFOEX info;
int i;
- unsigned int leftover_mask;
const char *plat = NULL;
const char *extra = NULL;
+ char acsd[MAX_PATH] = {0};
static struct {
unsigned major; unsigned minor; const char *version;
} win_version_table[] = {
- { 6, 0, "Windows \"Longhorn\"" },
+ { 6, 1, "Windows 7" },
+ { 6, 0, "Windows Vista" },
{ 5, 2, "Windows Server 2003" },
{ 5, 1, "Windows XP" },
{ 5, 0, "Windows 2000" },
@@ -1595,25 +1747,6 @@ get_uname(void)
{ 3, 51, "Windows NT 3.51" },
{ 0, 0, NULL }
};
-#ifdef VER_SUITE_BACKOFFICE
- static struct {
- unsigned int mask; const char *str;
- } win_mask_table[] = {
- { VER_SUITE_BACKOFFICE, " {backoffice}" },
- { VER_SUITE_BLADE, " {\"blade\" (2003, web edition)}" },
- { VER_SUITE_DATACENTER, " {datacenter}" },
- { VER_SUITE_ENTERPRISE, " {enterprise}" },
- { VER_SUITE_EMBEDDEDNT, " {embedded}" },
- { VER_SUITE_PERSONAL, " {personal}" },
- { VER_SUITE_SINGLEUSERTS,
- " {terminal services, single user}" },
- { VER_SUITE_SMALLBUSINESS, " {small business}" },
- { VER_SUITE_SMALLBUSINESS_RESTRICTED,
- " {small business, restricted}" },
- { VER_SUITE_TERMINAL, " {terminal services}" },
- { 0, NULL },
- };
-#endif
memset(&info, 0, sizeof(info));
info.dwOSVersionInfoSize = sizeof(info);
if (! GetVersionEx((LPOSVERSIONINFO)&info)) {
@@ -1622,14 +1755,19 @@ get_uname(void)
uname_result_is_set = 1;
return uname_result;
}
+#ifdef UNICODE
+ wcstombs(acsd, info.szCSDVersion, MAX_PATH);
+#else
+ strlcpy(acsd, info.szCSDVersion, sizeof(acsd));
+#endif
if (info.dwMajorVersion == 4 && info.dwMinorVersion == 0) {
if (info.dwPlatformId == VER_PLATFORM_WIN32_NT)
plat = "Windows NT 4.0";
else
plat = "Windows 95";
- if (info.szCSDVersion[1] == 'B')
+ if (acsd[1] == 'B')
extra = "OSR2 (B)";
- else if (info.szCSDVersion[1] == 'C')
+ else if (acsd[1] == 'C')
extra = "OSR2 (C)";
} else {
for (i=0; win_version_table[i].major>0; ++i) {
@@ -1641,29 +1779,30 @@ get_uname(void)
}
}
if (plat && !strcmp(plat, "Windows 98")) {
- if (info.szCSDVersion[1] == 'A')
+ if (acsd[1] == 'A')
extra = "SE (A)";
- else if (info.szCSDVersion[1] == 'B')
+ else if (acsd[1] == 'B')
extra = "SE (B)";
}
if (plat) {
if (!extra)
- extra = info.szCSDVersion;
+ extra = acsd;
tor_snprintf(uname_result, sizeof(uname_result), "%s %s",
plat, extra);
} else {
if (info.dwMajorVersion > 6 ||
- (info.dwMajorVersion==6 && info.dwMinorVersion>0))
+ (info.dwMajorVersion==6 && info.dwMinorVersion>1))
tor_snprintf(uname_result, sizeof(uname_result),
"Very recent version of Windows [major=%d,minor=%d] %s",
(int)info.dwMajorVersion,(int)info.dwMinorVersion,
- info.szCSDVersion);
+ acsd);
else
tor_snprintf(uname_result, sizeof(uname_result),
"Unrecognized version of Windows [major=%d,minor=%d] %s",
(int)info.dwMajorVersion,(int)info.dwMinorVersion,
- info.szCSDVersion);
+ acsd);
}
+#if !defined (WINCE)
#ifdef VER_SUITE_BACKOFFICE
if (info.wProductType == VER_NT_DOMAIN_CONTROLLER) {
strlcat(uname_result, " [domain controller]", sizeof(uname_result));
@@ -1672,18 +1811,7 @@ get_uname(void)
} else if (info.wProductType == VER_NT_WORKSTATION) {
strlcat(uname_result, " [workstation]", sizeof(uname_result));
}
- leftover_mask = info.wSuiteMask;
- for (i = 0; win_mask_table[i].mask; ++i) {
- if (info.wSuiteMask & win_mask_table[i].mask) {
- strlcat(uname_result, win_mask_table[i].str, sizeof(uname_result));
- leftover_mask &= ~win_mask_table[i].mask;
- }
- }
- if (leftover_mask) {
- size_t len = strlen(uname_result);
- tor_snprintf(uname_result+len, sizeof(uname_result)-len,
- " {0x%x}", info.wSuiteMask);
- }
+#endif
#endif
#else
strlcpy(uname_result, "Unknown platform", sizeof(uname_result));
@@ -1793,7 +1921,6 @@ spawn_exit(void)
* call _exit, not exit, from child processes. */
_exit(0);
#endif
-
}
/** Set *timeval to the current time of day. On error, log and terminate.
@@ -1813,8 +1940,15 @@ tor_gettimeofday(struct timeval *timeval)
uint64_t ft_64;
FILETIME ft_ft;
} ft;
+#if defined (WINCE)
+ /* wince do not have GetSystemTimeAsFileTime */
+ SYSTEMTIME stime;
+ GetSystemTime(&stime);
+ SystemTimeToFileTime(&stime,&ft.ft_ft);
+#else
/* number of 100-nsec units since Jan 1, 1601 */
GetSystemTimeAsFileTime(&ft.ft_ft);
+#endif
if (ft.ft_64 < EPOCH_BIAS) {
log_err(LD_GENERAL,"System time is before 1970; failing.");
exit(1);
@@ -2014,6 +2148,8 @@ tor_mutex_new(void)
void
tor_mutex_free(tor_mutex_t *m)
{
+ if (!m)
+ return;
tor_mutex_uninit(m);
tor_free(m);
}
@@ -2041,7 +2177,8 @@ tor_cond_new(void)
void
tor_cond_free(tor_cond_t *cond)
{
- tor_assert(cond);
+ if (!cond)
+ return;
if (pthread_cond_destroy(&cond->cond)) {
log_warn(LD_GENERAL,"Error freeing condition: %s", strerror(errno));
return;
@@ -2098,7 +2235,8 @@ tor_cond_new(void)
void
tor_cond_free(tor_cond_t *cond)
{
- tor_assert(cond);
+ if (!cond)
+ return;
DeleteCriticalSection(&cond->mutex);
/* XXXX notify? */
smartlist_free(cond->events);
@@ -2174,6 +2312,89 @@ tor_threads_init(void)
}
#endif
+#if defined(HAVE_MLOCKALL) && HAVE_DECL_MLOCKALL && defined(RLIMIT_MEMLOCK)
+/** Attempt to raise the current and max rlimit to infinity for our process.
+ * This only needs to be done once and can probably only be done when we have
+ * not already dropped privileges.
+ */
+static int
+tor_set_max_memlock(void)
+{
+ /* Future consideration for Windows is probably SetProcessWorkingSetSize
+ * This is similar to setting the memory rlimit of RLIMIT_MEMLOCK
+ * http://msdn.microsoft.com/en-us/library/ms686234(VS.85).aspx
+ */
+
+ struct rlimit limit;
+
+ /* RLIM_INFINITY is -1 on some platforms. */
+ limit.rlim_cur = RLIM_INFINITY;
+ limit.rlim_max = RLIM_INFINITY;
+
+ if (setrlimit(RLIMIT_MEMLOCK, &limit) == -1) {
+ if (errno == EPERM) {
+ log_warn(LD_GENERAL, "You appear to lack permissions to change memory "
+ "limits. Are you root?");
+ }
+ log_warn(LD_GENERAL, "Unable to raise RLIMIT_MEMLOCK: %s",
+ strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+#endif
+
+/** Attempt to lock all current and all future memory pages.
+ * This should only be called once and while we're privileged.
+ * Like mlockall() we return 0 when we're successful and -1 when we're not.
+ * Unlike mlockall() we return 1 if we've already attempted to lock memory.
+ */
+int
+tor_mlockall(void)
+{
+ static int memory_lock_attempted = 0;
+
+ if (memory_lock_attempted) {
+ return 1;
+ }
+
+ memory_lock_attempted = 1;
+
+ /*
+ * Future consideration for Windows may be VirtualLock
+ * VirtualLock appears to implement mlock() but not mlockall()
+ *
+ * http://msdn.microsoft.com/en-us/library/aa366895(VS.85).aspx
+ */
+
+#if defined(HAVE_MLOCKALL) && HAVE_DECL_MLOCKALL && defined(RLIMIT_MEMLOCK)
+ if (tor_set_max_memlock() == 0) {
+ log_debug(LD_GENERAL, "RLIMIT_MEMLOCK is now set to RLIM_INFINITY.");
+ }
+
+ if (mlockall(MCL_CURRENT|MCL_FUTURE) == 0) {
+ log_info(LD_GENERAL, "Insecure OS paging is effectively disabled.");
+ return 0;
+ } else {
+ if (errno == ENOSYS) {
+ /* Apple - it's 2009! I'm looking at you. Grrr. */
+ log_notice(LD_GENERAL, "It appears that mlockall() is not available on "
+ "your platform.");
+ } else if (errno == EPERM) {
+ log_notice(LD_GENERAL, "It appears that you lack the permissions to "
+ "lock memory. Are you root?");
+ }
+ log_notice(LD_GENERAL, "Unable to lock all current and future memory "
+ "pages: %s", strerror(errno));
+ return -1;
+ }
+#else
+ log_warn(LD_GENERAL, "Unable to lock memory pages. mlockall() unsupported?");
+ return -1;
+#endif
+}
+
/** Identity of the "main" thread */
static unsigned long main_thread_id = -1;
@@ -2325,20 +2546,26 @@ network_init(void)
char *
format_win32_error(DWORD err)
{
- LPVOID str = NULL;
+ TCHAR *str = NULL;
char *result;
/* Somebody once decided that this interface was better than strerror(). */
- FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &str,
+ (LPVOID)&str,
0, NULL);
if (str) {
- result = tor_strdup((char*)str);
+#ifdef UNICODE
+ char abuf[1024] = {0};
+ wcstombs(abuf,str,1024);
+ result = tor_strdup(abuf);
+#else
+ result = tor_strdup(str);
+#endif
LocalFree(str); /* LocalFree != free() */
} else {
result = tor_strdup("<unformattable error>");
diff --git a/src/common/compat.h b/src/common/compat.h
index 209d9fc38b..03e0686e8d 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -51,6 +51,22 @@
#include <netinet6/in6.h>
#endif
+#if defined (WINCE)
+#include <fcntl.h>
+#include <io.h>
+#include <math.h>
+#include <projects.h>
+#define snprintf _snprintf
+/* this is not exported as W .... */
+#define SHGetPathFromIDListW SHGetPathFromIDList
+/* wcecompat has vasprintf */
+#define HAVE_VASPRINTF
+/* no service here */
+#ifdef NT_SERVICE
+#undef NT_SERVICE
+#endif
+#endif // WINCE
+
#ifndef NULL_REP_IS_ZERO_BYTES
#error "It seems your platform does not represent NULL as zero. We can't cope."
#endif
@@ -177,8 +193,8 @@ extern INLINE double U64_TO_DBL(uint64_t x) {
/* ===== String compatibility */
#ifdef MS_WINDOWS
/* Windows names string functions differently from most other platforms. */
-#define strncasecmp strnicmp
-#define strcasecmp stricmp
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
#endif
#ifndef HAVE_STRLCAT
size_t strlcat(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2));
@@ -196,18 +212,26 @@ size_t strlcpy(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2));
#define U64_SCANF_ARG(a) (a)
/** Expands to a literal uint64_t-typed constant for the value <b>n</b>. */
#define U64_LITERAL(n) (n ## ui64)
+#define I64_PRINTF_ARG(a) (a)
+#define I64_SCANF_ARG(a) (a)
+#define I64_LITERAL(n) (n ## i64)
#else
#define U64_PRINTF_ARG(a) ((long long unsigned int)(a))
#define U64_SCANF_ARG(a) ((long long unsigned int*)(a))
#define U64_LITERAL(n) (n ## llu)
+#define I64_PRINTF_ARG(a) ((long long signed int)(a))
+#define I64_SCANF_ARG(a) ((long long signed int*)(a))
+#define I64_LITERAL(n) (n ## ll)
#endif
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
/** The formatting string used to put a uint64_t value in a printf() or
* scanf() function. See also U64_PRINTF_ARG and U64_SCANF_ARG. */
#define U64_FORMAT "%I64u"
+#define I64_FORMAT "%I64d"
#else
#define U64_FORMAT "%llu"
+#define I64_FORMAT "%lld"
#endif
/** Represents an mmaped file. Allocated via tor_mmap_file; freed with
@@ -235,6 +259,10 @@ int tor_snprintf(char *str, size_t size, const char *format, ...)
int tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
ATTR_NONNULL((1,3));
+int tor_asprintf(char **strp, const char *fmt, ...)
+ CHECK_PRINTF(2,3);
+int tor_vasprintf(char **strp, const char *fmt, va_list args);
+
const void *tor_memmem(const void *haystack, size_t hlen, const void *needle,
size_t nlen) ATTR_PURE ATTR_NONNULL((1,3));
static const void *tor_memstr(const void *haystack, size_t hlen,
@@ -267,6 +295,13 @@ extern const char TOR_TOLOWER_TABLE[];
#define TOR_TOLOWER(c) (TOR_TOLOWER_TABLE[(uint8_t)c])
#define TOR_TOUPPER(c) (TOR_TOUPPER_TABLE[(uint8_t)c])
+char *tor_strtok_r_impl(char *str, const char *sep, char **lasts);
+#ifdef HAVE_STRTOK_R
+#define tor_strtok_r(str, sep, lasts) strtok_r(str, sep, lasts)
+#else
+#define tor_strtok_r(str, sep, lasts) tor_strtok_r_impl(str, sep, lasts)
+#endif
+
#ifdef MS_WINDOWS
#define _SHORT_FILE_ (tor_fix_source_file(__FILE__))
const char *tor_fix_source_file(const char *fname);
@@ -445,6 +480,11 @@ typedef enum {
SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED = 0x08,
} socks5_reply_status_t;
+/* ===== Insecure rng */
+void tor_init_weak_random(unsigned seed);
+long tor_weak_random(void);
+#define TOR_RAND_MAX (RAND_MAX)
+
/* ===== OS compatibility */
const char *get_uname(void);
@@ -502,6 +542,8 @@ typedef struct tor_mutex_t {
#endif
} tor_mutex_t;
+int tor_mlockall(void);
+
#ifdef TOR_IS_MULTITHREADED
tor_mutex_t *tor_mutex_new(void);
void tor_mutex_init(tor_mutex_t *m);
@@ -536,6 +578,19 @@ void tor_cond_signal_all(tor_cond_t *cond);
#endif
#endif
+/** Macros for MIN/MAX. Never use these when the arguments could have
+ * side-effects.
+ * {With GCC extensions we could probably define a safer MIN/MAX. But
+ * depending on that safety would be dangerous, since not every platform
+ * has it.}
+ **/
+#ifndef MAX
+#define MAX(a,b) ( ((a)<(b)) ? (b) : (a) )
+#endif
+#ifndef MIN
+#define MIN(a,b) ( ((a)>(b)) ? (b) : (a) )
+#endif
+
/* Platform-specific helpers. */
#ifdef MS_WINDOWS
char *format_win32_error(DWORD err);
diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c
new file mode 100644
index 0000000000..250fa2bdb7
--- /dev/null
+++ b/src/common/compat_libevent.c
@@ -0,0 +1,553 @@
+/* Copyright (c) 2009-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file compat_libevent.c
+ * \brief Wrappers to handle porting between different versions of libevent.
+ *
+ * In an ideal world, we'd just use Libevent 2.0 from now on. But as of June
+ * 2009, Libevent 2.0 is still in alpha, and we will have old versions of
+ * Libevent for the forseeable future.
+ **/
+
+#include "orconfig.h"
+#include "compat.h"
+#include "compat_libevent.h"
+
+#include "util.h"
+#include "torlog.h"
+
+#ifdef HAVE_EVENT2_EVENT_H
+#include <event2/event.h>
+#else
+#include <event.h>
+#endif
+
+/** A number representing a version of Libevent.
+
+ This is a 4-byte number, with the first three bytes representing the
+ major, minor, and patchlevel respectively of the library. The fourth
+ byte is unused.
+
+ This is equivalent to the format of LIBEVENT_VERSION_NUMBER on Libevent
+ 2.0.1 or later. For versions of Libevent before 1.4.0, which followed the
+ format of "1.0, 1.0a, 1.0b", we define 1.0 to be equivalent to 1.0.0, 1.0a
+ to be equivalent to 1.0.1, and so on.
+*/
+typedef uint32_t le_version_t;
+
+/* Macros: returns the number of a libevent version. */
+#define V(major, minor, patch) \
+ (((major) << 24) | ((minor) << 16) | ((patch) << 8))
+#define V_OLD(major, minor, patch) \
+ V((major), (minor), (patch)-'a'+1)
+
+#define LE_OLD V(0,0,0)
+#define LE_OTHER V(0,0,99)
+
+static le_version_t tor_get_libevent_version(const char **v_out);
+
+#ifdef HAVE_EVENT_SET_LOG_CALLBACK
+/** A string which, if it appears in a libevent log, should be ignored. */
+static const char *suppress_msg = NULL;
+/** Callback function passed to event_set_log() so we can intercept
+ * log messages from libevent. */
+static void
+libevent_logging_callback(int severity, const char *msg)
+{
+ char buf[1024];
+ size_t n;
+ if (suppress_msg && strstr(msg, suppress_msg))
+ return;
+ n = strlcpy(buf, msg, sizeof(buf));
+ if (n && n < sizeof(buf) && buf[n-1] == '\n') {
+ buf[n-1] = '\0';
+ }
+ switch (severity) {
+ case _EVENT_LOG_DEBUG:
+ log(LOG_DEBUG, LD_NET, "Message from libevent: %s", buf);
+ break;
+ case _EVENT_LOG_MSG:
+ log(LOG_INFO, LD_NET, "Message from libevent: %s", buf);
+ break;
+ case _EVENT_LOG_WARN:
+ log(LOG_WARN, LD_GENERAL, "Warning from libevent: %s", buf);
+ break;
+ case _EVENT_LOG_ERR:
+ log(LOG_ERR, LD_GENERAL, "Error from libevent: %s", buf);
+ break;
+ default:
+ log(LOG_WARN, LD_GENERAL, "Message [%d] from libevent: %s",
+ severity, buf);
+ break;
+ }
+}
+/** Set hook to intercept log messages from libevent. */
+void
+configure_libevent_logging(void)
+{
+ event_set_log_callback(libevent_logging_callback);
+}
+/** Ignore any libevent log message that contains <b>msg</b>. */
+void
+suppress_libevent_log_msg(const char *msg)
+{
+ suppress_msg = msg;
+}
+#else
+void
+configure_libevent_logging(void)
+{
+}
+void
+suppress_libevent_log_msg(const char *msg)
+{
+ (void)msg;
+}
+#endif
+
+#ifndef HAVE_EVENT2_EVENT_H
+/** Work-alike replacement for event_new() on pre-Libevent-2.0 systems. */
+struct event *
+tor_event_new(struct event_base *base, int sock, short what,
+ void (*cb)(int, short, void *), void *arg)
+{
+ struct event *e = tor_malloc_zero(sizeof(struct event));
+ event_set(e, sock, what, cb, arg);
+ if (! base)
+ base = tor_libevent_get_base();
+ event_base_set(base, e);
+ return e;
+}
+/** Work-alike replacement for evtimer_new() on pre-Libevent-2.0 systems. */
+struct event *
+tor_evtimer_new(struct event_base *base,
+ void (*cb)(int, short, void *), void *arg)
+{
+ return tor_event_new(base, -1, 0, cb, arg);
+}
+/** Work-alike replacement for evsignal_new() on pre-Libevent-2.0 systems. */
+struct event *
+tor_evsignal_new(struct event_base * base, int sig,
+ void (*cb)(int, short, void *), void *arg)
+{
+ return tor_event_new(base, sig, EV_SIGNAL|EV_PERSIST, cb, arg);
+}
+/** Work-alike replacement for event_free() on pre-Libevent-2.0 systems. */
+void
+tor_event_free(struct event *ev)
+{
+ event_del(ev);
+ tor_free(ev);
+}
+#endif
+
+/** Global event base for use by the main thread. */
+struct event_base *the_event_base = NULL;
+
+/* This is what passes for version detection on OSX. We set
+ * MACOSX_KQUEUE_IS_BROKEN to true iff we're on a version of OSX before
+ * 10.4.0 (aka 1040). */
+#ifdef __APPLE__
+#ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
+#define MACOSX_KQUEUE_IS_BROKEN \
+ (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1040)
+#else
+#define MACOSX_KQUEUE_IS_BROKEN 0
+#endif
+#endif
+
+/** Initialize the Libevent library and set up the event base. */
+void
+tor_libevent_initialize(void)
+{
+ tor_assert(the_event_base == NULL);
+
+#ifdef __APPLE__
+ if (MACOSX_KQUEUE_IS_BROKEN ||
+ tor_get_libevent_version(NULL) < V_OLD(1,1,'b')) {
+ setenv("EVENT_NOKQUEUE","1",1);
+ }
+#endif
+
+#ifdef HAVE_EVENT2_EVENT_H
+ the_event_base = event_base_new();
+#else
+ the_event_base = event_init();
+#endif
+
+#if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
+ /* Making this a NOTICE for now so we can link bugs to a libevent versions
+ * or methods better. */
+ log(LOG_NOTICE, LD_GENERAL,
+ "Initialized libevent version %s using method %s. Good.",
+ event_get_version(), tor_libevent_get_method());
+#else
+ log(LOG_NOTICE, LD_GENERAL,
+ "Initialized old libevent (version 1.0b or earlier).");
+ log(LOG_WARN, LD_GENERAL,
+ "You have a *VERY* old version of libevent. It is likely to be buggy; "
+ "please build Tor with a more recent version.");
+#endif
+}
+
+/** Return the current Libevent event base that we're set up to use. */
+struct event_base *
+tor_libevent_get_base(void)
+{
+ return the_event_base;
+}
+
+#ifndef HAVE_EVENT_BASE_LOOPEXIT
+/* Replacement for event_base_loopexit on some very old versions of Libevent
+ that we are not yet brave enough to deprecate. */
+int
+tor_event_base_loopexit(struct event_base *base, struct timeval *tv)
+{
+ tor_assert(base == the_event_base);
+ return event_loopexit(tv);
+}
+#endif
+
+/** Return the name of the Libevent backend we're using. */
+const char *
+tor_libevent_get_method(void)
+{
+#ifdef HAVE_EVENT2_EVENT_H
+ return event_base_get_method(the_event_base);
+#elif defined(HAVE_EVENT_GET_METHOD)
+ return event_get_method();
+#else
+ return "<unknown>";
+#endif
+}
+
+/** Return the le_version_t for the current version of libevent. If the
+ * version is very new, return LE_OTHER. If the version is so old that it
+ * doesn't support event_get_version(), return LE_OLD. DOCDOC */
+static le_version_t
+tor_decode_libevent_version(const char *v)
+{
+ unsigned major, minor, patchlevel;
+ char c, e, extra;
+ int fields;
+
+ /* Try the new preferred "1.4.11-stable" format.
+ * Also accept "1.4.14b-stable". */
+ fields = sscanf(v, "%u.%u.%u%c%c", &major, &minor, &patchlevel, &c, &e);
+ if (fields == 3 ||
+ ((fields == 4 || fields == 5 ) && (c == '-' || c == '_')) ||
+ (fields == 5 && TOR_ISALPHA(c) && (e == '-' || e == '_'))) {
+ return V(major,minor,patchlevel);
+ }
+
+ /* Try the old "1.3e" format. */
+ fields = sscanf(v, "%u.%u%c%c", &major, &minor, &c, &extra);
+ if (fields == 3 && TOR_ISALPHA(c)) {
+ return V_OLD(major, minor, c);
+ } else if (fields == 2) {
+ return V(major, minor, 0);
+ }
+
+ return LE_OTHER;
+}
+
+/** Return an integer representing the binary interface of a Libevent library.
+ * Two different versions with different numbers are sure not to be binary
+ * compatible. Two different versions with the same numbers have a decent
+ * chance of binary compatibility.*/
+static int
+le_versions_compatibility(le_version_t v)
+{
+ if (v == LE_OTHER)
+ return 0;
+ if (v < V_OLD(1,0,'c'))
+ return 1;
+ else if (v < V(1,4,0))
+ return 2;
+ else if (v < V(1,4,99))
+ return 3;
+ else if (v < V(2,0,1))
+ return 4;
+ else /* Everything 2.0 and later should be compatible. */
+ return 5;
+}
+
+/** Return the version number of the currently running version of Libevent.
+ See le_version_t for info on the format.
+ */
+static le_version_t
+tor_get_libevent_version(const char **v_out)
+{
+ const char *v;
+ le_version_t r;
+#if defined(HAVE_EVENT_GET_VERSION_NUMBER)
+ v = event_get_version();
+ r = event_get_version_number();
+#elif defined (HAVE_EVENT_GET_VERSION)
+ v = event_get_version();
+ r = tor_decode_libevent_version(v);
+#else
+ v = "pre-1.0c";
+ r = LE_OLD;
+#endif
+ if (v_out)
+ *v_out = v;
+ return r;
+}
+
+/** Return a string representation of the version of the currently running
+ * version of Libevent. */
+const char *
+tor_libevent_get_version_str(void)
+{
+#ifdef HAVE_EVENT_GET_VERSION
+ return event_get_version();
+#else
+ return "pre-1.0c";
+#endif
+}
+
+/**
+ * Compare the current Libevent method and version to a list of versions
+ * which are known not to work. Warn the user as appropriate.
+ */
+void
+tor_check_libevent_version(const char *m, int server,
+ const char **badness_out)
+{
+ int buggy = 0, iffy = 0, slow = 0, thread_unsafe = 0;
+ le_version_t version;
+ const char *v = NULL;
+ const char *badness = NULL;
+ const char *sad_os = "";
+
+ version = tor_get_libevent_version(&v);
+
+ /* XXX Would it be worthwhile disabling the methods that we know
+ * are buggy, rather than just warning about them and then proceeding
+ * to use them? If so, we should probably not wrap this whole thing
+ * in HAVE_EVENT_GET_VERSION and HAVE_EVENT_GET_METHOD. -RD */
+ /* XXXX The problem is that it's not trivial to get libevent to change it's
+ * method once it's initialized, and it's not trivial to tell what method it
+ * will use without initializing it. I guess we could preemptively disable
+ * buggy libevent modes based on the version _before_ initializing it,
+ * though, but then there's no good way (afaict) to warn "I would have used
+ * kqueue, but instead I'm using select." -NM */
+ /* XXXX022 revist the above; it is fixable now. */
+ if (!strcmp(m, "kqueue")) {
+ if (version < V_OLD(1,1,'b'))
+ buggy = 1;
+ } else if (!strcmp(m, "epoll")) {
+ if (version < V(1,1,0))
+ iffy = 1;
+ } else if (!strcmp(m, "poll")) {
+ if (version < V_OLD(1,0,'e'))
+ buggy = 1;
+ if (version < V(1,1,0))
+ slow = 1;
+ } else if (!strcmp(m, "select")) {
+ if (version < V(1,1,0))
+ slow = 1;
+ } else if (!strcmp(m, "win32")) {
+ if (version < V_OLD(1,1,'b'))
+ buggy = 1;
+ }
+
+ /* Libevent versions before 1.3b do very badly on operating systems with
+ * user-space threading implementations. */
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+ if (server && version < V_OLD(1,3,'b')) {
+ thread_unsafe = 1;
+ sad_os = "BSD variants";
+ }
+#elif defined(__APPLE__) || defined(__darwin__)
+ if (server && version < V_OLD(1,3,'b')) {
+ thread_unsafe = 1;
+ sad_os = "Mac OS X";
+ }
+#endif
+
+ if (thread_unsafe) {
+ log(LOG_WARN, LD_GENERAL,
+ "Libevent version %s often crashes when running a Tor server with %s. "
+ "Please use the latest version of libevent (1.3b or later)",v,sad_os);
+ badness = "BROKEN";
+ } else if (buggy) {
+ log(LOG_WARN, LD_GENERAL,
+ "There are serious bugs in using %s with libevent %s. "
+ "Please use the latest version of libevent.", m, v);
+ badness = "BROKEN";
+ } else if (iffy) {
+ log(LOG_WARN, LD_GENERAL,
+ "There are minor bugs in using %s with libevent %s. "
+ "You may want to use the latest version of libevent.", m, v);
+ badness = "BUGGY";
+ } else if (slow && server) {
+ log(LOG_WARN, LD_GENERAL,
+ "libevent %s can be very slow with %s. "
+ "When running a server, please use the latest version of libevent.",
+ v,m);
+ badness = "SLOW";
+ }
+
+ *badness_out = badness;
+}
+
+#if defined(LIBEVENT_VERSION)
+#define HEADER_VERSION LIBEVENT_VERSION
+#elif defined(_EVENT_VERSION)
+#define HEADER_VERSION _EVENT_VERSION
+#endif
+
+/** See whether the headers we were built against differ from the library we
+ * linked against so much that we're likely to crash. If so, warn the
+ * user. */
+void
+tor_check_libevent_header_compatibility(void)
+{
+ (void) le_versions_compatibility;
+ (void) tor_decode_libevent_version;
+
+ /* In libevent versions before 2.0, it's hard to keep binary compatibility
+ * between upgrades, and unpleasant to detect when the version we compiled
+ * against is unlike the version we have linked against. Here's how. */
+#if defined(HEADER_VERSION) && defined(HAVE_EVENT_GET_VERSION)
+ /* We have a header-file version and a function-call version. Easy. */
+ if (strcmp(HEADER_VERSION, event_get_version())) {
+ le_version_t v1, v2;
+ int compat1 = -1, compat2 = -1;
+ int verybad;
+ v1 = tor_decode_libevent_version(HEADER_VERSION);
+ v2 = tor_decode_libevent_version(event_get_version());
+ compat1 = le_versions_compatibility(v1);
+ compat2 = le_versions_compatibility(v2);
+
+ verybad = compat1 != compat2;
+
+ log(verybad ? LOG_WARN : LOG_NOTICE,
+ LD_GENERAL, "We were compiled with headers from version %s "
+ "of Libevent, but we're using a Libevent library that says it's "
+ "version %s.", HEADER_VERSION, event_get_version());
+ if (verybad)
+ log_warn(LD_GENERAL, "This will almost certainly make Tor crash.");
+ else
+ log_info(LD_GENERAL, "I think these versions are binary-compatible.");
+ }
+#elif defined(HAVE_EVENT_GET_VERSION)
+ /* event_get_version but no _EVENT_VERSION. We might be in 1.4.0-beta or
+ earlier, where that's normal. To see whether we were compiled with an
+ earlier version, let's see whether the struct event defines MIN_HEAP_IDX.
+ */
+#ifdef HAVE_STRUCT_EVENT_MIN_HEAP_IDX
+ /* The header files are 1.4.0-beta or later. If the version is not
+ * 1.4.0-beta, we are incompatible. */
+ {
+ if (strcmp(event_get_version(), "1.4.0-beta")) {
+ log_warn(LD_GENERAL, "It's a little hard to tell, but you seem to have "
+ "Libevent 1.4.0-beta header files, whereas you have linked "
+ "against Libevent %s. This will probably make Tor crash.",
+ event_get_version());
+ }
+ }
+#else
+ /* Our headers are 1.3e or earlier. If the library version is not 1.4.x or
+ later, we're probably fine. */
+ {
+ const char *v = event_get_version();
+ if ((v[0] == '1' && v[2] == '.' && v[3] > '3') || v[0] > '1') {
+ log_warn(LD_GENERAL, "It's a little hard to tell, but you seem to have "
+ "Libevent header file from 1.3e or earlier, whereas you have "
+ "linked against Libevent %s. This will probably make Tor "
+ "crash.", event_get_version());
+ }
+ }
+#endif
+
+#elif defined(HEADER_VERSION)
+#warn "_EVENT_VERSION is defined but not get_event_version(): Libevent is odd."
+#else
+ /* Your libevent is ancient. */
+#endif
+}
+
+/*
+ If possible, we're going to try to use Libevent's periodic timer support,
+ since it does a pretty good job of making sure that periodic events get
+ called exactly M seconds apart, rather than starting each one exactly M
+ seconds after the time that the last one was run.
+ */
+#ifdef HAVE_EVENT2_EVENT_H
+#define HAVE_PERIODIC
+#define PERIODIC_FLAGS EV_PERSIST
+#else
+#define PERIODIC_FLAGS 0
+#endif
+
+/** Represents a timer that's run every N microseconds by Libevent. */
+struct periodic_timer_t {
+ /** Underlying event used to implement this periodic event. */
+ struct event *ev;
+ /** The callback we'll be invoking whenever the event triggers */
+ void (*cb)(struct periodic_timer_t *, void *);
+ /** User-supplied data for the callback */
+ void *data;
+#ifndef HAVE_PERIODIC
+ /** If Libevent doesn't know how to invoke events every N microseconds,
+ * we'll need to remember the timeout interval here. */
+ struct timeval tv;
+#endif
+};
+
+/** Libevent callback to implement a periodic event. */
+static void
+periodic_timer_cb(evutil_socket_t fd, short what, void *arg)
+{
+ periodic_timer_t *timer = arg;
+ (void) what;
+ (void) fd;
+#ifndef HAVE_PERIODIC
+ /** reschedule the event as needed. */
+ event_add(timer->ev, &timer->tv);
+#endif
+ timer->cb(timer, timer->data);
+}
+
+/** Create and schedule a new timer that will run every <b>tv</b> in
+ * the event loop of <b>base</b>. When the timer fires, it will
+ * run the timer in <b>cb</b> with the user-supplied data in <b>data</b>. */
+periodic_timer_t *
+periodic_timer_new(struct event_base *base,
+ const struct timeval *tv,
+ void (*cb)(periodic_timer_t *timer, void *data),
+ void *data)
+{
+ periodic_timer_t *timer;
+ tor_assert(base);
+ tor_assert(tv);
+ tor_assert(cb);
+ timer = tor_malloc_zero(sizeof(periodic_timer_t));
+ if (!(timer->ev = tor_event_new(base, -1, PERIODIC_FLAGS,
+ periodic_timer_cb, timer))) {
+ tor_free(timer);
+ return NULL;
+ }
+ timer->cb = cb;
+ timer->data = data;
+#ifndef HAVE_PERIODIC
+ memcpy(&timer->tv, tv, sizeof(struct timeval));
+#endif
+ event_add(timer->ev, (struct timeval *)tv); /*drop const for old libevent*/
+ return timer;
+}
+
+/** Stop and free a periodic timer */
+void
+periodic_timer_free(periodic_timer_t *timer)
+{
+ if (!timer)
+ return;
+ tor_event_free(timer->ev);
+ tor_free(timer);
+}
+
diff --git a/src/common/compat_libevent.h b/src/common/compat_libevent.h
new file mode 100644
index 0000000000..fdf5e0a18f
--- /dev/null
+++ b/src/common/compat_libevent.h
@@ -0,0 +1,65 @@
+/* Copyright (c) 2009, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef _TOR_COMPAT_LIBEVENT_H
+#define _TOR_COMPAT_LIBEVENT_H
+
+#include "orconfig.h"
+
+struct event;
+struct event_base;
+
+#ifdef HAVE_EVENT2_EVENT_H
+#include <event2/util.h>
+#else
+#define evutil_socket_t int
+#endif
+
+void configure_libevent_logging(void);
+void suppress_libevent_log_msg(const char *msg);
+
+#ifdef HAVE_EVENT2_EVENT_H
+#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);
+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
+
+typedef struct periodic_timer_t periodic_timer_t;
+
+periodic_timer_t *periodic_timer_new(struct event_base *base,
+ const struct timeval *tv,
+ void (*cb)(periodic_timer_t *timer, void *data),
+ void *data);
+void periodic_timer_free(periodic_timer_t *);
+
+#ifdef HAVE_EVENT_BASE_LOOPEXIT
+#define tor_event_base_loopexit event_base_loopexit
+#else
+struct timeval;
+int tor_event_base_loopexit(struct event_base *base, struct timeval *tv);
+#endif
+
+void tor_libevent_initialize(void);
+struct event_base *tor_libevent_get_base(void);
+const char *tor_libevent_get_method(void);
+void tor_check_libevent_version(const char *m, int server,
+ const char **badness_out);
+void tor_check_libevent_header_compatibility(void);
+const char *tor_libevent_get_version_str(void);
+
+#endif
+
diff --git a/src/common/container.c b/src/common/container.c
index 08fab5ced1..72f3470344 100644
--- a/src/common/container.c
+++ b/src/common/container.c
@@ -13,7 +13,7 @@
#include "compat.h"
#include "util.h"
-#include "log.h"
+#include "torlog.h"
#include "container.h"
#include "crypto.h"
@@ -44,7 +44,8 @@ smartlist_create(void)
void
smartlist_free(smartlist_t *sl)
{
- tor_assert(sl != NULL);
+ if (!sl)
+ return;
tor_free(sl->list);
tor_free(sl);
}
@@ -459,6 +460,42 @@ smartlist_sort(smartlist_t *sl, int (*compare)(const void **a, const void **b))
(int (*)(const void *,const void*))compare);
}
+/** Given a smartlist <b>sl</b> sorted with the function <b>compare</b>,
+ * return the most frequent member in the list. Break ties in favor of
+ * later elements. If the list is empty, return NULL.
+ */
+void *
+smartlist_get_most_frequent(const smartlist_t *sl,
+ int (*compare)(const void **a, const void **b))
+{
+ const void *most_frequent = NULL;
+ int most_frequent_count = 0;
+
+ const void *cur = NULL;
+ int i, count=0;
+
+ if (!sl->num_used)
+ return NULL;
+ for (i = 0; i < sl->num_used; ++i) {
+ const void *item = sl->list[i];
+ if (cur && 0 == compare(&cur, &item)) {
+ ++count;
+ } else {
+ if (cur && count >= most_frequent_count) {
+ most_frequent = cur;
+ most_frequent_count = count;
+ }
+ cur = item;
+ count = 1;
+ }
+ }
+ if (cur && count >= most_frequent_count) {
+ most_frequent = cur;
+ most_frequent_count = count;
+ }
+ return (void*)most_frequent;
+}
+
/** Given a sorted smartlist <b>sl</b> and the comparison function used to
* sort it, remove all duplicate members. If free_fn is provided, calls
* free_fn on each duplicate. Otherwise, just removes them. Preserves order.
@@ -550,6 +587,13 @@ smartlist_sort_strings(smartlist_t *sl)
smartlist_sort(sl, _compare_string_ptrs);
}
+/** Return the most frequent string in the sorted list <b>sl</b> */
+char *
+smartlist_get_most_frequent_string(smartlist_t *sl)
+{
+ return smartlist_get_most_frequent(sl, _compare_string_ptrs);
+}
+
/** Remove duplicate strings from a sorted list, and free them with tor_free().
*/
void
@@ -561,6 +605,38 @@ smartlist_uniq_strings(smartlist_t *sl)
/* Heap-based priority queue implementation for O(lg N) insert and remove.
* Recall that the heap property is that, for every index I, h[I] <
* H[LEFT_CHILD[I]] and h[I] < H[RIGHT_CHILD[I]].
+ *
+ * For us to remove items other than the topmost item, each item must store
+ * its own index within the heap. When calling the pqueue functions, tell
+ * them about the offset of the field that stores the index within the item.
+ *
+ * Example:
+ *
+ * typedef struct timer_t {
+ * struct timeval tv;
+ * int heap_index;
+ * } timer_t;
+ *
+ * static int compare(const void *p1, const void *p2) {
+ * const timer_t *t1 = p1, *t2 = p2;
+ * if (t1->tv.tv_sec < t2->tv.tv_sec) {
+ * return -1;
+ * } else if (t1->tv.tv_sec > t2->tv.tv_sec) {
+ * return 1;
+ * } else {
+ * return t1->tv.tv_usec - t2->tv_usec;
+ * }
+ * }
+ *
+ * void timer_heap_insert(smartlist_t *heap, timer_t *timer) {
+ * smartlist_pqueue_add(heap, compare, STRUCT_OFFSET(timer_t, heap_index),
+ * timer);
+ * }
+ *
+ * void timer_heap_pop(smartlist_t *heap) {
+ * return smartlist_pqueue_pop(heap, compare,
+ * STRUCT_OFFSET(timer_t, heap_index));
+ * }
*/
/* For a 1-indexed array, we would use LEFT_CHILD[x] = 2*x and RIGHT_CHILD[x]
@@ -572,12 +648,22 @@ smartlist_uniq_strings(smartlist_t *sl)
#define RIGHT_CHILD(i) ( 2*(i) + 2 )
#define PARENT(i) ( ((i)-1) / 2 )
+#define IDXP(p) ((int*)STRUCT_VAR_P(p, idx_field_offset))
+
+#define UPDATE_IDX(i) do { \
+ void *updated = sl->list[i]; \
+ *IDXP(updated) = i; \
+ } while (0)
+
+#define IDX_OF_ITEM(p) (*IDXP(p))
+
/** Helper. <b>sl</b> may have at most one violation of the heap property:
* the item at <b>idx</b> may be greater than one or both of its children.
* Restore the heap property. */
static INLINE void
smartlist_heapify(smartlist_t *sl,
int (*compare)(const void *a, const void *b),
+ int idx_field_offset,
int idx)
{
while (1) {
@@ -600,21 +686,28 @@ smartlist_heapify(smartlist_t *sl,
void *tmp = sl->list[idx];
sl->list[idx] = sl->list[best_idx];
sl->list[best_idx] = tmp;
+ UPDATE_IDX(idx);
+ UPDATE_IDX(best_idx);
idx = best_idx;
}
}
}
-/** Insert <b>item</b> into the heap stored in <b>sl</b>, where order
- * is determined by <b>compare</b>. */
+/** Insert <b>item</b> into the heap stored in <b>sl</b>, where order is
+ * determined by <b>compare</b> and the offset of the item in the heap is
+ * stored in an int-typed field at position <b>idx_field_offset</b> within
+ * item.
+ */
void
smartlist_pqueue_add(smartlist_t *sl,
int (*compare)(const void *a, const void *b),
+ int idx_field_offset,
void *item)
{
int idx;
smartlist_add(sl,item);
+ UPDATE_IDX(sl->num_used-1);
for (idx = sl->num_used - 1; idx; ) {
int parent = PARENT(idx);
@@ -622,6 +715,8 @@ smartlist_pqueue_add(smartlist_t *sl,
void *tmp = sl->list[parent];
sl->list[parent] = sl->list[idx];
sl->list[idx] = tmp;
+ UPDATE_IDX(parent);
+ UPDATE_IDX(idx);
idx = parent;
} else {
return;
@@ -630,32 +725,63 @@ smartlist_pqueue_add(smartlist_t *sl,
}
/** Remove and return the top-priority item from the heap stored in <b>sl</b>,
- * where order is determined by <b>compare</b>. <b>sl</b> must not be
- * empty. */
+ * where order is determined by <b>compare</b> and the item's position is
+ * stored at position <b>idx_field_offset</b> within the item. <b>sl</b> must
+ * not be empty. */
void *
smartlist_pqueue_pop(smartlist_t *sl,
- int (*compare)(const void *a, const void *b))
+ int (*compare)(const void *a, const void *b),
+ int idx_field_offset)
{
void *top;
tor_assert(sl->num_used);
top = sl->list[0];
+ *IDXP(top)=-1;
if (--sl->num_used) {
sl->list[0] = sl->list[sl->num_used];
- smartlist_heapify(sl, compare, 0);
+ UPDATE_IDX(0);
+ smartlist_heapify(sl, compare, idx_field_offset, 0);
}
return top;
}
+/** Remove the item <b>item</b> from the heap stored in <b>sl</b>,
+ * where order is determined by <b>compare</b> and the item's position is
+ * stored at position <b>idx_field_offset</b> within the item. <b>sl</b> must
+ * not be empty. */
+void
+smartlist_pqueue_remove(smartlist_t *sl,
+ int (*compare)(const void *a, const void *b),
+ int idx_field_offset,
+ void *item)
+{
+ int idx = IDX_OF_ITEM(item);
+ tor_assert(idx >= 0);
+ tor_assert(sl->list[idx] == item);
+ --sl->num_used;
+ *IDXP(item) = -1;
+ if (idx == sl->num_used) {
+ return;
+ } else {
+ sl->list[idx] = sl->list[sl->num_used];
+ UPDATE_IDX(idx);
+ smartlist_heapify(sl, compare, idx_field_offset, idx);
+ }
+}
+
/** Assert that the heap property is correctly maintained by the heap stored
* in <b>sl</b>, where order is determined by <b>compare</b>. */
void
smartlist_pqueue_assert_ok(smartlist_t *sl,
- int (*compare)(const void *a, const void *b))
+ int (*compare)(const void *a, const void *b),
+ int idx_field_offset)
{
int i;
- for (i = sl->num_used - 1; i > 0; --i) {
- tor_assert(compare(sl->list[PARENT(i)], sl->list[i]) <= 0);
+ for (i = sl->num_used - 1; i >= 0; --i) {
+ if (i>0)
+ tor_assert(compare(sl->list[PARENT(i)], sl->list[i]) <= 0);
+ tor_assert(IDX_OF_ITEM(sl->list[i]) == i);
}
}
@@ -681,6 +807,37 @@ smartlist_uniq_digests(smartlist_t *sl)
smartlist_uniq(sl, _compare_digests, _tor_free);
}
+/** Helper: compare two DIGEST256_LEN digests. */
+static int
+_compare_digests256(const void **_a, const void **_b)
+{
+ return memcmp((const char*)*_a, (const char*)*_b, DIGEST256_LEN);
+}
+
+/** Sort the list of DIGEST256_LEN-byte digests into ascending order. */
+void
+smartlist_sort_digests256(smartlist_t *sl)
+{
+ smartlist_sort(sl, _compare_digests256);
+}
+
+/** Return the most frequent member of the sorted list of DIGEST256_LEN
+ * digests in <b>sl</b> */
+char *
+smartlist_get_most_frequent_digest256(smartlist_t *sl)
+{
+ return smartlist_get_most_frequent(sl, _compare_digests256);
+}
+
+/** Remove duplicate 256-bit digests from a sorted list, and free them with
+ * tor_free().
+ */
+void
+smartlist_uniq_digests256(smartlist_t *sl)
+{
+ smartlist_uniq(sl, _compare_digests256, _tor_free);
+}
+
/** Helper: Declare an entry type and a map type to implement a mapping using
* ht.h. The map type will be called <b>maptype</b>. The key part of each
* entry is declared using the C declaration <b>keydecl</b>. All functions
@@ -1113,6 +1270,9 @@ void
strmap_free(strmap_t *map, void (*free_val)(void*))
{
strmap_entry_t **ent, **next, *this;
+ if (!map)
+ return;
+
for (ent = HT_START(strmap_impl, &map->head); ent != NULL; ent = next) {
this = *ent;
next = HT_NEXT_RMV(strmap_impl, &map->head, ent);
@@ -1134,6 +1294,8 @@ void
digestmap_free(digestmap_t *map, void (*free_val)(void*))
{
digestmap_entry_t **ent, **next, *this;
+ if (!map)
+ return;
for (ent = HT_START(digestmap_impl, &map->head); ent != NULL; ent = next) {
this = *ent;
next = HT_NEXT_RMV(digestmap_impl, &map->head, ent);
@@ -1220,6 +1382,7 @@ IMPLEMENT_ORDER_FUNC(find_nth_int, int)
IMPLEMENT_ORDER_FUNC(find_nth_time, time_t)
IMPLEMENT_ORDER_FUNC(find_nth_double, double)
IMPLEMENT_ORDER_FUNC(find_nth_uint32, uint32_t)
+IMPLEMENT_ORDER_FUNC(find_nth_int32, int32_t)
IMPLEMENT_ORDER_FUNC(find_nth_long, long)
/** Return a newly allocated digestset_t, optimized to hold a total of
@@ -1248,6 +1411,8 @@ digestset_new(int max_elements)
void
digestset_free(digestset_t *set)
{
+ if (!set)
+ return;
bitarray_free(set->ba);
tor_free(set);
}
diff --git a/src/common/container.h b/src/common/container.h
index c42b86977d..3568de0159 100644
--- a/src/common/container.h
+++ b/src/common/container.h
@@ -93,13 +93,22 @@ void smartlist_del_keeporder(smartlist_t *sl, int idx);
void smartlist_insert(smartlist_t *sl, int idx, void *val);
void smartlist_sort(smartlist_t *sl,
int (*compare)(const void **a, const void **b));
+void *smartlist_get_most_frequent(const smartlist_t *sl,
+ int (*compare)(const void **a, const void **b));
void smartlist_uniq(smartlist_t *sl,
int (*compare)(const void **a, const void **b),
void (*free_fn)(void *elt));
+
void smartlist_sort_strings(smartlist_t *sl);
void smartlist_sort_digests(smartlist_t *sl);
+void smartlist_sort_digests256(smartlist_t *sl);
+
+char *smartlist_get_most_frequent_string(smartlist_t *sl);
+char *smartlist_get_most_frequent_digest256(smartlist_t *sl);
+
void smartlist_uniq_strings(smartlist_t *sl);
void smartlist_uniq_digests(smartlist_t *sl);
+void smartlist_uniq_digests256(smartlist_t *sl);
void *smartlist_bsearch(smartlist_t *sl, const void *key,
int (*compare)(const void *key, const void **member))
ATTR_PURE;
@@ -109,11 +118,18 @@ int smartlist_bsearch_idx(const smartlist_t *sl, const void *key,
void smartlist_pqueue_add(smartlist_t *sl,
int (*compare)(const void *a, const void *b),
+ int idx_field_offset,
void *item);
void *smartlist_pqueue_pop(smartlist_t *sl,
- int (*compare)(const void *a, const void *b));
+ int (*compare)(const void *a, const void *b),
+ int idx_field_offset);
+void smartlist_pqueue_remove(smartlist_t *sl,
+ int (*compare)(const void *a, const void *b),
+ int idx_field_offset,
+ void *item);
void smartlist_pqueue_assert_ok(smartlist_t *sl,
- int (*compare)(const void *a, const void *b));
+ int (*compare)(const void *a, const void *b),
+ int idx_field_offset);
#define SPLIT_SKIP_SPACE 0x01
#define SPLIT_IGNORE_BLANK 0x02
@@ -627,6 +643,7 @@ void digestset_free(digestset_t* set);
int find_nth_int(int *array, int n_elements, int nth);
time_t find_nth_time(time_t *array, int n_elements, int nth);
double find_nth_double(double *array, int n_elements, int nth);
+int32_t find_nth_int32(int32_t *array, int n_elements, int nth);
uint32_t find_nth_uint32(uint32_t *array, int n_elements, int nth);
long find_nth_long(long *array, int n_elements, int nth);
static INLINE int
@@ -649,6 +666,11 @@ median_uint32(uint32_t *array, int n_elements)
{
return find_nth_uint32(array, n_elements, (n_elements-1)/2);
}
+static INLINE int32_t
+median_int32(int32_t *array, int n_elements)
+{
+ return find_nth_int32(array, n_elements, (n_elements-1)/2);
+}
static INLINE long
median_long(long *array, int n_elements)
{
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 751a5b0c61..e030c56064 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -27,6 +27,7 @@
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
+#include <openssl/engine.h>
#include <openssl/rand.h>
#include <openssl/opensslv.h>
#include <openssl/bn.h>
@@ -49,9 +50,9 @@
#define CRYPTO_PRIVATE
#include "crypto.h"
-#include "log.h"
+#include "../common/torlog.h"
#include "aes.h"
-#include "util.h"
+#include "../common/util.h"
#include "container.h"
#include "compat.h"
@@ -61,6 +62,33 @@
#include <openssl/engine.h>
+#ifdef ANDROID
+/* Android's OpenSSL seems to have removed all of its Engine support. */
+#define DISABLE_ENGINES
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x00908000l
+/* On OpenSSL versions before 0.9.8, there is no working SHA256
+ * implementation, so we use Tom St Denis's nice speedy one, slightly adapted
+ * to our needs */
+#define SHA256_CTX sha256_state
+#define SHA256_Init sha256_init
+#define SHA256_Update sha256_process
+#define LTC_ARGCHK(x) tor_assert(x)
+#include "sha256.c"
+#define SHA256_Final(a,b) sha256_done(b,a)
+
+static unsigned char *
+SHA256(const unsigned char *m, size_t len, unsigned char *d)
+{
+ SHA256_CTX ctx;
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, m, len);
+ SHA256_Final(d, &ctx);
+ return d;
+}
+#endif
+
/** Macro: is k a valid RSA public or private key? */
#define PUBLIC_KEY_OK(k) ((k) && (k)->key && (k)->key->n)
/** Macro: is k a valid RSA private key? */
@@ -94,7 +122,7 @@ struct crypto_dh_env_t {
};
static int setup_openssl_threading(void);
-static int tor_check_dh_key(BIGNUM *bn);
+static int tor_check_dh_key(int severity, BIGNUM *bn);
/** Return the number of bytes added by padding method <b>padding</b>.
*/
@@ -151,6 +179,7 @@ crypto_log_errors(int severity, const char *doing)
}
}
+#ifndef DISABLE_ENGINES
/** Log any OpenSSL engines we're using at NOTICE. */
static void
log_engine(const char *fn, ENGINE *e)
@@ -165,37 +194,82 @@ log_engine(const char *fn, ENGINE *e)
log(LOG_INFO, LD_CRYPTO, "Using default implementation for %s", fn);
}
}
+#endif
+
+#ifndef DISABLE_ENGINES
+/** Try to load an engine in a shared library via fully qualified path.
+ */
+static ENGINE *
+try_load_engine(const char *path, const char *engine)
+{
+ ENGINE *e = ENGINE_by_id("dynamic");
+ if (e) {
+ if (!ENGINE_ctrl_cmd_string(e, "ID", engine, 0) ||
+ !ENGINE_ctrl_cmd_string(e, "DIR_LOAD", "2", 0) ||
+ !ENGINE_ctrl_cmd_string(e, "DIR_ADD", path, 0) ||
+ !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) {
+ ENGINE_free(e);
+ e = NULL;
+ }
+ }
+ return e;
+}
+#endif
/** Initialize the crypto library. Return 0 on success, -1 on failure.
*/
int
-crypto_global_init(int useAccel)
+crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
{
if (!_crypto_global_initialized) {
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
_crypto_global_initialized = 1;
setup_openssl_threading();
- /* XXX the below is a bug, since we can't know if we're supposed
- * to be using hardware acceleration or not. we should arrange
- * for this function to be called before init_keys. But make it
- * not complain loudly, at least until we make acceleration work. */
- if (useAccel < 0) {
- log_info(LD_CRYPTO, "Initializing OpenSSL via tor_tls_init().");
- }
if (useAccel > 0) {
+#ifdef DISABLE_ENGINES
+ (void)accelName;
+ (void)accelDir;
+ log_warn(LD_CRYPTO, "No OpenSSL hardware acceleration support enabled.");
+#else
+ ENGINE *e = NULL;
+
log_info(LD_CRYPTO, "Initializing OpenSSL engine support.");
ENGINE_load_builtin_engines();
- if (!ENGINE_register_all_complete())
- return -1;
-
- /* XXXX make sure this isn't leaking. */
+ ENGINE_register_all_complete();
+
+ if (accelName) {
+ if (accelDir) {
+ log_info(LD_CRYPTO, "Trying to load dynamic OpenSSL engine \"%s\""
+ " via path \"%s\".", accelName, accelDir);
+ e = try_load_engine(accelName, accelDir);
+ } else {
+ log_info(LD_CRYPTO, "Initializing dynamic OpenSSL engine \"%s\""
+ " acceleration support.", accelName);
+ e = ENGINE_by_id(accelName);
+ }
+ if (!e) {
+ log_warn(LD_CRYPTO, "Unable to load dynamic OpenSSL engine \"%s\".",
+ accelName);
+ } else {
+ log_info(LD_CRYPTO, "Loaded dynamic OpenSSL engine \"%s\".",
+ accelName);
+ }
+ }
+ if (e) {
+ log_info(LD_CRYPTO, "Loaded OpenSSL hardware acceleration engine,"
+ " setting default ciphers.");
+ ENGINE_set_default(e, ENGINE_METHOD_ALL);
+ }
log_engine("RSA", ENGINE_get_default_RSA());
log_engine("DH", ENGINE_get_default_DH());
log_engine("RAND", ENGINE_get_default_RAND());
log_engine("SHA1", ENGINE_get_digest_engine(NID_sha1));
log_engine("3DES", ENGINE_get_cipher_engine(NID_des_ede3_ecb));
log_engine("AES", ENGINE_get_cipher_engine(NID_aes_128_ecb));
+#endif
+ } else {
+ log_info(LD_CRYPTO, "NOT using OpenSSL engine support.");
}
return crypto_seed_rng(1);
}
@@ -217,7 +291,11 @@ crypto_global_cleanup(void)
EVP_cleanup();
ERR_remove_state(0);
ERR_free_strings();
+
+#ifndef DISABLE_ENGINES
ENGINE_cleanup();
+#endif
+
CONF_modules_unload(1);
CRYPTO_cleanup_all_ex_data();
#ifdef TOR_IS_MULTITHREADED
@@ -259,7 +337,8 @@ _crypto_new_pk_env_evp_pkey(EVP_PKEY *pkey)
return _crypto_new_pk_env_rsa(rsa);
}
-/** Helper, used by tor-checkkey.c. Return the RSA from a crypto_pk_env_t. */
+/** Helper, used by tor-checkkey.c and tor-gencert.c. Return the RSA from a
+ * crypto_pk_env_t. */
RSA *
_crypto_pk_env_get_rsa(crypto_pk_env_t *env)
{
@@ -321,10 +400,12 @@ crypto_new_pk_env(void)
void
crypto_free_pk_env(crypto_pk_env_t *env)
{
- tor_assert(env);
+ if (!env)
+ return;
if (--env->refs > 0)
return;
+ tor_assert(env->refs == 0);
if (env->key)
RSA_free(env->key);
@@ -347,10 +428,7 @@ crypto_create_init_cipher(const char *key, int encrypt_mode)
return NULL;
}
- if (crypto_cipher_set_key(crypto, key)) {
- crypto_log_errors(LOG_WARN, "setting symmetric key");
- goto error;
- }
+ crypto_cipher_set_key(crypto, key);
if (encrypt_mode)
r = crypto_cipher_encrypt_init_cipher(crypto);
@@ -384,7 +462,8 @@ crypto_new_cipher_env(void)
void
crypto_free_cipher_env(crypto_cipher_env_t *env)
{
- tor_assert(env);
+ if (!env)
+ return;
tor_assert(env->cipher);
aes_free_cipher(env->cipher);
@@ -394,11 +473,11 @@ crypto_free_cipher_env(crypto_cipher_env_t *env)
/* public key crypto */
-/** Generate a new public/private keypair in <b>env</b>. Return 0 on
- * success, -1 on failure.
+/** Generate a <b>bits</b>-bit new public/private keypair in <b>env</b>.
+ * Return 0 on success, -1 on failure.
*/
int
-crypto_pk_generate_key(crypto_pk_env_t *env)
+crypto_pk_generate_key_with_bits(crypto_pk_env_t *env, int bits)
{
tor_assert(env);
@@ -406,7 +485,7 @@ crypto_pk_generate_key(crypto_pk_env_t *env)
RSA_free(env->key);
#if OPENSSL_VERSION_NUMBER < 0x00908000l
/* In OpenSSL 0.9.7, RSA_generate_key is all we have. */
- env->key = RSA_generate_key(PK_BYTES*8,65537, NULL, NULL);
+ env->key = RSA_generate_key(bits, 65537, NULL, NULL);
#else
/* In OpenSSL 0.9.8, RSA_generate_key is deprecated. */
{
@@ -419,7 +498,7 @@ crypto_pk_generate_key(crypto_pk_env_t *env)
r = RSA_new();
if (!r)
goto done;
- if (RSA_generate_key_ex(r, PK_BYTES*8, e, NULL) == -1)
+ if (RSA_generate_key_ex(r, bits, e, NULL) == -1)
goto done;
env->key = r;
@@ -701,14 +780,25 @@ crypto_pk_env_t *
crypto_pk_copy_full(crypto_pk_env_t *env)
{
RSA *new_key;
+ int privatekey = 0;
tor_assert(env);
tor_assert(env->key);
if (PRIVATE_KEY_OK(env)) {
new_key = RSAPrivateKey_dup(env->key);
+ privatekey = 1;
} else {
new_key = RSAPublicKey_dup(env->key);
}
+ if (!new_key) {
+ log_err(LD_CRYPTO, "Unable to duplicate a %s key: openssl failed.",
+ privatekey?"private":"public");
+ crypto_log_errors(LOG_ERR,
+ privatekey ? "Duplicating a private key" :
+ "Duplicating a public key");
+ tor_fragile_assert();
+ return NULL;
+ }
return _crypto_new_pk_env_rsa(new_key);
}
@@ -1178,19 +1268,14 @@ crypto_cipher_generate_key(crypto_cipher_env_t *env)
/** Set the symmetric key for the cipher in <b>env</b> to the first
* CIPHER_KEY_LEN bytes of <b>key</b>. Does not initialize the cipher.
- * Return 0 on success, -1 on failure.
*/
-int
+void
crypto_cipher_set_key(crypto_cipher_env_t *env, const char *key)
{
tor_assert(env);
tor_assert(key);
- if (!env->key)
- return -1;
-
memcpy(env->key, key, CIPHER_KEY_LEN);
- return 0;
}
/** Generate an initialization vector for our AES-CTR cipher; store it
@@ -1367,9 +1452,69 @@ crypto_digest(char *digest, const char *m, size_t len)
return (SHA1((const unsigned char*)m,len,(unsigned char*)digest) == NULL);
}
+int
+crypto_digest256(char *digest, const char *m, size_t len,
+ digest_algorithm_t algorithm)
+{
+ tor_assert(m);
+ tor_assert(digest);
+ tor_assert(algorithm == DIGEST_SHA256);
+ return (SHA256((const unsigned char*)m,len,(unsigned char*)digest) == NULL);
+}
+
+/** Set the digests_t in <b>ds_out</b> to contain every digest on the
+ * <b>len</b> bytes in <b>m</b> that we know how to compute. Return 0 on
+ * success, -1 on failure. */
+int
+crypto_digest_all(digests_t *ds_out, const char *m, size_t len)
+{
+ digest_algorithm_t i;
+ tor_assert(ds_out);
+ memset(ds_out, 0, sizeof(*ds_out));
+ if (crypto_digest(ds_out->d[DIGEST_SHA1], m, len) < 0)
+ return -1;
+ for (i = DIGEST_SHA256; i < N_DIGEST_ALGORITHMS; ++i) {
+ if (crypto_digest256(ds_out->d[i], m, len, i) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+/** Return the name of an algorithm, as used in directory documents. */
+const char *
+crypto_digest_algorithm_get_name(digest_algorithm_t alg)
+{
+ switch (alg) {
+ case DIGEST_SHA1:
+ return "sha1";
+ case DIGEST_SHA256:
+ return "sha256";
+ default:
+ tor_fragile_assert();
+ return "??unknown_digest??";
+ }
+}
+
+/** Given the name of a digest algorithm, return its integer value, or -1 if
+ * the name is not recognized. */
+int
+crypto_digest_algorithm_parse_name(const char *name)
+{
+ if (!strcmp(name, "sha1"))
+ return DIGEST_SHA1;
+ else if (!strcmp(name, "sha256"))
+ return DIGEST_SHA256;
+ else
+ return -1;
+}
+
/** Intermediate information about the digest of a stream of data. */
struct crypto_digest_env_t {
- SHA_CTX d;
+ union {
+ SHA_CTX sha1;
+ SHA256_CTX sha2;
+ } d;
+ digest_algorithm_t algorithm : 8;
};
/** Allocate and return a new digest object.
@@ -1379,7 +1524,19 @@ crypto_new_digest_env(void)
{
crypto_digest_env_t *r;
r = tor_malloc(sizeof(crypto_digest_env_t));
- SHA1_Init(&r->d);
+ SHA1_Init(&r->d.sha1);
+ r->algorithm = DIGEST_SHA1;
+ return r;
+}
+
+crypto_digest_env_t *
+crypto_new_digest256_env(digest_algorithm_t algorithm)
+{
+ crypto_digest_env_t *r;
+ tor_assert(algorithm == DIGEST_SHA256);
+ r = tor_malloc(sizeof(crypto_digest_env_t));
+ SHA256_Init(&r->d.sha2);
+ r->algorithm = algorithm;
return r;
}
@@ -1388,6 +1545,8 @@ crypto_new_digest_env(void)
void
crypto_free_digest_env(crypto_digest_env_t *digest)
{
+ if (!digest)
+ return;
memset(digest, 0, sizeof(crypto_digest_env_t));
tor_free(digest);
}
@@ -1400,30 +1559,51 @@ crypto_digest_add_bytes(crypto_digest_env_t *digest, const char *data,
{
tor_assert(digest);
tor_assert(data);
- /* Using the SHA1_*() calls directly means we don't support doing
- * SHA1 in hardware. But so far the delay of getting the question
+ /* Using the SHA*_*() calls directly means we don't support doing
+ * SHA in hardware. But so far the delay of getting the question
* to the hardware, and hearing the answer, is likely higher than
* just doing it ourselves. Hashes are fast.
*/
- SHA1_Update(&digest->d, (void*)data, len);
+ switch (digest->algorithm) {
+ case DIGEST_SHA1:
+ SHA1_Update(&digest->d.sha1, (void*)data, len);
+ break;
+ case DIGEST_SHA256:
+ SHA256_Update(&digest->d.sha2, (void*)data, len);
+ break;
+ default:
+ tor_fragile_assert();
+ break;
+ }
}
/** Compute the hash of the data that has been passed to the digest
* object; write the first out_len bytes of the result to <b>out</b>.
- * <b>out_len</b> must be \<= DIGEST_LEN.
+ * <b>out_len</b> must be \<= DIGEST256_LEN.
*/
void
crypto_digest_get_digest(crypto_digest_env_t *digest,
char *out, size_t out_len)
{
- unsigned char r[DIGEST_LEN];
- SHA_CTX tmpctx;
+ unsigned char r[DIGEST256_LEN];
+ crypto_digest_env_t tmpenv;
tor_assert(digest);
tor_assert(out);
- tor_assert(out_len <= DIGEST_LEN);
- /* memcpy into a temporary ctx, since SHA1_Final clears the context */
- memcpy(&tmpctx, &digest->d, sizeof(SHA_CTX));
- SHA1_Final(r, &tmpctx);
+ /* memcpy into a temporary ctx, since SHA*_Final clears the context */
+ memcpy(&tmpenv, digest, sizeof(crypto_digest_env_t));
+ switch (digest->algorithm) {
+ case DIGEST_SHA1:
+ tor_assert(out_len <= DIGEST_LEN);
+ SHA1_Final(r, &tmpenv.d.sha1);
+ break;
+ case DIGEST_SHA256:
+ tor_assert(out_len <= DIGEST256_LEN);
+ SHA256_Final(r, &tmpenv.d.sha2);
+ break;
+ default:
+ tor_fragile_assert();
+ break;
+ }
memcpy(out, r, out_len);
memset(r, 0, sizeof(r));
}
@@ -1559,7 +1739,7 @@ crypto_dh_generate_public(crypto_dh_env_t *dh)
crypto_log_errors(LOG_WARN, "generating DH key");
return -1;
}
- if (tor_check_dh_key(dh->dh->pub_key)<0) {
+ if (tor_check_dh_key(LOG_WARN, dh->dh->pub_key)<0) {
log_warn(LD_CRYPTO, "Weird! Our own DH key was invalid. I guess once-in-"
"the-universe chances really do happen. Trying again.");
/* Free and clear the keys, so OpenSSL will actually try again. */
@@ -1606,7 +1786,7 @@ crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey, size_t pubkey_len)
* See http://www.cl.cam.ac.uk/ftp/users/rja14/psandqs.ps.gz for some tips.
*/
static int
-tor_check_dh_key(BIGNUM *bn)
+tor_check_dh_key(int severity, BIGNUM *bn)
{
BIGNUM *x;
char *s;
@@ -1617,13 +1797,13 @@ tor_check_dh_key(BIGNUM *bn)
init_dh_param();
BN_set_word(x, 1);
if (BN_cmp(bn,x)<=0) {
- log_warn(LD_CRYPTO, "DH key must be at least 2.");
+ log_fn(severity, LD_CRYPTO, "DH key must be at least 2.");
goto err;
}
BN_copy(x,dh_param_p);
BN_sub_word(x, 1);
if (BN_cmp(bn,x)>=0) {
- log_warn(LD_CRYPTO, "DH key must be at most p-2.");
+ log_fn(severity, LD_CRYPTO, "DH key must be at most p-2.");
goto err;
}
BN_free(x);
@@ -1631,7 +1811,7 @@ tor_check_dh_key(BIGNUM *bn)
err:
BN_free(x);
s = BN_bn2hex(bn);
- log_warn(LD_CRYPTO, "Rejecting insecure DH key [%s]", s);
+ log_fn(severity, LD_CRYPTO, "Rejecting insecure DH key [%s]", s);
OPENSSL_free(s);
return -1;
}
@@ -1649,7 +1829,7 @@ tor_check_dh_key(BIGNUM *bn)
* where || is concatenation.)
*/
ssize_t
-crypto_dh_compute_secret(crypto_dh_env_t *dh,
+crypto_dh_compute_secret(int severity, crypto_dh_env_t *dh,
const char *pubkey, size_t pubkey_len,
char *secret_out, size_t secret_bytes_out)
{
@@ -1664,9 +1844,9 @@ crypto_dh_compute_secret(crypto_dh_env_t *dh,
if (!(pubkey_bn = BN_bin2bn((const unsigned char*)pubkey,
(int)pubkey_len, NULL)))
goto error;
- if (tor_check_dh_key(pubkey_bn)<0) {
+ if (tor_check_dh_key(severity, pubkey_bn)<0) {
/* Check for invalid public keys. */
- log_warn(LD_CRYPTO,"Rejected invalid g^x");
+ log_fn(severity, LD_CRYPTO,"Rejected invalid g^x");
goto error;
}
secret_tmp = tor_malloc(crypto_dh_get_bytes(dh));
@@ -1738,7 +1918,8 @@ crypto_expand_key_material(const char *key_in, size_t key_in_len,
void
crypto_dh_free(crypto_dh_env_t *dh)
{
- tor_assert(dh);
+ if (!dh)
+ return;
tor_assert(dh->dh);
DH_free(dh->dh);
tor_free(dh);
@@ -1763,6 +1944,14 @@ crypto_dh_free(crypto_dh_env_t *dh)
OPENSSL_VERSION_NUMBER <= 0x00907fffl) || \
(OPENSSL_VERSION_NUMBER >= 0x0090803fl))
+static void
+seed_weak_rng(void)
+{
+ unsigned seed;
+ crypto_rand((void*)&seed, sizeof(seed));
+ tor_init_weak_random(seed);
+}
+
/** Seed OpenSSL's random number generator with bytes from the operating
* system. <b>startup</b> should be true iff we have just started Tor and
* have not yet allocated a bunch of fds. Return 0 on success, -1 on failure.
@@ -1813,6 +2002,7 @@ crypto_seed_rng(int startup)
}
RAND_seed(buf, sizeof(buf));
memset(buf, 0, sizeof(buf));
+ seed_weak_rng();
return 0;
#else
for (i = 0; filenames[i]; ++i) {
@@ -1829,6 +2019,7 @@ crypto_seed_rng(int startup)
}
RAND_seed(buf, (int)sizeof(buf));
memset(buf, 0, sizeof(buf));
+ seed_weak_rng();
return 0;
}
@@ -1896,6 +2087,26 @@ crypto_rand_uint64(uint64_t max)
}
}
+/** Return a pseudorandom double d, chosen uniformly from the range
+ * 0.0 <= d < 1.0.
+ */
+double
+crypto_rand_double(void)
+{
+ /* We just use an unsigned int here; we don't really care about getting
+ * more than 32 bits of resolution */
+ unsigned int uint;
+ crypto_rand((char*)&uint, sizeof(uint));
+#if SIZEOF_INT == 4
+#define UINT_MAX_AS_DOUBLE 4294967296.0
+#elif SIZEOF_INT == 8
+#define UINT_MAX_AS_DOUBLE 1.8446744073709552e+19
+#else
+#error SIZEOF_INT is neither 4 nor 8
+#endif
+ return ((double)uint) / UINT_MAX_AS_DOUBLE;
+}
+
/** Generate and return a new random hostname starting with <b>prefix</b>,
* ending with <b>suffix</b>, and containing no less than
* <b>min_rand_len</b> and no more than <b>max_rand_len</b> random base32
@@ -2156,6 +2367,44 @@ digest_from_base64(char *digest, const char *d64)
#endif
}
+/** Base-64 encode DIGEST256_LINE bytes from <b>digest</b>, remove the
+ * trailing = and newline characters, and store the nul-terminated result in
+ * the first BASE64_DIGEST256_LEN+1 bytes of <b>d64</b>. */
+int
+digest256_to_base64(char *d64, const char *digest)
+{
+ char buf[256];
+ base64_encode(buf, sizeof(buf), digest, DIGEST256_LEN);
+ buf[BASE64_DIGEST256_LEN] = '\0';
+ memcpy(d64, buf, BASE64_DIGEST256_LEN+1);
+ return 0;
+}
+
+/** Given a base-64 encoded, nul-terminated digest in <b>d64</b> (without
+ * trailing newline or = characters), decode it and store the result in the
+ * first DIGEST256_LEN bytes at <b>digest</b>. */
+int
+digest256_from_base64(char *digest, const char *d64)
+{
+#ifdef USE_OPENSSL_BASE64
+ char buf_in[BASE64_DIGEST256_LEN+3];
+ char buf[256];
+ if (strlen(d64) != BASE64_DIGEST256_LEN)
+ return -1;
+ memcpy(buf_in, d64, BASE64_DIGEST256_LEN);
+ memcpy(buf_in+BASE64_DIGEST256_LEN, "=\n\0", 3);
+ if (base64_decode(buf, sizeof(buf), buf_in, strlen(buf_in)) != DIGEST256_LEN)
+ return -1;
+ memcpy(digest, buf, DIGEST256_LEN);
+ return 0;
+#else
+ if (base64_decode(digest, DIGEST256_LEN, d64, strlen(d64)) == DIGEST256_LEN)
+ return 0;
+ else
+ return -1;
+#endif
+}
+
/** Implements base32 encoding as in rfc3548. Limitation: Requires
* that srclen*8 is a multiple of 5.
*/
diff --git a/src/common/crypto.h b/src/common/crypto.h
index 20fdfa4d2f..a30e5bcbae 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -18,6 +18,9 @@
/** Length of the output of our message digest. */
#define DIGEST_LEN 20
+/** Length of the output of our second (improved) message digests. (For now
+ * this is just sha256, but any it can be any other 256-byte digest). */
+#define DIGEST256_LEN 32
/** Length of our symmetric cipher's keys. */
#define CIPHER_KEY_LEN 16
/** Length of our symmetric cipher's IV. */
@@ -27,9 +30,12 @@
/** Length of our DH keys. */
#define DH_BYTES (1024/8)
-/** Length of a message digest when encoded in base64 with trailing = signs
- * removed. */
+/** Length of a sha1 message digest when encoded in base64 with trailing =
+ * signs removed. */
#define BASE64_DIGEST_LEN 27
+/** Length of a sha256 message digest when encoded in base64 with trailing =
+ * signs removed. */
+#define BASE64_DIGEST256_LEN 43
/** Constants used to indicate no padding for public-key encryption */
#define PK_NO_PADDING 60000
@@ -48,6 +54,26 @@
#define FINGERPRINT_LEN 49
/** Length of hex encoding of SHA1 digest, not including final NUL. */
#define HEX_DIGEST_LEN 40
+/** Length of hex encoding of SHA256 digest, not including final NUL. */
+#define HEX_DIGEST256_LEN 64
+
+typedef enum {
+ DIGEST_SHA1 = 0,
+ DIGEST_SHA256 = 1,
+} digest_algorithm_t;
+#define N_DIGEST_ALGORITHMS (DIGEST_SHA256+1)
+
+/** A set of all the digests we know how to compute, taken on a single
+ * string. Any digests that are shorter than 256 bits are right-padded
+ * with 0 bits.
+ *
+ * Note that this representation wastes 12 bytes for the SHA1 case, so
+ * don't use it for anything where we need to allocate a whole bunch at
+ * once.
+ **/
+typedef struct {
+ char d[N_DIGEST_ALGORITHMS][DIGEST256_LEN];
+} digests_t;
typedef struct crypto_pk_env_t crypto_pk_env_t;
typedef struct crypto_cipher_env_t crypto_cipher_env_t;
@@ -55,7 +81,9 @@ typedef struct crypto_digest_env_t crypto_digest_env_t;
typedef struct crypto_dh_env_t crypto_dh_env_t;
/* global state */
-int crypto_global_init(int hardwareAccel);
+int crypto_global_init(int hardwareAccel,
+ const char *accelName,
+ const char *accelPath);
void crypto_thread_cleanup(void);
int crypto_global_cleanup(void);
@@ -71,7 +99,9 @@ crypto_cipher_env_t *crypto_new_cipher_env(void);
void crypto_free_cipher_env(crypto_cipher_env_t *env);
/* public key crypto */
-int crypto_pk_generate_key(crypto_pk_env_t *env);
+int crypto_pk_generate_key_with_bits(crypto_pk_env_t *env, int bits);
+#define crypto_pk_generate_key(env) \
+ crypto_pk_generate_key_with_bits((env), (PK_BYTES*8))
int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env,
const char *keyfile);
@@ -121,7 +151,7 @@ int crypto_pk_check_fingerprint_syntax(const char *s);
/* symmetric crypto */
int crypto_cipher_generate_key(crypto_cipher_env_t *env);
-int crypto_cipher_set_key(crypto_cipher_env_t *env, const char *key);
+void crypto_cipher_set_key(crypto_cipher_env_t *env, const char *key);
void crypto_cipher_generate_iv(char *iv_out);
int crypto_cipher_set_iv(crypto_cipher_env_t *env, const char *iv);
const char *crypto_cipher_get_key(crypto_cipher_env_t *env);
@@ -141,9 +171,15 @@ int crypto_cipher_decrypt_with_iv(crypto_cipher_env_t *env,
char *to, size_t tolen,
const char *from, size_t fromlen);
-/* SHA-1 */
+/* SHA-1 and other digests. */
int crypto_digest(char *digest, const char *m, size_t len);
+int crypto_digest256(char *digest, const char *m, size_t len,
+ digest_algorithm_t algorithm);
+int crypto_digest_all(digests_t *ds_out, const char *m, size_t len);
+const char *crypto_digest_algorithm_get_name(digest_algorithm_t alg);
+int crypto_digest_algorithm_parse_name(const char *name);
crypto_digest_env_t *crypto_new_digest_env(void);
+crypto_digest_env_t *crypto_new_digest256_env(digest_algorithm_t algorithm);
void crypto_free_digest_env(crypto_digest_env_t *digest);
void crypto_digest_add_bytes(crypto_digest_env_t *digest, const char *data,
size_t len);
@@ -162,7 +198,7 @@ int crypto_dh_get_bytes(crypto_dh_env_t *dh);
int crypto_dh_generate_public(crypto_dh_env_t *dh);
int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey_out,
size_t pubkey_out_len);
-ssize_t crypto_dh_compute_secret(crypto_dh_env_t *dh,
+ssize_t crypto_dh_compute_secret(int severity, crypto_dh_env_t *dh,
const char *pubkey, size_t pubkey_len,
char *secret_out, size_t secret_out_len);
void crypto_dh_free(crypto_dh_env_t *dh);
@@ -174,6 +210,7 @@ int crypto_seed_rng(int startup);
int crypto_rand(char *to, size_t n);
int crypto_rand_int(unsigned int max);
uint64_t crypto_rand_uint64(uint64_t max);
+double crypto_rand_double(void);
char *crypto_random_hostname(int min_rand_len, int max_rand_len,
const char *prefix, const char *suffix);
@@ -191,6 +228,8 @@ int base32_decode(char *dest, size_t destlen, const char *src, size_t srclen);
int digest_to_base64(char *d64, const char *digest);
int digest_from_base64(char *digest, const char *d64);
+int digest256_to_base64(char *d64, const char *digest);
+int digest256_from_base64(char *digest, const char *d64);
/** Length of RFC2440-style S2K specifier: the first 8 bytes are a salt, the
* 9th describes how much iteration to do. */
diff --git a/src/common/ht.h b/src/common/ht.h
index e6dd3d2b24..f598856d8a 100644
--- a/src/common/ht.h
+++ b/src/common/ht.h
@@ -42,6 +42,10 @@
#define HT_SIZE(head) \
((head)->hth_n_entries)
+/* Return memory usage for a hashtable (not counting the entries themselves) */
+#define HT_MEM_USAGE(head) \
+ (sizeof(*head) + (head)->hth_table_length * sizeof(void*))
+
#define HT_FIND(name, head, elm) name##_HT_FIND((head), (elm))
#define HT_INSERT(name, head, elm) name##_HT_INSERT((head), (elm))
#define HT_REPLACE(name, head, elm) name##_HT_REPLACE((head), (elm))
diff --git a/src/common/log.c b/src/common/log.c
index 6baef8e26c..b639e7a781 100644
--- a/src/common/log.c
+++ b/src/common/log.c
@@ -33,11 +33,9 @@
#include "compat.h"
#include "util.h"
#define LOG_PRIVATE
-#include "log.h"
+#include "torlog.h"
#include "container.h"
-#include <event.h>
-
#define TRUNCATED_STR "[...truncated]"
#define TRUNCATED_STR_LEN 14
@@ -83,7 +81,7 @@ should_log_function_name(log_domain_mask_t domain, int severity)
/* All debugging messages occur in interesting places. */
return 1;
case LOG_NOTICE:
- case LOG_WARN:
+ case LOG_WARN:
case LOG_ERR:
/* We care about places where bugs occur. */
return (domain == LD_BUG);
@@ -330,7 +328,7 @@ logv(int severity, log_domain_mask_t domain, const char *funcname,
/** Output a message to the log. */
void
-_log(int severity, log_domain_mask_t domain, const char *format, ...)
+tor_log(int severity, log_domain_mask_t domain, const char *format, ...)
{
va_list ap;
if (severity > _log_global_min_severity)
@@ -428,6 +426,8 @@ _log_err(log_domain_mask_t domain, const char *format, ...)
static void
log_free(logfile_t *victim)
{
+ if (!victim)
+ return;
tor_free(victim->severities);
tor_free(victim->filename);
tor_free(victim);
@@ -678,13 +678,11 @@ add_file_log(const log_severity_list_t *severity, const char *filename)
logfiles->needs_close = 1;
lf = logfiles;
_log_global_min_severity = get_min_log_level();
- UNLOCK_LOGS();
if (log_tor_version(lf, 0) < 0) {
- LOCK_LOGS();
delete_log(lf);
- UNLOCK_LOGS();
}
+ UNLOCK_LOGS();
return 0;
}
@@ -747,7 +745,7 @@ log_level_to_string(int level)
static const char *domain_list[] = {
"GENERAL", "CRYPTO", "NET", "CONFIG", "FS", "PROTOCOL", "MM",
"HTTP", "APP", "CONTROL", "CIRC", "REND", "BUG", "DIR", "DIRSERV",
- "OR", "EDGE", "ACCT", "HIST", NULL
+ "OR", "EDGE", "ACCT", "HIST", "HANDSHAKE", NULL
};
/** Return a bitmask for the log domain for which <b>domain</b> is the name,
@@ -925,65 +923,6 @@ switch_logs_debug(void)
UNLOCK_LOGS();
}
-#ifdef HAVE_EVENT_SET_LOG_CALLBACK
-/** A string which, if it appears in a libevent log, should be ignored. */
-static const char *suppress_msg = NULL;
-/** Callback function passed to event_set_log() so we can intercept
- * log messages from libevent. */
-static void
-libevent_logging_callback(int severity, const char *msg)
-{
- char buf[1024];
- size_t n;
- if (suppress_msg && strstr(msg, suppress_msg))
- return;
- n = strlcpy(buf, msg, sizeof(buf));
- if (n && n < sizeof(buf) && buf[n-1] == '\n') {
- buf[n-1] = '\0';
- }
- switch (severity) {
- case _EVENT_LOG_DEBUG:
- log(LOG_DEBUG, LD_NET, "Message from libevent: %s", buf);
- break;
- case _EVENT_LOG_MSG:
- log(LOG_INFO, LD_NET, "Message from libevent: %s", buf);
- break;
- case _EVENT_LOG_WARN:
- log(LOG_WARN, LD_GENERAL, "Warning from libevent: %s", buf);
- break;
- case _EVENT_LOG_ERR:
- log(LOG_ERR, LD_GENERAL, "Error from libevent: %s", buf);
- break;
- default:
- log(LOG_WARN, LD_GENERAL, "Message [%d] from libevent: %s",
- severity, buf);
- break;
- }
-}
-/** Set hook to intercept log messages from libevent. */
-void
-configure_libevent_logging(void)
-{
- event_set_log_callback(libevent_logging_callback);
-}
-/** Ignore any libevent log message that contains <b>msg</b>. */
-void
-suppress_libevent_log_msg(const char *msg)
-{
- suppress_msg = msg;
-}
-#else
-void
-configure_libevent_logging(void)
-{
-}
-void
-suppress_libevent_log_msg(const char *msg)
-{
- (void)msg;
-}
-#endif
-
#if 0
static void
dump_log_info(logfile_t *lf)
diff --git a/src/common/memarea.c b/src/common/memarea.c
index edd7bbe9ef..dac15434c0 100644
--- a/src/common/memarea.c
+++ b/src/common/memarea.c
@@ -11,7 +11,11 @@
#include "memarea.h"
#include "util.h"
#include "compat.h"
-#include "log.h"
+#include "torlog.h"
+
+/** If true, we try to detect any attempts to write beyond the length of a
+ * memarea. */
+#define USE_SENTINELS
/** All returned pointers should be aligned to the nearest multiple of this
* value. */
@@ -25,6 +29,24 @@
#error "void* is neither 4 nor 8 bytes long. I don't know how to align stuff."
#endif
+#ifdef USE_SENTINELS
+#define SENTINEL_VAL 0x90806622u
+#define SENTINEL_LEN sizeof(uint32_t)
+#define SET_SENTINEL(chunk) \
+ STMT_BEGIN \
+ set_uint32( &(chunk)->u.mem[chunk->mem_size], SENTINEL_VAL ); \
+ STMT_END
+#define CHECK_SENTINEL(chunk) \
+ STMT_BEGIN \
+ uint32_t sent_val = get_uint32(&(chunk)->u.mem[chunk->mem_size]); \
+ tor_assert(sent_val == SENTINEL_VAL); \
+ STMT_END
+#else
+#define SENTINEL_LEN 0
+#define SET_SENTINEL(chunk) STMT_NIL
+#define CHECK_SENTINEL(chunk) STMT_NIL
+#endif
+
/** Increment <b>ptr</b> until it is aligned to MEMAREA_ALIGN. */
static INLINE void *
realign_pointer(void *ptr)
@@ -79,15 +101,20 @@ alloc_chunk(size_t sz, int freelist_ok)
freelist = res->next_chunk;
res->next_chunk = NULL;
--freelist_len;
+ CHECK_SENTINEL(res);
return res;
} else {
size_t chunk_size = freelist_ok ? CHUNK_SIZE : sz;
- memarea_chunk_t *res = tor_malloc_roundup(&chunk_size);
+ memarea_chunk_t *res;
+ chunk_size += SENTINEL_LEN;
+ res = tor_malloc_roundup(&chunk_size);
res->next_chunk = NULL;
- res->mem_size = chunk_size - CHUNK_HEADER_SIZE;
+ res->mem_size = chunk_size - CHUNK_HEADER_SIZE - SENTINEL_LEN;
res->next_mem = res->u.mem;
- tor_assert(res->next_mem+res->mem_size == ((char*)res)+chunk_size);
+ tor_assert(res->next_mem+res->mem_size+SENTINEL_LEN ==
+ ((char*)res)+chunk_size);
tor_assert(realign_pointer(res->next_mem) == res->next_mem);
+ SET_SENTINEL(res);
return res;
}
}
@@ -95,8 +122,9 @@ alloc_chunk(size_t sz, int freelist_ok)
/** Release <b>chunk</b> from a memarea, either by adding it to the freelist
* or by freeing it if the freelist is already too big. */
static void
-chunk_free(memarea_chunk_t *chunk)
+chunk_free_unchecked(memarea_chunk_t *chunk)
{
+ CHECK_SENTINEL(chunk);
if (freelist_len < MAX_FREELIST_LEN) {
++freelist_len;
chunk->next_chunk = freelist;
@@ -124,7 +152,7 @@ memarea_drop_all(memarea_t *area)
memarea_chunk_t *chunk, *next;
for (chunk = area->first; chunk; chunk = next) {
next = chunk->next_chunk;
- chunk_free(chunk);
+ chunk_free_unchecked(chunk);
}
area->first = NULL; /*fail fast on */
tor_free(area);
@@ -140,7 +168,7 @@ memarea_clear(memarea_t *area)
if (area->first->next_chunk) {
for (chunk = area->first->next_chunk; chunk; chunk = next) {
next = chunk->next_chunk;
- chunk_free(chunk);
+ chunk_free_unchecked(chunk);
}
area->first->next_chunk = NULL;
}
@@ -183,6 +211,7 @@ memarea_alloc(memarea_t *area, size_t sz)
memarea_chunk_t *chunk = area->first;
char *result;
tor_assert(chunk);
+ CHECK_SENTINEL(chunk);
tor_assert(sz < SIZE_T_CEILING);
if (sz == 0)
sz = 1;
@@ -261,6 +290,7 @@ memarea_get_stats(memarea_t *area, size_t *allocated_out, size_t *used_out)
size_t a = 0, u = 0;
memarea_chunk_t *chunk;
for (chunk = area->first; chunk; chunk = chunk->next_chunk) {
+ CHECK_SENTINEL(chunk);
a += CHUNK_HEADER_SIZE + chunk->mem_size;
tor_assert(chunk->next_mem >= chunk->u.mem);
u += CHUNK_HEADER_SIZE + (chunk->next_mem - chunk->u.mem);
@@ -277,6 +307,7 @@ memarea_assert_ok(memarea_t *area)
tor_assert(area->first);
for (chunk = area->first; chunk; chunk = chunk->next_chunk) {
+ CHECK_SENTINEL(chunk);
tor_assert(chunk->next_mem >= chunk->u.mem);
tor_assert(chunk->next_mem <=
(char*) realign_pointer(chunk->u.mem+chunk->mem_size));
diff --git a/src/common/mempool.c b/src/common/mempool.c
index 1f79221b48..9d019d618e 100644
--- a/src/common/mempool.c
+++ b/src/common/mempool.c
@@ -65,7 +65,7 @@
#include "orconfig.h"
#include "util.h"
#include "compat.h"
-#include "log.h"
+#include "torlog.h"
#define ALLOC(x) tor_malloc(x)
#define FREE(x) tor_free(x)
#define ASSERT(x) tor_assert(x)
diff --git a/src/common/sha256.c b/src/common/sha256.c
new file mode 100644
index 0000000000..4236d48f5f
--- /dev/null
+++ b/src/common/sha256.c
@@ -0,0 +1,331 @@
+/* Copyright (c) 2009-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+/* This SHA256 implementation is adapted from the public domain one in
+ LibTomCrypt, version 1.6. Tor uses it on platforms where OpenSSL doesn't
+ have a SHA256. */
+
+
+typedef struct sha256_state {
+ uint64_t length;
+ uint32_t state[8], curlen;
+ unsigned char buf[64];
+} sha256_state;
+
+#define CRYPT_OK 0
+#define CRYPT_NOP -1
+#define CRYPT_INVALID_ARG -2
+
+#define LOAD32H(x,y) STMT_BEGIN x = ntohl(get_uint32((const char*)y)); STMT_END
+#define STORE32H(x,y) STMT_BEGIN set_uint32((char*)y, htonl(x)); STMT_END
+#define STORE64H(x,y) STMT_BEGIN \
+ set_uint32((char*)y, htonl((uint32_t)((x)>>32))); \
+ set_uint32(((char*)y)+4, htonl((uint32_t)((x)&0xffffffff))); \
+ STMT_END
+#define RORc(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
+#ifndef MIN
+ #define MIN(x, y) ( ((x)<(y))?(x):(y) )
+#endif
+
+
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
+ */
+
+/**
+ @file sha256.c
+ SHA256 by Tom St Denis
+*/
+
+
+#ifdef LTC_SMALL_CODE
+/* the K array */
+static const uint32_t K[64] = {
+ 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
+ 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
+ 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
+ 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+ 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
+ 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
+ 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
+ 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+ 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
+ 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
+ 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
+ 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+ 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+#endif
+
+/* Various logical functions */
+#define Ch(x,y,z) (z ^ (x & (y ^ z)))
+#define Maj(x,y,z) (((x | y) & z) | (x & y))
+#define S(x, n) RORc((x),(n))
+#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
+#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
+#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
+#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
+#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
+
+/* compress 512-bits */
+#ifdef LTC_CLEAN_STACK
+static int _sha256_compress(sha256_state * md, unsigned char *buf)
+#else
+static int sha256_compress(sha256_state * md, unsigned char *buf)
+#endif
+{
+ uint32_t S[8], W[64], t0, t1;
+#ifdef LTC_SMALL_CODE
+ uint32_t t;
+#endif
+ int i;
+
+ /* copy state into S */
+ for (i = 0; i < 8; i++) {
+ S[i] = md->state[i];
+ }
+
+ /* copy the state into 512-bits into W[0..15] */
+ for (i = 0; i < 16; i++) {
+ LOAD32H(W[i], buf + (4*i));
+ }
+
+ /* fill W[16..63] */
+ for (i = 16; i < 64; i++) {
+ W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
+ }
+
+ /* Compress */
+#ifdef LTC_SMALL_CODE
+#define RND(a,b,c,d,e,f,g,h,i) \
+ t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
+ t1 = Sigma0(a) + Maj(a, b, c); \
+ d += t0; \
+ h = t0 + t1;
+
+ for (i = 0; i < 64; ++i) {
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
+ t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
+ S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
+ }
+#else
+#define RND(a,b,c,d,e,f,g,h,i,ki) \
+ t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
+ t1 = Sigma0(a) + Maj(a, b, c); \
+ d += t0; \
+ h = t0 + t1;
+
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
+
+#undef RND
+
+#endif
+
+ /* feedback */
+ for (i = 0; i < 8; i++) {
+ md->state[i] = md->state[i] + S[i];
+ }
+ return CRYPT_OK;
+}
+
+#ifdef LTC_CLEAN_STACK
+static int sha256_compress(sha256_state * md, unsigned char *buf)
+{
+ int err;
+ err = _sha256_compress(md, buf);
+ burn_stack(sizeof(uint32_t) * 74);
+ return err;
+}
+#endif
+
+/**
+ Initialize the hash state
+ @param md The hash state you wish to initialize
+ @return CRYPT_OK if successful
+*/
+static int sha256_init(sha256_state * md)
+{
+ LTC_ARGCHK(md != NULL);
+
+ md->curlen = 0;
+ md->length = 0;
+ md->state[0] = 0x6A09E667UL;
+ md->state[1] = 0xBB67AE85UL;
+ md->state[2] = 0x3C6EF372UL;
+ md->state[3] = 0xA54FF53AUL;
+ md->state[4] = 0x510E527FUL;
+ md->state[5] = 0x9B05688CUL;
+ md->state[6] = 0x1F83D9ABUL;
+ md->state[7] = 0x5BE0CD19UL;
+ return CRYPT_OK;
+}
+
+/**
+ Process a block of memory though the hash
+ @param md The hash state
+ @param in The data to hash
+ @param inlen The length of the data (octets)
+ @return CRYPT_OK if successful
+*/
+static int sha256_process (sha256_state * md, const unsigned char *in, unsigned long inlen)
+{
+ unsigned long n;
+ int err;
+ LTC_ARGCHK(md != NULL);
+ LTC_ARGCHK(in != NULL);
+ if (md->curlen > sizeof(md->buf)) {
+ return CRYPT_INVALID_ARG;
+ }
+ while (inlen > 0) {
+ if (md->curlen == 0 && inlen >= 64) {
+ if ((err = sha256_compress (md, (unsigned char *)in)) != CRYPT_OK) {
+ return err;
+ }
+ md->length += 64 * 8;
+ in += 64;
+ inlen -= 64;
+ } else {
+ n = MIN(inlen, (64 - md->curlen));
+ memcpy(md->buf + md->curlen, in, (size_t)n);
+ md->curlen += n;
+ in += n;
+ inlen -= n;
+ if (md->curlen == 64) {
+ if ((err = sha256_compress (md, md->buf)) != CRYPT_OK) {
+ return err;
+ }
+ md->length += 8*64;
+ md->curlen = 0;
+ }
+ }
+ }
+ return CRYPT_OK;
+}
+
+/**
+ Terminate the hash to get the digest
+ @param md The hash state
+ @param out [out] The destination of the hash (32 bytes)
+ @return CRYPT_OK if successful
+*/
+static int sha256_done(sha256_state * md, unsigned char *out)
+{
+ int i;
+
+ LTC_ARGCHK(md != NULL);
+ LTC_ARGCHK(out != NULL);
+
+ if (md->curlen >= sizeof(md->buf)) {
+ return CRYPT_INVALID_ARG;
+ }
+
+
+ /* increase the length of the message */
+ md->length += md->curlen * 8;
+
+ /* append the '1' bit */
+ md->buf[md->curlen++] = (unsigned char)0x80;
+
+ /* if the length is currently above 56 bytes we append zeros
+ * then compress. Then we can fall back to padding zeros and length
+ * encoding like normal.
+ */
+ if (md->curlen > 56) {
+ while (md->curlen < 64) {
+ md->buf[md->curlen++] = (unsigned char)0;
+ }
+ sha256_compress(md, md->buf);
+ md->curlen = 0;
+ }
+
+ /* pad upto 56 bytes of zeroes */
+ while (md->curlen < 56) {
+ md->buf[md->curlen++] = (unsigned char)0;
+ }
+
+ /* store length */
+ STORE64H(md->length, md->buf+56);
+ sha256_compress(md, md->buf);
+
+ /* copy output */
+ for (i = 0; i < 8; i++) {
+ STORE32H(md->state[i], out+(4*i));
+ }
+#ifdef LTC_CLEAN_STACK
+ zeromem(md, sizeof(sha256_state));
+#endif
+ return CRYPT_OK;
+}
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha256.c,v $ */
+/* $Revision: 1.9 $ */
+/* $Date: 2006/11/01 09:28:17 $ */
diff --git a/src/common/test.h b/src/common/test.h
deleted file mode 100644
index 1e3db58333..0000000000
--- a/src/common/test.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/* Copyright (c) 2001-2003, Roger Dingledine.
- * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2010, The Tor Project, Inc. */
-/* See LICENSE for licensing information */
-
-#ifndef _TOR_TEST_H
-#define _TOR_TEST_H
-
-/**
- * \file test.h
- * \brief Macros used by unit tests.
- */
-
-#include "compat.h"
-
-#ifdef __GNUC__
-#define PRETTY_FUNCTION __PRETTY_FUNCTION__
-#else
-#define PRETTY_FUNCTION ""
-#endif
-
-#define test_fail_msg(msg) \
- STMT_BEGIN \
- have_failed = 1; \
- printf("\nFile %s: line %d (%s): %s", \
- _SHORT_FILE_, \
- __LINE__, \
- PRETTY_FUNCTION, \
- msg); \
- goto done; \
- STMT_END
-
-#define test_fail() test_fail_msg("Assertion failed.")
-
-#define test_assert(expr) \
- STMT_BEGIN \
- if (expr) { printf("."); fflush(stdout); } else { \
- have_failed = 1; \
- printf("\nFile %s: line %d (%s): assertion failed: (%s)\n", \
- _SHORT_FILE_, \
- __LINE__, \
- PRETTY_FUNCTION, \
- #expr); \
- goto done; \
- } STMT_END
-
-#define test_eq_type(tp, fmt, expr1, expr2) \
- STMT_BEGIN \
- tp _test_v1=(tp)(expr1); \
- tp _test_v2=(tp)(expr2); \
- if (_test_v1==_test_v2) { printf("."); fflush(stdout); } else { \
- have_failed = 1; \
- printf("\nFile %s: line %d (%s): Assertion failed: (%s==%s)\n" \
- " "fmt "!="fmt"\n", \
- _SHORT_FILE_, \
- __LINE__, \
- PRETTY_FUNCTION, \
- #expr1, #expr2, \
- _test_v1, _test_v2); \
- goto done; \
- } STMT_END
-
-#define test_eq(expr1, expr2) \
- test_eq_type(long, "%ld", expr1, expr2)
-
-#define test_eq_ptr(expr1, expr2) \
- test_eq_type(void*, "%p", expr1, expr2)
-
-#define test_neq_type(tp, fmt, expr1, expr2) \
- STMT_BEGIN \
- tp _test_v1=(tp)(expr1); \
- tp _test_v2=(tp)(expr2); \
- if (_test_v1!=_test_v2) { printf("."); fflush(stdout); } else { \
- have_failed = 1; \
- printf("\nFile %s: line %d (%s): Assertion failed: (%s!=%s)\n" \
- " ("fmt" == "fmt")\n", \
- _SHORT_FILE_, \
- __LINE__, \
- PRETTY_FUNCTION, \
- #expr1, #expr2, \
- _test_v1, _test_v2); \
- goto done; \
- } STMT_END
-
-#define test_neq(expr1, expr2) \
- test_neq_type(long, "%ld", expr1, expr2)
-
-#define test_neq_ptr(expr1, expr2) \
- test_neq_type(void *, "%p", expr1, expr2)
-
-#define test_streq(expr1, expr2) \
- STMT_BEGIN \
- const char *_test_v1=(expr1), *_test_v2=(expr2); \
- if (!strcmp(_test_v1,_test_v2)) { printf("."); fflush(stdout); } else { \
- have_failed = 1; \
- printf("\nFile %s: line %d (%s): Assertion failed: (%s==%s)\n"\
- " (\"%s\" != \"%s\")\n", \
- _SHORT_FILE_, \
- __LINE__, \
- PRETTY_FUNCTION, \
- #expr1, #expr2, \
- _test_v1, _test_v2); \
- goto done; \
- } STMT_END
-
-#define test_strneq(expr1, expr2) \
- STMT_BEGIN \
- const char *_test_v1=(expr1), *_test_v2=(expr2); \
- if (strcmp(_test_v1,_test_v2)) { printf("."); fflush(stdout); } else { \
- have_failed = 1; \
- printf("\nFile %s: line %d (%s): Assertion failed: (%s!=%s)\n"\
- " (\"%s\" == \"%s\")\n", \
- _SHORT_FILE_, \
- __LINE__, \
- PRETTY_FUNCTION, \
- #expr1, #expr2, \
- _test_v1, _test_v2); \
- goto done; \
- } STMT_END
-
-#define test_memeq(expr1, expr2, len) \
- STMT_BEGIN \
- const void *_test_v1=(expr1), *_test_v2=(expr2); \
- char *mem1, *mem2; \
- if (!memcmp(_test_v1,_test_v2,(len))) { \
- printf("."); fflush(stdout); } else { \
- have_failed = 1; \
- mem1 = tor_malloc(len*2+1); \
- mem2 = tor_malloc(len*2+1); \
- base16_encode(mem1, len*2+1, _test_v1, len); \
- base16_encode(mem2, len*2+1, _test_v2, len); \
- printf("\nFile %s: line %d (%s): Assertion failed: (%s==%s)\n" \
- " %s != %s\n", \
- _SHORT_FILE_, \
- __LINE__, \
- PRETTY_FUNCTION, \
- #expr1, #expr2, mem1, mem2); \
- tor_free(mem1); \
- tor_free(mem2); \
- goto done; \
- } STMT_END
-
-#define test_memeq_hex(expr1, hex) \
- STMT_BEGIN \
- const char *_test_v1 = (char*)(expr1); \
- const char *_test_v2 = (hex); \
- size_t _len_v2 = strlen(_test_v2); \
- char *_mem2 = tor_malloc(_len_v2/2); \
- tor_assert((_len_v2 & 1) == 0); \
- base16_decode(_mem2, _len_v2/2, _test_v2, _len_v2); \
- if (!memcmp(_mem2, _test_v1, _len_v2/2)) { \
- printf("."); fflush(stdout); } else { \
- char *_mem1 = tor_malloc(_len_v2+1); \
- base16_encode(_mem1, _len_v2+1, _test_v1, _len_v2/2); \
- printf("\nFile %s: line %d (%s): Assertion failed: (%s==%s)\n" \
- " %s != %s\n", \
- _SHORT_FILE_, \
- __LINE__, \
- PRETTY_FUNCTION, \
- #expr1, _test_v2, _mem1, _test_v2); \
- tor_free(_mem1); \
- tor_free(_mem2); \
- goto done; \
- } \
- tor_free(_mem2); \
- STMT_END
-
-#define test_memneq(expr1, expr2, len) \
- STMT_BEGIN \
- void *_test_v1=(expr1), *_test_v2=(expr2); \
- if (memcmp(_test_v1,_test_v2,(len))) { \
- printf("."); fflush(stdout); \
- } else { \
- have_failed = 1; \
- printf("\nFile %s: line %d (%s): Assertion failed: (%s!=%s)\n", \
- _SHORT_FILE_, \
- __LINE__, \
- PRETTY_FUNCTION, \
- #expr1, #expr2); \
- goto done; \
- } STMT_END
-
-#endif
-
diff --git a/src/common/torgzip.c b/src/common/torgzip.c
index 10bce33283..a247d6c177 100644
--- a/src/common/torgzip.c
+++ b/src/common/torgzip.c
@@ -13,20 +13,42 @@
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
-#ifdef _MSC_VER
-#include "..\..\contrib\zlib\zlib.h"
-#else
-#include <zlib.h>
-#endif
#include <string.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
+#include "torint.h"
#include "util.h"
-#include "log.h"
+#include "torlog.h"
#include "torgzip.h"
+/* zlib 1.2.4 and 1.2.5 do some "clever" things with macros. Instead of
+ saying "(defined(FOO) ? FOO : 0)" they like to say "FOO-0", on the theory
+ that nobody will care if the compile outputs a no-such-identifier warning.
+
+ Sorry, but we like -Werror over here, so I guess we need to define these.
+ I hope that zlib 1.2.6 doesn't break these too.
+*/
+#ifndef _LARGEFILE64_SOURCE
+#define _LARGEFILE64_SOURCE 0
+#endif
+#ifndef _LFS64_LARGEFILE
+#define _LFS64_LARGEFILE 0
+#endif
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 0
+#endif
+#ifndef off64_t
+#define off64_t int64_t
+#endif
+
+#ifdef _MSC_VER
+#include "..\..\contrib\zlib\zlib.h"
+#else
+#include <zlib.h>
+#endif
+
/** Set to 1 if zlib is a version that supports gzip; set to 0 if it doesn't;
* set to -1 if we haven't checked yet. */
static int gzip_is_supported = -1;
@@ -165,9 +187,7 @@ tor_gzip_compress(char **out, size_t *out_len,
deflateEnd(stream);
tor_free(stream);
}
- if (*out) {
- tor_free(*out);
- }
+ tor_free(*out);
return -1;
}
@@ -423,7 +443,8 @@ tor_zlib_process(tor_zlib_state_t *state,
void
tor_zlib_free(tor_zlib_state_t *state)
{
- tor_assert(state);
+ if (!state)
+ return;
if (state->compress)
deflateEnd(&state->stream);
diff --git a/src/common/torint.h b/src/common/torint.h
index 665b0b4c71..a57d501002 100644
--- a/src/common/torint.h
+++ b/src/common/torint.h
@@ -117,11 +117,10 @@ typedef unsigned int uint32_t;
#ifndef INT32_MAX
#define INT32_MAX 0x7fffffffu
#endif
-#endif
-
#ifndef INT32_MIN
#define INT32_MIN (-2147483647-1)
#endif
+#endif
#if (SIZEOF_LONG == 4)
#ifndef HAVE_INT32_T
diff --git a/src/common/log.h b/src/common/torlog.h
index 6a45fc3d0b..21219569e3 100644
--- a/src/common/log.h
+++ b/src/common/torlog.h
@@ -90,9 +90,10 @@
#define LD_ACCT (1u<<17)
/** Router history */
#define LD_HIST (1u<<18)
-
+/** OR handshaking */
+#define LD_HANDSHAKE (1u<<19)
/** Number of logging domains in the code. */
-#define N_LOGGING_DOMAINS 19
+#define N_LOGGING_DOMAINS 20
typedef uint32_t log_domain_mask_t;
@@ -134,16 +135,14 @@ void add_temp_log(int min_severity);
void close_temp_logs(void);
void rollback_log_changes(void);
void mark_logs_temp(void);
-void configure_libevent_logging(void);
-void suppress_libevent_log_msg(const char *msg);
void change_callback_log_severity(int loglevelMin, int loglevelMax,
log_callback cb);
void log_set_application_name(const char *name);
/* Outputs a message to stdout */
-void _log(int severity, log_domain_mask_t domain, const char *format, ...)
+void tor_log(int severity, log_domain_mask_t domain, const char *format, ...)
CHECK_PRINTF(3,4);
-#define log _log /* hack it so we don't conflict with log() as much */
+#define log tor_log /* hack it so we don't conflict with log() as much */
#ifdef __GNUC__
extern int _log_global_min_severity;
diff --git a/src/common/tortls.c b/src/common/tortls.c
index 4d11d6d7fe..fa89412f6e 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -16,6 +16,10 @@
#include "orconfig.h"
+#if defined (WINCE)
+#include <WinSock2.h>
+#endif
+
#include <assert.h>
#ifdef MS_WINDOWS /*wrkard for dtls1.h >= 0.9.8m of "#include <winsock.h>"*/
#define WIN32_WINNT 0x400
@@ -45,7 +49,7 @@
#include "crypto.h"
#include "tortls.h"
#include "util.h"
-#include "log.h"
+#include "torlog.h"
#include "container.h"
#include "ht.h"
#include <string.h>
@@ -82,7 +86,9 @@ static int use_unsafe_renegotiation_op = 0;
* SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION? */
static int use_unsafe_renegotiation_flag = 0;
-/** Structure holding the TLS state for a single connection. */
+/** Holds a SSL_CTX object and related state used to configure TLS
+ * connections.
+ */
typedef struct tor_tls_context_t {
int refcnt;
SSL_CTX *ctx;
@@ -184,10 +190,16 @@ static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa,
const char *cname_sign,
unsigned int lifetime);
static void tor_tls_unblock_renegotiation(tor_tls_t *tls);
-
-/** Global tls context. We keep it here because nobody else needs to
- * touch it. */
-static tor_tls_context_t *global_tls_context = NULL;
+static int tor_tls_context_init_one(tor_tls_context_t **ppcontext,
+ crypto_pk_env_t *identity,
+ unsigned int key_lifetime);
+static tor_tls_context_t *tor_tls_context_new(crypto_pk_env_t *identity,
+ unsigned int key_lifetime);
+
+/** Global TLS contexts. We keep them here because nobody else needs
+ * to touch them. */
+static tor_tls_context_t *server_tls_context = NULL;
+static tor_tls_context_t *client_tls_context = NULL;
/** True iff tor_tls_init() has been called. */
static int tls_library_is_initialized = 0;
@@ -195,30 +207,51 @@ static int tls_library_is_initialized = 0;
#define _TOR_TLS_SYSCALL (_MIN_TOR_TLS_ERROR_VAL - 2)
#define _TOR_TLS_ZERORETURN (_MIN_TOR_TLS_ERROR_VAL - 1)
+#include "tortls_states.h"
+
+/** Return the symbolic name of an OpenSSL state. */
+static const char *
+ssl_state_to_string(int ssl_state)
+{
+ static char buf[40];
+ int i;
+ for (i = 0; state_map[i].name; ++i) {
+ if (state_map[i].state == ssl_state)
+ return state_map[i].name;
+ }
+ tor_snprintf(buf, sizeof(buf), "Unknown state %d", ssl_state);
+ return buf;
+}
+
/** Log all pending tls errors at level <b>severity</b>. Use
* <b>doing</b> to describe our current activities.
*/
static void
-tls_log_errors(tor_tls_t *tls, int severity, const char *doing)
+tls_log_errors(tor_tls_t *tls, int severity, int domain, const char *doing)
{
+ const char *state = NULL;
+ int st;
unsigned long err;
const char *msg, *lib, *func, *addr;
addr = tls ? tls->address : NULL;
+ st = (tls && tls->ssl) ? tls->ssl->state : -1;
while ((err = ERR_get_error()) != 0) {
msg = (const char*)ERR_reason_error_string(err);
lib = (const char*)ERR_lib_error_string(err);
func = (const char*)ERR_func_error_string(err);
+ if (!state)
+ state = (st>=0)?ssl_state_to_string(st):"---";
if (!msg) msg = "(null)";
if (!lib) lib = "(null)";
if (!func) func = "(null)";
if (doing) {
- log(severity, LD_NET, "TLS error while %s%s%s: %s (in %s:%s)",
+ log(severity, domain, "TLS error while %s%s%s: %s (in %s:%s:%s)",
doing, addr?" with ":"", addr?addr:"",
- msg, lib, func);
+ msg, lib, func, state);
} else {
- log(severity, LD_NET, "TLS error%s%s: %s (in %s:%s)",
+ log(severity, domain, "TLS error%s%s: %s (in %s:%s:%s)",
addr?" with ":"", addr?addr:"",
- msg, lib, func);
+ msg, lib, func, state);
}
}
}
@@ -294,7 +327,7 @@ tor_tls_err_to_string(int err)
*/
static int
tor_tls_get_error(tor_tls_t *tls, int r, int extra,
- const char *doing, int severity)
+ const char *doing, int severity, int domain)
{
int err = SSL_get_error(tls->ssl, r);
int tor_error = TOR_TLS_ERROR_MISC;
@@ -309,25 +342,28 @@ tor_tls_get_error(tor_tls_t *tls, int r, int extra,
if (extra&CATCH_SYSCALL)
return _TOR_TLS_SYSCALL;
if (r == 0) {
- log(severity, LD_NET, "TLS error: unexpected close while %s", doing);
+ log(severity, LD_NET, "TLS error: unexpected close while %s (%s)",
+ doing, ssl_state_to_string(tls->ssl->state));
tor_error = TOR_TLS_ERROR_IO;
} else {
int e = tor_socket_errno(tls->socket);
log(severity, LD_NET,
- "TLS error: <syscall error while %s> (errno=%d: %s)",
- doing, e, tor_socket_strerror(e));
+ "TLS error: <syscall error while %s> (errno=%d: %s; state=%s)",
+ doing, e, tor_socket_strerror(e),
+ ssl_state_to_string(tls->ssl->state));
tor_error = tor_errno_to_tls_error(e);
}
- tls_log_errors(tls, severity, doing);
+ tls_log_errors(tls, severity, domain, doing);
return tor_error;
case SSL_ERROR_ZERO_RETURN:
if (extra&CATCH_ZERO)
return _TOR_TLS_ZERORETURN;
- log(severity, LD_NET, "TLS connection closed while %s", doing);
- tls_log_errors(tls, severity, doing);
+ log(severity, LD_NET, "TLS connection closed while %s in state %s",
+ doing, ssl_state_to_string(tls->ssl->state));
+ tls_log_errors(tls, severity, domain, doing);
return TOR_TLS_CLOSE;
default:
- tls_log_errors(tls, severity, doing);
+ tls_log_errors(tls, severity, domain, doing);
return TOR_TLS_ERROR_MISC;
}
}
@@ -341,11 +377,10 @@ tor_tls_init(void)
long version;
SSL_library_init();
SSL_load_error_strings();
- crypto_global_init(-1);
version = SSLeay();
- /* OpenSSL 0.9.8l introdeced SSL3_FLAGS_ALLOW_UNSAGE_LEGACY_RENEGOTIATION
+ /* OpenSSL 0.9.8l introduced SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
* here, but without thinking too hard about it: it turns out that the
* flag in question needed to be set at the last minute, and that it
* conflicted with an existing flag number that had already been added
@@ -364,8 +399,8 @@ tor_tls_init(void)
* leave their headers out of sync with their libraries.
*
* Yes, it _is_ almost as if the OpenSSL developers decided that no
- * program should be allowed to use renegotiation its first passed an
- * test of intelligence and determination.
+ * program should be allowed to use renegotiation unless it first passed
+ * a test of intelligence and determination.
*/
if (version >= 0x009080c0L && version < 0x009080d0L) {
log_notice(LD_GENERAL, "OpenSSL %s looks like version 0.9.8l; "
@@ -400,9 +435,15 @@ tor_tls_init(void)
void
tor_tls_free_all(void)
{
- if (global_tls_context) {
- tor_tls_context_decref(global_tls_context);
- global_tls_context = NULL;
+ if (server_tls_context) {
+ tor_tls_context_t *ctx = server_tls_context;
+ server_tls_context = NULL;
+ tor_tls_context_decref(ctx);
+ }
+ if (client_tls_context) {
+ tor_tls_context_t *ctx = client_tls_context;
+ client_tls_context = NULL;
+ tor_tls_context_decref(ctx);
}
if (!HT_EMPTY(&tlsmap_root)) {
log_warn(LD_MM, "Still have entries in the tlsmap at shutdown.");
@@ -511,7 +552,7 @@ tor_tls_create_certificate(crypto_pk_env_t *rsa,
x509 = NULL;
}
done:
- tls_log_errors(NULL, LOG_WARN, "generating certificate");
+ tls_log_errors(NULL, LOG_WARN, LD_NET, "generating certificate");
if (sign_pkey)
EVP_PKEY_free(sign_pkey);
if (pkey)
@@ -528,9 +569,9 @@ tor_tls_create_certificate(crypto_pk_env_t *rsa,
(TLS1_TXT_DHE_RSA_WITH_AES_256_SHA ":" \
TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":" \
SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA)
-/* Note: for setting up your own private testing network with link crypto
- * disabled, set the cipher lists to your cipher list to
- * SSL3_TXT_RSA_NULL_SHA. If you do this, you won't be able to communicate
+/* Note: to set up your own private testing network with link crypto
+ * disabled, set your Tors' cipher list to
+ * (SSL3_TXT_RSA_NULL_SHA). If you do this, you won't be able to communicate
* with any of the "real" Tors, though. */
#ifdef V2_HANDSHAKE_CLIENT
@@ -589,15 +630,97 @@ tor_tls_context_incref(tor_tls_context_t *ctx)
++ctx->refcnt;
}
-/** Create a new TLS context for use with Tor TLS handshakes.
- * <b>identity</b> should be set to the identity key used to sign the
- * certificate, and <b>nickname</b> set to the nickname to use.
+/** Create new global client and server TLS contexts.
+ *
+ * If <b>server_identity</b> is NULL, this will not generate a server
+ * TLS context. If <b>is_public_server</b> is non-zero, this will use
+ * the same TLS context for incoming and outgoing connections, and
+ * ignore <b>client_identity</b>. */
+int
+tor_tls_context_init(int is_public_server,
+ crypto_pk_env_t *client_identity,
+ crypto_pk_env_t *server_identity,
+ unsigned int key_lifetime)
+{
+ int rv1 = 0;
+ int rv2 = 0;
+
+ if (is_public_server) {
+ tor_tls_context_t *new_ctx;
+ tor_tls_context_t *old_ctx;
+
+ tor_assert(server_identity != NULL);
+
+ rv1 = tor_tls_context_init_one(&server_tls_context,
+ server_identity,
+ key_lifetime);
+
+ if (rv1 >= 0) {
+ new_ctx = server_tls_context;
+ tor_tls_context_incref(new_ctx);
+ old_ctx = client_tls_context;
+ client_tls_context = new_ctx;
+
+ if (old_ctx != NULL) {
+ tor_tls_context_decref(old_ctx);
+ }
+ }
+ } else {
+ if (server_identity != NULL) {
+ rv1 = tor_tls_context_init_one(&server_tls_context,
+ server_identity,
+ key_lifetime);
+ } else {
+ tor_tls_context_t *old_ctx = server_tls_context;
+ server_tls_context = NULL;
+
+ if (old_ctx != NULL) {
+ tor_tls_context_decref(old_ctx);
+ }
+ }
+
+ rv2 = tor_tls_context_init_one(&client_tls_context,
+ client_identity,
+ key_lifetime);
+ }
+
+ return MIN(rv1, rv2);
+}
+
+/** Create a new global TLS context.
*
* You can call this function multiple times. Each time you call it,
* it generates new certificates; all new connections will use
* the new SSL context.
*/
-int
+static int
+tor_tls_context_init_one(tor_tls_context_t **ppcontext,
+ crypto_pk_env_t *identity,
+ unsigned int key_lifetime)
+{
+ tor_tls_context_t *new_ctx = tor_tls_context_new(identity,
+ key_lifetime);
+ tor_tls_context_t *old_ctx = *ppcontext;
+
+ if (new_ctx != NULL) {
+ *ppcontext = new_ctx;
+
+ /* Free the old context if one existed. */
+ if (old_ctx != NULL) {
+ /* This is safe even if there are open connections: we reference-
+ * count tor_tls_context_t objects. */
+ tor_tls_context_decref(old_ctx);
+ }
+ }
+
+ return ((new_ctx != NULL) ? 0 : -1);
+}
+
+/** Create a new TLS context for use with Tor TLS handshakes.
+ * <b>identity</b> should be set to the identity key used to sign the
+ * certificate.
+ */
+static tor_tls_context_t *
tor_tls_context_new(crypto_pk_env_t *identity, unsigned int key_lifetime)
{
crypto_pk_env_t *rsa = NULL;
@@ -692,21 +815,15 @@ tor_tls_context_new(crypto_pk_env_t *identity, unsigned int key_lifetime)
always_accept_verify_cb);
/* let us realloc bufs that we're writing from */
SSL_CTX_set_mode(result->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
- /* Free the old context if one exists. */
- if (global_tls_context) {
- /* This is safe even if there are open connections: OpenSSL does
- * reference counting with SSL and SSL_CTX objects. */
- tor_tls_context_decref(global_tls_context);
- }
- global_tls_context = result;
+
if (rsa)
crypto_free_pk_env(rsa);
tor_free(nickname);
tor_free(nn2);
- return 0;
+ return result;
error:
- tls_log_errors(NULL, LOG_WARN, "creating TLS context");
+ tls_log_errors(NULL, LOG_WARN, LD_NET, "creating TLS context");
tor_free(nickname);
tor_free(nn2);
if (pkey)
@@ -719,7 +836,7 @@ tor_tls_context_new(crypto_pk_env_t *identity, unsigned int key_lifetime)
X509_free(cert);
if (idcert)
X509_free(idcert);
- return -1;
+ return NULL;
}
#ifdef V2_HANDSHAKE_SERVER
@@ -734,11 +851,11 @@ tor_tls_client_is_using_v2_ciphers(const SSL *ssl, const char *address)
/* If we reached this point, we just got a client hello. See if there is
* a cipher list. */
if (!(session = SSL_get_session((SSL *)ssl))) {
- log_warn(LD_NET, "No session on TLS?");
+ log_info(LD_NET, "No session on TLS?");
return 0;
}
if (!session->ciphers) {
- log_warn(LD_NET, "No ciphers on session");
+ log_info(LD_NET, "No ciphers on session");
return 0;
}
/* Now we need to see if there are any ciphers whose presence means we're
@@ -750,8 +867,7 @@ tor_tls_client_is_using_v2_ciphers(const SSL *ssl, const char *address)
strcmp(ciphername, TLS1_TXT_DHE_RSA_WITH_AES_256_SHA) &&
strcmp(ciphername, SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA) &&
strcmp(ciphername, "(NONE)")) {
- /* XXXX should be ld_debug */
- log_info(LD_NET, "Got a non-version-1 cipher called '%s'", ciphername);
+ log_debug(LD_NET, "Got a non-version-1 cipher called '%s'", ciphername);
// return 1;
goto dump_list;
}
@@ -767,8 +883,8 @@ tor_tls_client_is_using_v2_ciphers(const SSL *ssl, const char *address)
smartlist_add(elts, (char*)ciphername);
}
s = smartlist_join_strings(elts, ":", 0, NULL);
- log_info(LD_NET, "Got a non-version-1 cipher list from %s. It is: '%s'",
- address, s);
+ log_debug(LD_NET, "Got a non-version-1 cipher list from %s. It is: '%s'",
+ address, s);
tor_free(s);
smartlist_free(elts);
}
@@ -899,10 +1015,12 @@ tor_tls_new(int sock, int isServer)
{
BIO *bio = NULL;
tor_tls_t *result = tor_malloc_zero(sizeof(tor_tls_t));
+ tor_tls_context_t *context = isServer ? server_tls_context :
+ client_tls_context;
- tor_assert(global_tls_context); /* make sure somebody made it first */
- if (!(result->ssl = SSL_new(global_tls_context->ctx))) {
- tls_log_errors(NULL, LOG_WARN, "generating TLS context");
+ tor_assert(context); /* make sure somebody made it first */
+ if (!(result->ssl = SSL_new(context->ctx))) {
+ tls_log_errors(NULL, LOG_WARN, LD_NET, "creating SSL object");
tor_free(result);
return NULL;
}
@@ -918,7 +1036,7 @@ tor_tls_new(int sock, int isServer)
if (!SSL_set_cipher_list(result->ssl,
isServer ? SERVER_CIPHER_LIST : CLIENT_CIPHER_LIST)) {
- tls_log_errors(NULL, LOG_WARN, "setting ciphers");
+ tls_log_errors(NULL, LOG_WARN, LD_NET, "setting ciphers");
#ifdef SSL_set_tlsext_host_name
SSL_set_tlsext_host_name(result->ssl, NULL);
#endif
@@ -931,7 +1049,7 @@ tor_tls_new(int sock, int isServer)
result->socket = sock;
bio = BIO_new_socket(sock, BIO_NOCLOSE);
if (! bio) {
- tls_log_errors(NULL, LOG_WARN, "opening BIO");
+ tls_log_errors(NULL, LOG_WARN, LD_NET, "opening BIO");
#ifdef SSL_set_tlsext_host_name
SSL_set_tlsext_host_name(result->ssl, NULL);
#endif
@@ -941,8 +1059,8 @@ tor_tls_new(int sock, int isServer)
}
HT_INSERT(tlsmap, &tlsmap_root, result);
SSL_set_bio(result->ssl, bio, bio);
- tor_tls_context_incref(global_tls_context);
- result->context = global_tls_context;
+ tor_tls_context_incref(context);
+ result->context = context;
result->state = TOR_TLS_ST_HANDSHAKE;
result->isServer = isServer;
result->wantwrite_n = 0;
@@ -959,7 +1077,7 @@ tor_tls_new(int sock, int isServer)
#endif
/* Not expected to get called. */
- tls_log_errors(NULL, LOG_WARN, "generating TLS context");
+ tls_log_errors(NULL, LOG_WARN, LD_NET, "creating tor_tls_t object");
return result;
}
@@ -1038,7 +1156,9 @@ void
tor_tls_free(tor_tls_t *tls)
{
tor_tls_t *removed;
- tor_assert(tls && tls->ssl);
+ if (!tls)
+ return;
+ tor_assert(tls->ssl);
removed = HT_REMOVE(tlsmap, &tlsmap_root, tls);
if (!removed) {
log_warn(LD_BUG, "Freeing a TLS that was not in the ssl->tls map.");
@@ -1081,7 +1201,7 @@ tor_tls_read(tor_tls_t *tls, char *cp, size_t len)
#endif
return r;
}
- err = tor_tls_get_error(tls, r, CATCH_ZERO, "reading", LOG_DEBUG);
+ err = tor_tls_get_error(tls, r, CATCH_ZERO, "reading", LOG_DEBUG, LD_NET);
if (err == _TOR_TLS_ZERORETURN || err == TOR_TLS_CLOSE) {
log_debug(LD_NET,"read returned r=%d; TLS is closed",r);
tls->state = TOR_TLS_ST_CLOSED;
@@ -1117,7 +1237,7 @@ tor_tls_write(tor_tls_t *tls, const char *cp, size_t n)
tls->wantwrite_n = 0;
}
r = SSL_write(tls->ssl, cp, (int)n);
- err = tor_tls_get_error(tls, r, 0, "writing", LOG_INFO);
+ err = tor_tls_get_error(tls, r, 0, "writing", LOG_INFO, LD_NET);
if (err == TOR_TLS_DONE) {
return r;
}
@@ -1135,21 +1255,30 @@ int
tor_tls_handshake(tor_tls_t *tls)
{
int r;
+ int oldstate;
tor_assert(tls);
tor_assert(tls->ssl);
tor_assert(tls->state == TOR_TLS_ST_HANDSHAKE);
check_no_tls_errors();
+ oldstate = tls->ssl->state;
if (tls->isServer) {
+ log_debug(LD_HANDSHAKE, "About to call SSL_accept on %p (%s)", tls,
+ ssl_state_to_string(tls->ssl->state));
r = SSL_accept(tls->ssl);
} else {
+ log_debug(LD_HANDSHAKE, "About to call SSL_connect on %p (%s)", tls,
+ ssl_state_to_string(tls->ssl->state));
r = SSL_connect(tls->ssl);
}
+ if (oldstate != tls->ssl->state)
+ log_debug(LD_HANDSHAKE, "After call, %p was in state %s",
+ tls, ssl_state_to_string(tls->ssl->state));
/* We need to call this here and not earlier, since OpenSSL has a penchant
* for clearing its flags when you say accept or connect. */
tor_tls_unblock_renegotiation(tls);
- r = tor_tls_get_error(tls,r,0, "handshaking", LOG_INFO);
+ r = tor_tls_get_error(tls,r,0, "handshaking", LOG_INFO, LD_HANDSHAKE);
if (ERR_peek_error() != 0) {
- tls_log_errors(tls, tls->isServer ? LOG_INFO : LOG_WARN,
+ tls_log_errors(tls, tls->isServer ? LOG_INFO : LOG_WARN, LD_HANDSHAKE,
"handshaking");
return TOR_TLS_ERROR_MISC;
}
@@ -1170,7 +1299,8 @@ tor_tls_handshake(tor_tls_t *tls)
" get set. Fixing that.");
}
tls->wasV2Handshake = 1;
- log_debug(LD_NET, "Completed V2 TLS handshake with client; waiting "
+ log_debug(LD_HANDSHAKE,
+ "Completed V2 TLS handshake with client; waiting "
"for renegotiation.");
} else {
tls->wasV2Handshake = 0;
@@ -1182,10 +1312,13 @@ tor_tls_handshake(tor_tls_t *tls)
X509 *cert = SSL_get_peer_certificate(tls->ssl);
STACK_OF(X509) *chain = SSL_get_peer_cert_chain(tls->ssl);
int n_certs = sk_X509_num(chain);
- if (n_certs > 1 || (n_certs == 1 && cert != sk_X509_value(chain, 0)))
+ if (n_certs > 1 || (n_certs == 1 && cert != sk_X509_value(chain, 0))) {
+ log_debug(LD_HANDSHAKE, "Server sent back multiple certificates; it "
+ "looks like a v1 handshake on %p", tls);
tls->wasV2Handshake = 0;
- else {
- log_debug(LD_NET, "Server sent back a single certificate; looks like "
+ } else {
+ log_debug(LD_HANDSHAKE,
+ "Server sent back a single certificate; looks like "
"a v2 handshake on %p.", tls);
tls->wasV2Handshake = 1;
}
@@ -1193,7 +1326,7 @@ tor_tls_handshake(tor_tls_t *tls)
X509_free(cert);
#endif
if (SSL_set_cipher_list(tls->ssl, SERVER_CIPHER_LIST) == 0) {
- tls_log_errors(NULL, LOG_WARN, "re-setting ciphers");
+ tls_log_errors(NULL, LOG_WARN, LD_HANDSHAKE, "re-setting ciphers");
r = TOR_TLS_ERROR_MISC;
}
}
@@ -1216,7 +1349,8 @@ tor_tls_renegotiate(tor_tls_t *tls)
if (tls->state != TOR_TLS_ST_RENEGOTIATE) {
int r = SSL_renegotiate(tls->ssl);
if (r <= 0) {
- return tor_tls_get_error(tls, r, 0, "renegotiating", LOG_WARN);
+ return tor_tls_get_error(tls, r, 0, "renegotiating", LOG_WARN,
+ LD_HANDSHAKE);
}
tls->state = TOR_TLS_ST_RENEGOTIATE;
}
@@ -1225,7 +1359,8 @@ tor_tls_renegotiate(tor_tls_t *tls)
tls->state = TOR_TLS_ST_OPEN;
return TOR_TLS_DONE;
} else
- return tor_tls_get_error(tls, r, 0, "renegotiating handshake", LOG_INFO);
+ return tor_tls_get_error(tls, r, 0, "renegotiating handshake", LOG_INFO,
+ LD_HANDSHAKE);
}
/** Shut down an open tls connection <b>tls</b>. When finished, returns
@@ -1249,7 +1384,7 @@ tor_tls_shutdown(tor_tls_t *tls)
r = SSL_read(tls->ssl, buf, 128);
} while (r>0);
err = tor_tls_get_error(tls, r, CATCH_ZERO, "reading to shut down",
- LOG_INFO);
+ LOG_INFO, LD_NET);
if (err == _TOR_TLS_ZERORETURN) {
tls->state = TOR_TLS_ST_GOTCLOSE;
/* fall through... */
@@ -1265,7 +1400,7 @@ tor_tls_shutdown(tor_tls_t *tls)
return TOR_TLS_DONE;
}
err = tor_tls_get_error(tls, r, CATCH_SYSCALL|CATCH_ZERO, "shutting down",
- LOG_INFO);
+ LOG_INFO, LD_NET);
if (err == _TOR_TLS_SYSCALL) {
/* The underlying TCP connection closed while we were shutting down. */
tls->state = TOR_TLS_ST_CLOSED;
@@ -1297,7 +1432,7 @@ tor_tls_peer_has_cert(tor_tls_t *tls)
{
X509 *cert;
cert = SSL_get_peer_certificate(tls->ssl);
- tls_log_errors(tls, LOG_WARN, "getting peer certificate");
+ tls_log_errors(tls, LOG_WARN, LD_HANDSHAKE, "getting peer certificate");
if (!cert)
return 0;
X509_free(cert);
@@ -1324,7 +1459,7 @@ log_cert_lifetime(X509 *cert, const char *problem)
log_warn(LD_GENERAL, "Couldn't allocate BIO!"); goto end;
}
if (!(ASN1_TIME_print(bio, X509_get_notBefore(cert)))) {
- tls_log_errors(NULL, LOG_WARN, "printing certificate lifetime");
+ tls_log_errors(NULL, LOG_WARN, LD_NET, "printing certificate lifetime");
goto end;
}
BIO_get_mem_ptr(bio, &buf);
@@ -1332,7 +1467,7 @@ log_cert_lifetime(X509 *cert, const char *problem)
(void)BIO_reset(bio);
if (!(ASN1_TIME_print(bio, X509_get_notAfter(cert)))) {
- tls_log_errors(NULL, LOG_WARN, "printing certificate lifetime");
+ tls_log_errors(NULL, LOG_WARN, LD_NET, "printing certificate lifetime");
goto end;
}
BIO_get_mem_ptr(bio, &buf);
@@ -1346,13 +1481,11 @@ log_cert_lifetime(X509 *cert, const char *problem)
end:
/* Not expected to get invoked */
- tls_log_errors(NULL, LOG_WARN, "getting certificate lifetime");
+ tls_log_errors(NULL, LOG_WARN, LD_NET, "getting certificate lifetime");
if (bio)
BIO_free(bio);
- if (s1)
- tor_free(s1);
- if (s2)
- tor_free(s2);
+ tor_free(s1);
+ tor_free(s2);
}
/** Helper function: try to extract a link certificate and an identity
@@ -1420,7 +1553,7 @@ tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_env_t **identity_key)
if (!(id_pkey = X509_get_pubkey(id_cert)) ||
X509_verify(cert, id_pkey) <= 0) {
log_fn(severity,LD_PROTOCOL,"X509_verify on cert and pkey returned <= 0");
- tls_log_errors(tls, severity,"verifying certificate");
+ tls_log_errors(tls, severity, LD_HANDSHAKE, "verifying certificate");
goto done;
}
@@ -1439,7 +1572,7 @@ tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_env_t **identity_key)
/* This should never get invoked, but let's make sure in case OpenSSL
* acts unexpectedly. */
- tls_log_errors(tls, LOG_WARN, "finishing tor_tls_verify");
+ tls_log_errors(tls, LOG_WARN, LD_HANDSHAKE, "finishing tor_tls_verify");
return r;
}
@@ -1478,7 +1611,7 @@ tor_tls_check_lifetime(tor_tls_t *tls, int tolerance)
if (cert)
X509_free(cert);
/* Not expected to get invoked */
- tls_log_errors(tls, LOG_WARN, "checking certificate lifetime");
+ tls_log_errors(tls, LOG_WARN, LD_NET, "checking certificate lifetime");
return r;
}
@@ -1546,7 +1679,7 @@ _check_no_tls_errors(const char *fname, int line)
return;
log(LOG_WARN, LD_CRYPTO, "Unhandled OpenSSL errors found at %s:%d: ",
tor_fix_source_file(fname), line);
- tls_log_errors(NULL, LOG_WARN, NULL);
+ tls_log_errors(NULL, LOG_WARN, LD_NET, NULL);
}
/** Return true iff the initial TLS connection at <b>tls</b> did not use a v2
diff --git a/src/common/tortls.h b/src/common/tortls.h
index e4b1ad65f2..955027ba35 100644
--- a/src/common/tortls.h
+++ b/src/common/tortls.h
@@ -50,7 +50,10 @@ typedef struct tor_tls_t tor_tls_t;
const char *tor_tls_err_to_string(int err);
void tor_tls_free_all(void);
-int tor_tls_context_new(crypto_pk_env_t *rsa, unsigned int key_lifetime);
+int tor_tls_context_init(int is_public_server,
+ crypto_pk_env_t *client_identity,
+ crypto_pk_env_t *server_identity,
+ unsigned int key_lifetime);
tor_tls_t *tor_tls_new(int sock, int is_server);
void tor_tls_set_logged_address(tor_tls_t *tls, const char *address);
void tor_tls_set_renegotiate_callback(tor_tls_t *tls,
diff --git a/src/common/tortls_states.h b/src/common/tortls_states.h
new file mode 100644
index 0000000000..00f476dd66
--- /dev/null
+++ b/src/common/tortls_states.h
@@ -0,0 +1,414 @@
+/* Copyright (c) 2003, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/* Helper file: included only in tortls.c */
+
+#ifndef _TORTLS_STATES_H
+#define _TORTLS_STATES_H
+
+/* The main body of this file was mechanically generated with this
+ perl script:
+
+ my %keys = ();
+ for $fn (@ARGV) {
+ open(F, $fn);
+ while (<F>) {
+ next unless /^#define ((?:SSL|DTLS)\w*_ST_\w*)/;
+ $keys{$1} = 1;
+ }
+ close(F);
+ }
+ for $k (sort keys %keys) {
+ print "#ifdef $k\n S($k),\n#endif\n"
+ }
+*/
+
+/** Mapping from allowed value of SSL.state to the name of C macro for that
+ * state. Used for debugging an openssl connection. */
+static const struct { int state; const char *name; } state_map[] = {
+#define S(state) { state, #state }
+#ifdef DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A
+ S(DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A),
+#endif
+#ifdef DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B
+ S(DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B),
+#endif
+#ifdef DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A
+ S(DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A),
+#endif
+#ifdef DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B
+ S(DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B),
+#endif
+#ifdef SSL23_ST_CR_SRVR_HELLO_A
+ S(SSL23_ST_CR_SRVR_HELLO_A),
+#endif
+#ifdef SSL23_ST_CR_SRVR_HELLO_B
+ S(SSL23_ST_CR_SRVR_HELLO_B),
+#endif
+#ifdef SSL23_ST_CW_CLNT_HELLO_A
+ S(SSL23_ST_CW_CLNT_HELLO_A),
+#endif
+#ifdef SSL23_ST_CW_CLNT_HELLO_B
+ S(SSL23_ST_CW_CLNT_HELLO_B),
+#endif
+#ifdef SSL23_ST_SR_CLNT_HELLO_A
+ S(SSL23_ST_SR_CLNT_HELLO_A),
+#endif
+#ifdef SSL23_ST_SR_CLNT_HELLO_B
+ S(SSL23_ST_SR_CLNT_HELLO_B),
+#endif
+#ifdef SSL2_ST_CLIENT_START_ENCRYPTION
+ S(SSL2_ST_CLIENT_START_ENCRYPTION),
+#endif
+#ifdef SSL2_ST_GET_CLIENT_FINISHED_A
+ S(SSL2_ST_GET_CLIENT_FINISHED_A),
+#endif
+#ifdef SSL2_ST_GET_CLIENT_FINISHED_B
+ S(SSL2_ST_GET_CLIENT_FINISHED_B),
+#endif
+#ifdef SSL2_ST_GET_CLIENT_HELLO_A
+ S(SSL2_ST_GET_CLIENT_HELLO_A),
+#endif
+#ifdef SSL2_ST_GET_CLIENT_HELLO_B
+ S(SSL2_ST_GET_CLIENT_HELLO_B),
+#endif
+#ifdef SSL2_ST_GET_CLIENT_HELLO_C
+ S(SSL2_ST_GET_CLIENT_HELLO_C),
+#endif
+#ifdef SSL2_ST_GET_CLIENT_MASTER_KEY_A
+ S(SSL2_ST_GET_CLIENT_MASTER_KEY_A),
+#endif
+#ifdef SSL2_ST_GET_CLIENT_MASTER_KEY_B
+ S(SSL2_ST_GET_CLIENT_MASTER_KEY_B),
+#endif
+#ifdef SSL2_ST_GET_SERVER_FINISHED_A
+ S(SSL2_ST_GET_SERVER_FINISHED_A),
+#endif
+#ifdef SSL2_ST_GET_SERVER_FINISHED_B
+ S(SSL2_ST_GET_SERVER_FINISHED_B),
+#endif
+#ifdef SSL2_ST_GET_SERVER_HELLO_A
+ S(SSL2_ST_GET_SERVER_HELLO_A),
+#endif
+#ifdef SSL2_ST_GET_SERVER_HELLO_B
+ S(SSL2_ST_GET_SERVER_HELLO_B),
+#endif
+#ifdef SSL2_ST_GET_SERVER_VERIFY_A
+ S(SSL2_ST_GET_SERVER_VERIFY_A),
+#endif
+#ifdef SSL2_ST_GET_SERVER_VERIFY_B
+ S(SSL2_ST_GET_SERVER_VERIFY_B),
+#endif
+#ifdef SSL2_ST_SEND_CLIENT_CERTIFICATE_A
+ S(SSL2_ST_SEND_CLIENT_CERTIFICATE_A),
+#endif
+#ifdef SSL2_ST_SEND_CLIENT_CERTIFICATE_B
+ S(SSL2_ST_SEND_CLIENT_CERTIFICATE_B),
+#endif
+#ifdef SSL2_ST_SEND_CLIENT_CERTIFICATE_C
+ S(SSL2_ST_SEND_CLIENT_CERTIFICATE_C),
+#endif
+#ifdef SSL2_ST_SEND_CLIENT_CERTIFICATE_D
+ S(SSL2_ST_SEND_CLIENT_CERTIFICATE_D),
+#endif
+#ifdef SSL2_ST_SEND_CLIENT_FINISHED_A
+ S(SSL2_ST_SEND_CLIENT_FINISHED_A),
+#endif
+#ifdef SSL2_ST_SEND_CLIENT_FINISHED_B
+ S(SSL2_ST_SEND_CLIENT_FINISHED_B),
+#endif
+#ifdef SSL2_ST_SEND_CLIENT_HELLO_A
+ S(SSL2_ST_SEND_CLIENT_HELLO_A),
+#endif
+#ifdef SSL2_ST_SEND_CLIENT_HELLO_B
+ S(SSL2_ST_SEND_CLIENT_HELLO_B),
+#endif
+#ifdef SSL2_ST_SEND_CLIENT_MASTER_KEY_A
+ S(SSL2_ST_SEND_CLIENT_MASTER_KEY_A),
+#endif
+#ifdef SSL2_ST_SEND_CLIENT_MASTER_KEY_B
+ S(SSL2_ST_SEND_CLIENT_MASTER_KEY_B),
+#endif
+#ifdef SSL2_ST_SEND_REQUEST_CERTIFICATE_A
+ S(SSL2_ST_SEND_REQUEST_CERTIFICATE_A),
+#endif
+#ifdef SSL2_ST_SEND_REQUEST_CERTIFICATE_B
+ S(SSL2_ST_SEND_REQUEST_CERTIFICATE_B),
+#endif
+#ifdef SSL2_ST_SEND_REQUEST_CERTIFICATE_C
+ S(SSL2_ST_SEND_REQUEST_CERTIFICATE_C),
+#endif
+#ifdef SSL2_ST_SEND_REQUEST_CERTIFICATE_D
+ S(SSL2_ST_SEND_REQUEST_CERTIFICATE_D),
+#endif
+#ifdef SSL2_ST_SEND_SERVER_FINISHED_A
+ S(SSL2_ST_SEND_SERVER_FINISHED_A),
+#endif
+#ifdef SSL2_ST_SEND_SERVER_FINISHED_B
+ S(SSL2_ST_SEND_SERVER_FINISHED_B),
+#endif
+#ifdef SSL2_ST_SEND_SERVER_HELLO_A
+ S(SSL2_ST_SEND_SERVER_HELLO_A),
+#endif
+#ifdef SSL2_ST_SEND_SERVER_HELLO_B
+ S(SSL2_ST_SEND_SERVER_HELLO_B),
+#endif
+#ifdef SSL2_ST_SEND_SERVER_VERIFY_A
+ S(SSL2_ST_SEND_SERVER_VERIFY_A),
+#endif
+#ifdef SSL2_ST_SEND_SERVER_VERIFY_B
+ S(SSL2_ST_SEND_SERVER_VERIFY_B),
+#endif
+#ifdef SSL2_ST_SEND_SERVER_VERIFY_C
+ S(SSL2_ST_SEND_SERVER_VERIFY_C),
+#endif
+#ifdef SSL2_ST_SERVER_START_ENCRYPTION
+ S(SSL2_ST_SERVER_START_ENCRYPTION),
+#endif
+#ifdef SSL2_ST_X509_GET_CLIENT_CERTIFICATE
+ S(SSL2_ST_X509_GET_CLIENT_CERTIFICATE),
+#endif
+#ifdef SSL2_ST_X509_GET_SERVER_CERTIFICATE
+ S(SSL2_ST_X509_GET_SERVER_CERTIFICATE),
+#endif
+#ifdef SSL3_ST_CR_CERT_A
+ S(SSL3_ST_CR_CERT_A),
+#endif
+#ifdef SSL3_ST_CR_CERT_B
+ S(SSL3_ST_CR_CERT_B),
+#endif
+#ifdef SSL3_ST_CR_CERT_REQ_A
+ S(SSL3_ST_CR_CERT_REQ_A),
+#endif
+#ifdef SSL3_ST_CR_CERT_REQ_B
+ S(SSL3_ST_CR_CERT_REQ_B),
+#endif
+#ifdef SSL3_ST_CR_CERT_STATUS_A
+ S(SSL3_ST_CR_CERT_STATUS_A),
+#endif
+#ifdef SSL3_ST_CR_CERT_STATUS_B
+ S(SSL3_ST_CR_CERT_STATUS_B),
+#endif
+#ifdef SSL3_ST_CR_CHANGE_A
+ S(SSL3_ST_CR_CHANGE_A),
+#endif
+#ifdef SSL3_ST_CR_CHANGE_B
+ S(SSL3_ST_CR_CHANGE_B),
+#endif
+#ifdef SSL3_ST_CR_FINISHED_A
+ S(SSL3_ST_CR_FINISHED_A),
+#endif
+#ifdef SSL3_ST_CR_FINISHED_B
+ S(SSL3_ST_CR_FINISHED_B),
+#endif
+#ifdef SSL3_ST_CR_KEY_EXCH_A
+ S(SSL3_ST_CR_KEY_EXCH_A),
+#endif
+#ifdef SSL3_ST_CR_KEY_EXCH_B
+ S(SSL3_ST_CR_KEY_EXCH_B),
+#endif
+#ifdef SSL3_ST_CR_SESSION_TICKET_A
+ S(SSL3_ST_CR_SESSION_TICKET_A),
+#endif
+#ifdef SSL3_ST_CR_SESSION_TICKET_B
+ S(SSL3_ST_CR_SESSION_TICKET_B),
+#endif
+#ifdef SSL3_ST_CR_SRVR_DONE_A
+ S(SSL3_ST_CR_SRVR_DONE_A),
+#endif
+#ifdef SSL3_ST_CR_SRVR_DONE_B
+ S(SSL3_ST_CR_SRVR_DONE_B),
+#endif
+#ifdef SSL3_ST_CR_SRVR_HELLO_A
+ S(SSL3_ST_CR_SRVR_HELLO_A),
+#endif
+#ifdef SSL3_ST_CR_SRVR_HELLO_B
+ S(SSL3_ST_CR_SRVR_HELLO_B),
+#endif
+#ifdef SSL3_ST_CW_CERT_A
+ S(SSL3_ST_CW_CERT_A),
+#endif
+#ifdef SSL3_ST_CW_CERT_B
+ S(SSL3_ST_CW_CERT_B),
+#endif
+#ifdef SSL3_ST_CW_CERT_C
+ S(SSL3_ST_CW_CERT_C),
+#endif
+#ifdef SSL3_ST_CW_CERT_D
+ S(SSL3_ST_CW_CERT_D),
+#endif
+#ifdef SSL3_ST_CW_CERT_VRFY_A
+ S(SSL3_ST_CW_CERT_VRFY_A),
+#endif
+#ifdef SSL3_ST_CW_CERT_VRFY_B
+ S(SSL3_ST_CW_CERT_VRFY_B),
+#endif
+#ifdef SSL3_ST_CW_CHANGE_A
+ S(SSL3_ST_CW_CHANGE_A),
+#endif
+#ifdef SSL3_ST_CW_CHANGE_B
+ S(SSL3_ST_CW_CHANGE_B),
+#endif
+#ifdef SSL3_ST_CW_CLNT_HELLO_A
+ S(SSL3_ST_CW_CLNT_HELLO_A),
+#endif
+#ifdef SSL3_ST_CW_CLNT_HELLO_B
+ S(SSL3_ST_CW_CLNT_HELLO_B),
+#endif
+#ifdef SSL3_ST_CW_FINISHED_A
+ S(SSL3_ST_CW_FINISHED_A),
+#endif
+#ifdef SSL3_ST_CW_FINISHED_B
+ S(SSL3_ST_CW_FINISHED_B),
+#endif
+#ifdef SSL3_ST_CW_FLUSH
+ S(SSL3_ST_CW_FLUSH),
+#endif
+#ifdef SSL3_ST_CW_KEY_EXCH_A
+ S(SSL3_ST_CW_KEY_EXCH_A),
+#endif
+#ifdef SSL3_ST_CW_KEY_EXCH_B
+ S(SSL3_ST_CW_KEY_EXCH_B),
+#endif
+#ifdef SSL3_ST_SR_CERT_A
+ S(SSL3_ST_SR_CERT_A),
+#endif
+#ifdef SSL3_ST_SR_CERT_B
+ S(SSL3_ST_SR_CERT_B),
+#endif
+#ifdef SSL3_ST_SR_CERT_VRFY_A
+ S(SSL3_ST_SR_CERT_VRFY_A),
+#endif
+#ifdef SSL3_ST_SR_CERT_VRFY_B
+ S(SSL3_ST_SR_CERT_VRFY_B),
+#endif
+#ifdef SSL3_ST_SR_CHANGE_A
+ S(SSL3_ST_SR_CHANGE_A),
+#endif
+#ifdef SSL3_ST_SR_CHANGE_B
+ S(SSL3_ST_SR_CHANGE_B),
+#endif
+#ifdef SSL3_ST_SR_CLNT_HELLO_A
+ S(SSL3_ST_SR_CLNT_HELLO_A),
+#endif
+#ifdef SSL3_ST_SR_CLNT_HELLO_B
+ S(SSL3_ST_SR_CLNT_HELLO_B),
+#endif
+#ifdef SSL3_ST_SR_CLNT_HELLO_C
+ S(SSL3_ST_SR_CLNT_HELLO_C),
+#endif
+#ifdef SSL3_ST_SR_FINISHED_A
+ S(SSL3_ST_SR_FINISHED_A),
+#endif
+#ifdef SSL3_ST_SR_FINISHED_B
+ S(SSL3_ST_SR_FINISHED_B),
+#endif
+#ifdef SSL3_ST_SR_KEY_EXCH_A
+ S(SSL3_ST_SR_KEY_EXCH_A),
+#endif
+#ifdef SSL3_ST_SR_KEY_EXCH_B
+ S(SSL3_ST_SR_KEY_EXCH_B),
+#endif
+#ifdef SSL3_ST_SW_CERT_A
+ S(SSL3_ST_SW_CERT_A),
+#endif
+#ifdef SSL3_ST_SW_CERT_B
+ S(SSL3_ST_SW_CERT_B),
+#endif
+#ifdef SSL3_ST_SW_CERT_REQ_A
+ S(SSL3_ST_SW_CERT_REQ_A),
+#endif
+#ifdef SSL3_ST_SW_CERT_REQ_B
+ S(SSL3_ST_SW_CERT_REQ_B),
+#endif
+#ifdef SSL3_ST_SW_CERT_STATUS_A
+ S(SSL3_ST_SW_CERT_STATUS_A),
+#endif
+#ifdef SSL3_ST_SW_CERT_STATUS_B
+ S(SSL3_ST_SW_CERT_STATUS_B),
+#endif
+#ifdef SSL3_ST_SW_CHANGE_A
+ S(SSL3_ST_SW_CHANGE_A),
+#endif
+#ifdef SSL3_ST_SW_CHANGE_B
+ S(SSL3_ST_SW_CHANGE_B),
+#endif
+#ifdef SSL3_ST_SW_FINISHED_A
+ S(SSL3_ST_SW_FINISHED_A),
+#endif
+#ifdef SSL3_ST_SW_FINISHED_B
+ S(SSL3_ST_SW_FINISHED_B),
+#endif
+#ifdef SSL3_ST_SW_FLUSH
+ S(SSL3_ST_SW_FLUSH),
+#endif
+#ifdef SSL3_ST_SW_HELLO_REQ_A
+ S(SSL3_ST_SW_HELLO_REQ_A),
+#endif
+#ifdef SSL3_ST_SW_HELLO_REQ_B
+ S(SSL3_ST_SW_HELLO_REQ_B),
+#endif
+#ifdef SSL3_ST_SW_HELLO_REQ_C
+ S(SSL3_ST_SW_HELLO_REQ_C),
+#endif
+#ifdef SSL3_ST_SW_KEY_EXCH_A
+ S(SSL3_ST_SW_KEY_EXCH_A),
+#endif
+#ifdef SSL3_ST_SW_KEY_EXCH_B
+ S(SSL3_ST_SW_KEY_EXCH_B),
+#endif
+#ifdef SSL3_ST_SW_SESSION_TICKET_A
+ S(SSL3_ST_SW_SESSION_TICKET_A),
+#endif
+#ifdef SSL3_ST_SW_SESSION_TICKET_B
+ S(SSL3_ST_SW_SESSION_TICKET_B),
+#endif
+#ifdef SSL3_ST_SW_SRVR_DONE_A
+ S(SSL3_ST_SW_SRVR_DONE_A),
+#endif
+#ifdef SSL3_ST_SW_SRVR_DONE_B
+ S(SSL3_ST_SW_SRVR_DONE_B),
+#endif
+#ifdef SSL3_ST_SW_SRVR_HELLO_A
+ S(SSL3_ST_SW_SRVR_HELLO_A),
+#endif
+#ifdef SSL3_ST_SW_SRVR_HELLO_B
+ S(SSL3_ST_SW_SRVR_HELLO_B),
+#endif
+#ifdef SSL_ST_ACCEPT
+ S(SSL_ST_ACCEPT),
+#endif
+#ifdef SSL_ST_BEFORE
+ S(SSL_ST_BEFORE),
+#endif
+#ifdef SSL_ST_CONNECT
+ S(SSL_ST_CONNECT),
+#endif
+#ifdef SSL_ST_INIT
+ S(SSL_ST_INIT),
+#endif
+#ifdef SSL_ST_MASK
+ S(SSL_ST_MASK),
+#endif
+#ifdef SSL_ST_OK
+ S(SSL_ST_OK),
+#endif
+#ifdef SSL_ST_READ_BODY
+ S(SSL_ST_READ_BODY),
+#endif
+#ifdef SSL_ST_READ_DONE
+ S(SSL_ST_READ_DONE),
+#endif
+#ifdef SSL_ST_READ_HEADER
+ S(SSL_ST_READ_HEADER),
+#endif
+#ifdef SSL_ST_RENEGOTIATE
+ S(SSL_ST_RENEGOTIATE),
+#endif
+ { 0, NULL }
+};
+
+#endif
+
diff --git a/src/common/util.c b/src/common/util.c
index 0571a532cd..d511872964 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -15,7 +15,8 @@
#include "orconfig.h"
#include "util.h"
-#include "log.h"
+#include "torlog.h"
+#undef log
#include "crypto.h"
#include "torint.h"
#include "container.h"
@@ -25,11 +26,17 @@
#include <io.h>
#include <direct.h>
#include <process.h>
+#include <tchar.h>
#else
#include <dirent.h>
#include <pwd.h>
#endif
+/* math.h needs this on Linux */
+#ifndef __USE_ISOC99
+#define __USE_ISOC99 1
+#endif
+#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -285,7 +292,7 @@ tor_log_mallinfo(int severity)
struct mallinfo mi;
memset(&mi, 0, sizeof(mi));
mi = mallinfo();
- log(severity, LD_MM,
+ tor_log(severity, LD_MM,
"mallinfo() said: arena=%d, ordblks=%d, smblks=%d, hblks=%d, "
"hblkhd=%d, usmblks=%d, fsmblks=%d, uordblks=%d, fordblks=%d, "
"keepcost=%d",
@@ -308,6 +315,25 @@ tor_log_mallinfo(int severity)
* Math
* ===== */
+/**
+ * Returns the natural logarithm of d base 2. We define this wrapper here so
+ * as to make it easier not to conflict with Tor's log() macro.
+ */
+double
+tor_mathlog(double d)
+{
+ return log(d);
+}
+
+/** Return the long integer closest to d. We define this wrapper here so
+ * that not all users of math.h need to use the right incancations to get
+ * the c99 functions. */
+long
+tor_lround(double d)
+{
+ return lround(d);
+}
+
/** Returns floor(log2(u64)). If u64 is 0, (incorrectly) returns 0. */
int
tor_log2(uint64_t u64)
@@ -352,6 +378,36 @@ round_to_power_of_2(uint64_t u64)
return low;
}
+/** Return the lowest x such that x is at least <b>number</b>, and x modulo
+ * <b>divisor</b> == 0. */
+unsigned
+round_to_next_multiple_of(unsigned number, unsigned divisor)
+{
+ number += divisor - 1;
+ number -= number % divisor;
+ return number;
+}
+
+/** Return the lowest x such that x is at least <b>number</b>, and x modulo
+ * <b>divisor</b> == 0. */
+uint32_t
+round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor)
+{
+ number += divisor - 1;
+ number -= number % divisor;
+ return number;
+}
+
+/** Return the lowest x such that x is at least <b>number</b>, and x modulo
+ * <b>divisor</b> == 0. */
+uint64_t
+round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor)
+{
+ number += divisor - 1;
+ number -= number % divisor;
+ return number;
+}
+
/* =====
* String manipulation
* ===== */
@@ -634,6 +690,29 @@ find_whitespace_eos(const char *s, const char *eos)
return s;
}
+/** Return the first occurrence of <b>needle</b> in <b>haystack</b> that
+ * occurs at the start of a line (that is, at the beginning of <b>haystack</b>
+ * or immediately after a newline). Return NULL if no such string is found.
+ */
+const char *
+find_str_at_start_of_line(const char *haystack, const char *needle)
+{
+ size_t needle_len = strlen(needle);
+
+ do {
+ if (!strncmp(haystack, needle, needle_len))
+ return haystack;
+
+ haystack = strchr(haystack, '\n');
+ if (!haystack)
+ return NULL;
+ else
+ ++haystack;
+ } while (*haystack);
+
+ return NULL;
+}
+
/** Return true iff the 'len' bytes at 'mem' are all zero. */
int
tor_mem_is_zero(const char *mem, size_t len)
@@ -661,6 +740,13 @@ tor_digest_is_zero(const char *digest)
return tor_mem_is_zero(digest, DIGEST_LEN);
}
+/** Return true iff the DIGEST256_LEN bytes in digest are all zero. */
+int
+tor_digest256_is_zero(const char *digest)
+{
+ return tor_mem_is_zero(digest, DIGEST256_LEN);
+}
+
/* Helper: common code to check whether the result of a strtol or strtoul or
* strtoll is correct. */
#define CHECK_STRTOX_RESULT() \
@@ -712,7 +798,18 @@ tor_parse_ulong(const char *s, int base, unsigned long min,
CHECK_STRTOX_RESULT();
}
-/** As tor_parse_log, but return a unit64_t. Only base 10 is guaranteed to
+/** As tor_parse_long(), but return a double. */
+double
+tor_parse_double(const char *s, double min, double max, int *ok, char **next)
+{
+ char *endptr;
+ double r;
+
+ r = strtod(s, &endptr);
+ CHECK_STRTOX_RESULT();
+}
+
+/** As tor_parse_long, but return a uint64_t. Only base 10 is guaranteed to
* work for now. */
uint64_t
tor_parse_uint64(const char *s, int base, uint64_t min,
@@ -851,6 +948,9 @@ esc_for_log(const char *s)
case '\\':
case '\"':
case '\'':
+ case '\r':
+ case '\n':
+ case '\t':
len += 2;
break;
default:
@@ -912,8 +1012,7 @@ const char *
escaped(const char *s)
{
static char *_escaped_val = NULL;
- if (_escaped_val)
- tor_free(_escaped_val);
+ tor_free(_escaped_val);
if (s)
_escaped_val = esc_for_log(s);
@@ -1000,6 +1099,42 @@ wrap_string(smartlist_t *out, const char *string, size_t width,
* Time
* ===== */
+/**
+ * Converts struct timeval to a double value.
+ * Preserves microsecond precision, but just barely.
+ * Error is approx +/- 0.1 usec when dealing with epoch values.
+ */
+double
+tv_to_double(const struct timeval *tv)
+{
+ double conv = tv->tv_sec;
+ conv += tv->tv_usec/1000000.0;
+ return conv;
+}
+
+/**
+ * Converts timeval to milliseconds.
+ */
+int64_t
+tv_to_msec(const struct timeval *tv)
+{
+ int64_t conv = ((int64_t)tv->tv_sec)*1000L;
+ /* Round ghetto-style */
+ conv += ((int64_t)tv->tv_usec+500)/1000L;
+ return conv;
+}
+
+/**
+ * Converts timeval to microseconds.
+ */
+int64_t
+tv_to_usec(const struct timeval *tv)
+{
+ int64_t conv = ((int64_t)tv->tv_sec)*1000000L;
+ conv += tv->tv_usec;
+ return conv;
+}
+
/** Return the number of microseconds elapsed between *start and *end.
*/
long
@@ -1009,7 +1144,8 @@ tv_udiff(const struct timeval *start, const struct timeval *end)
long secdiff = end->tv_sec - start->tv_sec;
if (labs(secdiff+1) > LONG_MAX/1000000) {
- log_warn(LD_GENERAL, "comparing times too far apart.");
+ log_warn(LD_GENERAL, "comparing times on microsecond detail too far "
+ "apart: %ld seconds", secdiff);
return LONG_MAX;
}
@@ -1017,6 +1153,26 @@ tv_udiff(const struct timeval *start, const struct timeval *end)
return udiff;
}
+/** Return the number of milliseconds elapsed between *start and *end.
+ */
+long
+tv_mdiff(const struct timeval *start, const struct timeval *end)
+{
+ long mdiff;
+ long secdiff = end->tv_sec - start->tv_sec;
+
+ if (labs(secdiff+1) > LONG_MAX/1000) {
+ log_warn(LD_GENERAL, "comparing times on millisecond detail too far "
+ "apart: %ld seconds", secdiff);
+ return LONG_MAX;
+ }
+
+ /* Subtract and round */
+ mdiff = secdiff*1000L +
+ ((long)end->tv_usec - (long)start->tv_usec + 500L) / 1000L;
+ return mdiff;
+}
+
/** Yield true iff <b>y</b> is a leap-year. */
#define IS_LEAPYEAR(y) (!(y % 4) && ((y % 100) || !(y % 400)))
/** Helper: Return the number of leap-days between Jan 1, y1 and Jan 1, y2. */
@@ -1092,7 +1248,7 @@ format_rfc1123_time(char *buf, time_t t)
memcpy(buf+8, MONTH_NAMES[tm.tm_mon], 3);
}
-/** Parse the the RFC1123 encoding of some time (in GMT) from <b>buf</b>,
+/** Parse the RFC1123 encoding of some time (in GMT) from <b>buf</b>,
* and store the result in *<b>t</b>.
*
* Return 0 on success, -1 on failure.
@@ -1430,6 +1586,49 @@ ftime_definitely_before(time_t now, time_t when)
}
/* =====
+ * Rate limiting
+ * ===== */
+
+/** If the rate-limiter <b>lim</b> is ready at <b>now</b>, return the number
+ * of calls to rate_limit_is_ready (including this one!) since the last time
+ * rate_limit_is_ready returned nonzero. Otherwise return 0. */
+static int
+rate_limit_is_ready(ratelim_t *lim, time_t now)
+{
+ if (lim->rate + lim->last_allowed <= now) {
+ int res = lim->n_calls_since_last_time + 1;
+ lim->last_allowed = now;
+ lim->n_calls_since_last_time = 0;
+ return res;
+ } else {
+ ++lim->n_calls_since_last_time;
+ return 0;
+ }
+}
+
+/** If the rate-limiter <b>lim</b> is ready at <b>now</b>, return a newly
+ * allocated string indicating how many messages were suppressed, suitable to
+ * append to a log message. Otherwise return NULL. */
+char *
+rate_limit_log(ratelim_t *lim, time_t now)
+{
+ int n;
+ if ((n = rate_limit_is_ready(lim, now))) {
+ if (n == 1) {
+ return tor_strdup("");
+ } else {
+ char *cp=NULL;
+ tor_asprintf(&cp,
+ " [%d similar message(s) suppressed in last %d seconds]",
+ n-1, lim->rate);
+ return cp;
+ }
+ } else {
+ return NULL;
+ }
+}
+
+/* =====
* File helpers
* ===== */
@@ -1553,22 +1752,22 @@ check_private_dir(const char *dirname, cpd_check_t check)
tor_free(f);
if (r) {
if (errno != ENOENT) {
- log(LOG_WARN, LD_FS, "Directory %s cannot be read: %s", dirname,
- strerror(errno));
+ log_warn(LD_FS, "Directory %s cannot be read: %s", dirname,
+ strerror(errno));
return -1;
}
if (check == CPD_NONE) {
- log(LOG_WARN, LD_FS, "Directory %s does not exist.", dirname);
+ log_warn(LD_FS, "Directory %s does not exist.", dirname);
return -1;
} else if (check == CPD_CREATE) {
log_info(LD_GENERAL, "Creating directory %s", dirname);
-#ifdef MS_WINDOWS
+#if defined (MS_WINDOWS) && !defined (WINCE)
r = mkdir(dirname);
#else
r = mkdir(dirname, 0700);
#endif
if (r) {
- log(LOG_WARN, LD_FS, "Error creating directory %s: %s", dirname,
+ log_warn(LD_FS, "Error creating directory %s: %s", dirname,
strerror(errno));
return -1;
}
@@ -1578,7 +1777,7 @@ check_private_dir(const char *dirname, cpd_check_t check)
return 0;
}
if (!(st.st_mode & S_IFDIR)) {
- log(LOG_WARN, LD_FS, "%s is not a directory", dirname);
+ log_warn(LD_FS, "%s is not a directory", dirname);
return -1;
}
#ifndef MS_WINDOWS
@@ -1591,7 +1790,7 @@ check_private_dir(const char *dirname, cpd_check_t check)
pw = getpwuid(st.st_uid);
- log(LOG_WARN, LD_FS, "%s is not owned by this user (%s, %d) but by "
+ log_warn(LD_FS, "%s is not owned by this user (%s, %d) but by "
"%s (%d). Perhaps you are running Tor as the wrong user?",
dirname, process_ownername, (int)getuid(),
pw ? pw->pw_name : "<unknown>", (int)st.st_uid);
@@ -1600,9 +1799,9 @@ check_private_dir(const char *dirname, cpd_check_t check)
return -1;
}
if (st.st_mode & 0077) {
- log(LOG_WARN, LD_FS, "Fixing permissions on directory %s", dirname);
+ log_warn(LD_FS, "Fixing permissions on directory %s", dirname);
if (chmod(dirname, 0700)) {
- log(LOG_WARN, LD_FS, "Could not chmod directory %s: %s", dirname,
+ log_warn(LD_FS, "Could not chmod directory %s: %s", dirname,
strerror(errno));
return -1;
} else {
@@ -1633,12 +1832,13 @@ write_str_to_file(const char *fname, const char *str, int bin)
}
/** Represents a file that we're writing to, with support for atomic commit:
- * we can write into a a temporary file, and either remove the file on
+ * we can write into a temporary file, and either remove the file on
* failure, or replace the original file on success. */
struct open_file_t {
char *tempname; /**< Name of the temporary file. */
char *filename; /**< Name of the original file. */
- int rename_on_close; /**< Are we using the temporary file or not? */
+ unsigned rename_on_close:1; /**< Are we using the temporary file or not? */
+ unsigned binary:1; /**< Did we open in binary mode? */
int fd; /**< fd for the open file. */
FILE *stdio_file; /**< stdio wrapper for <b>fd</b>. */
};
@@ -1686,7 +1886,7 @@ start_writing_to_file(const char *fname, int open_flags, int mode,
} else {
open_name = new_file->tempname = tor_malloc(tempname_len);
if (tor_snprintf(new_file->tempname, tempname_len, "%s.tmp", fname)<0) {
- log(LOG_WARN, LD_GENERAL, "Failed to generate filename");
+ log_warn(LD_GENERAL, "Failed to generate filename");
goto err;
}
/* We always replace an existing temporary file if there is one. */
@@ -1694,9 +1894,12 @@ start_writing_to_file(const char *fname, int open_flags, int mode,
open_flags &= ~O_EXCL;
new_file->rename_on_close = 1;
}
+ if (open_flags & O_BINARY)
+ new_file->binary = 1;
- if ((new_file->fd = open(open_name, open_flags, mode)) < 0) {
- log(LOG_WARN, LD_FS, "Couldn't open \"%s\" (%s) for writing: %s",
+ new_file->fd = open(open_name, open_flags, mode);
+ if (new_file->fd < 0) {
+ log_warn(LD_FS, "Couldn't open \"%s\" (%s) for writing: %s",
open_name, fname, strerror(errno));
goto err;
}
@@ -1732,7 +1935,8 @@ fdopen_file(open_file_t *file_data)
if (file_data->stdio_file)
return file_data->stdio_file;
tor_assert(file_data->fd >= 0);
- if (!(file_data->stdio_file = fdopen(file_data->fd, "a"))) {
+ if (!(file_data->stdio_file = fdopen(file_data->fd,
+ file_data->binary?"ab":"a"))) {
log_warn(LD_FS, "Couldn't fdopen \"%s\" [%d]: %s", file_data->filename,
file_data->fd, strerror(errno));
}
@@ -1832,7 +2036,7 @@ write_chunks_to_file_impl(const char *fname, const smartlist_t *chunks,
{
result = write_all(fd, chunk->bytes, chunk->len, 0);
if (result < 0) {
- log(LOG_WARN, LD_FS, "Error writing to \"%s\": %s", fname,
+ log_warn(LD_FS, "Error writing to \"%s\": %s", fname,
strerror(errno));
goto err;
}
@@ -2088,7 +2292,40 @@ unescape_string(const char *s, char **result, size_t *size_out)
const char *
parse_config_line_from_str(const char *line, char **key_out, char **value_out)
{
+ /* I believe the file format here is supposed to be:
+ FILE = (EMPTYLINE | LINE)* (EMPTYLASTLINE | LASTLINE)?
+
+ EMPTYLASTLINE = SPACE* | COMMENT
+ EMPTYLINE = EMPTYLASTLINE NL
+ SPACE = ' ' | '\r' | '\t'
+ COMMENT = '#' NOT-NL*
+ NOT-NL = Any character except '\n'
+ NL = '\n'
+
+ LASTLINE = SPACE* KEY SPACE* VALUES
+ LINE = LASTLINE NL
+ KEY = KEYCHAR+
+ KEYCHAR = Any character except ' ', '\r', '\n', '\t', '#', "\"
+
+ VALUES = QUOTEDVALUE | NORMALVALUE
+ QUOTEDVALUE = QUOTE QVITEM* QUOTE EOLSPACE?
+ QUOTE = '"'
+ QVCHAR = KEYCHAR | ESC ('n' | 't' | 'r' | '"' | ESC |'\'' | OCTAL | HEX)
+ ESC = "\\"
+ OCTAL = ODIGIT (ODIGIT ODIGIT?)?
+ HEX = ('x' | 'X') HEXDIGIT HEXDIGIT
+ ODIGIT = '0' .. '7'
+ HEXDIGIT = '0'..'9' | 'a' .. 'f' | 'A' .. 'F'
+ EOLSPACE = SPACE* COMMENT?
+
+ NORMALVALUE = (VALCHAR | ESC ESC_IGNORE | CONTINUATION)* EOLSPACE?
+ VALCHAR = Any character except ESC, '#', and '\n'
+ ESC_IGNORE = Any character except '#' or '\n'
+ CONTINUATION = ESC NL ( COMMENT NL )*
+ */
+
const char *key, *val, *cp;
+ int continuation = 0;
tor_assert(key_out);
tor_assert(value_out);
@@ -2112,9 +2349,10 @@ parse_config_line_from_str(const char *line, char **key_out, char **value_out)
return line;
}
- /* Skip until the next space. */
+ /* Skip until the next space or \ followed by newline. */
key = line;
- while (*line && !TOR_ISSPACE(*line) && *line != '#')
+ while (*line && !TOR_ISSPACE(*line) && *line != '#' &&
+ ! (line[0] == '\\' && line[1] == '\n'))
++line;
*key_out = tor_strndup(key, line-key);
@@ -2125,7 +2363,7 @@ parse_config_line_from_str(const char *line, char **key_out, char **value_out)
val = line;
/* Find the end of the line. */
- if (*line == '\"') {
+ if (*line == '\"') { // XXX No continuation handling is done here
if (!(line = unescape_string(line, value_out, NULL)))
return NULL;
while (*line == ' ' || *line == '\t')
@@ -2133,18 +2371,53 @@ parse_config_line_from_str(const char *line, char **key_out, char **value_out)
if (*line && *line != '#' && *line != '\n')
return NULL;
} else {
- while (*line && *line != '\n' && *line != '#')
- ++line;
+ /* Look for the end of the line. */
+ while (*line && *line != '\n' && (*line != '#' || continuation)) {
+ if (*line == '\\' && line[1] == '\n') {
+ continuation = 1;
+ line += 2;
+ } else if (*line == '#') {
+ do {
+ ++line;
+ } while (*line && *line != '\n');
+ if (*line == '\n')
+ ++line;
+ } else {
+ ++line;
+ }
+ }
+
if (*line == '\n') {
cp = line++;
} else {
cp = line;
}
+ /* Now back cp up to be the last nonspace character */
while (cp>val && TOR_ISSPACE(*(cp-1)))
--cp;
tor_assert(cp >= val);
+
+ /* Now copy out and decode the value. */
*value_out = tor_strndup(val, cp-val);
+ if (continuation) {
+ char *v_out, *v_in;
+ v_out = v_in = *value_out;
+ while (*v_in) {
+ if (*v_in == '#') {
+ do {
+ ++v_in;
+ } while (*v_in && *v_in != '\n');
+ if (*v_in == '\n')
+ ++v_in;
+ } else if (v_in[0] == '\\' && v_in[1] == '\n') {
+ v_in += 2;
+ } else {
+ *v_out++ = *v_in++;
+ }
+ }
+ *v_out = '\0';
+ }
}
if (*line == '#') {
@@ -2163,19 +2436,22 @@ char *
expand_filename(const char *filename)
{
tor_assert(filename);
+#ifdef MS_WINDOWS
+ return tor_strdup(filename);
+#else
if (*filename == '~') {
- size_t len;
- char *home, *result;
+ char *home, *result=NULL;
const char *rest;
if (filename[1] == '/' || filename[1] == '\0') {
home = getenv("HOME");
if (!home) {
log_warn(LD_CONFIG, "Couldn't find $HOME environment variable while "
- "expanding \"%s\"", filename);
- return NULL;
+ "expanding \"%s\"; defaulting to \"\".", filename);
+ home = tor_strdup("");
+ } else {
+ home = tor_strdup(home);
}
- home = tor_strdup(home);
rest = strlen(filename)>=2?(filename+2):"";
} else {
#ifdef HAVE_PWD_H
@@ -2202,21 +2478,19 @@ expand_filename(const char *filename)
if (strlen(home)>1 && !strcmpend(home,PATH_SEPARATOR)) {
home[strlen(home)-1] = '\0';
}
- /* Plus one for /, plus one for NUL.
- * Round up to 16 in case we can't do math. */
- len = strlen(home)+strlen(rest)+16;
- result = tor_malloc(len);
- tor_snprintf(result,len,"%s"PATH_SEPARATOR"%s",home,rest);
+ tor_asprintf(&result,"%s"PATH_SEPARATOR"%s",home,rest);
tor_free(home);
return result;
} else {
return tor_strdup(filename);
}
+#endif
}
#define MAX_SCANF_WIDTH 9999
-/** DOCDOC */
+/** Helper: given an ASCII-encoded decimal digit, return its numeric value.
+ * NOTE: requires that its input be in-bounds. */
static int
digit_to_num(char d)
{
@@ -2225,7 +2499,10 @@ digit_to_num(char d)
return num;
}
-/** DOCDOC */
+/** Helper: Read an unsigned int from *<b>bufp</b> of up to <b>width</b>
+ * characters. (Handle arbitrary width if <b>width</b> is less than 0.) On
+ * success, store the result in <b>out</b>, advance bufp to the next
+ * character, and return 0. On failure, return -1. */
static int
scan_unsigned(const char **bufp, unsigned *out, int width)
{
@@ -2252,7 +2529,9 @@ scan_unsigned(const char **bufp, unsigned *out, int width)
return 0;
}
-/** DOCDOC */
+/** Helper: copy up to <b>width</b> non-space characters from <b>bufp</b> to
+ * <b>out</b>. Make sure <b>out</b> is nul-terminated. Advance <b>bufp</b>
+ * to the next non-space character or the EOS. */
static int
scan_string(const char **bufp, char *out, int width)
{
@@ -2341,7 +2620,12 @@ tor_vsscanf(const char *buf, const char *pattern, va_list ap)
* and store the results in the corresponding argument fields. Differs from
* sscanf in that it: Only handles %u and %Ns. Does not handle arbitrarily
* long widths. %u does not consume any space. Is locale-independent.
- * Returns -1 on malformed patterns. */
+ * Returns -1 on malformed patterns.
+ *
+ * (As with other locale-independent functions, we need this to parse data that
+ * is in ASCII without worrying that the C library's locale-handling will make
+ * miscellaneous characters look like numbers, spaces, and so on.)
+ */
int
tor_sscanf(const char *buf, const char *pattern, ...)
{
@@ -2362,20 +2646,32 @@ tor_listdir(const char *dirname)
smartlist_t *result;
#ifdef MS_WINDOWS
char *pattern;
+ TCHAR tpattern[MAX_PATH] = {0};
+ char name[MAX_PATH] = {0};
HANDLE handle;
WIN32_FIND_DATA findData;
size_t pattern_len = strlen(dirname)+16;
pattern = tor_malloc(pattern_len);
tor_snprintf(pattern, pattern_len, "%s\\*", dirname);
- if (INVALID_HANDLE_VALUE == (handle = FindFirstFile(pattern, &findData))) {
+#ifdef UNICODE
+ mbstowcs(tpattern,pattern,MAX_PATH);
+#else
+ strlcpy(tpattern, pattern, MAX_PATH);
+#endif
+ if (INVALID_HANDLE_VALUE == (handle = FindFirstFile(tpattern, &findData))) {
tor_free(pattern);
return NULL;
}
result = smartlist_create();
while (1) {
- if (strcmp(findData.cFileName, ".") &&
- strcmp(findData.cFileName, "..")) {
- smartlist_add(result, tor_strdup(findData.cFileName));
+#ifdef UNICODE
+ wcstombs(name,findData.cFileName,MAX_PATH);
+#else
+ strlcpy(name,findData.cFileName,sizeof(name));
+#endif
+ if (strcmp(name, ".") &&
+ strcmp(name, "..")) {
+ smartlist_add(result, tor_strdup(name));
}
if (!FindNextFile(handle, &findData)) {
DWORD err;
@@ -2574,3 +2870,18 @@ write_pidfile(char *filename)
}
}
+#ifdef MS_WINDOWS
+HANDLE
+load_windows_system_library(const TCHAR *library_name)
+{
+ TCHAR path[MAX_PATH];
+ unsigned n;
+ n = GetSystemDirectory(path, MAX_PATH);
+ if (n == 0 || n + _tcslen(library_name) + 2 >= MAX_PATH)
+ return 0;
+ _tcscat(path, TEXT("\\"));
+ _tcscat(path, library_name);
+ return LoadLibrary(path);
+}
+#endif
+
diff --git a/src/common/util.h b/src/common/util.h
index fa66d7cf40..833fd904c7 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -43,7 +43,7 @@
* stderr. */
#define tor_assert(expr) STMT_BEGIN \
if (PREDICT_UNLIKELY(!(expr))) { \
- log(LOG_ERR, LD_BUG, "%s:%d: %s: Assertion %s failed; aborting.", \
+ log_err(LD_BUG, "%s:%d: %s: Assertion %s failed; aborting.", \
_SHORT_FILE_, __LINE__, __func__, #expr); \
fprintf(stderr,"%s:%d %s: Assertion %s failed; aborting.\n", \
_SHORT_FILE_, __LINE__, __func__, #expr); \
@@ -152,8 +152,18 @@ void tor_log_mallinfo(int severity);
#define bool_neq(a,b) (!(a)!=!(b))
/* Math functions */
+double tor_mathlog(double d) ATTR_CONST;
+long tor_lround(double d) ATTR_CONST;
int tor_log2(uint64_t u64) ATTR_CONST;
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);
+
+/* Compute the CEIL of <b>a</b> divided by <b>b</b>, for nonnegative <b>a</b>
+ * and positive <b>b</b>. Works on integer types only. Not defined if a+b can
+ * overflow. */
+#define CEIL_DIV(a,b) (((a)+(b)-1)/(b))
/* String manipulation */
@@ -179,6 +189,8 @@ long tor_parse_long(const char *s, int base, long min,
long max, int *ok, char **next);
unsigned long tor_parse_ulong(const char *s, int base, unsigned long min,
unsigned long max, int *ok, char **next);
+double tor_parse_double(const char *s, double min, double max, int *ok,
+ char **next);
uint64_t tor_parse_uint64(const char *s, int base, uint64_t min,
uint64_t max, int *ok, char **next);
const char *hex_str(const char *from, size_t fromlen) ATTR_NONNULL((1));
@@ -188,8 +200,11 @@ const char *eat_whitespace_no_nl(const char *s) ATTR_PURE;
const char *eat_whitespace_eos_no_nl(const char *s, const char *eos) ATTR_PURE;
const char *find_whitespace(const char *s) ATTR_PURE;
const char *find_whitespace_eos(const char *s, const char *eos) ATTR_PURE;
+const char *find_str_at_start_of_line(const char *haystack, const char *needle)
+ ATTR_PURE;
int tor_mem_is_zero(const char *mem, size_t len) ATTR_PURE;
int tor_digest_is_zero(const char *digest) ATTR_PURE;
+int tor_digest256_is_zero(const char *digest) ATTR_PURE;
char *esc_for_log(const char *string) ATTR_MALLOC;
const char *escaped(const char *string);
struct smartlist_t;
@@ -207,7 +222,11 @@ void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen);
int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen);
/* Time helpers */
+double tv_to_double(const struct timeval *tv);
+int64_t tv_to_msec(const struct timeval *tv);
+int64_t tv_to_usec(const struct timeval *tv);
long tv_udiff(const struct timeval *start, const struct timeval *end);
+long tv_mdiff(const struct timeval *start, const struct timeval *end);
time_t tor_timegm(struct tm *tm);
#define RFC1123_TIME_LEN 29
void format_rfc1123_time(char *buf, time_t t);
@@ -238,6 +257,33 @@ int ftime_maybe_before(time_t now, time_t when);
int ftime_definitely_after(time_t now, time_t when);
int ftime_definitely_before(time_t now, time_t when);
+/* Rate-limiter */
+
+/** A ratelim_t remembers how often an event is occurring, and how often
+ * it's allowed to occur. Typical usage is something like:
+ *
+ <pre>
+ if (possibly_very_frequent_event()) {
+ const int INTERVAL = 300;
+ static ratelim_t warning_limit = RATELIM_INIT(INTERVAL);
+ char *m;
+ if ((m = rate_limit_log(&warning_limit, approx_time()))) {
+ log_warn(LD_GENERAL, "The event occurred!%s", m);
+ tor_free(m);
+ }
+ }
+ </pre>
+ */
+typedef struct ratelim_t {
+ int rate;
+ time_t last_allowed;
+ int n_calls_since_last_time;
+} ratelim_t;
+
+#define RATELIM_INIT(r) { (r), 0, 0 }
+
+char *rate_limit_log(ratelim_t *lim, time_t now);
+
/* File helpers */
ssize_t write_all(int fd, const char *buf, size_t count, int isSocket);
ssize_t read_all(int fd, char *buf, size_t count, int isSocket);
@@ -294,5 +340,11 @@ void start_daemon(void);
void finish_daemon(const char *desired_cwd);
void write_pidfile(char *filename);
+#ifdef MS_WINDOWS
+HANDLE load_windows_system_library(const TCHAR *library_name);
+#endif
+
+const char *libor_get_digests(void);
+
#endif
diff --git a/src/common/util_codedigest.c b/src/common/util_codedigest.c
new file mode 100644
index 0000000000..88fe508b92
--- /dev/null
+++ b/src/common/util_codedigest.c
@@ -0,0 +1,11 @@
+
+#include "util.h"
+
+const char *
+libor_get_digests(void)
+{
+ return ""
+#include "common_sha1.i"
+ ;
+}
+
diff --git a/src/config/geoip b/src/config/geoip
index 6e2cbbdf49..e28e7b0a53 100644
--- a/src/config/geoip
+++ b/src/config/geoip
@@ -1,4 +1,4 @@
-# Last updated based on October 1 2010 Maxmind GeoLite Country
+# Last updated based on December 1 2010 Maxmind GeoLite Country
# wget http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
# cut -d, -f3-5 < GeoIPCountryWhois.csv|sed 's/"//g' > geoip
16777216,17301503,AU
@@ -45,7 +45,14 @@
35651584,36700159,IT
36700160,36962303,AE
36962304,37224447,IL
-37224448,37486591,UA
+37224448,37265407,UA
+37265408,37268479,CZ
+37268480,37289983,UA
+37289984,37298175,RU
+37298176,37355519,UA
+37355520,37421055,RU
+37421056,37486591,UA
+37486592,37748735,RU
37748736,38273023,SE
38273024,38797311,KZ
38797312,39059455,PT
@@ -56,7 +63,15 @@
40370176,40894463,DK
40894464,41418751,IT
41418752,41943039,GB
+42467328,42991615,ES
+42991616,43253759,IR
+43253760,43515903,NO
+43515904,43778047,ES
+43778048,44040191,IT
44040192,45088767,DE
+45088768,46137343,IR
+46137344,46661631,IT
+46661632,47710207,DE
50331648,68257567,US
68257568,68257599,CA
68257600,68259583,US
@@ -261,9 +276,7 @@
209831680,209831711,DE
209831712,209845143,US
209845144,209845151,DE
-209845152,209854735,US
-209854736,209854743,SE
-209854744,209867103,US
+209845152,209867103,US
209867104,209867111,CA
209867112,209868799,US
209868800,209869055,IR
@@ -293,9 +306,7 @@
211363752,211363759,PR
211363760,211368655,US
211368656,211368663,PR
-211368664,211403527,US
-211403528,211403535,MS
-211403536,211410031,US
+211368664,211410031,US
211410032,211410039,PR
211410040,211410119,US
211410120,211410135,PR
@@ -533,7 +544,8 @@
214698336,214698343,US
214698344,214698351,VI
214698352,214698359,US
-214698360,214698375,VI
+214698360,214698367,PR
+214698368,214698375,VI
214698376,214698383,US
214698384,214698639,PR
214698640,214698655,VI
@@ -572,7 +584,6 @@
217028008,217046775,US
217046776,217046783,PR
217046784,234881023,US
-234882304,234882559,AP
234883072,234884095,JP
234885120,234889215,VN
234889216,234913791,KR
@@ -670,8 +681,7 @@
405979136,405995519,PR
406003712,406011903,US
406011904,406028287,BS
-406044672,406052863,US
-406061056,406126591,US
+406028288,406126591,US
406142976,406147071,US
406147072,406151167,CA
406159360,406175743,US
@@ -698,15 +708,27 @@
409862144,410124287,US
410124288,410177751,CA
410177752,410177755,US
-410177756,410185355,CA
+410177756,410180643,CA
+410180644,410180647,US
+410180648,410185355,CA
410185356,410185359,US
410185360,410185407,CA
410185408,410185411,US
-410185412,410187047,CA
+410185412,410185555,CA
+410185556,410185559,US
+410185560,410186719,CA
+410186720,410186723,US
+410186724,410186971,CA
+410186972,410186979,US
+410186980,410186983,CA
+410186984,410186999,US
+410187000,410187047,CA
410187048,410187055,US
410187056,410187175,CA
410187176,410187183,US
-410187184,410187703,CA
+410187184,410187231,CA
+410187232,410187239,US
+410187240,410187703,CA
410187704,410187707,US
410187708,410189823,CA
410189824,410648575,US
@@ -788,7 +810,9 @@
418693120,418709503,CA
418709504,418766847,US
418766848,418770943,CA
-418770944,419430399,US
+418770944,418775039,US
+418775040,418807807,CA
+418807808,419430399,US
419430400,436207615,GB
436207616,452984831,US
452984832,452985855,JP
@@ -879,7 +903,6 @@
460155904,460156927,AU
460156928,460158975,KH
460158976,460159999,JP
-460160000,460161023,ID
460161024,460193791,MO
460193792,460210175,JP
460210176,460214271,HK
@@ -893,7 +916,6 @@
460263424,460267519,NP
460267520,460275711,ID
460275712,460277759,AU
-460277760,460278783,PG
460278784,460279807,JP
460279808,460283903,AU
460283904,460292095,KR
@@ -929,7 +951,7 @@
460596224,460597247,AU
460597248,460598271,JP
460598272,460599295,CN
-460599296,460600319,IN
+460599296,460601343,IN
460601344,460602367,AF
460602368,460603391,KH
460603392,460718079,KR
@@ -946,6 +968,51 @@
460943360,460945407,AU
460947456,460980223,JP
460980224,460981247,NC
+460982272,460983295,JP
+460983296,460984319,HK
+460984320,460988415,PG
+460988416,460994559,JP
+460994560,460995583,MY
+460995584,460996607,SG
+460996608,461008895,JP
+461008896,461012991,AU
+461012992,461045759,KR
+461045760,461047807,ID
+461047808,461049855,JP
+461049856,461050879,TH
+461050880,461051903,NZ
+461051904,461053951,AU
+461053952,461062143,AP
+461062144,461078527,IN
+461078528,461094911,FJ
+461094912,461099007,AP
+461099008,461100031,JP
+461100032,461101055,MN
+461101056,461102079,IN
+461102080,461103103,ID
+461103104,461111295,PH
+461111296,461127679,IN
+461127680,461131775,PH
+461131776,461135871,ID
+461135872,461139967,AU
+461144064,461209599,KR
+461209600,461225983,SG
+461225984,461227007,WF
+461227008,461228031,SG
+461228032,461229055,IN
+461229056,461230079,JP
+461230080,461234175,AU
+461234176,461242367,MY
+461242368,461258751,KR
+461258752,461279231,JP
+461279232,461281279,AU
+461281280,461282303,PH
+461282304,461283327,MY
+461283328,461287423,JP
+461287424,461307903,HK
+461307904,461357055,JP
+461357056,461369343,AU
+461369344,461373439,JP
461373440,461504511,CN
461504512,461570047,TH
461570048,461572095,ID
@@ -980,7 +1047,9 @@
469696512,469712895,PK
469712896,469729279,KR
469729280,469762047,IN
-469762048,539624567,US
+469762048,520093695,US
+524288000,528482303,GB
+536870912,539624567,US
539624568,539624575,IE
539624576,539624703,US
539624704,539624735,GB
@@ -1001,7 +1070,10 @@
539626496,539626543,GB
539626544,539627127,US
539627128,539627135,SE
-539627136,539627391,US
+539627136,539627231,US
+539627232,539627247,JP
+539627248,539627263,AN
+539627264,539627391,US
539627392,539627399,JP
539627400,539627407,IE
539627408,539627423,JP
@@ -1077,7 +1149,11 @@
540814016,540814079,US
540814080,540814271,TW
540814272,540814279,DE
-540814280,540819455,US
+540814280,540814511,US
+540814512,540814519,SG
+540814520,540814719,US
+540814720,540814735,SG
+540814736,540819455,US
540819456,540823551,CA
540823552,540826671,US
540826672,540826719,CA
@@ -1112,6 +1188,7 @@
543691008,543844351,US
543844352,543844607,CH
543844608,603979775,US
+603979776,620756991,AU
637534208,644067391,US
644067392,644067455,CA
644067456,644835071,US
@@ -1131,6 +1208,8 @@
691863552,691929087,ZA
691929088,691994623,SN
691994624,692011007,ZM
+692011008,692027391,ZA
+692027392,692035583,MG
692043776,692060159,NA
692060160,692191231,EG
692191232,692207615,CI
@@ -1172,6 +1251,13 @@
692760576,692768767,ZA
692768768,692772863,MG
692772864,692776959,ZA
+692776960,692781055,AO
+692781056,692785151,BW
+692785152,692789247,NG
+692789248,692793343,KE
+692793344,692797439,GH
+692797440,692801535,CG
+692801536,692805631,NG
692830208,692834303,NG
692834304,692838399,TZ
692838400,692842495,ZA
@@ -1186,6 +1272,7 @@
692860928,692862975,ZA
692862976,692869119,NG
692869120,692871167,TZ
+692871168,692873215,ZA
692875264,692877311,ZA
692877312,692879359,GA
692879360,692881407,ZA
@@ -1198,6 +1285,7 @@
692893696,692895743,KE
692895744,692897791,NG
692897792,692905983,ZA
+692905984,692908031,ZW
692969472,692971519,TZ
692973568,692975615,MZ
692975616,692977663,EG
@@ -1209,6 +1297,7 @@
692983808,692984831,KE
692984832,692987903,ZA
692987904,692988927,GH
+692988928,692989951,ZW
692989952,692990975,BF
692992000,692993023,MW
692993024,692994047,EG
@@ -1239,6 +1328,12 @@
693018624,693019647,UG
693019648,693020671,ZA
693020672,693021695,TZ
+693021696,693022719,NG
+693022720,693023743,KE
+693023744,693026815,ZA
+693026816,693027839,MU
+693027840,693028863,CD
+693028864,693029887,ZA
693101568,693102591,KE
693102592,693103615,CD
693103616,693104639,GN
@@ -1248,6 +1343,10 @@
693107712,693239807,KE
693239808,693370879,SN
693370880,693403647,ZA
+693403648,693411839,KE
+693411840,693420031,NG
+693420032,693428223,UG
+693428224,693436415,SZ
693501952,693510143,LR
693510144,693518335,SC
693518336,693534719,ZA
@@ -1642,12 +1741,15 @@
703594496,704118783,ZA
704118784,704380927,MA
704380928,704643071,LY
+704643072,721420287,AU
721420288,738197503,JP
738197504,771751935,US
771751936,771817471,RU
771817472,771948543,TR
771948544,772014079,RU
-772014080,772145151,DE
+772014080,772057727,DE
+772057728,772057735,IT
+772057736,772145151,DE
772145152,772210687,ES
772210688,772276223,IE
772276224,772341759,RU
@@ -1657,22 +1759,187 @@
772538368,772603903,GR
772603904,772669439,CZ
772669440,772734975,CH
+772734976,772800511,NO
772800512,772802559,GB
772802560,772804607,RU
772804608,772806655,BZ
772806656,772808703,RU
+772808704,772810751,GB
+772810752,772812799,FR
+772812800,772814847,NO
+772814848,772816895,ES
+772816896,772818943,RU
+772818944,772820991,DE
+772820992,772823039,GB
+772823040,772825087,IT
+772825088,772827135,RU
+772827136,772829183,RS
+772829184,772831231,EE
+772831232,772833279,CZ
+772833280,772835327,RU
+772835328,772837375,CY
+772837376,772839423,KZ
+772839424,772841471,CH
+772841472,772843519,GB
+772843520,772845567,IT
+772845568,772847615,RU
+772847616,772849663,GB
+772849664,772851711,BG
+772851712,772853759,CH
+772853760,772855807,GB
+772855808,772857855,DE
+772857856,772859903,RU
+772859904,772861951,SE
+772861952,772863999,UA
+772864000,772870143,NL
+772870144,772872191,NO
+772872192,772874239,NL
+772874240,772876287,IE
+772876288,772880383,RU
+772880384,772882431,GB
+772882432,772884479,FR
+772884480,772884543,GB
+772884544,772884735,LB
+772884736,772884799,GB
+772884800,772885503,LB
+772885504,772885567,GB
+772885568,772885759,LB
+772885760,772885823,GB
+772885824,772886527,LB
+772886528,772888575,FR
+772888576,772890623,GB
+772890624,772892671,RU
+772892672,772894719,DE
+772894720,772896767,PL
+772896768,772898815,RS
+772898816,772900863,TR
+772900864,772902911,ES
+772902912,772904959,RS
+772904960,772907007,IT
+772907008,772909055,GB
+772909056,772911103,LU
+772911104,772913151,GB
+772913152,772915199,SE
+772915200,772917247,FI
+772917248,772919295,RU
+772919296,772923391,GB
+772923392,772925439,AT
+772925440,772927487,GB
+772927488,772929535,UA
+772929536,772931583,RU
+772931584,772933631,UA
+772933632,772935679,GB
+772935680,772937727,PS
+772937728,772939775,IT
+772939776,772941823,BE
+772941824,772943871,ES
+772943872,772945919,GB
+772945920,772947967,DE
+772947968,772950015,AZ
+772950016,772952063,ES
+772952064,772954111,GB
+772954112,772958207,FR
+772958208,772960255,PL
+772960256,772962303,GB
+772962304,772966399,FR
+772966400,772968447,IT
+772968448,772970495,SK
+772970496,772972543,GB
+772972544,772974591,SA
+772974592,772978687,GB
+772978688,772980735,DE
+772980736,772982783,FR
+772982784,772984831,RU
+772984832,772986879,FR
+772986880,772988927,GB
+772988928,772990975,FR
+772990976,772993023,IT
+772993024,772995071,DE
+772995072,772997119,IR
+772997120,772999167,BE
+772999168,773001215,SI
773001216,773003263,NO
+773003264,773005311,FR
+773005312,773007359,NL
+773007360,773009407,KZ
+773009408,773011455,IT
+773011456,773013503,DE
+773013504,773015551,RU
+773015552,773017599,AE
+773017600,773019647,IL
+773019648,773021695,DE
+773021696,773023743,AM
+773023744,773025791,RO
+773025792,773027839,RU
+773027840,773031935,FR
+773031936,773033983,CH
+773033984,773036031,LV
+773036032,773038079,DE
+773038080,773040127,GB
+773040128,773042175,NL
+773042176,773044223,FR
+773044224,773046271,RU
+773046272,773048319,LB
+773048320,773050367,LV
+773050368,773052415,IE
+773052416,773054463,NL
+773054464,773056511,AL
+773056512,773058559,IT
+773058560,773060607,BE
+773060608,773062655,DK
773062656,773062911,TR
773062912,773063167,US
-773063168,773063935,TR
-773063936,773064703,US
-773064704,773066751,TR
+773063168,773063424,TR
+773063425,773063436,US
+773063437,773063935,TR
+773063936,773065215,US
+773065216,773066751,TR
773066752,773070847,AT
773070848,773074943,DE
773074944,773079039,PL
773079040,773083135,RU
773083136,773087231,IT
773087232,773091327,LB
+773091328,773095423,GB
+773095424,773099519,RO
+773099520,773103615,TR
+773103616,773107711,FR
+773107712,773111807,RU
+773111808,773115903,TJ
+773115904,773119999,PS
+773120000,773124095,GB
+773124096,773128191,CH
+773128192,773132287,DE
+773132288,773134335,IT
+773134336,773134847,CH
+773134848,773135359,IT
+773135360,773135871,CH
+773135872,773136383,IT
+773136384,773140479,DK
+773140480,773144575,CY
+773144576,773148671,RU
+773148672,773152767,IR
+773152768,773156863,SE
+773156864,773165055,FR
+773165056,773168127,NL
+773168128,773168383,US
+773168384,773173247,NL
+773173248,773177343,IT
+773177344,773181439,FR
+773181440,773185535,PL
+773185536,773189631,NL
+773189632,773197823,RU
+773197824,773201919,CH
+773201920,773206015,DE
+773206016,773210111,RU
+773210112,773214207,US
+773214208,773218303,FR
+773218304,773222399,IS
+773222400,773226495,SE
+773226496,773230591,IE
+773230592,773234687,RS
+773234688,773238783,PL
+773238784,773242879,NL
773324800,773586943,ES
773586944,773588991,IT
773588992,773591039,PL
@@ -1722,9 +1989,12 @@
773675008,773677055,GB
773677056,773679103,DE
773679104,773679135,IT
-773679136,773679359,A2
+773679136,773679327,A2
+773679328,773679359,IT
773679360,773679423,GB
-773679424,773681151,A2
+773679424,773679615,A2
+773679616,773680191,IT
+773680192,773681151,A2
773681152,773683199,RU
773683200,773685247,FR
773685248,773687295,UA
@@ -1795,7 +2065,6 @@
773820416,773822463,TR
773822464,773824511,RU
773824512,773826559,FR
-773826560,773828607,NL
773828608,773830655,HU
773830656,773832703,NO
773832704,773834751,FR
@@ -1820,11 +2089,184 @@
773963776,773971967,ME
773971968,773980159,UA
773980160,773988351,GB
-773988352,774004735,ES
+773988352,774003199,ES
+774003200,774003263,TR
+774003264,774003711,ES
+774003712,774004223,BE
+774004224,774004479,ES
+774004480,774004511,BE
+774004512,774004735,ES
774004736,774012927,IR
774012928,774021119,RU
774021120,774029311,IR
774029312,774037503,RO
+774037504,774045695,SK
+774045696,774053887,FR
+774053888,774061567,DE
+774061568,774061695,BZ
+774061696,774061823,DE
+774061824,774061951,BZ
+774061952,774062079,DE
+774062080,774070271,YE
+774070272,774078463,ES
+774078464,774086655,BA
+774086656,774094847,BG
+774094848,774103039,HU
+774103040,774111231,UA
+774111232,774119423,RU
+774119424,774127615,CZ
+774127616,774135807,LT
+774135808,774143999,IR
+774144000,774152191,KZ
+774152192,774160383,BA
+774160384,774160415,VA
+774160416,774160448,LI
+774160449,774160480,IM
+774160481,774160514,IS
+774160515,774160547,RU
+774160548,774160580,AE
+774160581,774160612,DK
+774160613,774160639,AT
+774160640,774160671,GI
+774160672,774160702,CY
+774160703,774160735,CH
+774160736,774160768,GR
+774160769,774160801,IL
+774160802,774160832,BG
+774160833,774160864,NO
+774160865,774160869,BR
+774160870,774160873,CA
+774160874,774160895,CR
+774160896,774160927,PA
+774160928,774160935,CU
+774160936,774160946,BS
+774160947,774160956,KY
+774160957,774160966,JM
+774160967,774160976,PR
+774160977,774160986,VG
+774160987,774160996,CO
+774160997,774161006,GT
+774161007,774161016,CN
+774161017,774161026,EG
+774161027,774161036,FJ
+774161037,774161046,IN
+774161047,774161056,MH
+774161057,774161066,JP
+774161067,774161076,MX
+774161077,774161086,NZ
+774161087,774161096,MY
+774161097,774161106,PE
+774161107,774161116,PH
+774161117,774161126,SA
+774161127,774161136,SC
+774161137,774161146,SG
+774161147,774161151,VA
+774161152,774161162,AQ
+774161163,774161172,KR
+774161173,774161182,TH
+774161183,774161192,QA
+774161193,774161202,VI
+774161203,774161212,BM
+774161213,774161222,BB
+774161223,774161232,AW
+774161233,774161242,BZ
+774161243,774161252,MC
+774161253,774161262,GB
+774161263,774161272,TR
+774161273,774161282,MT
+774161283,774161292,SE
+774161293,774161302,US
+774161303,774161312,HK
+774161313,774161322,IE
+774161323,774161332,PK
+774161333,774161337,KW
+774161338,774161342,JO
+774161343,774161347,OM
+774161348,774161352,ID
+774161353,774161357,TW
+774161358,774161362,AI
+774161363,774161367,KN
+774161368,774161372,GD
+774161373,774161377,DO
+774161378,774161382,PY
+774161383,774161387,EE
+774161388,774161392,LU
+774161393,774161397,SK
+774161398,774161402,SI
+774161403,774161405,LC
+774161406,774161408,VA
+774161409,774161418,AU
+774161419,774161428,GL
+774161429,774161438,HU
+774161439,774161448,MK
+774161449,774161458,PS
+774161459,774161468,UZ
+774161469,774161478,BD
+774161479,774161488,KP
+774161489,774161498,MN
+774161499,774161518,VA
+774161519,774161528,TW
+774161529,774161538,DO
+774161539,774161548,PY
+774161549,774161558,EE
+774161559,774161568,SK
+774161569,774161578,LC
+774161579,774161588,VE
+774161589,774161598,TC
+774161599,774161608,US
+774161609,774161618,LI
+774161619,774161628,AE
+774161629,774161638,PA
+774161639,774161648,RU
+774161649,774161658,HK
+774161659,774161664,VA
+774161665,774161674,CY
+774161675,774161684,CL
+774161685,774161694,NI
+774161695,774161704,AG
+774161705,774161714,AM
+774161715,774161724,IR
+774161725,774161734,RO
+774161735,774161744,UA
+774161745,774161754,NP
+774161755,774161764,PG
+774161765,774168575,VA
+774168576,774176767,PL
+774176768,774184959,IT
+774184960,774193151,GB
+774193152,774209535,ES
+774209536,774217727,RU
+774217728,774224127,GB
+774224128,774224159,CN
+774224160,774225279,GB
+774225280,774225343,CN
+774225344,774225359,GB
+774225360,774225375,UA
+774225376,774225391,GB
+774225392,774225407,UA
+774225408,774225599,GB
+774225600,774225615,PK
+774225616,774225631,GB
+774225632,774225647,CN
+774225648,774225663,UA
+774225664,774225671,LK
+774225672,774225679,US
+774225680,774225687,CN
+774225688,774225695,CA
+774225696,774225703,RU
+774225704,774225711,LK
+774225712,774225719,PK
+774225720,774225791,GB
+774225792,774225807,UA
+774225808,774225823,GB
+774225824,774225919,US
+774225920,774234111,UA
+774234112,774242303,IT
+774242304,774258687,RU
+774258688,774266879,SA
+774266880,774275071,RU
+774275072,774283263,IR
+774283264,774291455,GB
774373376,774389759,RS
774389760,774406143,BG
774406144,774422527,IT
@@ -1850,7 +2292,11 @@
774750208,774782975,RU
774782976,774799359,UA
774799360,774815743,RU
-774897664,774963199,RU
+774815744,774832127,SE
+774832128,774848511,RU
+774848512,774864895,BG
+774864896,774881279,CZ
+774881280,774963199,RU
774963200,774995967,GE
774995968,775028735,RO
775028736,775061503,PT
@@ -1864,6 +2310,20 @@
775290880,775323647,MT
775323648,775356415,SI
775356416,775389183,MD
+775389184,775421951,BG
+775421952,775487487,BY
+775487488,775520255,AT
+775520256,775553023,SY
+775553024,775585791,EU
+775585792,775618559,SY
+775618560,775651327,SE
+775651328,775684095,DE
+775684096,775716863,PS
+775716864,775749631,GB
+775749632,775847935,RU
+775847936,775880703,RO
+775880704,775913471,UA
+775913472,775946239,RU
775946240,776077311,GB
776077312,776208383,NO
776208384,776339455,GB
@@ -1882,6 +2342,7 @@
778502144,778534911,GR
778534912,778567679,CY
778567680,778633215,TR
+778633216,778698751,FR
778698752,778764287,TR
778764288,778829823,HU
778829824,778895359,RO
@@ -1896,27 +2357,221 @@
779747328,779878399,SI
779878400,780009471,AT
780009472,780140543,CH
+780140544,780206079,DE
+780206080,780271615,NL
+780271616,780337151,AM
+780337152,780402687,EE
+780402688,780468223,FI
+780468224,780533759,UA
+780533760,780599295,PL
+780599296,780664831,CZ
+780664832,780664960,NL
+780664961,780730367,FR
+780730368,780795903,IE
+780795904,780861439,RU
+780861440,780926975,HU
+780926976,780992511,CH
+780992512,781058047,IT
+781058048,781123583,DE
+781123584,781189119,IR
+781189120,781320191,NL
+781320192,781451263,RU
+781451264,781455359,PL
+781455360,781459455,UA
+781459456,781463551,IR
+781463552,781467647,RU
+781467648,781475839,PL
+781475840,781479935,RU
+781479936,781484031,UA
+781484032,781488127,RU
+781488128,781496319,PL
+781496320,781504511,RU
+781582336,781590527,UA
+781590528,781598719,SI
+781598720,781615103,UA
+781615104,781631487,RU
+781631488,781639679,SK
+781639680,781651967,RU
+781651968,781654015,PL
+781654016,781656063,RU
+781656064,781658111,RO
+781658112,781662207,UA
+781662208,781664255,SK
+781664256,781666303,UA
+781666304,781668351,PL
+781668352,781670399,UA
+781670400,781672447,RU
+781672448,781674495,BE
+781674496,781676543,RU
+781676544,781678591,PL
+781678592,781682687,RS
+781713408,781844479,SA
+781844480,781975551,TR
+781975552,782106623,GB
+782106624,782254079,RU
+782254080,782270463,UA
+782270464,782305791,RU
+782305792,782306303,RO
+782306304,782319615,RU
+782319616,782335999,ME
+782336000,782352383,RU
+782352384,782368767,SY
+782368768,782385151,UA
+782385152,782401535,SE
+782401536,782417919,FR
+782417920,782434303,AM
+782761984,782893055,PL
+783679488,783681535,FR
+783681536,783683583,IE
+783683584,783685631,DE
+783685632,783687679,RU
+783687680,783689727,PT
+783689728,783691775,FR
+783691776,783693823,BY
+783693824,783695871,GB
+783695872,783697919,TR
+783697920,783699967,FR
+783699968,783702015,UA
+783702016,783704063,IT
+783704064,783706111,PL
+783706112,783708159,NL
+783708160,783710207,FI
+783710208,783712255,NL
+783712256,783714303,RU
+783714304,783718399,DE
+783718400,783720447,IT
+783720448,783722495,FI
+783722496,783724543,AM
+783724544,783726591,NL
+783726592,783728639,IS
+783728640,783730687,BE
+783730688,783732735,SE
+783732736,783734783,FR
+783734784,783736831,NL
+783736832,783738879,SI
+783810560,783843327,SA
+783843328,783876095,BH
+783876096,783908863,UA
+783908864,783941631,JO
+783941632,783974399,PL
+783974400,784007167,KW
+784007168,784039935,RU
+784039936,784072703,PL
+784072704,784105471,RU
+784105472,784138239,HR
788529152,805306367,CA
805306368,822083583,US
822083584,822083839,AP
822083840,822084095,AU
+822084608,822085631,ID
+822085632,822087679,AU
+822087680,822089727,JP
+822089728,822090751,ID
+822090752,822091775,NZ
+822091776,822099967,BD
+822099968,822116351,TH
+822116352,822149119,MN
+822149120,822214655,KR
822214656,822345727,AU
822345728,822607871,CN
+822607872,822870015,KR
+822870016,823132159,IN
+823132160,824180735,KR
+824180736,825229311,IN
825229312,825360383,TH
825360384,825361407,AP
+825361408,825363455,ID
+825363456,825364479,MY
+825364480,825376767,KR
+825376768,825393151,IN
+825393152,825409535,KR
+825409536,825419775,NZ
+825419776,825420799,TH
+825420800,825421823,MY
+825421824,825425919,NZ
825425920,825491455,AU
-830406656,830472703,AU
+825491456,825753599,CN
+825753600,826277887,KR
+826277888,828375039,CN
+828375040,829423615,JP
+829423616,830210047,CN
+830210048,830341119,MY
+830341120,830406655,NP
+830406656,830474239,AU
+830474240,830475263,SG
+830475264,830476287,AU
+830476288,830480383,JP
+830480384,830488575,SG
+830488576,830496767,TW
+830496768,830498815,JP
+830498816,830499839,GU
+830499840,830500863,IN
+830500864,830504959,TW
+830504960,830513151,JP
+830513152,830517247,IN
+830517248,830521343,ID
+830521344,830529535,KR
+830529536,830537727,AU
+830537728,830603263,JP
+830603264,830734335,HK
+830734336,830996479,JP
+830996480,831258623,IN
+831258624,831389695,CN
+831389696,831512575,KR
+831512576,831513599,AU
+831513600,831514623,NZ
+831514624,831515647,HK
+831515648,831516671,AU
+831516672,831518719,JP
+831518720,831519743,AU
+831519744,831520767,IN
+831520768,832045055,PH
+832045056,832307199,CN
+832307200,832308223,MN
+832308224,832311295,JP
+832311296,832312319,AU
+832312320,832313343,ID
+832313344,832315391,AU
+832315392,832319487,KH
+832319488,832320511,NU
+832320512,832321535,VN
+832321536,832323583,ID
+832323584,832348159,IN
+832348160,832372735,JP
+832372736,832438271,PH
+832438272,832569343,TW
+832569344,833617919,KR
+836763648,837025791,NZ
+837025792,837287935,TH
+837287936,837550079,CN
+837550080,837566463,IN
+837566464,837599231,KR
+837599232,837603327,MY
+837603328,837604351,VN
+837812224,838074367,JP
+838074368,838139903,NP
+838139904,838205439,SG
+838205440,838238207,KR
+838238208,838262783,VN
+838262784,838270975,CN
+838270976,838336511,KR
+838336512,838467583,IN
+838467584,838729727,JP
+838729728,838795263,KR
838795264,838860799,AP
838860800,838926335,US
838991872,838999039,US
838999040,838999295,CA
838999296,839010559,US
839010560,839010815,CA
-839010816,839022079,US
-839022080,839023103,CA
-839023104,839254015,US
-839385088,839909375,US
-840957952,843055103,US
+839010816,839017983,US
+839017984,839018239,CA
+839018240,839023359,US
+839023360,839023615,CA
+839023616,843055103,US
+843055104,844103679,CA
+844103680,844627967,US
+847249408,855638015,US
855638016,872415231,GB
872415232,889192447,US
889192448,905969663,DE
@@ -2443,13 +3098,9 @@
1040470272,1040470335,DE
1040470336,1040470399,EU
1040470400,1040470431,DE
-1040470432,1040470783,EU
-1040470784,1040471295,NL
-1040471296,1040471487,EU
-1040471488,1040471711,NL
-1040471712,1040471743,EU
-1040471744,1040471775,NL
-1040471776,1040472991,EU
+1040470432,1040471487,EU
+1040471488,1040471551,NL
+1040471552,1040472991,EU
1040472992,1040473087,NL
1040473088,1040473855,EU
1040473856,1040474111,NL
@@ -2469,10 +3120,14 @@
1040982016,1040982279,A2
1040982280,1040982287,NG
1040982288,1040982583,A2
-1040982584,1040982607,DK
+1040982584,1040982591,DK
+1040982592,1040982599,A2
+1040982600,1040982607,DK
1040982608,1040982631,A2
1040982632,1040982639,DE
-1040982640,1040983807,A2
+1040982640,1040982943,A2
+1040982944,1040982951,DK
+1040982952,1040983807,A2
1040983808,1040983815,NG
1040983816,1040984143,A2
1040984144,1040984151,NG
@@ -2521,13 +3176,9 @@
1041696872,1041696879,GB
1041696880,1041697699,FR
1041697700,1041697703,GB
-1041697704,1041697919,FR
-1041697920,1041697983,GB
-1041697984,1041698047,FR
+1041697704,1041698047,FR
1041698048,1041698077,GB
-1041698078,1041698135,FR
-1041698136,1041698143,GB
-1041698144,1041698207,FR
+1041698078,1041698207,FR
1041698208,1041698223,GB
1041698224,1041698247,FR
1041698248,1041698255,GB
@@ -2565,23 +3216,19 @@
1041701648,1041701663,GB
1041701664,1041702167,FR
1041702168,1041702175,GB
-1041702176,1041702303,FR
-1041702304,1041702311,GB
+1041702176,1041702306,FR
+1041702307,1041702311,GB
1041702312,1041702327,FR
1041702328,1041702335,GB
1041702336,1041702351,FR
1041702352,1041702399,GB
-1041702400,1041702855,FR
-1041702856,1041702863,GB
-1041702864,1041703575,FR
+1041702400,1041703575,FR
1041703576,1041703583,GB
1041703584,1041704119,FR
1041704120,1041704127,GB
1041704128,1041704159,FR
1041704160,1041704175,GB
-1041704176,1041704319,FR
-1041704320,1041704383,GB
-1041704384,1041704407,FR
+1041704176,1041704407,FR
1041704408,1041704431,GB
1041704432,1041704439,FR
1041704440,1041704455,GB
@@ -2601,7 +3248,9 @@
1041704848,1041704863,GB
1041704864,1041704879,FR
1041704880,1041704887,GB
-1041704888,1041705231,FR
+1041704888,1041704943,FR
+1041704944,1041704959,GB
+1041704960,1041705231,FR
1041705232,1041705239,GB
1041705240,1041705255,FR
1041705256,1041705279,GB
@@ -2671,7 +3320,9 @@
1041707632,1041707639,GB
1041707640,1041707679,FR
1041707680,1041707687,GB
-1041707688,1041707895,FR
+1041707688,1041707807,FR
+1041707808,1041707815,GB
+1041707816,1041707895,FR
1041707896,1041707903,GB
1041707904,1041707999,FR
1041708000,1041708007,GB
@@ -2755,8 +3406,8 @@
1041711584,1041711599,GB
1041711600,1041711943,FR
1041711944,1041711951,GB
-1041711952,1041712399,FR
-1041712400,1041712415,GB
+1041711952,1041712407,FR
+1041712408,1041712415,GB
1041712416,1041712423,FR
1041712424,1041712431,GB
1041712432,1041713095,FR
@@ -2773,9 +3424,7 @@
1041714072,1041714079,GB
1041714080,1041714095,FR
1041714096,1041714103,GB
-1041714104,1041714111,FR
-1041714112,1041714175,GB
-1041714176,1041714523,FR
+1041714104,1041714523,FR
1041714524,1041714527,GB
1041714528,1041714775,FR
1041714776,1041714783,GB
@@ -2818,10 +3467,12 @@
1041715952,1041715999,FR
1041716000,1041716015,GB
1041716016,1041716047,FR
-1041716048,1041716063,GB
-1041716064,1041716111,FR
+1041716048,1041716095,GB
+1041716096,1041716111,FR
1041716112,1041716223,GB
-1041716224,1041716311,FR
+1041716224,1041716231,FR
+1041716232,1041716239,GB
+1041716240,1041716311,FR
1041716312,1041716319,GB
1041716320,1041716439,FR
1041716440,1041716447,GB
@@ -2843,7 +3494,9 @@
1041717168,1041717183,GB
1041717184,1041717199,FR
1041717200,1041717247,GB
-1041717248,1041717687,FR
+1041717248,1041717503,FR
+1041717504,1041717511,IT
+1041717512,1041717687,FR
1041717688,1041717695,GB
1041717696,1041718112,FR
1041718113,1041718119,GB
@@ -2887,7 +3540,9 @@
1041719229,1041719231,GB
1041719232,1041719247,FR
1041719248,1041719263,GB
-1041719264,1041719683,FR
+1041719264,1041719383,FR
+1041719384,1041719391,GB
+1041719392,1041719683,FR
1041719684,1041719687,GB
1041719688,1041719703,FR
1041719704,1041719711,GB
@@ -2935,7 +3590,9 @@
1041722568,1041722623,GB
1041722624,1041722703,FR
1041722704,1041722711,GB
-1041722712,1041722983,FR
+1041722712,1041722743,FR
+1041722744,1041722751,GB
+1041722752,1041722983,FR
1041722984,1041723007,GB
1041723008,1041723047,FR
1041723048,1041723135,GB
@@ -2960,16 +3617,15 @@
1041725168,1041725175,FR
1041725176,1041725183,GB
1041725184,1041725191,FR
-1041725192,1041725231,GB
+1041725192,1041725199,IT
+1041725200,1041725231,GB
1041725232,1041725255,FR
1041725256,1041725279,GB
1041725280,1041725375,FR
1041725376,1041725407,GB
1041725408,1041725749,FR
1041725750,1041725751,GB
-1041725752,1041725815,FR
-1041725816,1041725823,GB
-1041725824,1041725863,FR
+1041725752,1041725863,FR
1041725864,1041725871,GB
1041725872,1041726063,FR
1041726064,1041726079,GB
@@ -3044,30 +3700,32 @@
1041729568,1041729615,FR
1041729616,1041729623,GB
1041729624,1041729663,FR
-1041729664,1041729791,GB
-1041729792,1041730239,FR
+1041729664,1041729935,GB
+1041729936,1041729951,FR
+1041729952,1041730047,GB
+1041730048,1041730239,FR
1041730240,1041730247,GB
1041730248,1041730639,FR
1041730640,1041730655,GB
-1041730656,1041731919,FR
-1041731920,1041731935,GB
+1041730656,1041731927,FR
+1041731928,1041731935,GB
1041731936,1041731975,FR
1041731976,1041732031,GB
1041732032,1041732055,FR
1041732056,1041732063,GB
-1041732064,1041732095,FR
-1041732096,1041732111,GB
+1041732064,1041732103,FR
+1041732104,1041732111,GB
1041732112,1041732127,FR
1041732128,1041732191,GB
1041732192,1041732255,FR
1041732256,1041732295,GB
1041732296,1041732303,FR
1041732304,1041732311,GB
-1041732312,1041732447,FR
-1041732448,1041732455,GB
-1041732456,1041732463,FR
-1041732464,1041732479,GB
-1041732480,1041732863,FR
+1041732312,1041732471,FR
+1041732472,1041732479,GB
+1041732480,1041732519,FR
+1041732520,1041732527,GB
+1041732528,1041732863,FR
1041732864,1041732871,GB
1041732872,1041732879,FR
1041732880,1041732927,GB
@@ -3075,8 +3733,8 @@
1041732960,1041732967,GB
1041732968,1041732991,FR
1041732992,1041733103,GB
-1041733104,1041733511,FR
-1041733512,1041733535,GB
+1041733104,1041733519,FR
+1041733520,1041733535,GB
1041733536,1041733567,FR
1041733568,1041733631,GB
1041733632,1041734927,FR
@@ -3100,9 +3758,7 @@
1041735664,1041736375,FR
1041736376,1041736383,GB
1041736384,1041736423,FR
-1041736424,1041736447,GB
-1041736448,1041736455,FR
-1041736456,1041736463,GB
+1041736424,1041736463,GB
1041736464,1041736527,FR
1041736528,1041736535,GB
1041736536,1041736543,FR
@@ -3131,8 +3787,8 @@
1041737400,1041737423,GB
1041737424,1041737455,FR
1041737456,1041737463,GB
-1041737464,1041737479,FR
-1041737480,1041737503,GB
+1041737464,1041737487,FR
+1041737488,1041737503,GB
1041737504,1041737583,FR
1041737584,1041737599,GB
1041737600,1041737607,FR
@@ -3172,8 +3828,8 @@
1041738608,1041738703,FR
1041738704,1041738711,GB
1041738712,1041738735,FR
-1041738736,1041738743,GB
-1041738744,1041739079,FR
+1041738736,1041738751,GB
+1041738752,1041739079,FR
1041739080,1041739087,GB
1041739088,1041739167,FR
1041739168,1041739175,GB
@@ -3226,7 +3882,7 @@
1041741608,1041741615,GB
1041741616,1041741631,FR
1041741632,1041741647,GB
-1041741648,1041741663,FR
+1041741648,1041741663,DE
1041741664,1041741679,GB
1041741680,1041741687,FR
1041741688,1041741823,GB
@@ -3432,7 +4088,9 @@
1041757504,1041757519,GB
1041757520,1041757583,FR
1041757584,1041757591,GB
-1041757592,1041757631,FR
+1041757592,1041757607,FR
+1041757608,1041757615,GB
+1041757616,1041757631,FR
1041757632,1041757647,GB
1041757648,1041757663,FR
1041757664,1041757671,GB
@@ -3487,9 +4145,12 @@
1042288416,1042292735,CH
1042292736,1042293247,NL
1042293248,1042293503,GB
-1042293504,1042293535,NL
+1042293504,1042293535,IT
1042293536,1042293631,IR
-1042293632,1042296063,GE
+1042293632,1042293759,GE
+1042293760,1042293985,IT
+1042293986,1042294783,NL
+1042294784,1042296063,GE
1042296064,1042296191,CY
1042296192,1042296575,GE
1042296576,1042296831,BY
@@ -3631,8 +4292,10 @@
1043356032,1043357695,DE
1043357696,1043365887,CH
1043365888,1043398655,PT
-1043398656,1043464191,GB
-1043464192,1043464799,NL
+1043398656,1043464311,GB
+1043464312,1043464351,NL
+1043464352,1043464383,GB
+1043464384,1043464799,NL
1043464800,1043464807,GB
1043464808,1043464823,NL
1043464824,1043464831,GB
@@ -4229,7 +4892,8 @@
1044454512,1044454559,NO
1044454560,1044454583,SE
1044454584,1044454655,NO
-1044454656,1044455423,SE
+1044454656,1044454911,SE
+1044454912,1044455423,NO
1044455424,1044463615,EE
1044463616,1044479999,SE
1044480000,1044488191,CH
@@ -4246,10 +4910,14 @@
1044588288,1044588575,GB
1044588576,1044588607,DE
1044588608,1044588799,GB
-1044588800,1044590463,DE
-1044590464,1044590591,GB
+1044588800,1044589567,DE
+1044589568,1044590079,GB
+1044590080,1044590335,DE
+1044590336,1044590591,GB
1044590592,1044590671,DE
-1044590672,1044590847,GB
+1044590672,1044590719,GB
+1044590720,1044590783,DE
+1044590784,1044590847,GB
1044590848,1044591615,DE
1044591616,1044591871,GB
1044591872,1044592127,DE
@@ -4311,7 +4979,9 @@
1044697088,1044697343,DE
1044697344,1044697855,AT
1044697856,1044698110,DE
-1044698111,1044701183,AT
+1044698111,1044698111,AT
+1044698112,1044698367,DE
+1044698368,1044701183,AT
1044701184,1044709375,EG
1044709376,1044717567,RU
1044717568,1044742143,GB
@@ -4329,9 +4999,7 @@
1044774912,1044800383,NO
1044800384,1044800511,IT
1044800512,1044840447,NO
-1044840448,1044842751,FI
-1044842752,1044842815,AX
-1044842816,1044905983,FI
+1044840448,1044905983,FI
1044905984,1044908031,GB
1044908032,1044909055,US
1044909056,1044910847,GB
@@ -4377,9 +5045,7 @@
1044930928,1044930967,BE
1044930968,1044930975,FR
1044930976,1044930979,GB
-1044930980,1044931231,BE
-1044931232,1044931239,GB
-1044931240,1044931375,BE
+1044930980,1044931375,BE
1044931376,1044931391,GB
1044931392,1044931407,BE
1044931408,1044931439,GB
@@ -4403,12 +5069,14 @@
1044931904,1044931911,GB
1044931912,1044931915,BE
1044931916,1044931919,GB
-1044931920,1044931935,BE
+1044931920,1044931923,BE
+1044931924,1044931927,GB
+1044931928,1044931935,BE
1044931936,1044931951,GB
1044931952,1044931975,BE
1044931976,1044931983,GB
-1044931984,1044932063,BE
-1044932064,1044932087,GB
+1044931984,1044932047,BE
+1044932048,1044932087,GB
1044932088,1044932383,BE
1044932384,1044932391,GB
1044932392,1044932399,BE
@@ -4435,8 +5103,8 @@
1044932952,1044932959,GB
1044932960,1044933007,BE
1044933008,1044933015,GB
-1044933016,1044933023,BE
-1044933024,1044933039,GB
+1044933016,1044933019,BE
+1044933020,1044933039,GB
1044933040,1044933055,BE
1044933056,1044933071,GB
1044933072,1044933103,BE
@@ -4472,12 +5140,14 @@
1044933848,1044933863,BE
1044933864,1044933871,GB
1044933872,1044933919,BE
-1044933920,1044933951,GB
-1044933952,1044934191,BE
+1044933920,1044933935,GB
+1044933936,1044934191,BE
1044934192,1044934199,GB
1044934200,1044934239,BE
1044934240,1044934247,GB
-1044934248,1044934359,BE
+1044934248,1044934287,BE
+1044934288,1044934295,GB
+1044934296,1044934359,BE
1044934360,1044934503,GB
1044934504,1044934575,BE
1044934576,1044934583,GB
@@ -4612,16 +5282,14 @@
1045013472,1045018207,GB
1045018208,1045018231,FI
1045018232,1045018367,GB
-1045018368,1045018423,ES
-1045018424,1045018431,GB
-1045018432,1045018559,ES
+1045018368,1045018559,ES
1045018560,1045018623,GB
1045018624,1045018751,ES
1045018752,1045020159,GB
1045020160,1045020255,ES
1045020256,1045020287,GB
-1045020288,1045020639,ES
-1045020640,1045020671,GB
+1045020288,1045020655,ES
+1045020656,1045020671,GB
1045020672,1045037055,NO
1045037056,1045119231,GR
1045119232,1045119743,AL
@@ -4765,8 +5433,7 @@
1045743680,1045743743,GB
1045743744,1045743803,SE
1045743804,1045743807,GB
-1045743808,1045743999,SE
-1045744000,1045744007,LU
+1045743808,1045744007,SE
1045744008,1045744015,GB
1045744016,1045744031,SE
1045744032,1045744063,GB
@@ -4853,8 +5520,13 @@
1046229120,1046282239,NO
1046282240,1046283007,DE
1046283008,1046283263,BZ
-1046283264,1046284287,DE
-1046284288,1046285311,BZ
+1046283264,1046283327,LU
+1046283328,1046284287,DE
+1046284288,1046285055,BZ
+1046285056,1046285119,HR
+1046285120,1046285183,MT
+1046285184,1046285247,BZ
+1046285248,1046285311,BA
1046285312,1046286663,DE
1046286664,1046286671,BZ
1046286672,1046286927,DE
@@ -4892,8 +5564,7 @@
1046316032,1046316543,FR
1046316544,1046317055,DK
1046317056,1046317567,ES
-1046317568,1046317823,GB
-1046317824,1046318335,NL
+1046317568,1046318335,NL
1046318336,1046318591,GB
1046318592,1046320127,NL
1046320128,1046320639,GB
@@ -4924,10 +5595,8 @@
1046338048,1046339839,EU
1046339840,1046340095,FR
1046340096,1046340607,EU
-1046340608,1046341119,NL
-1046341120,1046341631,EU
-1046341632,1046341887,FR
-1046341888,1046342143,EU
+1046340608,1046340863,NL
+1046340864,1046342143,EU
1046342144,1046342719,NL
1046342720,1046343423,EU
1046343424,1046343935,NL
@@ -5189,8 +5858,8 @@
1046528600,1046528603,DE
1046528604,1046528607,GB
1046528608,1046528639,DE
-1046528640,1046528671,GB
-1046528672,1046528767,DE
+1046528640,1046528703,GB
+1046528704,1046528767,DE
1046528768,1046530047,GB
1046530048,1046530687,DE
1046530688,1046530815,GB
@@ -5216,8 +5885,8 @@
1046535312,1046535359,GB
1046535360,1046535423,DE
1046535424,1046535487,GB
-1046535488,1046535615,DE
-1046535616,1046535619,GB
+1046535488,1046535551,DE
+1046535552,1046535619,GB
1046535620,1046535623,DE
1046535624,1046535631,GB
1046535632,1046535935,DE
@@ -5276,13 +5945,17 @@
1046543104,1046543263,GB
1046543264,1046543295,DE
1046543296,1046543327,GB
-1046543328,1046543351,DE
-1046543352,1046543359,GB
+1046543328,1046543343,DE
+1046543344,1046543359,GB
1046543360,1046543615,DE
1046543616,1046544127,GB
1046544128,1046544383,DE
1046544384,1046560767,IT
-1046560768,1046585343,ES
+1046560768,1046569831,ES
+1046569832,1046569839,GB
+1046569840,1046570591,ES
+1046570592,1046570607,CH
+1046570608,1046585343,ES
1046585344,1046609919,NO
1046609920,1046675455,IT
1046675456,1046708223,ES
@@ -5381,8 +6054,8 @@
1046896384,1046897663,GB
1046897664,1046898431,BE
1046898432,1046898687,EU
-1046898688,1046898943,BE
-1046898944,1046899167,EU
+1046898688,1046898975,BE
+1046898976,1046899167,EU
1046899168,1046904831,BE
1046904832,1046937599,RU
1046937600,1047003135,GR
@@ -5424,7 +6097,9 @@
1047340800,1047341055,NO
1047341056,1047343871,SE
1047343872,1047344127,NO
-1047344128,1047347199,SE
+1047344128,1047346431,SE
+1047346432,1047346687,FI
+1047346688,1047347199,SE
1047347200,1047363583,DE
1047363584,1047371775,CZ
1047371776,1047379967,RU
@@ -5449,8 +6124,8 @@
1047563304,1047563311,CH
1047563312,1047563319,DE
1047563320,1047563323,CH
-1047563324,1047563347,DE
-1047563348,1047563355,CH
+1047563324,1047563351,DE
+1047563352,1047563355,CH
1047563356,1047563363,DE
1047563364,1047563367,ES
1047563368,1047563403,DE
@@ -5466,7 +6141,9 @@
1047563452,1047563455,NL
1047563456,1047563467,DE
1047563468,1047563471,CH
-1047563472,1047566363,DE
+1047563472,1047565131,DE
+1047565132,1047565135,GB
+1047565136,1047566363,DE
1047566364,1047566367,CH
1047566368,1047566403,DE
1047566404,1047566415,CH
@@ -5480,9 +6157,13 @@
1047566492,1047566499,CH
1047566500,1047566507,DE
1047566508,1047566511,CH
-1047566512,1047566535,DE
+1047566512,1047566519,DE
+1047566520,1047566527,CH
+1047566528,1047566535,DE
1047566536,1047566539,CH
-1047566540,1047566559,DE
+1047566540,1047566543,DE
+1047566544,1047566547,CH
+1047566548,1047566559,DE
1047566560,1047566563,CH
1047566564,1047566847,DE
1047566848,1047566851,AT
@@ -5491,7 +6172,9 @@
1047566872,1047566879,CH
1047566880,1047566891,DE
1047566892,1047566903,CH
-1047566904,1047566963,DE
+1047566904,1047566947,DE
+1047566948,1047566951,AT
+1047566952,1047566963,DE
1047566964,1047566967,AT
1047566968,1047566995,DE
1047566996,1047566999,CH
@@ -5550,7 +6233,9 @@
1047567756,1047567759,CH
1047567760,1047567799,DE
1047567800,1047567803,CH
-1047567804,1047567847,DE
+1047567804,1047567823,DE
+1047567824,1047567839,CH
+1047567840,1047567847,DE
1047567848,1047567851,CH
1047567852,1047567855,BE
1047567856,1047567871,DE
@@ -5578,7 +6263,9 @@
1047568368,1047568383,DE
1047568384,1047576575,NL
1047576576,1047584767,HU
-1047584768,1047592959,NL
+1047584768,1047592735,NL
+1047592736,1047592743,FR
+1047592744,1047592959,NL
1047592960,1047601151,BA
1047601152,1047625727,RU
1047625728,1047633919,NO
@@ -5589,7 +6276,8 @@
1047728128,1047732223,SE
1047732224,1047740415,EU
1047740416,1047740431,US
-1047740432,1047740543,EU
+1047740432,1047740447,DE
+1047740448,1047740543,EU
1047740544,1047740671,DE
1047740672,1047740927,A2
1047740928,1047781663,EU
@@ -5600,7 +6288,14 @@
1047782720,1047782751,SE
1047782752,1047782783,NO
1047782784,1047782815,FI
-1047782816,1047789567,EU
+1047782816,1047789375,EU
+1047789376,1047789383,GB
+1047789384,1047789407,EU
+1047789408,1047789423,DE
+1047789424,1047789439,EU
+1047789440,1047789471,SE
+1047789472,1047789535,EU
+1047789536,1047789567,DE
1047789568,1047806031,AT
1047806032,1047806047,IT
1047806048,1047822335,AT
@@ -5668,8 +6363,8 @@
1048604966,1048604967,UA
1048604968,1048604971,LT
1048604972,1048604975,UA
-1048604976,1048605071,LT
-1048605072,1048607231,UA
+1048604976,1048605079,LT
+1048605080,1048607231,UA
1048607232,1048607247,EE
1048607248,1048607487,UA
1048607488,1048607519,EE
@@ -6425,7 +7120,9 @@
1049020480,1049020543,GE
1049020544,1049026559,DE
1049026560,1049026815,EU
-1049026816,1049032143,DE
+1049026816,1049031871,DE
+1049031872,1049031903,EU
+1049031904,1049032143,DE
1049032144,1049032167,EU
1049032168,1049032171,DE
1049032172,1049032175,EU
@@ -6433,7 +7130,9 @@
1049032288,1049032295,EU
1049032296,1049032383,DE
1049032384,1049032399,EU
-1049032400,1049032639,DE
+1049032400,1049032623,DE
+1049032624,1049032631,EU
+1049032632,1049032639,DE
1049032640,1049032647,EU
1049032648,1049032699,DE
1049032700,1049032703,EU
@@ -6605,9 +7304,7 @@
1049778336,1049778351,AE
1049778352,1049778535,DE
1049778536,1049778543,AT
-1049778544,1049779063,DE
-1049779064,1049779071,PL
-1049779072,1049779135,DE
+1049778544,1049779135,DE
1049779136,1049779167,AE
1049779168,1049782303,DE
1049782304,1049782335,AE
@@ -6627,7 +7324,9 @@
1049787136,1049787391,PL
1049787392,1049790207,DE
1049790208,1049790463,LU
-1049790464,1049817151,DE
+1049790464,1049794559,DE
+1049794560,1049795583,CH
+1049795584,1049817151,DE
1049817152,1049817159,PL
1049817160,1049817287,DE
1049817288,1049817295,AE
@@ -6860,13 +7559,11 @@
1051578352,1051578363,GB
1051578364,1051578367,DE
1051578368,1051580415,SZ
-1051580416,1051584511,GB
-1051584512,1051585663,MG
-1051585664,1051585919,GB
-1051585920,1051586047,MG
-1051586048,1051586175,GB
-1051586176,1051586303,MG
-1051586304,1051590655,GB
+1051580416,1051584767,GB
+1051584768,1051585535,MG
+1051585536,1051585599,GB
+1051585600,1051585663,MG
+1051585664,1051590655,GB
1051590656,1051702527,ES
1051702528,1051702783,US
1051702784,1051721727,ES
@@ -6967,7 +7664,9 @@
1052003840,1052003967,EU
1052003968,1052003999,DE
1052004000,1052004671,EU
-1052004672,1052004759,DE
+1052004672,1052004687,DE
+1052004688,1052004703,EU
+1052004704,1052004759,DE
1052004760,1052004767,EU
1052004768,1052004783,DE
1052004784,1052004815,EU
@@ -7080,9 +7779,7 @@
1052016896,1052017151,DE
1052017152,1052017231,EU
1052017232,1052017247,DE
-1052017248,1052017279,EU
-1052017280,1052017343,DE
-1052017344,1052017471,EU
+1052017248,1052017471,EU
1052017472,1052017503,DE
1052017504,1052017535,EU
1052017536,1052017567,DE
@@ -8256,13 +8953,9 @@
1053340416,1053340479,EU
1053340480,1053340511,NL
1053340512,1053340671,EU
-1053340672,1053341183,GB
-1053341184,1053341439,EU
-1053341440,1053341567,GB
+1053340672,1053341567,GB
1053341568,1053341575,EU
-1053341576,1053341599,GB
-1053341600,1053341615,EU
-1053341616,1053341695,GB
+1053341576,1053341695,GB
1053341696,1053343743,EU
1053343744,1053344255,FI
1053344256,1053344511,EU
@@ -8282,8 +8975,8 @@
1053350336,1053350351,EU
1053350352,1053350359,IE
1053350360,1053350367,EU
-1053350368,1053350383,IE
-1053350384,1053350399,EU
+1053350368,1053350391,IE
+1053350392,1053350399,EU
1053350400,1053350479,BE
1053350480,1053350655,EU
1053350656,1053350911,BE
@@ -8370,7 +9063,8 @@
1053835264,1053835775,DE
1053835776,1053837311,EU
1053837312,1053837439,FK
-1053837440,1053837567,EU
+1053837440,1053837455,GB
+1053837456,1053837567,EU
1053837568,1053837823,GB
1053837824,1053838335,FK
1053838336,1053838591,DE
@@ -8627,8 +9321,8 @@
1055200424,1055201023,EU
1055201024,1055201279,US
1055201280,1055203327,EU
-1055203328,1055203359,CZ
-1055203360,1055203839,EU
+1055203328,1055203343,CZ
+1055203344,1055203839,EU
1055203840,1055204095,CZ
1055204096,1055204863,EU
1055204864,1055205119,CZ
@@ -8685,8 +9379,8 @@
1055218448,1055218463,EU
1055218464,1055218471,PT
1055218472,1055218479,EU
-1055218480,1055219711,PT
-1055219712,1055220223,EU
+1055218480,1055218687,PT
+1055218688,1055220223,EU
1055220224,1055220287,NL
1055220288,1055220351,EU
1055220352,1055220399,NL
@@ -8795,8 +9489,8 @@
1056244256,1056244287,FR
1056244288,1056244335,MC
1056244336,1056244351,FR
-1056244352,1056244447,CH
-1056244448,1056244479,MC
+1056244352,1056244415,CH
+1056244416,1056244479,MC
1056244480,1056251903,CH
1056251904,1056260095,RU
1056260096,1056276479,CZ
@@ -8813,7 +9507,6 @@
1056505856,1056514047,PT
1056514048,1056522239,IT
1056522240,1056538623,AT
-1056538624,1056546815,DE
1056546816,1056555007,NO
1056555008,1056571391,GB
1056571392,1056669695,NL
@@ -8850,9 +9543,7 @@
1056964608,1061227007,US
1061227008,1061227263,HT
1061227264,1061227774,BO
-1061227775,1061478143,US
-1061478144,1061478399,BO
-1061478400,1061518015,US
+1061227775,1061518015,US
1061518016,1061518047,A2
1061518048,1061558271,US
1061558272,1061559295,PK
@@ -8860,13 +9551,7 @@
1061588736,1061588991,GU
1061588992,1061633567,US
1061633568,1061633575,CA
-1061633576,1061749152,US
-1061749153,1061749182,PR
-1061749183,1061749183,US
-1061749184,1061749191,PR
-1061749192,1061749199,US
-1061749200,1061749231,PR
-1061749232,1061762047,US
+1061633576,1061762047,US
1061762048,1061762303,FR
1061762304,1061776479,US
1061776480,1061776639,CA
@@ -9034,11 +9719,9 @@
1065583424,1065583439,HK
1065583440,1065611263,US
1065611264,1065615359,PR
-1065615360,1065806947,US
-1065806948,1065806957,TH
-1065806958,1065811967,US
+1065615360,1065811967,US
1065811968,1065820159,CA
-1065820160,1065873407,US
+1065824256,1065873407,US
1065873408,1065877503,PR
1065877504,1065906175,US
1065906176,1065908223,KY
@@ -9261,11 +9944,7 @@
1071477248,1071480831,CA
1071480832,1071985631,US
1071985632,1071985663,ML
-1071985664,1072440639,US
-1072440640,1072440671,CA
-1072440672,1072445631,US
-1072445632,1072445663,AU
-1072445664,1072512951,US
+1071985664,1072512951,US
1072512952,1072512959,CA
1072512960,1072619023,US
1072619024,1072619039,CA
@@ -9310,7 +9989,7 @@
1072785472,1072790015,US
1072790016,1072790031,JP
1072790032,1072922623,US
-1072922624,1072922879,PH
+1072922624,1072922879,CA
1072922880,1072923135,US
1072923136,1072923391,CA
1072923392,1072923903,US
@@ -9333,33 +10012,33 @@
1072928128,1072928255,US
1072928256,1072928263,CA
1072928264,1072928287,US
-1072928288,1072928319,CA
-1072928320,1072928447,US
+1072928288,1072928383,CA
+1072928384,1072928447,US
1072928448,1072929535,CA
1072929536,1072929791,US
1072929792,1072930047,CA
1072930048,1072930303,US
1072930304,1072931071,CA
-1072931072,1072931327,US
-1072931328,1072931583,CA
+1072931072,1072931199,US
+1072931200,1072931583,CA
1072931584,1072931839,SY
1072931840,1072932607,CA
1072932608,1072932863,NG
1072932864,1072934399,CA
-1072934400,1072934783,US
+1072934400,1072934655,US
+1072934656,1072934783,CA
1072934784,1072934847,AU
1072934848,1072934879,CA
1072934880,1072934911,TW
1072934912,1072934943,CA
1072934944,1072934975,PH
-1072934976,1072935135,US
+1072934976,1072935039,CA
+1072935040,1072935135,US
1072935136,1072935159,CA
1072935160,1072935167,US
1072935168,1072935679,CA
1072935680,1072935807,PH
-1072935808,1072935871,CA
-1072935872,1072935935,US
-1072935936,1072936447,CA
+1072935808,1072936447,CA
1072936448,1072936703,PH
1072936704,1072937215,US
1072937216,1072937471,IR
@@ -9367,7 +10046,9 @@
1072937728,1072938239,CA
1072938240,1072938495,VG
1072938496,1072938751,CA
-1072938752,1072940031,US
+1072938752,1072939007,US
+1072939008,1072939519,CA
+1072939520,1072940031,US
1072940032,1072955391,CA
1072955392,1073022975,US
1073022976,1073025791,HN
@@ -9398,9 +10079,7 @@
1073045504,1073047551,CO
1073047552,1073049599,PR
1073049600,1073053695,BS
-1073053696,1073090269,US
-1073090270,1073090300,PE
-1073090301,1073091397,US
+1073053696,1073091397,US
1073091398,1073091407,CH
1073091408,1073092335,US
1073092336,1073092351,CA
@@ -9469,8 +10148,8 @@
1073394192,1073394207,MX
1073394208,1073394239,CA
1073394240,1073394247,MX
-1073394248,1073394255,US
-1073394256,1073394271,MX
+1073394248,1073394263,US
+1073394264,1073394271,MX
1073394272,1073394279,US
1073394280,1073394287,MX
1073394288,1073394295,US
@@ -9685,7 +10364,9 @@
1075558912,1075576831,US
1075576832,1075576871,NO
1075576872,1075576879,GB
-1075576880,1075576967,NO
+1075576880,1075576951,NO
+1075576952,1075576959,GB
+1075576960,1075576967,NO
1075576968,1075576975,GB
1075576976,1075576991,NO
1075576992,1075577023,GB
@@ -9804,7 +10485,9 @@
1075972096,1075972351,GB
1075972352,1075973887,US
1075973888,1075974143,CA
-1075974144,1075976191,US
+1075974144,1075975167,US
+1075975168,1075975423,CA
+1075975424,1075976191,US
1075976192,1075976511,CA
1075976512,1075976543,US
1075976544,1075976647,CA
@@ -9863,8 +10546,8 @@
1075988480,1075988735,US
1075988736,1075988991,CA
1075988992,1075989119,US
-1075989120,1075989183,CA
-1075989184,1075989247,US
+1075989120,1075989231,CA
+1075989232,1075989247,US
1075989248,1075989311,FI
1075989312,1075989359,CA
1075989360,1075989375,US
@@ -10108,22 +10791,23 @@
1076049920,1076050175,IL
1076050176,1076166655,US
1076183040,1076183071,IN
-1076183072,1076183103,US
-1076183104,1076183135,CA
-1076183136,1076183263,US
-1076183264,1076183295,CA
+1076183072,1076183231,US
+1076183232,1076183295,CA
1076183296,1076183807,US
1076183808,1076184063,CA
-1076184064,1076184127,US
+1076184064,1076184095,VE
+1076184096,1076184127,US
1076184128,1076184159,VE
-1076184160,1076184191,US
+1076184160,1076184191,PK
1076184192,1076184223,IN
1076184224,1076184255,US
1076184256,1076184287,BE
1076184288,1076184319,CA
1076184320,1076184575,US
-1076184576,1076184703,SG
-1076184704,1076184895,US
+1076184576,1076184639,CA
+1076184640,1076184703,SG
+1076184704,1076184831,CA
+1076184832,1076184895,US
1076184896,1076184927,FR
1076184928,1076184959,US
1076184960,1076184991,VE
@@ -10137,7 +10821,9 @@
1076185504,1076185535,DO
1076185536,1076185599,US
1076185600,1076185855,MY
-1076185856,1076185983,US
+1076185856,1076185919,US
+1076185920,1076185951,CA
+1076185952,1076185983,US
1076185984,1076186015,PK
1076186016,1076186047,US
1076186048,1076186079,IN
@@ -10147,17 +10833,20 @@
1076186368,1076186623,CA
1076186624,1076186751,US
1076186752,1076186783,CA
-1076186784,1076187391,US
+1076186784,1076186815,TW
+1076186816,1076187391,US
1076187392,1076187647,CA
1076187648,1076187679,BE
-1076187680,1076187775,US
+1076187680,1076187743,US
+1076187744,1076187775,CA
1076187776,1076187807,AU
1076187808,1076187903,US
1076187904,1076188159,CA
1076188160,1076188287,US
1076188288,1076188415,BE
-1076188416,1076188671,MY
-1076188672,1076189183,US
+1076188416,1076188799,US
+1076188800,1076188927,CA
+1076188928,1076189183,US
1076189184,1076189215,VE
1076189216,1076189279,CA
1076189280,1076189311,US
@@ -10171,24 +10860,35 @@
1076190144,1076190175,BE
1076190176,1076190207,IN
1076190208,1076190463,CA
-1076190464,1076190815,US
+1076190464,1076190655,US
+1076190656,1076190719,CA
+1076190720,1076190783,US
+1076190784,1076190815,CA
1076190816,1076190847,IN
-1076190848,1076192255,US
+1076190848,1076190913,US
+1076190914,1076190945,IN
+1076190946,1076191231,US
+1076191232,1076191487,CA
+1076191488,1076192063,US
+1076192064,1076192191,CA
+1076192192,1076192255,US
1076192256,1076192383,BE
-1076192384,1076192767,US
+1076192384,1076192639,US
+1076192640,1076192767,CA
1076192768,1076192831,IN
-1076192832,1076193023,US
-1076193024,1076193055,GB
+1076192832,1076192895,KR
+1076192896,1076193055,US
1076193056,1076193087,AU
1076193088,1076193151,US
1076193152,1076193183,TR
1076193184,1076193247,US
1076193248,1076193279,CA
-1076193280,1076194367,US
+1076193280,1076193535,PK
+1076193536,1076194367,US
1076194368,1076194399,IN
1076194400,1076194431,IL
-1076194432,1076194495,US
-1076194496,1076194527,BE
+1076194432,1076194463,IN
+1076194464,1076194527,BE
1076194528,1076194559,US
1076194560,1076194815,CA
1076194816,1076195071,US
@@ -10198,28 +10898,33 @@
1076195584,1076195871,US
1076195872,1076195903,BE
1076195904,1076195935,CA
-1076195936,1076196095,US
-1076196096,1076196383,CA
-1076196384,1076196479,US
+1076195936,1076195999,US
+1076196000,1076196031,CN
+1076196032,1076196063,CA
+1076196064,1076196095,US
+1076196096,1076196415,CA
+1076196416,1076196479,US
1076196480,1076196511,FR
-1076196512,1076196543,AT
-1076196544,1076196641,US
+1076196512,1076196575,AT
+1076196576,1076196607,CA
+1076196608,1076196641,US
1076196642,1076196671,BE
1076196672,1076196703,US
1076196704,1076196735,FR
-1076196736,1076197119,US
+1076196736,1076196863,US
+1076196864,1076196991,IN
+1076196992,1076197119,US
1076197120,1076197375,CA
1076197376,1076197631,US
1076197632,1076197663,BE
-1076197664,1076198655,US
+1076197664,1076198399,US
+1076198400,1076198655,CA
1076198656,1076198911,AE
1076198912,1076218015,US
1076218016,1076218023,GB
1076218024,1076219407,US
1076219408,1076219415,GB
-1076219416,1076281631,US
-1076281632,1076281663,AT
-1076281664,1076281695,US
+1076219416,1076281695,US
1076281696,1076281727,TH
1076281728,1076282111,US
1076282112,1076282143,AU
@@ -11223,9 +11928,11 @@
1077940206,1077940209,IT
1077940210,1077940213,US
1077940214,1077940217,MX
-1077940218,1077963775,US
-1077963776,1077964031,CA
-1077964032,1077977087,US
+1077940218,1077960839,US
+1077960840,1077960847,CA
+1077960848,1077960943,US
+1077960944,1077960951,CO
+1077960952,1077977087,US
1077977088,1077985279,CA
1077985280,1077993471,US
1077993472,1078001663,CA
@@ -11248,13 +11955,11 @@
1078280192,1078280575,CA
1078280576,1078280591,US
1078280592,1078280639,CA
-1078280640,1078280655,CR
+1078280640,1078280655,US
1078280656,1078280671,CA
1078280672,1078280695,US
-1078280696,1078280943,CA
-1078280944,1078281071,US
-1078281072,1078281079,CA
-1078281080,1078281087,US
+1078280696,1078280895,CA
+1078280896,1078281087,US
1078281088,1078281279,CA
1078281280,1078281295,US
1078281296,1078281663,CA
@@ -11279,16 +11984,13 @@
1078283264,1078283264,US
1078283265,1078283375,CA
1078283376,1078283391,MX
-1078283392,1078283407,CA
-1078283408,1078283423,US
+1078283392,1078283423,US
1078283424,1078283487,CA
-1078283488,1078283495,US
-1078283496,1078283551,CA
+1078283488,1078283503,US
+1078283504,1078283551,CA
1078283552,1078283583,US
1078283584,1078283647,CA
-1078283648,1078283663,US
-1078283664,1078283671,CA
-1078283672,1078283679,US
+1078283648,1078283679,US
1078283680,1078283687,CA
1078283688,1078283695,US
1078283696,1078283751,CA
@@ -11296,21 +11998,19 @@
1078283776,1078284031,CA
1078284032,1078284159,BS
1078284160,1078284255,CA
-1078284256,1078284287,US
-1078284288,1078284319,CA
-1078284320,1078284351,US
+1078284256,1078284351,US
1078284352,1078284367,CA
1078284368,1078284383,BV
1078284384,1078284399,US
1078284400,1078284687,CA
1078284688,1078284695,US
1078284696,1078284703,MX
-1078284704,1078284991,CA
+1078284704,1078284719,CA
+1078284720,1078284735,US
+1078284736,1078284991,CA
1078284992,1078285007,US
1078285008,1078285015,CA
-1078285016,1078285023,US
-1078285024,1078285031,CA
-1078285032,1078285039,US
+1078285016,1078285039,US
1078285040,1078285191,CA
1078285192,1078285215,US
1078285216,1078285231,CA
@@ -11324,12 +12024,16 @@
1078285304,1078285567,US
1078285568,1078285639,CA
1078285640,1078285647,US
-1078285648,1078285695,CA
+1078285648,1078285655,CA
+1078285656,1078285663,US
+1078285664,1078285695,CA
1078285696,1078285703,MX
1078285704,1078285711,US
1078285712,1078285919,CA
1078285920,1078285943,US
-1078285944,1078286047,CA
+1078285944,1078285951,CA
+1078285952,1078286015,US
+1078286016,1078286047,CA
1078286048,1078286079,US
1078286080,1078286111,CA
1078286112,1078286115,US
@@ -11361,13 +12065,15 @@
1078287184,1078287199,US
1078287200,1078287231,CA
1078287232,1078287247,US
-1078287248,1078287295,CA
-1078287296,1078287311,US
+1078287248,1078287279,CA
+1078287280,1078287311,US
1078287312,1078287327,CA
1078287328,1078287343,US
1078287344,1078287759,CA
1078287760,1078287767,US
-1078287768,1078287839,CA
+1078287768,1078287775,CA
+1078287776,1078287807,US
+1078287808,1078287839,CA
1078287840,1078287863,US
1078287864,1078288383,CA
1078288384,1078309695,US
@@ -11690,21 +12396,20 @@
1079354704,1079354711,CA
1079354712,1079355359,US
1079355360,1079355367,CA
-1079355368,1079355903,US
-1079355904,1079355939,CA
-1079355940,1079355951,AU
-1079355952,1079356415,CA
-1079356416,1079356663,US
+1079355368,1079355967,US
+1079355968,1079355991,CA
+1079355992,1079356663,US
1079356664,1079356671,CA
1079356672,1079377919,US
1079377920,1079378943,CA
1079378944,1079379711,US
1079379712,1079380927,CA
-1079380928,1079381183,US
-1079381184,1079381503,CA
-1079381504,1079381599,US
+1079380928,1079380991,US
+1079380992,1079381567,CA
+1079381568,1079381599,US
1079381600,1079381631,WS
-1079381632,1079382015,US
+1079381632,1079381759,CA
+1079381760,1079382015,US
1079382016,1079382527,CA
1079382528,1079383039,US
1079383040,1079383295,VG
@@ -11713,25 +12418,28 @@
1079384064,1079384319,LR
1079384320,1079384575,CA
1079384576,1079385087,ZW
-1079385088,1079385471,CA
+1079385088,1079385343,US
+1079385344,1079385471,CA
1079385472,1079385599,US
1079385600,1079385855,CA
1079385856,1079386111,SZ
-1079386112,1079386623,US
+1079386112,1079386623,CA
1079386624,1079386879,SG
1079386880,1079387135,EG
1079387136,1079387903,US
1079387904,1079388159,PH
1079388160,1079389439,CA
-1079389440,1079389951,US
+1079389440,1079389567,US
+1079389568,1079389695,CA
+1079389696,1079389951,US
1079389952,1079390719,CA
1079390720,1079391487,US
1079391488,1079391615,CA
1079391616,1079391679,US
1079391680,1079391743,CA
1079391744,1079392255,HT
-1079392256,1079393279,CA
-1079393280,1079394047,US
+1079392256,1079393791,CA
+1079393792,1079394047,US
1079394048,1079394063,CA
1079394064,1079394071,SG
1079394072,1079394079,CA
@@ -11747,31 +12455,27 @@
1079396096,1079396351,CA
1079396352,1079397375,MP
1079397376,1079397631,MH
-1079397632,1079398399,US
-1079398400,1079399583,CA
+1079397632,1079399583,CA
1079399584,1079399599,US
-1079399600,1079399935,CA
-1079399936,1079400447,US
+1079399600,1079400447,CA
1079400448,1079400511,FR
1079400512,1079400575,CA
1079400576,1079400639,US
-1079400640,1079400703,CA
-1079400704,1079400831,US
+1079400640,1079400767,CA
+1079400768,1079400831,US
1079400832,1079401215,CA
1079401216,1079401471,US
-1079401472,1079401983,CA
-1079401984,1079402495,US
-1079402496,1079403007,CA
-1079403008,1079403519,US
-1079403520,1079403775,CA
+1079401472,1079403775,CA
1079403776,1079403807,US
-1079403808,1079403839,CA
-1079403840,1079403935,US
+1079403808,1079403903,CA
+1079403904,1079403935,US
1079403936,1079403999,CA
-1079404000,1079404799,US
+1079404000,1079404031,US
+1079404032,1079404543,CA
+1079404544,1079404799,US
1079404800,1079405023,CA
-1079405024,1079405247,US
-1079405248,1079405407,CA
+1079405024,1079405119,US
+1079405120,1079405407,CA
1079405408,1079405439,BD
1079405440,1079405567,US
1079405568,1079407103,CA
@@ -11790,35 +12494,24 @@
1079410944,1079411199,CA
1079411200,1079411455,US
1079411456,1079411711,PK
-1079411712,1079412735,CA
-1079412736,1079413247,US
-1079413248,1079413311,CA
+1079411712,1079413311,CA
1079413312,1079413343,US
-1079413344,1079414271,CA
-1079414272,1079415039,US
+1079413344,1079414783,CA
+1079414784,1079415039,US
1079415040,1079415295,HN
-1079415296,1079415551,CA
-1079415552,1079416319,US
-1079416320,1079419135,CA
-1079419136,1079419903,US
-1079419904,1079420159,CA
-1079420160,1079420671,US
-1079420672,1079421951,CA
+1079415296,1079415807,CA
+1079415808,1079416319,US
+1079416320,1079421951,CA
1079421952,1079422207,US
-1079422208,1079422463,CA
-1079422464,1079423487,MZ
-1079423488,1079423999,CA
-1079424000,1079424767,MZ
-1079424768,1079425279,US
+1079422208,1079425023,CA
+1079425024,1079425279,US
1079425280,1079425535,CA
1079425536,1079425551,US
1079425552,1079427071,CA
1079427072,1079427327,US
1079427328,1079427583,CA
1079427584,1079428095,PW
-1079428096,1079429375,CA
-1079429376,1079429887,US
-1079429888,1079431679,CA
+1079428096,1079431679,CA
1079431680,1079432191,ZM
1079432192,1079432703,CA
1079432704,1079432959,US
@@ -11845,7 +12538,8 @@
1079576496,1079578623,PR
1079578624,1079585391,US
1079585392,1079585407,IN
-1079585408,1079664639,US
+1079585408,1079648255,US
+1079656448,1079664639,US
1079664640,1079668735,CA
1079668736,1079827871,US
1079827872,1079827887,RU
@@ -11863,7 +12557,9 @@
1079946432,1079946463,CA
1079946464,1079953567,US
1079953568,1079953599,GB
-1079953600,1079994367,US
+1079953600,1079962879,US
+1079962880,1079963135,GB
+1079963136,1079994367,US
1079994368,1079996415,CA
1079996416,1080021999,US
1080022000,1080022007,GT
@@ -11996,7 +12692,6 @@
1080750612,1080820871,US
1080820872,1080820879,PR
1080820880,1080954879,US
-1080955904,1080957183,US
1080957952,1080958207,A2
1080958208,1080958463,BH
1080958464,1080958719,A2
@@ -12038,9 +12733,7 @@
1081369120,1081369151,CO
1081369152,1081369599,US
1081369600,1081370111,CO
-1081370112,1081377055,US
-1081377056,1081377071,VE
-1081377072,1081377079,US
+1081370112,1081377079,US
1081377080,1081377087,VE
1081377088,1081377119,US
1081377120,1081377135,VE
@@ -12055,20 +12748,16 @@
1081377824,1081377887,US
1081377888,1081377919,VE
1081377920,1081377935,US
-1081377936,1081377999,VE
-1081378000,1081378015,US
+1081377936,1081377983,VE
+1081377984,1081378015,US
1081378016,1081378047,VE
-1081378048,1081378303,US
-1081378304,1081378319,VE
-1081378320,1081378375,US
+1081378048,1081378375,US
1081378376,1081378399,VE
1081378400,1081378495,US
1081378496,1081378575,VE
1081378576,1081378607,US
1081378608,1081378655,VE
-1081378656,1081378751,US
-1081378752,1081378815,VE
-1081378816,1081379327,US
+1081378656,1081379327,US
1081379328,1081379839,VE
1081379840,1081385215,US
1081385216,1081385535,PA
@@ -12077,9 +12766,7 @@
1081385992,1081385999,US
1081386000,1081386015,PA
1081386016,1081386047,VE
-1081386048,1081386623,US
-1081386624,1081386687,PA
-1081386688,1081387519,US
+1081386048,1081387519,US
1081387520,1081388031,PA
1081388032,1081388127,US
1081388128,1081388143,PA
@@ -12090,9 +12777,7 @@
1081393408,1081393751,CL
1081393752,1081393759,US
1081393760,1081393783,CL
-1081393784,1081393799,US
-1081393800,1081393807,CL
-1081393808,1081393831,US
+1081393784,1081393831,US
1081393832,1081393839,CL
1081393840,1081393887,US
1081393888,1081393903,CL
@@ -12102,13 +12787,23 @@
1081397760,1081398783,CL
1081398784,1081399295,US
1081399296,1081401343,CL
-1081401344,1081401391,AR
+1081401344,1081401375,AR
+1081401376,1081401383,US
+1081401384,1081401391,AR
1081401392,1081401415,US
-1081401416,1081401535,AR
-1081401536,1081401567,US
-1081401568,1081401735,AR
-1081401736,1081401743,US
-1081401744,1081402367,AR
+1081401416,1081401471,AR
+1081401472,1081401567,US
+1081401568,1081401599,AR
+1081401600,1081401615,US
+1081401616,1081401735,AR
+1081401736,1081401751,US
+1081401752,1081401775,AR
+1081401776,1081401791,US
+1081401792,1081401807,AR
+1081401808,1081401815,US
+1081401816,1081401823,AR
+1081401824,1081401855,US
+1081401856,1081402367,AR
1081402368,1081402895,US
1081402896,1081403007,AR
1081403008,1081403055,US
@@ -12127,8 +12822,8 @@
1081403904,1081403967,AR
1081403968,1081404031,US
1081404032,1081404095,AR
-1081404096,1081404991,US
-1081404992,1081405119,AR
+1081404096,1081405055,US
+1081405056,1081405119,AR
1081405120,1081409791,US
1081409792,1081410047,PR
1081410048,1081410559,US
@@ -12145,43 +12840,31 @@
1081413584,1081413631,PR
1081413632,1081416191,US
1081416192,1081416447,PR
-1081416448,1081419199,US
-1081419200,1081419231,PR
-1081419232,1081419263,US
-1081419264,1081419391,PR
+1081416448,1081419327,US
+1081419328,1081419391,PR
1081419392,1081419423,US
1081419424,1081419431,PR
1081419432,1081419447,US
1081419448,1081419455,PR
-1081419456,1081419487,US
-1081419488,1081419519,PR
-1081419520,1081419775,US
+1081419456,1081419775,US
1081419776,1081420287,PR
1081420288,1081420319,US
1081420320,1081420351,PR
-1081420352,1081420479,US
-1081420480,1081420543,PR
-1081420544,1081421183,US
-1081421184,1081421215,PR
-1081421216,1081442367,US
+1081420352,1081442367,US
1081442368,1081442399,CL
-1081442400,1081442463,US
-1081442464,1081442495,CL
-1081442496,1081442911,US
+1081442400,1081442911,US
1081442912,1081442927,CL
1081442928,1081442959,US
1081442960,1081442967,CL
1081442968,1081443327,US
-1081443328,1081444863,CL
-1081444864,1081445303,US
-1081445304,1081445311,CL
-1081445312,1081445375,US
-1081445376,1081450495,CL
-1081450496,1081460735,US
+1081443328,1081444351,CL
+1081444352,1081445375,US
+1081445376,1081446399,CL
+1081446400,1081460735,US
1081460736,1081462783,PA
1081462784,1081462815,CO
-1081462816,1081462911,BR
-1081462912,1081462919,US
+1081462816,1081462847,BR
+1081462848,1081462919,US
1081462920,1081462927,BR
1081462928,1081463231,US
1081463232,1081463247,BR
@@ -12360,9 +13043,7 @@
1082093680,1082093695,AU
1082093696,1082097055,US
1082097056,1082097071,CA
-1082097072,1082097143,US
-1082097144,1082097151,AU
-1082097152,1082138623,US
+1082097072,1082138623,US
1082138624,1082140671,A2
1082140672,1082314751,US
1082314752,1082315263,CA
@@ -12380,9 +13061,7 @@
1082348400,1082348407,BE
1082348408,1082348415,US
1082348416,1082348423,GB
-1082348424,1082348439,US
-1082348440,1082348447,SE
-1082348448,1082348471,US
+1082348424,1082348471,US
1082348472,1082348479,GB
1082348480,1082348735,US
1082348736,1082348799,NL
@@ -12402,9 +13081,7 @@
1082349776,1082349783,IT
1082349784,1082349815,US
1082349816,1082349823,RU
-1082349824,1082350623,US
-1082350624,1082350639,IT
-1082350640,1082350655,US
+1082349824,1082350655,US
1082350656,1082350671,IT
1082350672,1082350911,US
1082350912,1082350943,RU
@@ -12426,15 +13103,13 @@
1082952704,1082952959,CA
1082952960,1082982399,US
1082982400,1083015167,CA
-1083015168,1083396095,US
+1083015168,1083263743,US
+1083263744,1083263999,GB
+1083264000,1083396095,US
1083396096,1083400191,BM
1083400192,1083417727,US
1083417728,1083417791,CA
-1083417792,1083421695,US
-1083421696,1083421759,AU
-1083421760,1083424511,US
-1083424512,1083424767,AU
-1083424768,1083437055,US
+1083417792,1083437055,US
1083437056,1083441151,CA
1083441152,1083486911,US
1083486912,1083486943,IS
@@ -12580,8 +13255,8 @@
1086022208,1086022303,US
1086022304,1086022367,CA
1086022368,1086022591,US
-1086022592,1086022655,CA
-1086022656,1086023175,US
+1086022592,1086022623,CA
+1086022624,1086023175,US
1086023176,1086023183,GB
1086023184,1086023215,US
1086023216,1086023223,CA
@@ -12595,15 +13270,15 @@
1086027392,1086027407,IT
1086027408,1086027423,US
1086027424,1086027455,VN
-1086027456,1086028663,US
+1086027456,1086028031,US
+1086028032,1086028287,PA
+1086028288,1086028663,US
1086028664,1086028671,BR
1086028672,1086028751,US
1086028752,1086028759,BR
1086028760,1086029567,US
1086029568,1086029599,BO
-1086029600,1086029703,US
-1086029704,1086029719,GB
-1086029720,1086029727,US
+1086029600,1086029727,US
1086029728,1086029743,CA
1086029744,1086309887,US
1086309888,1086310143,AU
@@ -12811,17 +13486,13 @@
1089154969,1089154977,IN
1089154978,1089155011,US
1089155012,1089155031,TR
-1089155032,1089156607,US
-1089156608,1089156863,CA
-1089156864,1089167359,US
+1089155032,1089167359,US
1089167360,1089171455,CA
1089171456,1089171967,A2
1089171968,1089172735,US
1089172736,1089172839,A2
1089172840,1089172863,US
-1089172864,1089172879,A2
-1089172880,1089172887,US
-1089172888,1089172895,A2
+1089172864,1089172895,A2
1089172896,1089172927,US
1089172928,1089172983,A2
1089172984,1089172991,US
@@ -12840,9 +13511,7 @@
1089192592,1089192599,IT
1089192600,1089196623,CA
1089196624,1089196639,US
-1089196640,1089197311,CA
-1089197312,1089197567,AU
-1089197568,1089200127,CA
+1089196640,1089200127,CA
1089200128,1089200751,US
1089200752,1089200783,CA
1089200784,1089203439,US
@@ -12953,13 +13622,14 @@
1089970176,1089974271,PR
1089974272,1090146303,US
1090146304,1090150399,CA
-1090150400,1090154495,US
-1090158592,1090207743,US
+1090150400,1090207743,US
1090207744,1090215935,CA
1090215936,1090355199,US
1090355200,1090356327,CA
1090356328,1090356335,US
-1090356336,1090357535,CA
+1090356336,1090356407,CA
+1090356408,1090356415,US
+1090356416,1090357535,CA
1090357536,1090357567,US
1090357568,1090357663,CA
1090357664,1090357679,US
@@ -12977,10 +13647,10 @@
1090396160,1090423759,US
1090423760,1090423783,FI
1090423784,1090424095,US
-1090424096,1090424111,FI
-1090424112,1090424287,US
-1090424288,1090424303,FI
-1090424304,1090424831,US
+1090424096,1090424127,FI
+1090424128,1090424287,US
+1090424288,1090424319,FI
+1090424320,1090424831,US
1090424832,1090428927,CA
1090428928,1090445311,US
1090445312,1090447359,CA
@@ -13075,9 +13745,7 @@
1091797264,1091797279,IT
1091797280,1091797855,US
1091797856,1091797871,IT
-1091797872,1091797999,US
-1091798000,1091798015,DE
-1091798016,1091798639,US
+1091797872,1091798639,US
1091798640,1091798647,CN
1091798648,1091798783,US
1091798784,1091799039,CN
@@ -13087,7 +13755,11 @@
1091800320,1091800327,JP
1091800328,1091802111,US
1091802112,1091802367,CA
-1091802368,1091803135,US
+1091802368,1091802831,US
+1091802832,1091802847,CN
+1091802848,1091802863,US
+1091802864,1091802871,HK
+1091802872,1091803135,US
1091803136,1091803391,CN
1091803392,1091803711,US
1091803712,1091803775,TH
@@ -13097,17 +13769,15 @@
1091804264,1091804271,BM
1091804272,1091806719,US
1091806720,1091806847,IT
-1091806848,1091807087,US
-1091807088,1091807095,MY
-1091807096,1091807231,US
+1091806848,1091807231,US
1091807232,1091807487,CA
1091807488,1091807999,US
1091808000,1091808511,CA
1091808512,1091809375,US
1091809376,1091809391,GB
1091809392,1091809407,US
-1091809408,1091809439,JP
-1091809440,1091811839,US
+1091809408,1091809471,JP
+1091809472,1091811839,US
1091811840,1091812095,IT
1091812096,1091812351,US
1091812352,1091812607,CN
@@ -13165,8 +13835,8 @@
1093057104,1093057119,JP
1093057120,1093057263,US
1093057264,1093057279,IT
-1093057280,1093057295,US
-1093057296,1093057343,CY
+1093057280,1093057311,US
+1093057312,1093057343,CY
1093057344,1093057391,US
1093057392,1093057407,RO
1093057408,1093057423,PH
@@ -13218,9 +13888,13 @@
1093112416,1093112431,CA
1093112432,1093112479,US
1093112480,1093112527,CA
-1093112528,1093112895,US
+1093112528,1093112855,US
+1093112856,1093112863,CA
+1093112864,1093112895,US
1093112896,1093112911,CA
-1093112912,1093114623,US
+1093112912,1093113087,US
+1093113088,1093113119,CA
+1093113120,1093114623,US
1093114624,1093114679,CA
1093114680,1093114703,US
1093114704,1093114711,CA
@@ -13423,15 +14097,20 @@
1093740096,1093740159,JP
1093740160,1093740167,US
1093740168,1093740191,CN
-1093740192,1093740335,US
+1093740192,1093740223,US
+1093740224,1093740239,CN
+1093740240,1093740247,US
+1093740248,1093740255,HK
+1093740256,1093740271,US
+1093740272,1093740279,CN
+1093740280,1093740335,US
1093740336,1093740351,SG
1093740352,1093740415,JP
1093740416,1093741599,US
1093741600,1093741607,ES
1093741608,1093743103,US
1093743104,1093743359,HK
-1093743360,1093743391,US
-1093743392,1093743423,PH
+1093743360,1093743423,US
1093743424,1093743487,JP
1093743488,1093743743,US
1093743744,1093743807,CA
@@ -13441,9 +14120,9 @@
1093746880,1093746943,DE
1093746944,1093748799,US
1093748800,1093748863,CN
-1093748864,1094319583,US
-1094319584,1094319599,CA
-1094319600,1094549687,US
+1093748864,1093753111,US
+1093753112,1093753119,CN
+1093753120,1094549687,US
1094549688,1094549695,CA
1094549696,1094549783,US
1094549784,1094549791,AU
@@ -13972,9 +14651,7 @@
1096960768,1096960895,GB
1096960896,1096961023,US
1096961024,1096961151,GB
-1096961152,1096964119,US
-1096964120,1096964127,GB
-1096964128,1096964263,US
+1096961152,1096964263,US
1096964264,1096964271,IN
1096964272,1096968127,US
1096968128,1096968159,CA
@@ -14008,29 +14685,19 @@
1097067520,1097068031,GB
1097068032,1097069055,US
1097069056,1097069311,CA
-1097069312,1097727999,US
+1097069312,1097131439,US
+1097131440,1097131447,HK
+1097131448,1097727999,US
1097728000,1097729151,CA
1097729152,1097729167,US
1097729168,1097730847,CA
1097730848,1097730855,US
-1097730856,1097730919,CA
-1097730920,1097730927,US
-1097730928,1097731447,CA
+1097730856,1097731447,CA
1097731448,1097731455,GB
1097731456,1097736191,CA
1097736192,1097768959,US
1097768960,1097777151,CA
-1097777152,1097798495,US
-1097798496,1097798527,CA
-1097798528,1097799167,US
-1097799168,1097799199,CA
-1097799200,1097799231,US
-1097799232,1097799423,CA
-1097799424,1097799679,US
-1097799680,1097799711,CA
-1097799712,1097799775,US
-1097799776,1097799871,CA
-1097799872,1097800959,US
+1097777152,1097800959,US
1097800960,1097800991,CY
1097800992,1097801183,US
1097801184,1097801215,DE
@@ -14206,12 +14873,17 @@
1101983232,1101983743,AN
1101983744,1102004223,US
1102004224,1102004479,IN
-1102004480,1102005503,US
+1102004480,1102004735,US
+1102004736,1102004991,IN
+1102004992,1102005247,US
+1102005248,1102005503,CA
1102005504,1102005759,PK
1102005760,1102005823,BE
1102005824,1102006271,US
1102006272,1102006527,CA
-1102006528,1102007599,US
+1102006528,1102007295,US
+1102007296,1102007551,PK
+1102007552,1102007599,US
1102007600,1102007615,AR
1102007616,1102007679,US
1102007680,1102007695,IN
@@ -14223,7 +14895,10 @@
1102008096,1102008103,CA
1102008104,1102008159,US
1102008160,1102008167,GB
-1102008168,1102008639,US
+1102008168,1102008223,US
+1102008224,1102008231,CA
+1102008232,1102008607,US
+1102008608,1102008639,CA
1102008640,1102008671,BE
1102008672,1102008735,US
1102008736,1102008767,BE
@@ -14233,8 +14908,7 @@
1102010624,1102010879,PK
1102010880,1102011647,US
1102011648,1102011663,VE
-1102011664,1102011679,GB
-1102011680,1102011743,US
+1102011664,1102011743,US
1102011744,1102011759,TR
1102011760,1102011855,US
1102011856,1102011871,CR
@@ -14246,13 +14920,19 @@
1102012976,1102012991,RU
1102012992,1102013167,US
1102013168,1102013183,VE
-1102013184,1102016255,US
+1102013184,1102014271,US
+1102014272,1102014335,IN
+1102014336,1102014399,CA
+1102014400,1102016255,US
1102016256,1102016287,AR
-1102016288,1102019583,US
+1102016288,1102016351,US
+1102016352,1102016383,MY
+1102016384,1102019583,US
1102019584,1102019711,IN
1102019712,1102389247,US
1102389248,1102393343,CA
-1102393344,1102446591,US
+1102393344,1102397439,US
+1102413824,1102446591,US
1102446592,1102448383,HN
1102448384,1102449151,US
1102449152,1102449407,SV
@@ -14442,7 +15122,7 @@
1107247104,1107275775,US
1107275776,1107279871,CA
1107279872,1107288063,US
-1107288064,1107296255,CA
+1107288064,1107292159,CA
1107296256,1107701759,US
1107701760,1107705855,CA
1107705856,1107800063,US
@@ -14620,8 +15300,7 @@
1109705824,1109705839,CD
1109705840,1109705855,US
1109705856,1109705983,CD
-1109705984,1109706239,HT
-1109706240,1109707007,US
+1109705984,1109707007,US
1109707008,1109707263,JM
1109707264,1109707519,US
1109707520,1109707775,MW
@@ -14746,7 +15425,9 @@
1110458848,1110458879,US
1110458880,1110458927,CA
1110458928,1110458943,US
-1110458944,1110459071,CA
+1110458944,1110459007,CA
+1110459008,1110459023,US
+1110459024,1110459071,CA
1110459072,1110459087,US
1110459088,1110459151,CA
1110459152,1110459167,US
@@ -14766,8 +15447,8 @@
1110460320,1110460383,US
1110460384,1110460447,CA
1110460448,1110460479,US
-1110460480,1110460511,CA
-1110460512,1110460671,US
+1110460480,1110460607,CA
+1110460608,1110460671,US
1110460672,1110460719,CA
1110460720,1110460743,US
1110460744,1110460775,CA
@@ -14832,16 +15513,15 @@
1110870816,1110870847,HK
1110870848,1110870919,US
1110870920,1110870927,JP
-1110870928,1110921215,US
-1110925312,1110929407,US
+1110870928,1110887423,US
+1110887424,1110887679,IE
+1110887680,1110929407,US
1110929408,1110933503,BM
1110933504,1111195647,US
1111195648,1111212031,CA
1111212032,1111228415,US
1111228416,1111244799,AR
-1111244800,1111472127,US
-1111472128,1111472383,AU
-1111472384,1111888905,US
+1111244800,1111888905,US
1111888906,1111888915,IN
1111888916,1111900223,US
1111900224,1111900287,NL
@@ -14923,9 +15603,7 @@
1114054656,1114062847,CA
1114062848,1114095615,US
1114095616,1114103807,CA
-1114103808,1114163967,US
-1114163968,1114164479,VI
-1114164480,1114170095,US
+1114103808,1114170095,US
1114170096,1114170111,CA
1114170112,1114505215,US
1114505216,1114507263,CA
@@ -14949,9 +15627,7 @@
1114533376,1114533887,ZA
1114533888,1114537983,AO
1114537984,1114550271,CA
-1114550272,1114623999,US
-1114624000,1114625023,NZ
-1114625024,1114627071,US
+1114550272,1114627071,US
1114627072,1114628095,NZ
1114628096,1114653951,US
1114653952,1114653983,MO
@@ -14992,9 +15668,7 @@
1114881344,1114881407,CY
1114881408,1114881471,US
1114881472,1114881535,CY
-1114881536,1114881743,US
-1114881744,1114881759,CA
-1114881760,1114930175,US
+1114881536,1114930175,US
1114930176,1114930303,GB
1114930304,1114966815,US
1114966816,1114966831,GB
@@ -15022,6 +15696,7 @@
1115117568,1115118591,HN
1115118592,1115119615,SV
1115119616,1115127807,US
+1115127808,1115131903,CA
1115131904,1115135999,US
1115136000,1115138671,CA
1115138672,1115138679,US
@@ -15077,9 +15752,7 @@
1115698432,1115698687,DO
1115698688,1115698783,US
1115698784,1115698791,CO
-1115698792,1115698943,US
-1115698944,1115698951,CA
-1115698952,1115698983,US
+1115698792,1115698983,US
1115698984,1115698991,CO
1115698992,1115699903,US
1115699904,1115699911,CA
@@ -15089,9 +15762,7 @@
1115700224,1115700479,DO
1115700480,1115700735,US
1115700736,1115700743,CA
-1115700744,1115700791,US
-1115700792,1115700799,CA
-1115700800,1115705343,US
+1115700744,1115705343,US
1115705344,1115709439,CA
1115709440,1115783167,US
1115783168,1115784599,CA
@@ -15361,8 +16032,8 @@
1117417280,1117417343,US
1117417344,1117418655,CA
1117418656,1117418671,US
-1117418672,1117419007,CA
-1117419008,1117419519,US
+1117418672,1117419263,CA
+1117419264,1117419519,US
1117419520,1117419775,CA
1117419776,1117420543,US
1117420544,1117421055,CA
@@ -15450,12 +16121,15 @@
1118031760,1118031799,US
1118031800,1118031871,CA
1118031872,1118126079,US
-1118126080,1118126591,CA
-1118126592,1118126847,US
+1118126080,1118126719,CA
+1118126720,1118126847,US
1118126848,1118127231,CA
1118127232,1118127359,US
1118127360,1118127615,CA
-1118127616,1118128383,US
+1118127616,1118128191,US
+1118128192,1118128255,MY
+1118128256,1118128319,CA
+1118128320,1118128383,MY
1118128384,1118128639,CA
1118128640,1118129151,US
1118129152,1118129663,CA
@@ -15481,12 +16155,17 @@
1118134912,1118134975,CA
1118134976,1118135007,US
1118135008,1118135039,IN
-1118135040,1118135647,US
+1118135040,1118135567,US
+1118135568,1118135583,CA
+1118135584,1118135615,US
+1118135616,1118135631,TZ
+1118135632,1118135647,US
1118135648,1118135663,CA
-1118135664,1118135791,US
-1118135792,1118135807,ID
+1118135664,1118135807,US
1118135808,1118136191,CA
-1118136192,1118136831,US
+1118136192,1118136319,US
+1118136320,1118136351,CA
+1118136352,1118136831,US
1118136832,1118136863,IN
1118136864,1118136895,BE
1118136896,1118136927,US
@@ -15499,15 +16178,24 @@
1118137280,1118137311,FR
1118137312,1118138559,US
1118138560,1118138591,AU
-1118138592,1118139903,US
+1118138592,1118138623,FR
+1118138624,1118138879,US
+1118138880,1118139135,CA
+1118139136,1118139903,US
1118139904,1118140415,CA
-1118140416,1118140735,US
+1118140416,1118140703,US
+1118140704,1118140735,IN
1118140736,1118140767,AU
-1118140768,1118141183,US
+1118140768,1118140831,US
+1118140832,1118140895,VE
+1118140896,1118141183,US
1118141184,1118141439,CA
1118141440,1118141695,US
1118141696,1118141951,CA
-1118141952,1118151215,US
+1118141952,1118141967,CN
+1118141968,1118142063,US
+1118142064,1118142079,IN
+1118142080,1118151215,US
1118151216,1118151231,TT
1118151232,1118151391,US
1118151392,1118151407,PR
@@ -15607,7 +16295,8 @@
1118476896,1118477535,CA
1118477536,1118477543,US
1118477544,1118478335,CA
-1118478336,1118789783,US
+1118478336,1118502911,US
+1118568448,1118789783,US
1118789784,1118789791,BB
1118789792,1118790351,US
1118790352,1118790367,GB
@@ -15615,12 +16304,10 @@
1118791552,1118791567,LU
1118791568,1118791599,US
1118791600,1118791615,ES
-1118791616,1118792703,US
-1118792704,1118792831,JM
-1118792832,1118792959,US
-1118792960,1118793087,JM
-1118793088,1118793343,US
-1118793344,1118793727,JM
+1118791616,1118792815,US
+1118792816,1118792831,DO
+1118792832,1118793471,US
+1118793472,1118793727,CO
1118793728,1118793823,US
1118793824,1118793839,CA
1118793840,1118793935,US
@@ -16027,8 +16714,7 @@
1118992736,1118992743,SA
1118992744,1118992767,A2
1118992768,1118992839,US
-1118992840,1118993919,A2
-1118993920,1118994431,GY
+1118992840,1118994431,A2
1118994432,1119023735,US
1119023736,1119023743,UY
1119023744,1119109119,US
@@ -16150,16 +16836,13 @@
1119469568,1119477759,CA
1119477760,1119486623,US
1119486624,1119486631,AU
-1119486632,1119490015,US
-1119490016,1119490047,IE
-1119490048,1119490495,US
+1119486632,1119490495,US
1119490496,1119490527,GI
1119490528,1119502335,US
1119502336,1119510527,CA
1119510528,1119558143,US
1119558144,1119558655,PR
1119558656,1119567871,US
-1119567872,1119571967,CA
1119571968,1119580159,US
1119580160,1119584255,CA
1119584256,1119999935,US
@@ -16218,18 +16901,22 @@
1120299264,1120299519,US
1120299520,1120300799,PK
1120300800,1120301055,US
-1120301056,1120306175,CA
-1120306176,1120306943,PH
+1120301056,1120304895,CA
+1120304896,1120305151,US
+1120305152,1120306687,CA
+1120306688,1120306943,PH
1120306944,1120307199,US
1120307200,1120307967,EC
1120307968,1120308223,PH
-1120308224,1120309247,HT
-1120309248,1120310015,CA
+1120308224,1120309247,CA
+1120309248,1120309503,US
+1120309504,1120309759,CA
+1120309760,1120310015,US
1120310016,1120310783,PH
1120310784,1120311807,CA
1120311808,1120312063,US
1120312064,1120312447,PH
-1120312448,1120312575,US
+1120312448,1120312575,CA
1120312576,1120312831,PH
1120312832,1120313343,CA
1120313344,1120313599,US
@@ -16239,7 +16926,9 @@
1120321536,1120346111,US
1120346112,1120350207,CA
1120350208,1120370687,US
-1120370688,1120371511,CA
+1120370688,1120371487,CA
+1120371488,1120371503,US
+1120371504,1120371511,CA
1120371512,1120371519,US
1120371520,1120371647,CA
1120371648,1120371651,US
@@ -16249,7 +16938,9 @@
1120372080,1120372223,US
1120372224,1120372479,CA
1120372480,1120372735,US
-1120372736,1120374047,CA
+1120372736,1120373423,CA
+1120373424,1120373503,US
+1120373504,1120374047,CA
1120374048,1120374063,US
1120374064,1120374271,CA
1120374272,1120374303,US
@@ -16295,7 +16986,9 @@
1120378920,1120378927,US
1120378928,1120379039,CA
1120379040,1120379071,PA
-1120379072,1120380027,CA
+1120379072,1120379167,CA
+1120379168,1120379183,US
+1120379184,1120380027,CA
1120380028,1120380031,US
1120380032,1120380095,CA
1120380096,1120380127,US
@@ -16319,8 +17012,8 @@
1120381120,1120382231,CA
1120382232,1120382239,US
1120382240,1120382271,CA
-1120382272,1120382335,US
-1120382336,1120382431,CA
+1120382272,1120382367,US
+1120382368,1120382431,CA
1120382432,1120382463,US
1120382464,1120382975,CA
1120382976,1120383263,US
@@ -16342,14 +17035,17 @@
1120385144,1120385151,US
1120385152,1120385183,GB
1120385184,1120385535,CA
-1120385536,1120485759,US
+1120385536,1120386559,US
+1120386560,1120386815,CA
+1120386816,1120485759,US
1120485760,1120485887,CA
1120485888,1120486079,US
1120486080,1120486143,IN
1120486144,1120486399,US
1120486400,1120486911,CA
1120486912,1120487039,US
-1120487040,1120487167,CA
+1120487040,1120487103,IN
+1120487104,1120487167,CA
1120487168,1120487199,US
1120487200,1120487231,CA
1120487232,1120487359,US
@@ -16357,9 +17053,7 @@
1120487392,1120487423,BE
1120487424,1120487679,CA
1120487680,1120487935,US
-1120487936,1120488191,CA
-1120488192,1120488447,US
-1120488448,1120488703,CA
+1120487936,1120488703,CA
1120488704,1120488767,US
1120488768,1120488799,VE
1120488800,1120488831,IL
@@ -16371,8 +17065,7 @@
1120489344,1120489471,US
1120489472,1120489727,CA
1120489728,1120489983,US
-1120489984,1120490111,SG
-1120490112,1120490751,CA
+1120489984,1120490751,CA
1120490752,1120490783,GB
1120490784,1120491007,US
1120491008,1120491775,CA
@@ -16389,7 +17082,9 @@
1120493824,1120494079,CA
1120494080,1120494335,US
1120494336,1120494591,CA
-1120494592,1120495359,US
+1120494592,1120494975,US
+1120494976,1120495039,CA
+1120495040,1120495359,US
1120495360,1120495615,CA
1120495616,1120495743,US
1120495744,1120495871,SG
@@ -16399,20 +17094,21 @@
1120496288,1120496385,US
1120496386,1120496638,CA
1120496639,1120496639,US
-1120496640,1120497023,CA
-1120497024,1120497151,IN
+1120496640,1120497151,CA
1120497152,1120497183,BE
1120497184,1120497215,US
1120497216,1120497247,BE
-1120497248,1120497375,US
+1120497248,1120497311,US
+1120497312,1120497343,IN
+1120497344,1120497375,US
1120497376,1120497663,CA
1120497664,1120497791,US
1120497792,1120497919,AU
1120497920,1120497983,US
1120497984,1120498013,BE
1120498014,1120498143,US
-1120498144,1120498175,CA
-1120498176,1120498943,US
+1120498144,1120498303,CA
+1120498304,1120498943,US
1120498944,1120499199,CA
1120499200,1120499487,US
1120499488,1120499519,CA
@@ -16434,9 +17130,7 @@
1120568640,1120568671,CA
1120568672,1120575167,US
1120575168,1120575199,CA
-1120575200,1120616807,US
-1120616808,1120616815,CA
-1120616816,1120641023,US
+1120575200,1120641023,US
1120641024,1120657407,CA
1120657408,1120735487,US
1120735488,1120735743,BB
@@ -16462,7 +17156,9 @@
1120744704,1120854015,US
1120854016,1120862207,CA
1120862208,1120870399,US
-1120874496,1120874519,A2
+1120874496,1120874503,A2
+1120874504,1120874511,US
+1120874512,1120874519,A2
1120874520,1120874527,US
1120874528,1120874631,A2
1120874632,1120874639,US
@@ -16495,7 +17191,9 @@
1120876800,1120878359,US
1120878360,1120878591,A2
1120878592,1120886783,US
-1120886784,1120894975,CA
+1120886784,1120888127,CA
+1120888128,1120888159,US
+1120888160,1120894975,CA
1120894976,1120911359,US
1120911360,1120914415,CA
1120914416,1120914431,AT
@@ -16534,7 +17232,7 @@
1121247504,1121247511,AW
1121247512,1121247519,VG
1121247520,1121247527,BZ
-1121247528,1121247535,GI
+1121247528,1121247535,CA
1121247536,1121247543,BZ
1121247544,1121247551,CA
1121247552,1121247559,VG
@@ -16542,7 +17240,7 @@
1121247568,1121247583,PA
1121247584,1121247591,CY
1121247592,1121247615,CA
-1121247616,1121247631,BZ
+1121247616,1121247631,PA
1121247632,1121247639,AW
1121247640,1121247647,VG
1121247648,1121247663,US
@@ -16581,8 +17279,7 @@
1121248448,1121248495,BZ
1121248496,1121248783,CA
1121248784,1121248799,VG
-1121248800,1121248831,GI
-1121248832,1121248863,CA
+1121248800,1121248863,CA
1121248864,1121248879,VG
1121248880,1121248911,CA
1121248912,1121248919,BZ
@@ -16590,8 +17287,7 @@
1121248960,1121248983,CA
1121248984,1121248991,AW
1121248992,1121249023,VG
-1121249024,1121249279,CA
-1121249280,1121249375,SE
+1121249024,1121249375,CA
1121249376,1121249383,VG
1121249384,1121249407,CA
1121249408,1121249439,AG
@@ -16619,7 +17315,9 @@
1121250208,1121250239,CA
1121250240,1121250303,GB
1121250304,1121250815,BZ
-1121250816,1121250879,AG
+1121250816,1121250831,AG
+1121250832,1121250839,BZ
+1121250840,1121250879,AG
1121250880,1121250911,CA
1121250912,1121250927,VG
1121250928,1121250935,CA
@@ -16630,15 +17328,14 @@
1121251048,1121251055,AW
1121251056,1121251071,CA
1121251072,1121251079,GB
-1121251080,1121251103,CY
-1121251104,1121251135,CA
+1121251080,1121251087,CY
+1121251088,1121251135,CA
1121251136,1121251167,AG
1121251168,1121251199,VG
1121251200,1121251263,AW
1121251264,1121251271,CA
1121251272,1121251279,KN
-1121251280,1121251287,CA
-1121251288,1121251295,MU
+1121251280,1121251295,CA
1121251296,1121251311,IM
1121251312,1121251583,CA
1121251584,1121251591,BZ
@@ -17014,11 +17711,7 @@
1122093808,1122093815,HK
1122093816,1122103471,US
1122103472,1122103479,BE
-1122103480,1122108671,US
-1122108672,1122108735,GR
-1122108736,1122125978,US
-1122125979,1122125988,PH
-1122125989,1122125996,US
+1122103480,1122125996,US
1122125997,1122126004,GB
1122126005,1122126239,US
1122126240,1122126249,GB
@@ -17033,16 +17726,14 @@
1122197608,1122197623,US
1122197624,1122197631,FR
1122197632,1122197695,US
-1122197696,1122197759,GB
+1122197696,1122197727,GB
+1122197728,1122197735,US
+1122197736,1122197759,GB
1122197760,1122197767,US
1122197768,1122197775,FR
1122197776,1122197823,US
1122197824,1122197831,GB
-1122197832,1122197839,US
-1122197840,1122197855,GB
-1122197856,1122197887,US
-1122197888,1122198015,GB
-1122198016,1122203135,US
+1122197832,1122203135,US
1122203136,1122203391,GB
1122203392,1122320959,US
1122320960,1122320995,PT
@@ -17065,13 +17756,9 @@
1122480168,1122480207,US
1122480208,1122480223,GB
1122480224,1122480231,PL
-1122480232,1122480343,US
-1122480344,1122480351,PR
-1122480352,1122480415,US
+1122480232,1122480415,US
1122480416,1122480423,CL
-1122480424,1122480447,US
-1122480448,1122480455,PR
-1122480456,1122480479,US
+1122480424,1122480479,US
1122480480,1122480487,CA
1122480488,1122493055,US
1122493056,1122493183,ES
@@ -17082,11 +17769,11 @@
1122496000,1122497407,US
1122497408,1122497471,SV
1122497472,1122497535,US
-1122497536,1122498303,PR
-1122498304,1122498559,US
+1122497536,1122498047,PR
+1122498048,1122498559,US
1122498560,1122498815,PR
-1122498816,1122499327,US
-1122499328,1122500095,PR
+1122498816,1122499583,US
+1122499584,1122500095,PR
1122500096,1122506751,US
1122506752,1122507007,IN
1122507008,1122525855,US
@@ -17095,13 +17782,9 @@
1122526097,1122526111,RU
1122526112,1122526454,US
1122526455,1122526462,RU
-1122526463,1122526517,US
-1122526518,1122526541,HK
-1122526542,1122526876,US
+1122526463,1122526876,US
1122526877,1122526888,RU
-1122526889,1122526925,US
-1122526926,1122526939,RU
-1122526940,1122528183,US
+1122526889,1122528183,US
1122528184,1122528254,RU
1122528255,1122528603,US
1122528604,1122528613,ES
@@ -17138,15 +17821,11 @@
1123582272,1123582399,US
1123582400,1123582431,DE
1123582432,1123582463,CA
-1123582464,1123583327,US
-1123583328,1123583359,CA
-1123583360,1123583455,US
+1123582464,1123583455,US
1123583456,1123583519,CY
1123583520,1123584351,US
1123584352,1123584383,DE
-1123584384,1123584703,US
-1123584704,1123584735,CA
-1123584736,1123588063,US
+1123584384,1123588063,US
1123588064,1123588095,CY
1123588096,1123590143,US
1123590144,1123598335,VI
@@ -17163,15 +17842,7 @@
1123801088,1123801343,RU
1123801344,1123848191,US
1123848192,1123852287,CA
-1123852288,1123862080,US
-1123862081,1123862270,RU
-1123862271,1123862454,US
-1123862455,1123862520,RU
-1123862521,1123862592,US
-1123862593,1123862782,RU
-1123862783,1123862880,US
-1123862881,1123862888,RU
-1123862889,1123870063,US
+1123852288,1123870063,US
1123870064,1123870071,GB
1123870072,1123870295,US
1123870296,1123870303,HK
@@ -17234,9 +17905,7 @@
1125091744,1125091759,US
1125091760,1125091775,UY
1125091776,1125091839,CA
-1125091840,1125093375,US
-1125093376,1125093407,TH
-1125093408,1125093471,US
+1125091840,1125093471,US
1125093472,1125093503,IL
1125093504,1125093567,SK
1125093568,1125093631,AU
@@ -17244,8 +17913,7 @@
1125094464,1125094527,BR
1125094528,1125094655,US
1125094656,1125094671,GB
-1125094672,1125094687,SK
-1125094688,1125094783,US
+1125094672,1125094783,US
1125094784,1125094799,GB
1125094800,1125094847,CA
1125094848,1125094911,BR
@@ -17354,11 +18022,110 @@
1125120848,1125120863,US
1125120864,1125120895,GB
1125120896,1125121023,RO
-1125121024,1125474303,US
+1125121024,1125454111,US
+1125454112,1125454119,ES
+1125454120,1125454143,US
+1125454144,1125454151,GB
+1125454152,1125454271,US
+1125454272,1125454279,DE
+1125454280,1125454303,US
+1125454304,1125454323,NO
+1125454324,1125454327,SG
+1125454328,1125454343,US
+1125454344,1125454351,NO
+1125454352,1125454371,US
+1125454372,1125454375,ES
+1125454376,1125454383,US
+1125454384,1125454395,NO
+1125454396,1125454411,US
+1125454412,1125454423,NO
+1125454424,1125454435,ES
+1125454436,1125454439,NO
+1125454440,1125454447,ES
+1125454448,1125454451,NO
+1125454452,1125454459,US
+1125454460,1125454463,NO
+1125454464,1125454467,ES
+1125454468,1125454471,NO
+1125454472,1125454479,ES
+1125454480,1125454483,NO
+1125454484,1125454487,ES
+1125454488,1125454495,NO
+1125454496,1125454499,CA
+1125454500,1125454503,ES
+1125454504,1125454507,US
+1125454508,1125454511,ES
+1125454512,1125454527,NO
+1125454528,1125454543,US
+1125454544,1125454555,ES
+1125454556,1125454587,US
+1125454588,1125454591,CA
+1125454592,1125455359,US
+1125455360,1125455363,CA
+1125455364,1125455367,US
+1125455368,1125455371,GB
+1125455372,1125455395,US
+1125455396,1125455399,NO
+1125455400,1125455423,US
+1125455424,1125455427,ES
+1125455428,1125455431,GB
+1125455432,1125455435,US
+1125455436,1125455439,ES
+1125455440,1125455443,CA
+1125455444,1125455447,US
+1125455448,1125455451,NO
+1125455452,1125455475,US
+1125455476,1125455479,NO
+1125455480,1125455491,US
+1125455492,1125455495,GB
+1125455496,1125455499,CA
+1125455500,1125455507,US
+1125455508,1125455515,ES
+1125455516,1125455519,CA
+1125455520,1125455523,ES
+1125455524,1125455527,US
+1125455528,1125455531,ES
+1125455532,1125455535,NO
+1125455536,1125455543,US
+1125455544,1125455547,ES
+1125455548,1125455551,VG
+1125455552,1125455555,ES
+1125455556,1125455559,US
+1125455560,1125455563,NZ
+1125455564,1125455567,ES
+1125455568,1125455571,US
+1125455572,1125455575,NO
+1125455576,1125455579,AN
+1125455580,1125456131,US
+1125456132,1125456135,NO
+1125456136,1125456151,US
+1125456152,1125456155,NL
+1125456156,1125456163,US
+1125456164,1125456167,NO
+1125456168,1125456175,US
+1125456176,1125456179,NO
+1125456180,1125456191,US
+1125456192,1125456195,GB
+1125456196,1125456199,NO
+1125456200,1125456203,AN
+1125456204,1125456207,US
+1125456208,1125456211,SG
+1125456212,1125456231,US
+1125456232,1125456239,ES
+1125456240,1125456247,GB
+1125456248,1125456259,AN
+1125456260,1125456263,ES
+1125456264,1125456407,US
+1125456408,1125456411,AN
+1125456412,1125456415,US
+1125456416,1125456419,AN
+1125456420,1125474303,US
1125474304,1125478399,CA
1125478400,1125479199,US
1125479200,1125479231,BR
-1125479232,1125498879,US
+1125479232,1125493127,US
+1125493128,1125493135,CA
+1125493136,1125498879,US
1125498880,1125508095,CA
1125508096,1125508351,PA
1125508352,1125514495,CA
@@ -17382,9 +18149,17 @@
1125540704,1125540711,US
1125540712,1125540927,CA
1125540928,1125540959,US
-1125540960,1125543935,CA
+1125540960,1125541151,CA
+1125541152,1125541159,CN
+1125541160,1125541183,CA
+1125541184,1125541215,KY
+1125541216,1125543935,CA
1125543936,1125545983,US
-1125548032,1125552127,CA
+1125548032,1125548291,CA
+1125548292,1125548351,US
+1125548352,1125550079,CA
+1125550080,1125550335,US
+1125550336,1125552127,CA
1125552128,1125572607,US
1125572608,1125576703,CA
1125576704,1125613567,US
@@ -17411,15 +18186,12 @@
1126682720,1126682727,PR
1126682728,1126682823,US
1126682824,1126682831,PR
-1126682832,1126907535,US
-1126907536,1126907543,ES
-1126907544,1126924287,US
+1126682832,1126924287,US
1126924288,1126928383,CA
1126928384,1126948863,US
1126948864,1126949375,CA
1126949376,1126949503,GB
-1126949504,1126949551,CA
-1126949552,1126949559,GB
+1126949504,1126949559,CA
1126949560,1126949567,BZ
1126949568,1126949583,CA
1126949584,1126949591,LB
@@ -17428,35 +18200,21 @@
1126949616,1126949631,LB
1126949632,1126949695,CA
1126949696,1126949759,PK
-1126949760,1126949823,CA
-1126949824,1126949855,US
-1126949856,1126950191,CA
+1126949760,1126950191,CA
1126950192,1126950199,ES
1126950200,1126950207,HR
-1126950208,1126950303,CA
-1126950304,1126950335,US
-1126950336,1126950367,CA
-1126950368,1126950399,US
-1126950400,1126950415,CA
+1126950208,1126950415,CA
1126950416,1126950423,PK
1126950424,1126950431,RU
1126950432,1126950463,CA
1126950464,1126950495,IT
-1126950496,1126950527,US
-1126950528,1126950559,CA
-1126950560,1126950591,US
-1126950592,1126950599,CA
+1126950496,1126950599,CA
1126950600,1126950607,CN
1126950608,1126950623,CA
1126950624,1126950655,FR
1126950656,1126950783,CA
1126950784,1126950847,MY
-1126950848,1126950911,US
-1126950912,1126951039,CA
-1126951040,1126951071,US
-1126951072,1126951103,CA
-1126951104,1126951135,US
-1126951136,1126951775,CA
+1126950848,1126951775,CA
1126951776,1126951783,PH
1126951784,1126951967,CA
1126951968,1126951975,KP
@@ -17470,29 +18228,13 @@
1126952264,1126952271,PH
1126952272,1126952447,CA
1126952448,1126952511,AE
-1126952512,1126952543,US
-1126952544,1126952559,CA
+1126952512,1126952559,CA
1126952560,1126952567,TH
-1126952568,1126952703,CA
-1126952704,1126952767,CY
-1126952768,1126952895,CA
+1126952568,1126952895,CA
1126952896,1126952959,CY
1126952960,1127677951,US
1127677952,1127694335,CA
-1127694336,1127874559,US
-1127875328,1127875839,US
-1127875840,1127876095,CA
-1127876608,1127876863,US
-1127877120,1127877375,US
-1127877376,1127877631,CA
-1127878144,1127878399,US
-1127878400,1127878911,CA
-1127878912,1127879167,US
-1127879680,1127879935,CA
-1127879936,1127880191,US
-1127880448,1127880703,US
-1127880704,1127882751,CA
-1127882752,1127923711,US
+1127694336,1127923711,US
1127923712,1127931903,CA
1127931904,1127976191,US
1127976192,1127976223,IL
@@ -17542,7 +18284,9 @@
1132947432,1132947439,CA
1132947440,1133785375,US
1133785376,1133785383,NE
-1133785384,1133785471,US
+1133785384,1133785391,US
+1133785392,1133785407,GB
+1133785408,1133785471,US
1133785472,1133785503,GB
1133785504,1133785567,US
1133785568,1133785599,BE
@@ -18280,13 +19024,9 @@
1136721920,1136787455,CA
1136787456,1137090815,US
1137090816,1137091327,NZ
-1137091328,1137134083,US
-1137134084,1137134099,CA
-1137134100,1137134283,US
-1137134284,1137134331,CA
-1137134332,1137189135,US
+1137091328,1137189135,US
1137189136,1137189151,IE
-1137189152,1137189183,GB
+1137189152,1137189183,US
1137189184,1137189247,IE
1137189248,1137189255,GB
1137189256,1137189263,US
@@ -18299,9 +19039,7 @@
1137278976,1137283071,CA
1137283072,1137287167,US
1137287168,1137295359,CA
-1137295360,1137337599,US
-1137337600,1137337855,CA
-1137337856,1137369087,US
+1137295360,1137369087,US
1137369088,1137369519,CA
1137369520,1137369535,US
1137369536,1137370111,CA
@@ -18631,8 +19369,7 @@
1138164008,1138164015,FR
1138164016,1138164127,CA
1138164128,1138164151,FR
-1138164152,1138164159,GB
-1138164160,1138164175,CA
+1138164152,1138164175,CA
1138164176,1138164183,SK
1138164184,1138164191,PH
1138164192,1138164199,PK
@@ -18643,8 +19380,7 @@
1138164256,1138164263,LB
1138164264,1138164271,FR
1138164272,1138164279,PH
-1138164280,1138164311,CA
-1138164312,1138164327,GB
+1138164280,1138164327,CA
1138164328,1138164335,PA
1138164336,1138164367,CA
1138164368,1138164375,PH
@@ -18661,14 +19397,11 @@
1138164832,1138164839,PH
1138164840,1138164863,CA
1138164864,1138165247,US
-1138165248,1138165255,GB
-1138165256,1138165311,CA
+1138165248,1138165311,CA
1138165312,1138165319,US
1138165320,1138165431,CA
1138165432,1138165439,LB
-1138165440,1138165463,CA
-1138165464,1138165471,GB
-1138165472,1138165487,CA
+1138165440,1138165487,CA
1138165488,1138165503,SK
1138165504,1138165807,CA
1138165808,1138165815,FR
@@ -18734,10 +19467,13 @@
1138212864,1138216959,CA
1138216960,1138271087,US
1138271088,1138271103,TN
-1138271104,1138417663,US
+1138271104,1138401279,US
+1138409472,1138417663,US
1138417664,1138417695,CA
1138417696,1138417727,DE
-1138417728,1138450959,US
+1138417728,1138421759,US
+1138421760,1138421791,DE
+1138421792,1138450959,US
1138450960,1138450967,JM
1138450968,1138450991,US
1138450992,1138450999,MX
@@ -18764,8 +19500,7 @@
1138452016,1138452047,US
1138452048,1138452055,AU
1138452056,1138452063,GB
-1138452064,1138452255,US
-1138452256,1138452263,GB
+1138452064,1138452263,US
1138452264,1138452271,IN
1138452272,1138452287,US
1138452288,1138452295,GR
@@ -18785,7 +19520,9 @@
1138454016,1138454271,RU
1138454272,1138454591,US
1138454592,1138454599,CA
-1138454600,1138499583,US
+1138454600,1138480127,US
+1138480128,1138482687,AU
+1138482688,1138499583,US
1138499584,1138503679,CA
1138503680,1138508031,US
1138508032,1138508095,GB
@@ -18814,35 +19551,23 @@
1138512672,1138512895,US
1138512896,1138512927,ID
1138512928,1138548735,US
-1138548736,1138549260,CA
-1138549261,1138549347,HK
-1138549348,1138549503,CA
-1138549504,1138549631,PL
-1138549632,1138550015,CA
-1138550016,1138552575,US
-1138552576,1138556927,CA
+1138548736,1138556927,CA
1138556928,1138593791,US
1138593792,1138597887,CA
1138597888,1138600447,US
1138600448,1138600703,BE
1138600704,1138615299,US
1138615300,1138615323,IT
-1138615324,1138655241,US
-1138655242,1138655316,CA
-1138655317,1138655328,US
-1138655329,1138655336,CA
-1138655337,1138655374,US
+1138615324,1138655245,US
+1138655246,1138655316,CA
+1138655317,1138655374,US
1138655375,1138655382,CA
-1138655383,1138655422,US
-1138655423,1138655430,RU
-1138655431,1138655446,US
+1138655383,1138655446,US
1138655447,1138655454,CA
1138655455,1138655458,US
1138655459,1138655486,CA
1138655487,1138655503,US
-1138655504,1138655513,MX
-1138655514,1138655519,US
-1138655520,1138655521,MX
+1138655504,1138655521,MX
1138655522,1138655609,US
1138655610,1138655617,MX
1138655618,1138655695,US
@@ -18851,84 +19576,39 @@
1138655716,1138655723,GB
1138655724,1138655841,US
1138655842,1138655849,CN
-1138655850,1138655857,US
-1138655858,1138655865,CN
-1138655866,1138655899,US
+1138655850,1138655899,US
1138655900,1138655911,MX
-1138655912,1138656021,US
-1138656022,1138656029,TW
-1138656030,1138656077,US
+1138655912,1138656077,US
1138656078,1138656093,MX
-1138656094,1138656097,US
-1138656098,1138656113,GB
-1138656114,1138656121,US
-1138656122,1138656129,GB
-1138656130,1138656141,US
+1138656094,1138656141,US
1138656142,1138656173,GB
1138656174,1138656190,US
1138656191,1138656198,CH
1138656199,1138656206,GB
1138656207,1138656222,US
1138656223,1138656230,EG
-1138656231,1138656301,US
-1138656302,1138656309,MO
-1138656310,1138656330,US
-1138656331,1138656338,TR
-1138656339,1138656398,US
-1138656399,1138656406,MO
-1138656407,1138656407,GB
-1138656408,1138656413,US
-1138656414,1138656415,GB
-1138656416,1138656521,US
-1138656522,1138656529,EG
-1138656530,1138656661,US
+1138656231,1138656661,US
1138656662,1138656669,MA
1138656670,1138656745,US
1138656746,1138656753,AE
-1138656754,1138656777,US
-1138656778,1138656793,UY
-1138656794,1138656933,US
-1138656934,1138656941,UY
-1138656942,1138656973,US
-1138656974,1138656981,UY
-1138656982,1138656997,US
-1138656998,1138657005,UY
-1138657006,1138657041,US
-1138657042,1138657056,SA
-1138657057,1138657123,US
+1138656754,1138657123,US
1138657124,1138657131,EG
-1138657132,1138657159,US
-1138657160,1138657173,MO
+1138657132,1138657173,US
1138657174,1138657181,EG
-1138657182,1138657193,US
-1138657194,1138657195,AE
-1138657196,1138657197,US
-1138657198,1138657199,EG
-1138657200,1138657201,AE
-1138657202,1138657205,EG
+1138657182,1138657197,US
+1138657198,1138657205,EG
1138657206,1138657206,US
1138657207,1138657214,EG
1138657215,1138657222,IN
1138657223,1138657235,US
1138657236,1138657244,MA
-1138657245,1138657346,US
-1138657347,1138657354,MO
-1138657355,1138657504,US
+1138657245,1138657324,US
+1138657325,1138657332,LK
+1138657333,1138657504,US
1138657505,1138657520,EG
-1138657521,1138657569,US
-1138657570,1138657577,UY
-1138657578,1138657597,US
-1138657598,1138657605,UY
-1138657606,1138657671,US
-1138657672,1138657679,UY
-1138657680,1138657681,US
-1138657682,1138657691,UY
-1138657692,1138657707,US
-1138657708,1138657732,UY
-1138657733,1138657748,US
+1138657521,1138657748,US
1138657749,1138657780,GB
-1138657781,1138657790,UY
-1138657791,1138658057,US
+1138657781,1138658057,US
1138658058,1138658123,GB
1138658124,1138658175,US
1138658176,1138658302,GB
@@ -18937,35 +19617,30 @@
1138658497,1138658497,US
1138658498,1138658525,PK
1138658526,1138659081,US
-1138659082,1138659211,ES
-1138659212,1138659369,US
+1138659082,1138659207,ES
+1138659208,1138659369,US
1138659370,1138659401,GB
1138659402,1138659465,US
1138659466,1138659497,GB
1138659498,1138659593,US
1138659594,1138659609,LK
1138659610,1138659642,GB
-1138659643,1138659650,US
-1138659651,1138659660,UY
-1138659661,1138659673,US
+1138659643,1138659673,US
1138659674,1138659681,MA
1138659682,1138659705,US
1138659706,1138659713,CA
-1138659714,1138659721,UY
-1138659722,1138659723,US
+1138659714,1138659723,US
1138659724,1138659731,ID
1138659732,1138659789,US
1138659790,1138659797,ID
-1138659798,1138659805,UY
+1138659798,1138659805,US
1138659806,1138659813,ID
-1138659814,1138659823,UY
+1138659814,1138659823,US
1138659824,1138659831,ID
1138659832,1138659849,US
1138659850,1138659857,MA
1138659858,1138659889,GB
-1138659890,1138659903,US
-1138659904,1138659911,CA
-1138659912,1138659922,US
+1138659890,1138659922,US
1138659923,1138659930,LK
1138659931,1138659983,US
1138659984,1138659999,EG
@@ -18991,9 +19666,7 @@
1138660362,1138660483,EG
1138660484,1138660499,US
1138660500,1138660507,AE
-1138660508,1138660563,US
-1138660564,1138660571,GB
-1138660572,1138660617,US
+1138660508,1138660617,US
1138660618,1138660625,AE
1138660626,1138660633,EG
1138660634,1138660665,US
@@ -19001,13 +19674,11 @@
1138660674,1138660694,US
1138660695,1138660726,GB
1138660727,1138660734,EG
-1138660735,1138660778,US
-1138660779,1138660786,MY
-1138660787,1138660805,US
+1138660735,1138660805,US
1138660806,1138660821,EG
1138660822,1138660873,US
1138660874,1138660881,EG
-1138660882,1138660889,MA
+1138660882,1138660889,US
1138660890,1138660897,EG
1138660898,1138660921,US
1138660922,1138660929,EG
@@ -19024,14 +19695,9 @@
1138661056,1138661063,EG
1138661064,1138661169,US
1138661170,1138661177,LK
-1138661178,1138661185,US
-1138661186,1138661193,UY
-1138661194,1138661201,US
+1138661178,1138661201,US
1138661202,1138661209,MA
-1138661210,1138661217,UY
-1138661218,1138661249,US
-1138661250,1138661257,UY
-1138661258,1138661265,US
+1138661210,1138661265,US
1138661266,1138661281,EG
1138661282,1138661299,US
1138661300,1138661307,GB
@@ -19059,9 +19725,7 @@
1138661914,1138661954,EG
1138661955,1138661985,US
1138661986,1138661993,EG
-1138661994,1138662017,US
-1138662018,1138662025,EG
-1138662026,1138662057,US
+1138661994,1138662057,US
1138662058,1138662107,EG
1138662108,1138662169,US
1138662170,1138662233,EG
@@ -19081,8 +19745,8 @@
1138662802,1138662841,US
1138662842,1138662849,GB
1138662850,1138662966,US
-1138662967,1138662974,EG
-1138662975,1138663037,US
+1138662967,1138662982,EG
+1138662983,1138663037,US
1138663038,1138663166,GB
1138663167,1138712575,US
1138712576,1138713583,CA
@@ -19110,15 +19774,11 @@
1138819072,1138851839,CA
1138851840,1138851847,US
1138851848,1138851855,IN
-1138851856,1138865562,US
-1138865563,1138865566,IN
-1138865567,1138865578,US
+1138851856,1138865578,US
1138865579,1138865586,IN
1138865587,1138874252,US
1138874253,1138874264,UY
-1138874265,1138879999,US
-1138880000,1138880511,CA
-1138880512,1138882331,US
+1138874265,1138882331,US
1138882332,1138882339,GB
1138882340,1138882445,US
1138882446,1138882453,GB
@@ -19126,16 +19786,30 @@
1138917376,1138937855,CA
1138937856,1138941951,US
1138941952,1138950143,CA
-1138950144,1139120127,US
-1139120128,1139124223,NZ
-1139124224,1139146751,US
+1138950144,1139146751,US
1139146752,1139154943,GT
1139154944,1139167231,JM
1139167232,1139179519,US
-1139179520,1139195903,CA
-1139195904,1139204095,US
-1139212288,1139261439,US
-1139261440,1139269631,CA
+1139179520,1139188223,CA
+1139188224,1139188479,GB
+1139188480,1139188735,CA
+1139188736,1139188991,GB
+1139188992,1139189503,US
+1139189504,1139189759,CA
+1139189760,1139190015,US
+1139190016,1139191551,CA
+1139191552,1139191807,GB
+1139191808,1139192063,CA
+1139192064,1139192575,US
+1139192576,1139192831,GB
+1139192832,1139193215,US
+1139193216,1139193599,CA
+1139193600,1139195135,US
+1139195136,1139195391,GB
+1139195392,1139195775,US
+1139195776,1139195903,CA
+1139195904,1139265535,US
+1139265536,1139269631,CA
1139269632,1142187775,US
1142187776,1142187783,PR
1142187784,1142191847,US
@@ -19164,11 +19838,38 @@
1145261056,1145261119,IN
1145261120,1145261311,US
1145261312,1145261375,IN
-1145261376,1145262079,US
-1145262080,1145266175,CA
-1145266176,1145307135,US
+1145261376,1145307135,US
1145307136,1145311231,CA
-1145311232,1145376767,US
+1145311232,1145315559,US
+1145315560,1145315567,GB
+1145315568,1145331711,US
+1145331712,1145331967,DK
+1145331968,1145333031,US
+1145333032,1145333039,IT
+1145333040,1145333239,US
+1145333240,1145333247,CN
+1145333248,1145333327,US
+1145333328,1145333343,CN
+1145333344,1145333351,US
+1145333352,1145333367,CN
+1145333368,1145333375,PA
+1145333376,1145333503,BD
+1145333504,1145333863,US
+1145333864,1145333871,EG
+1145333872,1145333879,US
+1145333880,1145333903,CN
+1145333904,1145333911,US
+1145333912,1145333919,CN
+1145333920,1145334055,US
+1145334056,1145334063,CN
+1145334064,1145334143,US
+1145334144,1145334167,CN
+1145334168,1145334175,HK
+1145334176,1145335167,US
+1145335168,1145335199,CN
+1145335200,1145335215,US
+1145335216,1145335231,CN
+1145335232,1145376767,US
1145376768,1145380863,CA
1145380864,1145405439,US
1145405440,1145413631,CA
@@ -19176,7 +19877,11 @@
1145421824,1145430015,CA
1145430016,1145475071,US
1145475072,1145479167,CA
-1145479168,1145491455,US
+1145479168,1145483583,US
+1145483584,1145483591,VG
+1145483592,1145484031,US
+1145484032,1145484063,VG
+1145484064,1145503743,US
1145503744,1145520127,CA
1145520128,1145552895,US
1145552896,1145556991,CA
@@ -19205,9 +19910,7 @@
1151889792,1151889823,MA
1151889824,1151889839,CA
1151889840,1151889847,PH
-1151889848,1151889919,CA
-1151889920,1151889943,GB
-1151889944,1151890007,CA
+1151889848,1151890007,CA
1151890008,1151890015,GB
1151890016,1151890079,CA
1151890080,1151890087,GB
@@ -19217,35 +19920,23 @@
1151890216,1151890223,GB
1151890224,1151892735,CA
1151892736,1151892991,MA
-1151892992,1151897599,CA
-1151897600,1151943679,US
-1151943680,1151943807,GB
-1151943808,1151943871,NL
-1151943872,1151943935,CA
-1151943936,1151943999,DE
+1151892992,1151894783,CA
+1151894784,1151895039,US
+1151895040,1151895295,CA
+1151895296,1151895807,US
+1151895808,1151895919,CA
+1151895920,1151895935,US
+1151895936,1151896079,CA
+1151896080,1151896087,US
+1151896088,1151896127,CA
+1151896128,1151896191,US
+1151896192,1151896319,CA
+1151896320,1151943999,US
1151944000,1151944063,HK
-1151944064,1151944079,CH
-1151944080,1151944095,NO
-1151944096,1151944111,KR
-1151944112,1151944127,US
-1151944128,1151944159,AU
-1151944160,1151944175,FR
-1151944176,1151944575,US
-1151944576,1151944703,ES
-1151944704,1151945727,US
-1151945728,1151945759,RU
+1151944064,1151945759,US
1151945760,1151945791,IE
-1151945792,1151945823,IT
-1151945824,1151945855,AT
-1151945856,1151945887,SE
-1151945888,1151945919,US
-1151945920,1151945935,JP
-1151945936,1151946239,US
-1151946240,1151946751,GB
-1151946752,1151954943,US
-1151959040,1152057343,US
-1152057344,1152061439,CA
-1152061440,1152073727,US
+1151945792,1151954943,US
+1151959040,1152073727,US
1152073728,1152077823,CA
1152077824,1152581631,US
1152581632,1152614399,CA
@@ -19255,13 +19946,22 @@
1154488320,1154488575,A2
1154488576,1156071423,US
1156071424,1156079615,CA
-1156079616,1156259839,US
+1156079616,1156129479,US
+1156129480,1156129487,SG
+1156129488,1156129495,JP
+1156129496,1156129503,US
+1156129504,1156129791,CA
+1156129792,1156129983,US
+1156129984,1156129999,CY
+1156130000,1156130015,US
+1156130016,1156130303,CA
+1156130304,1156131327,US
+1156131328,1156131583,CA
+1156131584,1156259839,US
1156259840,1156265983,CA
1156265984,1156296703,US
1156296704,1156300799,CA
-1156300800,1156335367,US
-1156335368,1156335375,PR
-1156335376,1157670431,US
+1156300800,1157670431,US
1157670432,1157670463,CA
1157670464,1157713663,US
1157713664,1157713791,CA
@@ -19926,9 +20626,7 @@
1159480440,1159480447,CA
1159480448,1159481167,US
1159481168,1159481183,VG
-1159481184,1159481855,US
-1159481856,1159481887,EG
-1159481888,1159482423,US
+1159481184,1159482423,US
1159482424,1159482431,AN
1159482432,1159512063,US
1159512064,1159512159,CA
@@ -19940,8 +20638,8 @@
1159513024,1159513343,CA
1159513344,1159513375,US
1159513376,1159513439,CA
-1159513440,1159513471,US
-1159513472,1159513519,CA
+1159513440,1159513487,US
+1159513488,1159513519,CA
1159513520,1159513535,US
1159513536,1159513567,CA
1159513568,1159513599,US
@@ -19959,32 +20657,34 @@
1159517120,1159517151,CA
1159517152,1159517183,US
1159517184,1159517327,CA
-1159517328,1159517343,US
-1159517344,1159517359,CA
-1159517360,1159517439,US
-1159517440,1159517599,CA
+1159517328,1159517567,US
+1159517568,1159517599,CA
1159517600,1159517631,US
-1159517632,1159517679,CA
-1159517680,1159517695,US
+1159517632,1159517663,CA
+1159517664,1159517695,US
1159517696,1159517975,CA
1159517976,1159517991,US
-1159517992,1159518007,CA
-1159518008,1159518015,US
+1159517992,1159517999,CA
+1159518000,1159518015,US
1159518016,1159518175,CA
1159518176,1159518199,US
1159518200,1159518207,CA
1159518208,1159519743,US
1159519744,1159520767,CA
1159520768,1159520799,US
-1159520800,1159521023,CA
-1159521024,1159521087,US
+1159520800,1159520959,CA
+1159520960,1159520975,US
+1159520976,1159521007,CA
+1159521008,1159521087,US
1159521088,1159521199,CA
1159521200,1159521215,US
1159521216,1159521823,CA
1159521824,1159521855,US
1159521856,1159522031,CA
1159522032,1159522047,US
-1159522048,1159522095,CA
+1159522048,1159522063,CA
+1159522064,1159522071,US
+1159522072,1159522095,CA
1159522096,1159522111,US
1159522112,1159522143,CA
1159522144,1159522167,US
@@ -19997,9 +20697,7 @@
1159522304,1159523327,CA
1159523328,1159523583,US
1159523584,1159524351,CA
-1159524352,1159525071,US
-1159525072,1159525087,CA
-1159525088,1159525375,US
+1159524352,1159525375,US
1159525376,1159526399,CA
1159526400,1159527935,US
1159527936,1159528191,CA
@@ -20020,17 +20718,17 @@
1159657072,1159657087,NZ
1159657088,1159659063,US
1159659064,1159659079,IN
-1159659080,1159667967,US
-1159667968,1159668991,AU
-1159668992,1159669247,US
-1159669248,1159669759,AU
-1159669760,1159700479,US
+1159659080,1159668479,US
+1159668480,1159668735,CA
+1159668736,1159694591,US
+1159694592,1159694847,CA
+1159694848,1159700479,US
1159700480,1159725055,CA
1159725056,1159988735,US
1159988736,1159988991,MX
-1159988992,1159990783,US
-1159990784,1159991039,MX
-1159991040,1159995935,US
+1159988992,1159995647,US
+1159995648,1159995655,AU
+1159995656,1159995935,US
1159995936,1159995951,CA
1159995952,1159996063,US
1159996064,1159996079,GB
@@ -20105,56 +20803,17 @@
1160017160,1160019967,CA
1160019968,1160364031,US
1160364032,1160368127,CA
-1160368128,1160392751,US
-1160392752,1160392799,CA
-1160392800,1160392815,US
-1160392816,1160392939,CA
-1160392940,1160392959,US
-1160392960,1160393031,CA
-1160393032,1160393039,US
-1160393040,1160393055,CA
-1160393056,1160393087,US
-1160393088,1160393151,CA
-1160393152,1160393215,US
-1160393216,1160393279,CA
-1160393280,1160393295,HK
-1160393296,1160393311,CA
-1160393312,1160393327,US
-1160393328,1160393343,CA
-1160393344,1160393359,US
-1160393360,1160393535,CA
-1160393536,1160393599,US
-1160393600,1160393791,CA
-1160393792,1160393799,HK
-1160393800,1160393807,US
-1160393808,1160393871,CA
-1160393872,1160393879,GB
-1160393880,1160393951,CA
-1160393952,1160393959,HK
-1160393960,1160393983,CA
-1160393984,1160394239,US
-1160394240,1160394295,CA
-1160394296,1160394303,US
-1160394304,1160394495,CA
-1160394496,1160394751,US
-1160394752,1160395007,CA
-1160395008,1160395263,US
-1160395264,1160395391,CA
-1160395392,1160395775,US
-1160395776,1160396031,CA
-1160396032,1160396287,US
-1160396288,1160396543,CA
-1160396544,1160397007,US
+1160368128,1160397007,US
1160397008,1160397023,GB
-1160397024,1160405503,US
-1160405504,1160405615,DO
-1160405616,1160405631,US
+1160397024,1160405631,US
1160405632,1160406015,DO
1160406016,1160406271,US
1160406272,1160406303,VE
1160406304,1160406319,US
1160406320,1160406335,DO
-1160406336,1160406479,US
+1160406336,1160406431,US
+1160406432,1160406447,ES
+1160406448,1160406479,US
1160406480,1160406487,A2
1160406488,1160408095,US
1160408096,1160408111,GD
@@ -20170,7 +20829,9 @@
1160410192,1160410207,BM
1160410208,1160410239,US
1160410240,1160410255,MX
-1160410256,1160410447,US
+1160410256,1160410287,US
+1160410288,1160410303,DO
+1160410304,1160410447,US
1160410448,1160410463,UY
1160410464,1160410479,TT
1160410480,1160410495,US
@@ -20219,9 +20880,7 @@
1160437504,1160437535,PT
1160437536,1160437695,US
1160437696,1160437759,IN
-1160437760,1160483263,US
-1160483264,1160483295,MX
-1160483296,1160486911,US
+1160437760,1160486911,US
1160486912,1160487423,AU
1160487424,1160503295,US
1160503296,1160503871,A2
@@ -20378,19 +21037,9 @@
1160925184,1160941535,US
1160941536,1160941567,CA
1160941568,1160945663,US
-1160947712,1160948991,US
-1160948992,1160949023,CA
-1160949024,1160949087,US
-1160949120,1160949151,US
-1160949168,1160949183,JP
-1160949200,1160949215,US
-1160949248,1160949535,US
-1160949632,1160949759,CY
-1160949760,1160973439,US
+1160953856,1160973439,US
1160973440,1160973503,MX
-1160973504,1160973567,US
-1160973568,1160973599,CA
-1160973600,1160973863,US
+1160973504,1160973863,US
1160973864,1160973871,GR
1160973872,1160974591,US
1160974592,1160974623,HK
@@ -20408,7 +21057,9 @@
1161293824,1161297919,CA
1161297920,1161298303,US
1161298304,1161298311,IL
-1161298312,1161304591,US
+1161298312,1161300511,US
+1161300512,1161300519,CA
+1161300520,1161304591,US
1161304592,1161304599,AU
1161304600,1161311743,US
1161311744,1161311759,KN
@@ -20471,8 +21122,14 @@
1161627744,1161627759,US
1161627760,1161627775,GB
1161627776,1161627807,US
-1161627808,1161627863,AR
-1161627864,1161628479,US
+1161627808,1161627823,AR
+1161627824,1161627831,AU
+1161627832,1161627863,AR
+1161627864,1161627871,US
+1161627872,1161627879,GB
+1161627880,1161627895,US
+1161627896,1161627903,AZ
+1161627904,1161628479,US
1161628480,1161628487,GB
1161628488,1161628607,US
1161628608,1161628639,AR
@@ -20560,7 +21217,7 @@
1161632664,1161632719,US
1161632720,1161632735,GB
1161632736,1161633023,US
-1161633024,1161633055,IL
+1161633024,1161633055,CA
1161633056,1161633215,US
1161633216,1161633231,EE
1161633232,1161634063,US
@@ -20569,7 +21226,7 @@
1161634128,1161634135,AR
1161634136,1161634199,US
1161634200,1161634207,NZ
-1161634208,1161634239,AR
+1161634208,1161634239,US
1161634240,1161634247,GB
1161634248,1161634271,US
1161634272,1161634287,CH
@@ -20699,11 +21356,21 @@
1161650848,1161650863,AR
1161650864,1161650927,US
1161650928,1161650935,HR
-1161650936,1161651103,US
+1161650936,1161651055,US
+1161651056,1161651071,PL
+1161651072,1161651103,US
1161651104,1161651135,GB
1161651136,1161651487,US
1161651488,1161651503,GB
-1161651504,1161651967,US
+1161651504,1161651535,US
+1161651536,1161651543,PL
+1161651544,1161651551,US
+1161651552,1161651559,CA
+1161651560,1161651599,US
+1161651600,1161651607,AR
+1161651608,1161651647,US
+1161651648,1161651711,PL
+1161651712,1161651967,US
1161651968,1161651975,CH
1161651976,1161652007,US
1161652008,1161652015,GB
@@ -20713,7 +21380,9 @@
1161652128,1161652135,AR
1161652136,1161653023,US
1161653024,1161653055,AR
-1161653056,1161653791,US
+1161653056,1161653503,US
+1161653504,1161653759,CA
+1161653760,1161653791,US
1161653792,1161653799,SI
1161653800,1161653831,US
1161653832,1161653839,HR
@@ -20736,9 +21405,7 @@
1161790840,1161790848,CA
1161790849,1161818111,US
1161818112,1161822207,CA
-1161822208,1161832671,US
-1161832672,1161832703,CL
-1161832704,1161832799,US
+1161822208,1161832799,US
1161832800,1161832831,ZA
1161832832,1161832863,DE
1161832864,1161833967,US
@@ -20749,8 +21416,7 @@
1161836032,1161836063,CA
1161836064,1161836159,US
1161836160,1161836191,BR
-1161836192,1161836255,US
-1161836256,1161836287,UA
+1161836192,1161836287,US
1161836288,1161836319,RS
1161836320,1161836383,US
1161836384,1161836415,CY
@@ -20759,9 +21425,7 @@
1161836480,1161836511,UA
1161836512,1161837567,US
1161837568,1161837823,JP
-1161837824,1161838351,US
-1161838352,1161838367,GB
-1161838368,1161838548,US
+1161837824,1161838548,US
1161838549,1161838560,RU
1161838561,1161841101,US
1161841102,1161841112,DE
@@ -20824,8 +21488,8 @@
1162059776,1162067967,CA
1162067968,1162215423,US
1162215424,1162280959,CA
-1162280960,1162296007,US
-1162296008,1162296023,CA
+1162280960,1162296015,US
+1162296016,1162296023,CA
1162296024,1162296407,US
1162296408,1162296415,CA
1162296416,1162297343,US
@@ -20887,7 +21551,7 @@
1162811648,1162812159,US
1162812160,1162812415,DO
1162812416,1162813439,BS
-1162813440,1162821631,CO
+1162813440,1162821631,US
1162821632,1162823679,PR
1162823680,1162825727,GT
1162825728,1162827775,US
@@ -20901,16 +21565,11 @@
1162870784,1162871295,BB
1162871296,1162874367,LC
1162874368,1162887167,BB
-1162903552,1162923391,US
-1162923392,1162923519,BE
-1162923520,1162924031,US
-1162924032,1162924287,AU
-1162924288,1162925983,US
+1162903552,1162925983,US
1162925984,1162926015,AU
1162926016,1162926071,US
1162926072,1162926079,AU
-1162926080,1162932223,US
-1162936320,1163395071,US
+1162926080,1163395071,US
1163395072,1163395839,A2
1163395840,1163395847,BD
1163395848,1163395855,ID
@@ -21350,13 +22009,15 @@
1163876472,1163876479,PA
1163876480,1163878399,US
1163878400,1163878407,CN
-1163878408,1167320679,US
-1167320680,1167320687,IN
-1167320688,1167321959,US
+1163878408,1167321959,US
1167321960,1167321967,GB
1167321968,1167322695,US
1167322696,1167322703,IN
-1167322704,1167325935,US
+1167322704,1167323799,US
+1167323800,1167323807,IN
+1167323808,1167323823,US
+1167323824,1167323831,IN
+1167323832,1167325935,US
1167325936,1167325951,CA
1167325952,1167326207,US
1167326208,1167326271,IN
@@ -21367,14 +22028,17 @@
1167326400,1167326431,IN
1167326432,1167326439,US
1167326440,1167326447,IN
-1167326448,1167326463,US
-1167326464,1167326719,IN
-1167326720,1167693199,US
+1167326448,1167326983,US
+1167326984,1167326991,IN
+1167326992,1167327111,US
+1167327112,1167327119,IN
+1167327120,1167327207,US
+1167327208,1167327215,IN
+1167327216,1167693199,US
1167693200,1167693215,UA
1167693216,1167851519,US
1167851520,1168113663,CA
-1168113664,1168121855,US
-1168130048,1168138239,US
+1168113664,1168138239,US
1168138240,1168146431,JM
1168146432,1168211967,US
1168211968,1168220159,CA
@@ -21382,30 +22046,29 @@
1168318720,1168318975,CA
1168318976,1168321535,US
1168321536,1168321791,CA
-1168321792,1168330751,US
-1168343040,1168393215,US
+1168321792,1168393215,US
1168393216,1168394271,CA
1168394272,1168394279,US
1168394280,1168394375,CA
1168394376,1168394383,US
-1168394384,1168394407,CA
-1168394408,1168394415,US
-1168394416,1168394423,CA
+1168394384,1168394423,CA
1168394424,1168394463,US
1168394464,1168394471,CA
1168394472,1168394479,US
-1168394480,1168394495,CA
-1168394496,1168394511,US
+1168394480,1168394503,CA
+1168394504,1168394511,US
1168394512,1168394527,CA
1168394528,1168394559,US
-1168394560,1168394687,CA
-1168394688,1168420863,US
+1168394560,1168394751,CA
+1168394752,1168420863,US
1168420864,1168424959,CA
1168424960,1168474111,US
1168474112,1168506879,CA
1168508928,1168510975,US
1168510976,1168515071,CA
-1168515072,1168670719,US
+1168515072,1168535551,US
+1168535552,1168539647,CA
+1168539648,1168670719,US
1168670720,1168687103,CA
1168687104,1168859135,US
1168859136,1168863231,CA
@@ -21431,13 +22094,11 @@
1168952888,1168952895,CA
1168952896,1168952959,US
1168952960,1168953343,CA
-1168953344,1168954015,US
-1168954016,1168954047,EG
-1168954048,1168954075,US
+1168953344,1168954075,US
1168954076,1168954079,CA
-1168954080,1168955647,US
-1168955648,1168956415,CA
-1168956416,1168957439,US
+1168954080,1168955903,US
+1168955904,1168956159,CA
+1168956160,1168957439,US
1168957440,1168958047,CA
1168958048,1168958055,DE
1168958056,1168958063,CA
@@ -21455,11 +22116,7 @@
1168958464,1168958479,CA
1168958480,1168958495,US
1168958496,1168958527,FR
-1168958528,1168958655,US
-1168958656,1168958687,EG
-1168958688,1168958719,US
-1168958720,1168958975,CA
-1168958976,1168960543,US
+1168958528,1168960543,US
1168960544,1168960591,CA
1168960592,1168960607,US
1168960608,1168960623,CA
@@ -21477,7 +22134,8 @@
1168961992,1168961999,CA
1168962000,1168962303,US
1168962304,1168962559,CA
-1168962560,1168963071,US
+1168962560,1168963039,US
+1168963040,1168963071,ES
1168963072,1168965631,CA
1168965632,1168973823,US
1168973824,1168982015,CA
@@ -21521,8 +22179,13 @@
1169186048,1169186303,SG
1169186304,1169203199,US
1169203200,1169211391,CA
-1169211392,1170448383,US
-1170456576,1170461183,US
+1169211392,1170456959,US
+1170456960,1170456975,CR
+1170456976,1170456991,US
+1170456992,1170457007,PR
+1170457008,1170458063,US
+1170458064,1170458079,DE
+1170458080,1170461183,US
1170461184,1170461439,CO
1170461440,1170461695,US
1170461696,1170462719,IL
@@ -21532,13 +22195,83 @@
1170489344,1170497535,CA
1170497536,1170505727,US
1170505728,1170522111,CA
-1170522112,1170544255,US
+1170522112,1170539329,US
+1170539330,1170539330,CN
+1170539331,1170539393,US
+1170539394,1170539394,TR
+1170539395,1170539399,US
+1170539400,1170539400,TR
+1170539401,1170539416,US
+1170539417,1170539417,TR
+1170539418,1170539463,US
+1170539464,1170539464,CN
+1170539465,1170539466,US
+1170539467,1170539467,IE
+1170539468,1170539523,US
+1170539524,1170539524,IE
+1170539525,1170539586,US
+1170539587,1170539587,FR
+1170539588,1170539590,US
+1170539591,1170539591,CN
+1170539592,1170539592,US
+1170539593,1170539593,CN
+1170539594,1170539652,US
+1170539653,1170539653,GB
+1170539654,1170539714,US
+1170539715,1170539715,PK
+1170539716,1170539776,US
+1170539777,1170539777,FR
+1170539778,1170539778,US
+1170539779,1170539779,FR
+1170539780,1170539969,US
+1170539970,1170539970,KH
+1170539971,1170540038,US
+1170540039,1170540039,PH
+1170540040,1170540097,US
+1170540098,1170540098,TR
+1170540099,1170540104,US
+1170540105,1170540105,PK
+1170540106,1170540231,US
+1170540232,1170540232,CN
+1170540233,1170540289,US
+1170540290,1170540290,CN
+1170540291,1170544199,US
+1170544200,1170544207,TR
+1170544208,1170544255,US
1170544256,1170544383,IN
-1170544384,1170544639,US
+1170544384,1170544387,US
+1170544388,1170544391,BD
+1170544392,1170544431,US
+1170544432,1170544439,CN
+1170544440,1170544511,US
+1170544512,1170544575,SE
+1170544576,1170544639,US
1170544640,1170544767,MY
1170544768,1170547455,US
1170547456,1170547711,CA
-1170547712,1175977983,US
+1170547712,1170553087,US
+1170553088,1170553151,GB
+1170553152,1170553215,FR
+1170553216,1170553343,PK
+1170553344,1170553407,CN
+1170553408,1170553431,US
+1170553432,1170553435,TR
+1170553436,1170553439,CA
+1170553440,1170553471,US
+1170553472,1170553535,PK
+1170553536,1170553599,CN
+1170553600,1170553855,US
+1170553856,1170553983,MY
+1170553984,1170554367,US
+1170554368,1170554431,CN
+1170554432,1170554463,US
+1170554464,1170554479,CN
+1170554480,1170554483,TR
+1170554484,1170554487,BD
+1170554488,1170554495,CN
+1170554496,1170554559,US
+1170554560,1170554623,CN
+1170554624,1175977983,US
1175977984,1176068167,CA
1176068168,1176068175,US
1176068176,1176068191,CA
@@ -21556,7 +22289,11 @@
1176108560,1176502271,CA
1176502272,1176512151,US
1176512152,1176512159,GB
-1176512160,1176609535,US
+1176512160,1176513879,US
+1176513880,1176513887,GB
+1176513888,1176514271,US
+1176514272,1176514303,IN
+1176514304,1176609535,US
1176609536,1176609583,CA
1176609584,1176609599,US
1176609600,1176609615,CA
@@ -21587,13 +22324,15 @@
1176620992,1176620999,US
1176621000,1176621023,CA
1176621024,1176621055,US
-1176621056,1176622079,CA
-1176622080,1176623103,US
-1176623104,1176623359,CA
+1176621056,1176623359,CA
1176623360,1176623487,US
-1176623488,1176623615,CA
+1176623488,1176623567,CA
+1176623568,1176623583,US
+1176623584,1176623615,CA
1176623616,1176623871,US
-1176623872,1176629303,CA
+1176623872,1176629287,CA
+1176629288,1176629295,US
+1176629296,1176629303,CA
1176629304,1176629311,US
1176629312,1176629343,CA
1176629344,1176629375,US
@@ -21604,13 +22343,11 @@
1176629472,1176629503,US
1176629504,1176629519,CA
1176629520,1176629535,NZ
-1176629536,1176629695,CA
-1176629696,1176629727,US
+1176629536,1176629631,CA
+1176629632,1176629727,US
1176629728,1176631295,CA
1176631296,1176631551,NL
-1176631552,1176631807,US
-1176631808,1176632063,CR
-1176632064,1176662015,US
+1176631552,1176662015,US
1176662016,1176666111,CA
1176666112,1176682527,US
1176682528,1176682535,JM
@@ -21638,7 +22375,13 @@
1176752128,1176756223,CA
1176756224,1176764415,US
1176764416,1176768511,PM
-1176768512,1176776703,US
+1176768512,1176770751,US
+1176770752,1176770783,AE
+1176770784,1176770831,US
+1176770832,1176770847,BR
+1176770848,1176771895,US
+1176771896,1176771903,AE
+1176771904,1176776703,US
1176776704,1176780799,CA
1176780800,1176895487,US
1176895488,1176896519,CA
@@ -21664,11 +22407,11 @@
1177053696,1177053951,GB
1177053952,1177059327,US
1177059328,1177061375,CA
-1177061376,1177063423,US
-1177063424,1177067519,CA
-1177067520,1177071615,US
-1177071616,1177074687,CA
-1177074688,1177164255,US
+1177061376,1177062399,US
+1177062400,1177074943,CA
+1177074944,1177075199,US
+1177075200,1177075455,CA
+1177075456,1177164255,US
1177164256,1177164263,CA
1177164264,1177164415,US
1177164416,1177164479,CA
@@ -21678,11 +22421,7 @@
1177164928,1177164943,CA
1177164944,1177165311,US
1177165312,1177165823,CA
-1177165824,1177168127,US
-1177168128,1177168143,FR
-1177168144,1177169687,US
-1177169688,1177169695,GB
-1177169696,1177175199,US
+1177165824,1177175199,US
1177175200,1177175231,CZ
1177175232,1177182527,US
1177182528,1177182591,CA
@@ -21832,7 +22571,9 @@
1208197520,1208197527,AU
1208197528,1208197559,US
1208197560,1208197567,AU
-1208197568,1208197631,US
+1208197568,1208197579,US
+1208197580,1208197583,GB
+1208197584,1208197631,US
1208197632,1208197639,AU
1208197640,1208197671,US
1208197672,1208197679,MX
@@ -21848,7 +22589,9 @@
1208198280,1208198287,ZA
1208198288,1208198303,US
1208198304,1208198319,FR
-1208198320,1208198463,US
+1208198320,1208198343,US
+1208198344,1208198347,GB
+1208198348,1208198463,US
1208198464,1208198471,CA
1208198472,1208198559,US
1208198560,1208198575,IN
@@ -22087,23 +22830,41 @@
1208337920,1208338175,A2
1208338176,1208516607,US
1208516608,1208516623,MX
-1208516624,1208516671,US
+1208516624,1208516639,US
+1208516640,1208516671,CN
1208516672,1208516735,TR
1208516736,1208516799,ID
1208516800,1208516855,US
1208516856,1208516859,CN
-1208516860,1208518143,US
+1208516860,1208517001,US
+1208517002,1208517002,CN
+1208517003,1208517009,US
+1208517010,1208517011,CN
+1208517012,1208517017,US
+1208517018,1208517018,GB
+1208517019,1208517019,US
+1208517020,1208517020,FR
+1208517021,1208517119,US
+1208517120,1208517375,KH
+1208517376,1208517631,US
+1208517632,1208517887,KH
+1208517888,1208518143,US
1208518144,1208518207,MY
-1208518208,1208518291,US
+1208518208,1208518246,US
+1208518247,1208518247,KH
+1208518248,1208518263,US
+1208518264,1208518264,GB
+1208518265,1208518271,US
+1208518272,1208518287,GB
+1208518288,1208518291,US
1208518292,1208518295,CN
-1208518296,1208519167,US
+1208518296,1208518335,US
+1208518336,1208518399,TR
+1208518400,1208519167,US
1208519168,1208519423,CN
1208519424,1208519551,US
1208519552,1208519679,TR
-1208519680,1208519935,CA
-1208519936,1208521983,US
-1208521984,1208522239,CA
-1208522240,1208523775,US
+1208519680,1208523775,US
1208523776,1208523903,GB
1208523904,1208523991,US
1208523992,1208523995,TR
@@ -22114,9 +22875,7 @@
1208524224,1208524287,US
1208524288,1208524351,PK
1208524352,1208524415,CN
-1208524416,1208524563,US
-1208524564,1208524567,IT
-1208524568,1208525823,US
+1208524416,1208525823,US
1208525824,1208526079,CA
1208526080,1208527615,US
1208527616,1208527871,CA
@@ -22181,8 +22940,7 @@
1208587419,1208587426,TR
1208587427,1208587427,US
1208587428,1208587443,GB
-1208587444,1208587457,TW
-1208587458,1208587479,US
+1208587444,1208587479,US
1208587480,1208587487,LK
1208587488,1208587488,US
1208587489,1208587504,GB
@@ -22201,9 +22959,7 @@
1208587738,1208587759,CN
1208587760,1208587873,US
1208587874,1208587881,PK
-1208587882,1208587909,US
-1208587910,1208587943,UY
-1208587944,1208587944,US
+1208587882,1208587944,US
1208587945,1208587976,GB
1208587977,1208588071,US
1208588072,1208588079,RU
@@ -22215,11 +22971,7 @@
1208588212,1208588219,CA
1208588220,1208588427,US
1208588428,1208588435,MO
-1208588436,1208588437,US
-1208588438,1208588445,PK
-1208588446,1208588451,US
-1208588452,1208588455,EG
-1208588456,1208588463,US
+1208588436,1208588463,US
1208588464,1208588476,AU
1208588477,1208588591,US
1208588592,1208588599,IN
@@ -22227,22 +22979,15 @@
1208588729,1208588760,GB
1208588761,1208588771,US
1208588772,1208588779,GB
-1208588780,1208588819,US
-1208588820,1208588839,PK
-1208588840,1208588941,US
-1208588942,1208588949,MO
-1208588950,1208588953,US
+1208588780,1208588953,US
1208588954,1208588961,TR
1208588962,1208588972,US
1208588973,1208588985,GB
1208588986,1208588989,US
1208588990,1208589000,GB
-1208589001,1208589011,US
-1208589012,1208589021,MO
-1208589022,1208589065,US
-1208589066,1208589073,CA
-1208589074,1208589082,GB
-1208589083,1208589156,US
+1208589001,1208589065,US
+1208589066,1208589081,CA
+1208589082,1208589156,US
1208589157,1208589165,GB
1208589166,1208589174,US
1208589175,1208589186,CA
@@ -22262,16 +23007,12 @@
1208589971,1208590002,GB
1208590003,1208590004,US
1208590005,1208590014,GB
-1208590015,1208590045,US
-1208590046,1208590053,SA
-1208590054,1208590061,US
+1208590015,1208590061,US
1208590062,1208590071,CN
1208590072,1208590091,US
1208590092,1208590108,GB
1208590109,1208590115,US
-1208590116,1208590119,EG
-1208590120,1208590120,US
-1208590121,1208590123,EG
+1208590116,1208590123,EG
1208590124,1208590140,US
1208590141,1208590154,CA
1208590155,1208590157,US
@@ -22285,25 +23026,16 @@
1208590266,1208590335,US
1208590336,1208598527,CA
1208598528,1208647679,US
-1208647680,1208656159,CA
-1208656160,1208656191,US
-1208656192,1208656223,CA
-1208656224,1208656255,US
-1208656256,1208656319,CA
+1208647680,1208656319,CA
1208656320,1208656351,US
-1208656352,1208656383,CA
-1208656384,1208656511,ID
+1208656352,1208656511,CA
1208656512,1208656543,US
1208656544,1208656575,CA
1208656576,1208656583,DO
1208656584,1208656591,PA
-1208656592,1208656599,RS
-1208656600,1208656607,UA
-1208656608,1208656639,US
+1208656592,1208656639,CA
1208656640,1208656703,MY
-1208656704,1208656711,UA
-1208656712,1208656735,CA
-1208656736,1208656767,US
+1208656704,1208656767,CA
1208656768,1208656895,MY
1208656896,1208656903,CA
1208656904,1208656911,LB
@@ -22324,24 +23056,18 @@
1208657720,1208657727,CH
1208657728,1208657775,CA
1208657776,1208657783,PA
-1208657784,1208657823,CA
-1208657824,1208657831,DO
-1208657832,1208657855,CA
+1208657784,1208657855,CA
1208657856,1208657871,PA
1208657872,1208657919,CA
1208657920,1208657975,MA
1208657976,1208657983,CA
1208657984,1208657991,CN
1208657992,1208658015,MA
-1208658016,1208658023,CA
-1208658024,1208658031,DO
+1208658016,1208658031,CA
1208658032,1208658039,MA
-1208658040,1208658047,CA
-1208658048,1208658079,US
-1208658080,1208658103,CA
+1208658040,1208658103,CA
1208658104,1208658111,FR
-1208658112,1208658119,DO
-1208658120,1208658127,CA
+1208658112,1208658127,CA
1208658128,1208658143,MA
1208658144,1208658159,CA
1208658160,1208658167,MA
@@ -22349,29 +23075,23 @@
1208658176,1208658199,MA
1208658200,1208658223,CA
1208658224,1208658239,MA
-1208658240,1208658247,CY
-1208658248,1208658263,CA
+1208658240,1208658263,CA
1208658264,1208658271,KE
1208658272,1208658279,IL
1208658280,1208658303,CA
1208658304,1208658335,US
1208658336,1208658343,KE
-1208658344,1208658351,CA
-1208658352,1208658367,US
-1208658368,1208658431,CA
-1208658432,1208658767,US
+1208658344,1208658431,CA
+1208658432,1208658687,US
+1208658688,1208658767,CA
1208658768,1208658775,MA
-1208658776,1208658783,UA
-1208658784,1208658799,CA
+1208658776,1208658799,CA
1208658800,1208658807,KE
-1208658808,1208658815,RS
-1208658816,1208658847,CA
+1208658808,1208658847,CA
1208658848,1208658855,MA
1208658856,1208658879,CA
1208658880,1208658887,DO
-1208658888,1208658895,GB
-1208658896,1208659103,CA
-1208659104,1208659135,US
+1208658888,1208659135,CA
1208659136,1208659151,CN
1208659152,1208659167,CA
1208659168,1208659199,AE
@@ -22390,9 +23110,7 @@
1208659744,1208659775,ID
1208659776,1208659791,CA
1208659792,1208659799,US
-1208659800,1208659815,CA
-1208659816,1208659823,UA
-1208659824,1208659831,CA
+1208659800,1208659831,CA
1208659832,1208659839,ID
1208659840,1208659903,PK
1208659904,1208721407,US
@@ -22408,13 +23126,14 @@
1208814720,1208814855,US
1208814856,1208814863,CA
1208814864,1208832455,US
-1208832456,1208832463,CA
+1208832456,1208832463,CN
1208832464,1208832567,US
1208832568,1208832575,CN
-1208832576,1208832607,US
+1208832576,1208832599,US
+1208832600,1208832607,CN
1208832608,1208832623,IT
1208832624,1208832631,NZ
-1208832632,1208832639,US
+1208832632,1208832639,HK
1208832640,1208832703,IN
1208832704,1208832775,US
1208832776,1208832783,CA
@@ -22429,8 +23148,8 @@
1208920008,1208920015,US
1208920016,1208922111,CA
1208922112,1208954879,US
-1208954880,1208958463,CA
-1208958464,1208975359,US
+1208954880,1208958975,CA
+1208958976,1208975359,US
1208975360,1208980191,CA
1208980192,1208980223,US
1208980224,1208980503,CA
@@ -22442,15 +23161,9 @@
1208995456,1208995471,CA
1208995472,1209004863,US
1209004864,1209004927,GB
-1209004928,1209189308,US
-1209189309,1209189310,ES
-1209189311,1209189342,US
-1209189343,1209189374,ES
-1209189375,1209189379,US
+1209004928,1209189379,US
1209189380,1209189395,MX
-1209189396,1209189631,US
-1209189632,1209189887,MX
-1209189888,1209190147,US
+1209189396,1209190147,US
1209190148,1209190163,MX
1209190164,1209190167,US
1209190168,1209190195,GR
@@ -22458,52 +23171,99 @@
1209190852,1209190883,CA
1209190884,1209190911,US
1209190912,1209191167,MX
-1209191168,1209270579,US
+1209191168,1209270543,US
+1209270544,1209270547,CN
+1209270548,1209270579,US
1209270580,1209270583,ID
1209270584,1209270759,US
-1209270760,1209270767,CA
-1209270768,1209270859,US
+1209270760,1209270763,CA
+1209270764,1209270859,US
1209270860,1209270863,CA
-1209270864,1209270919,US
-1209270920,1209270923,CA
-1209270924,1209271067,US
+1209270864,1209271067,US
1209271068,1209271071,VN
-1209271072,1209271095,US
-1209271096,1209271099,CA
-1209271100,1209271111,US
+1209271072,1209271111,US
1209271112,1209271115,CA
-1209271116,1209271435,US
+1209271116,1209271207,US
+1209271208,1209271211,FR
+1209271212,1209271371,US
+1209271372,1209271375,PE
+1209271376,1209271435,US
1209271436,1209271439,CN
1209271440,1209271463,US
1209271464,1209271467,IN
1209271468,1209271491,US
1209271492,1209271499,CA
1209271500,1209271503,MX
-1209271504,1209271507,TR
-1209271508,1209271527,US
+1209271504,1209271527,US
1209271528,1209271531,CA
1209271532,1209271579,US
1209271580,1209271583,BD
-1209271584,1209271691,US
+1209271584,1209271607,US
+1209271608,1209271611,KH
+1209271612,1209271639,US
+1209271640,1209271643,CZ
+1209271644,1209271691,US
1209271692,1209271695,CA
-1209271696,1209271827,US
-1209271828,1209271831,CA
-1209271832,1209271871,US
+1209271696,1209271791,US
+1209271792,1209271795,GB
+1209271796,1209271871,US
1209271872,1209271875,TR
1209271876,1209271967,US
1209271968,1209271971,VN
1209271972,1209271975,TR
-1209271976,1209272003,US
-1209272004,1209272007,GB
-1209272008,1209272035,US
-1209272036,1209272039,IT
-1209272040,1209273663,US
+1209271976,1209271995,US
+1209271996,1209271999,FR
+1209272000,1209272015,US
+1209272016,1209272019,GB
+1209272020,1209272031,US
+1209272032,1209272035,GB
+1209272036,1209272407,US
+1209272408,1209272415,PE
+1209272416,1209272447,US
+1209272448,1209272479,KH
+1209272480,1209272511,US
+1209272512,1209272575,CN
+1209272576,1209272583,US
+1209272584,1209272591,PH
+1209272592,1209272655,US
+1209272656,1209272671,TR
+1209272672,1209272895,US
+1209272896,1209272959,CN
+1209272960,1209273215,US
+1209273216,1209273279,CN
+1209273280,1209273647,US
+1209273648,1209273655,CN
+1209273656,1209273663,US
1209273664,1209273671,BD
-1209273672,1209274623,US
-1209274624,1209274751,CA
+1209273672,1209273991,US
+1209273992,1209273999,FR
+1209274000,1209274031,US
+1209274032,1209274039,TR
+1209274040,1209274115,US
+1209274116,1209274119,CZ
+1209274120,1209274135,US
+1209274136,1209274151,TR
+1209274152,1209274175,US
+1209274176,1209274239,FR
+1209274240,1209274303,US
+1209274304,1209274367,CN
+1209274368,1209274607,US
+1209274608,1209274623,FR
+1209274624,1209274751,CN
1209274752,1209274815,US
1209274816,1209274879,CA
-1209274880,1209275910,US
+1209274880,1209274911,CZ
+1209274912,1209274927,US
+1209274928,1209274943,TR
+1209274944,1209274959,US
+1209274960,1209274967,PH
+1209274968,1209275071,US
+1209275072,1209275135,GB
+1209275136,1209275863,US
+1209275864,1209275871,FR
+1209275872,1209275906,US
+1209275907,1209275908,KH
+1209275909,1209275910,US
1209275911,1209275911,MY
1209275912,1209275924,US
1209275925,1209275925,CN
@@ -22513,44 +23273,76 @@
1209275932,1209275932,CN
1209275933,1209276351,US
1209276352,1209276415,CN
-1209276416,1209276511,US
-1209276512,1209276543,VN
-1209276544,1209276799,US
+1209276416,1209276799,US
1209276800,1209276807,BD
-1209276808,1209277183,US
-1209277184,1209277215,BD
-1209277216,1209277575,US
+1209276808,1209276815,FR
+1209276816,1209276911,US
+1209276912,1209276927,TR
+1209276928,1209277087,US
+1209277088,1209277095,FR
+1209277096,1209277103,US
+1209277104,1209277119,TR
+1209277120,1209277135,US
+1209277136,1209277143,FR
+1209277144,1209277155,US
+1209277156,1209277156,SE
+1209277157,1209277177,US
+1209277178,1209277178,FR
+1209277179,1209277575,US
1209277576,1209277583,BD
-1209277584,1209278911,US
+1209277584,1209278207,US
+1209278208,1209278463,IE
+1209278464,1209278911,US
1209278912,1209278919,TR
1209278920,1209279167,US
1209279168,1209279231,VN
-1209279232,1209279871,US
+1209279232,1209279615,US
+1209279616,1209279743,GB
+1209279744,1209279871,US
1209279872,1209279935,MY
1209279936,1209280191,US
1209280192,1209280255,VN
-1209280256,1209280975,US
-1209280976,1209280983,IT
-1209280984,1209281247,US
+1209280256,1209280575,US
+1209280576,1209280607,FR
+1209280608,1209280619,US
+1209280620,1209280623,GB
+1209280624,1209280959,US
+1209280960,1209280975,GB
+1209280976,1209281247,US
1209281248,1209281279,CA
-1209281280,1209281983,US
+1209281280,1209281535,KH
+1209281536,1209281983,US
1209281984,1209282047,TR
-1209282048,1209283587,US
+1209282048,1209282583,US
+1209282584,1209282591,GB
+1209282592,1209283479,US
+1209283480,1209283487,GB
+1209283488,1209283535,US
+1209283536,1209283543,GB
+1209283544,1209283587,US
1209283588,1209283591,CN
-1209283592,1209283751,US
+1209283592,1209283695,US
+1209283696,1209283703,GB
+1209283704,1209283751,US
1209283752,1209283759,BD
1209283760,1209283871,US
1209283872,1209283875,TR
1209283876,1209283967,US
1209283968,1209284095,GB
-1209284096,1209284799,US
+1209284096,1209284223,US
+1209284224,1209284351,IE
+1209284352,1209284759,US
+1209284760,1209284767,FR
+1209284768,1209284799,US
1209284800,1209284815,TR
1209284816,1209284831,CN
1209284832,1209284855,US
1209284856,1209284863,TR
1209284864,1209285063,US
1209285064,1209285071,TR
-1209285072,1209347839,US
+1209285072,1209285183,US
+1209285184,1209285247,TR
+1209285248,1209347839,US
1209347840,1209348095,GB
1209348096,1209357215,US
1209357216,1209357231,SI
@@ -22579,7 +23371,9 @@
1209860576,1209860607,IN
1209860608,1209860863,US
1209860864,1209860895,CY
-1209860896,1209861119,US
+1209860896,1209860927,US
+1209860928,1209860959,AU
+1209860960,1209861119,US
1209861120,1209861375,CA
1209861376,1209861759,US
1209861760,1209861887,FR
@@ -22612,7 +23406,11 @@
1209867200,1209867231,IN
1209867232,1209867263,US
1209867264,1209867519,CA
-1209867520,1209884671,US
+1209867520,1209877934,US
+1209877935,1209877938,PK
+1209877939,1209879554,US
+1209879555,1209879558,PE
+1209879559,1209884671,US
1209884672,1209884679,IT
1209884680,1209884687,ES
1209884688,1209884823,US
@@ -22894,7 +23692,9 @@
1210088960,1210088967,GB
1210088968,1210089047,US
1210089048,1210089055,MX
-1210089056,1210089823,US
+1210089056,1210089375,US
+1210089376,1210089383,CA
+1210089384,1210089823,US
1210089824,1210089855,CA
1210089856,1210090071,US
1210090072,1210090079,MX
@@ -23268,8 +24068,8 @@
1210418208,1210427039,US
1210427040,1210427071,JP
1210427072,1210449919,US
-1210449920,1210468743,CA
-1210468744,1210468767,US
+1210449920,1210468751,CA
+1210468752,1210468767,US
1210468768,1210580991,CA
1210580992,1210861207,US
1210861208,1210861215,GB
@@ -23300,14 +24100,11 @@
1211036032,1211036095,EC
1211036096,1211036703,US
1211036704,1211036719,BO
-1211036720,1211036727,US
-1211036728,1211036735,JM
+1211036720,1211036735,US
1211036736,1211036751,GT
1211036752,1211036991,US
1211036992,1211037055,BR
-1211037056,1211037455,US
-1211037456,1211037471,CR
-1211037472,1211037519,US
+1211037056,1211037519,US
1211037520,1211037535,UY
1211037536,1211037679,US
1211037680,1211037695,AR
@@ -23336,8 +24133,8 @@
1211304320,1211304351,NL
1211304352,1211304703,CA
1211304704,1211304767,GB
-1211304768,1211304799,US
-1211304800,1211304959,CA
+1211304768,1211304831,US
+1211304832,1211304959,CA
1211304960,1211305983,US
1211305984,1211306111,NL
1211306112,1211306751,US
@@ -23357,10 +24154,18 @@
1211308704,1211308719,VG
1211308720,1211308735,CA
1211308736,1211308751,BV
-1211308752,1211309055,CA
+1211308752,1211308767,CA
+1211308768,1211308783,US
+1211308784,1211309055,CA
1211309056,1211309311,US
1211309312,1211310079,CA
-1211310080,1211314383,US
+1211310080,1211313219,US
+1211313220,1211313231,IN
+1211313232,1211313431,US
+1211313432,1211313439,IN
+1211313440,1211313567,US
+1211313568,1211313579,IN
+1211313580,1211314383,US
1211314384,1211314399,CA
1211314400,1211314415,US
1211314416,1211314423,CA
@@ -23368,9 +24173,7 @@
1211314640,1211314671,CA
1211314672,1211314863,US
1211314864,1211314879,CA
-1211314880,1211315711,US
-1211315712,1211316223,CA
-1211316224,1211316479,US
+1211314880,1211316479,US
1211316480,1211316991,CA
1211316992,1211317503,US
1211317504,1211317759,CA
@@ -23391,9 +24194,9 @@
1211367504,1211367519,CH
1211367520,1211367615,US
1211367616,1211367679,GB
-1211367680,1211367935,GI
+1211367680,1211367935,US
1211367936,1211368191,CA
-1211368192,1211368447,CY
+1211368192,1211368447,EE
1211368448,1211384279,US
1211384280,1211384287,GB
1211384288,1211387983,US
@@ -23446,9 +24249,7 @@
1219256320,1219264511,CA
1219264512,1219272703,US
1219272704,1219276799,CA
-1219276800,1219290047,US
-1219290048,1219290063,CA
-1219290064,1219290623,US
+1219276800,1219290623,US
1219290624,1219290751,AU
1219290752,1219295295,US
1219295296,1219295359,GR
@@ -23486,12 +24287,9 @@
1224278600,1224278607,AU
1224278608,1224278815,US
1224278816,1224278823,CH
-1224278824,1224285695,US
-1224285696,1224286207,GB
-1224286208,1224286719,US
+1224278824,1224286719,US
1224286720,1224286975,CA
-1224286976,1224290303,US
-1224290304,1224290815,GB
+1224286976,1224290815,US
1224290816,1224291071,CA
1224291072,1224292095,US
1224292096,1224292351,CA
@@ -23503,9 +24301,7 @@
1224299520,1224299775,CA
1224299776,1224303359,US
1224303360,1224303367,CA
-1224303368,1224305151,US
-1224305152,1224305663,GB
-1224305664,1224311063,US
+1224303368,1224311063,US
1224311064,1224311071,MX
1224311072,1224311247,US
1224311248,1224311255,CA
@@ -23522,8 +24318,7 @@
1224317440,1224317695,CA
1224317696,1224318207,US
1224318208,1224318463,CA
-1224318464,1224320511,US
-1224320512,1224321023,GB
+1224318464,1224321023,US
1224321024,1224321535,CA
1224321536,1224322559,US
1224322560,1224323071,GB
@@ -23553,9 +24348,7 @@
1242300416,1242562559,CA
1242562560,1244659711,US
1244659712,1244790783,CA
-1244790784,1244821247,US
-1244821248,1244821375,CA
-1244821376,1244831743,US
+1244790784,1244831743,US
1244831744,1244839935,CA
1244839936,1244848127,US
1244848128,1244852223,CA
@@ -23567,12 +24360,8 @@
1246864900,1246864958,EG
1246864959,1246872069,US
1246872070,1246872081,GB
-1246872082,1246873461,US
-1246873462,1246873469,CA
-1246873470,1246873491,US
-1246873492,1246873501,GR
-1246873502,1246874112,US
-1246874113,1246874216,GB
+1246872082,1246874127,US
+1246874128,1246874216,GB
1246874217,1246874290,US
1246874291,1246874304,CA
1246874305,1246874368,US
@@ -23587,9 +24376,10 @@
1246902784,1246903039,NL
1246903040,1246937087,US
1246937088,1246945279,CA
-1246945280,1246949375,US
-1246953472,1247027199,US
-1247027200,1247035391,A2
+1246945280,1247027199,US
+1247027200,1247034559,A2
+1247034560,1247034575,US
+1247034576,1247035391,A2
1247035392,1247069303,US
1247069304,1247069311,VA
1247069312,1247070815,US
@@ -23622,7 +24412,25 @@
1249010688,1249011711,CA
1249011712,1249019903,US
1249019904,1249020927,CA
-1249020928,1249029119,US
+1249020928,1249027175,US
+1249027176,1249027183,IN
+1249027184,1249027391,US
+1249027392,1249027407,PH
+1249027408,1249027455,US
+1249027456,1249027471,CA
+1249027472,1249027503,US
+1249027504,1249027519,CA
+1249027520,1249027551,US
+1249027552,1249027559,CA
+1249027560,1249027647,US
+1249027648,1249027655,AU
+1249027656,1249027823,US
+1249027824,1249027839,CA
+1249027840,1249027887,US
+1249027888,1249027895,EG
+1249027896,1249027919,US
+1249027920,1249027935,AU
+1249027936,1249029119,US
1249029120,1249030143,CA
1249030144,1249036287,US
1249036288,1249037311,TC
@@ -23639,7 +24447,42 @@
1249099776,1249101823,CA
1249101824,1249102847,PR
1249102848,1249103871,CA
-1249103872,1249106943,US
+1249103872,1249103887,TW
+1249103888,1249103903,PH
+1249103904,1249103951,US
+1249103952,1249103967,TW
+1249103968,1249104095,US
+1249104096,1249104111,TW
+1249104112,1249104127,US
+1249104128,1249104191,GB
+1249104192,1249104255,US
+1249104256,1249104319,GB
+1249104320,1249104351,US
+1249104352,1249104367,AU
+1249104368,1249104383,US
+1249104384,1249104447,GB
+1249104448,1249104511,US
+1249104512,1249104543,GB
+1249104544,1249104551,ES
+1249104552,1249104575,US
+1249104576,1249104607,ES
+1249104608,1249104895,US
+1249104896,1249104959,GB
+1249104960,1249105119,US
+1249105120,1249105127,AR
+1249105128,1249105135,US
+1249105136,1249105143,CH
+1249105144,1249105183,US
+1249105184,1249105191,ZA
+1249105192,1249105215,US
+1249105216,1249105279,GB
+1249105280,1249105295,CA
+1249105296,1249105367,US
+1249105368,1249105375,ES
+1249105376,1249105535,US
+1249105536,1249105567,ES
+1249105568,1249105599,CA
+1249105600,1249106943,US
1249106944,1249107967,CA
1249107968,1249130495,US
1249130496,1249131519,JM
@@ -23652,7 +24495,11 @@
1249171456,1249173503,CA
1249173504,1249179831,US
1249179832,1249179839,CA
-1249179840,1249191935,US
+1249179840,1249179967,US
+1249179968,1249179983,SE
+1249179984,1249180031,US
+1249180032,1249180095,TW
+1249180096,1249191935,US
1249191936,1249193983,CA
1249193984,1249203199,US
1249203200,1249204223,GD
@@ -23660,7 +24507,9 @@
1249210368,1249212415,KY
1249212416,1249217535,US
1249217536,1249218559,CA
-1249218560,1249236991,US
+1249218560,1249221887,US
+1249221888,1249222655,RO
+1249222656,1249236991,US
1249236992,1249239039,KY
1249239040,1249245183,US
1249245184,1249247231,CA
@@ -23692,7 +24541,9 @@
1249474560,1249475583,CA
1249475584,1249484799,US
1249484800,1249486847,CA
-1249486848,1249506303,US
+1249486848,1249492735,US
+1249492736,1249492991,CA
+1249492992,1249506303,US
1249506304,1249507327,CA
1249507328,1249522687,US
1249522688,1249523711,CA
@@ -23702,7 +24553,9 @@
1249542144,1249544191,CA
1249544192,1249562623,US
1249562624,1249564671,CA
-1249564672,1249571839,US
+1249564672,1249568319,US
+1249568320,1249568327,NL
+1249568328,1249571839,US
1249571840,1249572863,CA
1249572864,1249577087,US
1249577088,1249577983,CA
@@ -23726,9 +24579,15 @@
1249796096,1249804287,CA
1249804288,1249838847,US
1249838848,1249838911,IN
-1249838912,1249839423,US
+1249838912,1249838975,US
+1249838976,1249839039,IN
+1249839040,1249839423,US
1249839424,1249839487,VE
-1249839488,1249845311,US
+1249839488,1249843231,US
+1249843232,1249843247,IN
+1249843248,1249843423,US
+1249843424,1249843439,IN
+1249843440,1249845311,US
1249845312,1249845327,IN
1249845328,1249845343,US
1249845344,1249845375,IN
@@ -24309,8 +25168,8 @@
1255007488,1255007711,CA
1255007712,1255011343,US
1255011344,1255011359,CA
-1255011360,1255011367,US
-1255011368,1255011551,CA
+1255011360,1255011375,US
+1255011376,1255011551,CA
1255011552,1255011559,US
1255011560,1255011839,CA
1255011840,1255039631,US
@@ -24329,8 +25188,7 @@
1255058672,1255058687,GB
1255058688,1255059151,US
1255059152,1255059167,GB
-1255059168,1255059199,BS
-1255059200,1255059327,US
+1255059168,1255059327,US
1255059328,1255059343,NL
1255059344,1255059359,US
1255059360,1255059407,CA
@@ -24357,19 +25215,15 @@
1255062848,1255062863,CA
1255062864,1255063551,US
1255063552,1255071743,PR
-1255071744,1255193599,US
-1255193600,1255194623,GB
-1255194624,1255210495,US
+1255071744,1255210495,US
1255210496,1255211007,DE
1255211008,1255276543,US
1255276544,1255342079,CA
1255342080,1255369055,US
1255369056,1255369087,DE
-1255369088,1255372287,US
-1255372288,1255372543,CA
-1255372544,1255373823,US
-1255373824,1255374079,CA
-1255374080,1255489535,US
+1255369088,1255373759,US
+1255373760,1255373791,DE
+1255373792,1255489535,US
1255489536,1255505919,PR
1255505920,1255514111,US
1255514112,1255522303,CA
@@ -24383,9 +25237,9 @@
1255753216,1255753471,GB
1255753472,1255768063,US
1255768064,1255768575,CA
-1255768576,1255771135,US
-1255771136,1255772159,CA
-1255772160,1255780351,US
+1255768576,1255770367,US
+1255770368,1255770623,CA
+1255770624,1255780351,US
1255780352,1255782399,CA
1255782400,1255796743,US
1255796744,1255796751,GB
@@ -24395,28 +25249,26 @@
1256001536,1256005631,CA
1256005632,1256057975,US
1256057976,1256057983,BZ
-1256057984,1256079359,US
+1256057984,1256057999,US
+1256058000,1256058007,CA
+1256058008,1256058719,US
+1256058720,1256058727,CA
+1256058728,1256079359,US
1256079360,1256087551,KY
-1256087552,1256098303,US
-1256098304,1256098339,CA
-1256098340,1256098343,US
-1256098344,1256098815,CA
+1256087552,1256098559,US
+1256098560,1256098815,CA
1256098816,1263264273,US
1263264274,1263264289,PK
-1263264290,1263264305,CA
+1263264290,1263264305,US
1263264306,1263264354,PK
-1263264355,1263264386,US
-1263264387,1263264450,CA
-1263264451,1263264767,US
-1263264768,1263265023,CA
-1263265024,1263266559,US
-1263266560,1263266815,CA
-1263266816,1263267327,US
+1263264355,1263266623,US
+1263266624,1263266655,CA
+1263266656,1263267327,US
1263267328,1263267583,CA
1263267584,1263267647,US
1263267648,1263267679,CA
-1263267680,1263268095,US
-1263268096,1263268191,CA
+1263267680,1263267839,US
+1263267840,1263268191,CA
1263268192,1263268275,US
1263268276,1263268340,CA
1263268341,1263268343,US
@@ -24425,20 +25277,15 @@
1263268608,1263268672,CA
1263268673,1263268769,US
1263268770,1263268863,CA
-1263268864,1263269119,US
-1263269120,1263269631,CA
-1263269632,1263270143,US
-1263270144,1263270911,CA
-1263270912,1263271423,US
+1263268864,1263271423,US
1263271424,1263271679,CA
1263271680,1264717823,US
1264717824,1264718335,CA
1264718336,1264736255,US
1264736256,1264737279,DO
-1264737280,1264738303,US
-1264779264,1264980223,US
-1264980224,1264980479,HK
-1264980480,1264980735,US
+1264737280,1264762879,US
+1264762880,1264766975,CA
+1264766976,1264980735,US
1264980736,1264980743,CA
1264980744,1266107759,US
1266107760,1266107775,UM
@@ -24456,7 +25303,23 @@
1268252672,1268776959,CA
1268776960,1275600895,US
1275600896,1275604991,BM
-1275604992,1275621375,US
+1275604992,1275605263,US
+1275605264,1275605279,PL
+1275605280,1275605567,US
+1275605568,1275605583,PL
+1275605584,1275605823,US
+1275605824,1275605839,PL
+1275605840,1275606207,US
+1275606208,1275606223,PL
+1275606224,1275606367,US
+1275606368,1275606383,PL
+1275606384,1275606975,US
+1275606976,1275606991,PL
+1275606992,1275607071,US
+1275607072,1275607087,PL
+1275607088,1275607407,US
+1275607408,1275607423,PL
+1275607424,1275621375,US
1275621376,1275625471,CA
1275625472,1275658239,US
1275658240,1275658495,GB
@@ -24854,7 +25717,29 @@
1279956312,1279956351,CA
1279956352,1279956455,US
1279956456,1279956463,PA
-1279956464,1279959551,US
+1279956464,1279956998,US
+1279956999,1279957007,IN
+1279957008,1279957119,US
+1279957120,1279957128,IN
+1279957129,1279957135,US
+1279957136,1279957151,IN
+1279957152,1279957231,US
+1279957232,1279957243,IN
+1279957244,1279957375,US
+1279957376,1279957383,IN
+1279957384,1279957407,US
+1279957408,1279957427,IN
+1279957428,1279957431,US
+1279957432,1279957439,IN
+1279957440,1279957631,US
+1279957632,1279957651,IN
+1279957652,1279957655,US
+1279957656,1279957674,IN
+1279957675,1279958020,US
+1279958021,1279958030,IN
+1279958031,1279958399,US
+1279958400,1279958495,IN
+1279958496,1279959551,US
1279959552,1279959807,CA
1279959808,1279960063,US
1279960064,1279960127,CA
@@ -24903,8 +25788,8 @@
1279975264,1279975295,EG
1279975296,1279975407,US
1279975408,1279975423,NZ
-1279975424,1279975679,CA
-1279975680,1279975959,US
+1279975424,1279975695,CA
+1279975696,1279975959,US
1279975960,1279975967,CA
1279975968,1279975975,HK
1279975976,1279975983,US
@@ -24921,7 +25806,19 @@
1279978272,1279978303,US
1279978304,1279978367,CA
1279978368,1279978495,VG
-1279978496,1279979559,US
+1279978496,1279978683,US
+1279978684,1279978692,IN
+1279978693,1279978693,US
+1279978694,1279978702,IN
+1279978703,1279978891,US
+1279978892,1279978899,IN
+1279978900,1279978927,US
+1279978928,1279978939,IN
+1279978940,1279979007,US
+1279979008,1279979263,IN
+1279979264,1279979327,US
+1279979328,1279979391,IN
+1279979392,1279979559,US
1279979560,1279979575,CA
1279979576,1279979583,US
1279979584,1279980063,CA
@@ -24930,7 +25827,17 @@
1279980080,1279980127,CA
1279980128,1279980135,US
1279980136,1279981567,CA
-1279981568,1279999999,US
+1279981568,1279981823,US
+1279981824,1279981855,VG
+1279981856,1279982778,US
+1279982779,1279982788,IN
+1279982789,1279983047,US
+1279983048,1279983072,IN
+1279983073,1279983079,US
+1279983080,1279983087,IN
+1279983088,1279983519,US
+1279983520,1279983532,IN
+1279983533,1279999999,US
1280000000,1280032767,CA
1280032768,1280040959,US
1280040960,1280043527,CA
@@ -25059,193 +25966,8 @@
1280049072,1280049095,CA
1280049096,1280049127,US
1280049128,1280049151,CA
-1280049152,1280073735,US
-1280073736,1280073743,DE
-1280073744,1280073759,US
-1280073760,1280073767,CA
-1280073768,1280073775,US
-1280073776,1280073791,CA
-1280073792,1280073799,CR
-1280073800,1280073807,US
-1280073808,1280073815,MY
-1280073816,1280073823,CA
-1280073824,1280073831,US
-1280073832,1280073847,CA
-1280073848,1280073855,LT
-1280073856,1280073863,UA
-1280073864,1280073879,US
-1280073880,1280073887,CA
-1280073888,1280073895,RU
-1280073896,1280073903,US
-1280073904,1280073911,CA
-1280073912,1280073919,NL
-1280073920,1280073935,CA
-1280073936,1280073943,US
-1280073944,1280073951,ZA
-1280073952,1280073959,CR
-1280073960,1280073967,FR
-1280073968,1280073975,US
-1280073976,1280073983,CA
-1280073984,1280073999,US
-1280074000,1280074007,BR
-1280074008,1280074023,US
-1280074024,1280074039,CA
-1280074040,1280074047,US
-1280074048,1280074055,HU
-1280074056,1280074071,US
-1280074072,1280074087,CA
-1280074088,1280074095,US
-1280074096,1280074103,IL
-1280074104,1280074127,US
-1280074128,1280074135,CA
-1280074136,1280074143,CN
-1280074144,1280074151,GB
-1280074152,1280074159,CA
-1280074160,1280074175,US
-1280074176,1280074183,CA
-1280074184,1280074199,US
-1280074200,1280074207,MY
-1280074208,1280074215,DE
-1280074216,1280074223,US
-1280074224,1280074231,CA
-1280074232,1280074239,SG
-1280074240,1280074247,GB
-1280074248,1280074255,US
-1280074256,1280074263,DE
-1280074264,1280074271,FR
-1280074272,1280074279,CA
-1280074280,1280074287,US
-1280074288,1280074295,CA
-1280074296,1280074303,US
-1280074304,1280074311,CA
-1280074312,1280074319,RU
-1280074320,1280074327,US
-1280074328,1280074359,CA
-1280074360,1280074375,US
-1280074376,1280074383,CA
-1280074384,1280074391,PA
-1280074392,1280074399,US
-1280074400,1280074415,CA
-1280074416,1280074423,JP
-1280074424,1280074431,CA
-1280074432,1280074439,US
-1280074440,1280074455,CA
-1280074456,1280074463,US
-1280074464,1280074479,CA
-1280074480,1280074487,AU
-1280074488,1280074495,PA
-1280074496,1280074511,US
-1280074512,1280074519,MY
-1280074520,1280074527,CA
-1280074528,1280074567,US
-1280074568,1280074575,CA
-1280074576,1280074583,NL
-1280074584,1280074599,US
-1280074600,1280074607,CA
-1280074608,1280074615,US
-1280074616,1280074623,CA
-1280074624,1280074631,VG
-1280074632,1280074639,CA
-1280074640,1280074655,US
-1280074656,1280074663,AU
-1280074664,1280074671,CA
-1280074672,1280074687,US
-1280074688,1280074695,FR
-1280074696,1280074703,CA
-1280074704,1280074711,MY
-1280074712,1280074719,CA
-1280074720,1280074735,US
-1280074736,1280074751,CA
-1280074752,1280074759,US
-1280074760,1280074767,RO
-1280074768,1280074775,CA
-1280074776,1280074783,AE
-1280074784,1280074791,AU
-1280074792,1280074799,US
-1280074800,1280074807,NL
-1280074808,1280074815,GB
-1280074816,1280074823,CA
-1280074824,1280074831,FR
-1280074832,1280074839,IL
-1280074840,1280074847,CO
-1280074848,1280074855,IT
-1280074856,1280074871,CA
-1280074872,1280074887,US
-1280074888,1280074895,CA
-1280074896,1280074911,US
-1280074912,1280074919,CA
-1280074920,1280074935,US
-1280074936,1280074943,GB
-1280074944,1280074959,CA
-1280074960,1280074967,US
-1280074968,1280074975,CA
-1280074976,1280074999,US
-1280075000,1280075007,GI
-1280075008,1280075015,US
-1280075016,1280075039,CA
-1280075040,1280075047,IE
-1280075048,1280075055,NL
-1280075056,1280075063,RU
-1280075064,1280075071,IT
-1280075072,1280075087,CA
-1280075088,1280075095,US
-1280075096,1280075103,CL
-1280075104,1280075119,US
-1280075120,1280075127,CA
-1280075128,1280075135,MY
-1280075136,1280075143,CA
-1280075144,1280075151,US
-1280075152,1280075159,MY
-1280075160,1280075167,US
-1280075168,1280075175,MY
-1280075176,1280075183,CA
-1280075184,1280075191,US
-1280075192,1280075231,CA
-1280075232,1280075239,NL
-1280075240,1280075271,US
-1280075272,1280075295,CA
-1280075296,1280075303,US
-1280075304,1280075327,CA
-1280075328,1280075343,US
-1280075344,1280075351,CA
-1280075352,1280075359,MY
-1280075360,1280075367,US
-1280075368,1280075375,CA
-1280075376,1280075383,US
-1280075384,1280075391,CA
-1280075392,1280075415,MY
-1280075416,1280075423,US
-1280075424,1280075439,CA
-1280075440,1280075471,US
-1280075472,1280075487,CA
-1280075488,1280075495,CR
-1280075496,1280075503,GB
-1280075504,1280075511,CA
-1280075512,1280075519,CN
-1280075520,1280075527,PH
-1280075528,1280075535,CA
-1280075536,1280075543,IT
-1280075544,1280075551,ZA
-1280075552,1280075559,TR
-1280075560,1280075567,AE
-1280075568,1280075575,US
-1280075576,1280075583,CA
-1280075584,1280075615,US
-1280075616,1280075623,GB
-1280075624,1280075655,CA
-1280075656,1280075679,US
-1280075680,1280075687,MY
-1280075688,1280075719,CA
-1280075720,1280075727,US
-1280075728,1280075759,CA
-1280075760,1280075767,US
-1280075768,1280075775,GB
-1280075776,1280075783,US
-1280075784,1280078711,CA
-1280078712,1280078719,US
-1280078720,1280078743,CA
-1280078744,1280078751,US
-1280078752,1280081919,CA
+1280049152,1280073727,US
+1280073728,1280081919,CA
1280081920,1280090111,US
1280090112,1280091135,AI
1280091136,1280092159,VG
@@ -25257,9 +25979,11 @@
1280097280,1280097791,LC
1280097792,1280098303,AG
1280098304,1280102399,PR
-1280102400,1280131071,US
+1280102400,1280122879,US
1280131072,1280139263,CA
-1280139264,1287877503,US
+1280139264,1287612122,US
+1287612123,1287612136,SE
+1287612137,1287877503,US
1287877504,1287877567,UM
1287877568,1290252799,US
1290252800,1290252863,GB
@@ -25333,8 +26057,7 @@
1296238592,1296239103,NL
1296239104,1296239231,FR
1296239232,1296239359,NL
-1296239360,1296239615,ES
-1296239616,1296240127,FR
+1296239360,1296240127,FR
1296240128,1296241151,BE
1296241152,1296241407,IT
1296241408,1296242175,NL
@@ -25388,7 +26111,8 @@
1296251328,1296251359,IE
1296251360,1296251391,DE
1296251392,1296251775,NL
-1296251776,1296252111,FR
+1296251776,1296252095,FR
+1296252096,1296252111,US
1296252112,1296252127,GB
1296252128,1296252143,ES
1296252144,1296252159,US
@@ -25404,7 +26128,9 @@
1296252320,1296252367,FR
1296252368,1296252383,DE
1296252384,1296252415,IE
-1296252416,1296252687,FR
+1296252416,1296252671,FR
+1296252672,1296252679,GB
+1296252680,1296252687,FR
1296252688,1296252695,NL
1296252696,1296252703,IE
1296252704,1296252711,DE
@@ -25424,7 +26150,7 @@
1296252880,1296252887,DE
1296252888,1296252895,IE
1296252896,1296252911,BE
-1296252912,1296252919,FR
+1296252912,1296252919,GB
1296252920,1296252927,PL
1296252928,1296255743,DE
1296255744,1296255999,FR
@@ -25438,7 +26164,8 @@
1296259584,1296259839,FR
1296259840,1296260351,NL
1296260352,1296260607,US
-1296260608,1296262143,FR
+1296260608,1296260863,DE
+1296260864,1296262143,FR
1296262144,1296262655,US
1296262656,1296262911,CA
1296262912,1296263935,US
@@ -25493,15 +26220,15 @@
1296466384,1296466399,NO
1296466400,1296466415,AO
1296466416,1296466431,NG
-1296466432,1296466559,NO
+1296466432,1296466439,TZ
+1296466440,1296466559,NO
1296466560,1296466583,NG
1296466584,1296466607,NO
1296466608,1296466623,NG
1296466624,1296466639,NO
1296466640,1296466655,NG
1296466656,1296466671,BJ
-1296466672,1296466679,NG
-1296466680,1296466687,NO
+1296466672,1296466687,NO
1296466688,1296466719,BJ
1296466720,1296466751,NO
1296466752,1296466759,ML
@@ -25547,7 +26274,7 @@
1296606336,1296606367,AT
1296606368,1296606399,CH
1296606400,1296607231,AT
-1296607232,1296607743,DE
+1296607232,1296607743,CH
1296607744,1296607999,NL
1296608000,1296609023,CH
1296609024,1296609279,NL
@@ -25712,12 +26439,7 @@
1296957440,1296973823,BG
1296973824,1296990207,CZ
1296990208,1297006591,BG
-1297006592,1297018623,BA
-1297018624,1297019135,MD
-1297019136,1297020927,BA
-1297020928,1297021183,RS
-1297021184,1297021439,MD
-1297021440,1297022207,BA
+1297006592,1297022207,BA
1297022208,1297022463,MD
1297022464,1297022975,BA
1297022976,1297039359,LT
@@ -25788,7 +26510,8 @@
1297867584,1297867647,SC
1297867648,1297867687,RU
1297867688,1297867695,CY
-1297867696,1297867871,RU
+1297867696,1297867855,RU
+1297867856,1297867871,MK
1297867872,1297867879,ES
1297867880,1297868799,RU
1297868800,1297870847,DE
@@ -25817,7 +26540,7 @@
1297993312,1297997823,CZ
1297997824,1298006015,IT
1298006016,1298014207,RU
-1298014208,1298014719,LB
+1298014208,1298014719,LT
1298014720,1298014975,RU
1298014976,1298015231,LT
1298015232,1298015487,RU
@@ -25917,7 +26640,9 @@
1299016960,1299017215,NL
1299017216,1299017727,RU
1299017728,1299021823,BE
-1299021824,1299026111,CH
+1299021824,1299024559,CH
+1299024560,1299024575,DE
+1299024576,1299026111,CH
1299026112,1299026127,ES
1299026128,1299026251,CH
1299026252,1299026263,PT
@@ -25952,7 +26677,10 @@
1306263552,1306271743,KE
1306271744,1306279935,RU
1306279936,1306286079,IT
-1306286080,1306288127,CH
+1306286080,1306287103,CH
+1306287104,1306287615,IT
+1306287616,1306287903,CH
+1306287904,1306288127,IT
1306288128,1306296319,AT
1306296320,1306311143,RU
1306311144,1306311151,CH
@@ -26034,6 +26762,7 @@
1307435008,1307443199,DE
1307443200,1307451391,IT
1307451392,1307459583,SE
+1307459584,1307467775,BG
1307467776,1307484159,RU
1307484160,1307488767,GB
1307488768,1307489023,IE
@@ -26119,14 +26848,13 @@
1307756448,1307756543,GB
1307756544,1307756847,FR
1307756848,1307756863,US
-1307756864,1307756903,FR
+1307756864,1307756903,GB
1307756904,1307756911,US
-1307756912,1307757063,FR
+1307756912,1307757063,GB
1307757064,1307757071,US
-1307757072,1307757183,FR
+1307757072,1307757183,GB
1307757184,1307757247,US
-1307757248,1307757567,FR
-1307757568,1307758591,GB
+1307757248,1307758591,GB
1307758592,1307762687,SM
1307762688,1307766783,PL
1307766784,1307770879,GB
@@ -26151,14 +26879,18 @@
1307848704,1307852799,CH
1307852800,1307856895,RU
1307856896,1307860991,IT
-1307860992,1307861119,DE
+1307860992,1307861079,DE
+1307861080,1307861083,LU
+1307861084,1307861119,DE
1307861120,1307861123,LU
1307861124,1307861127,A2
1307861128,1307861151,DE
1307861152,1307861155,LU
1307861156,1307861919,DE
1307861920,1307861935,LU
-1307861936,1307864127,DE
+1307861936,1307861983,DE
+1307861984,1307861987,A2
+1307861988,1307864127,DE
1307864128,1307864135,LU
1307864136,1307864143,DE
1307864144,1307864147,A2
@@ -26177,7 +26909,9 @@
1307887104,1307889663,DK
1307889664,1307893759,RU
1307893760,1307897855,SE
-1307897856,1307901951,AT
+1307897856,1307901663,AT
+1307901664,1307901671,DE
+1307901672,1307901951,AT
1307901952,1307906047,JO
1307906048,1307906599,CH
1307906600,1307906607,DK
@@ -26196,7 +26930,9 @@
1307919700,1307919703,ZA
1307919704,1307920575,GB
1307920576,1307920583,AU
-1307920584,1307921471,GB
+1307920584,1307921431,GB
+1307921432,1307921439,BD
+1307921440,1307921471,GB
1307921472,1307921535,ES
1307921536,1307922431,GB
1307922432,1307926527,NL
@@ -26800,7 +27536,9 @@
1315860480,1315864575,IR
1315864576,1315868671,CH
1315868672,1315872767,RU
-1315872768,1315876863,GB
+1315872768,1315875183,GB
+1315875184,1315875199,ES
+1315875200,1315876863,GB
1315876864,1315880959,IT
1315880960,1315885055,BE
1315885056,1315889151,CZ
@@ -26890,7 +27628,9 @@
1317640704,1317641215,GB
1317641216,1317641471,IE
1317641472,1317641727,GB
-1317641728,1317642975,IE
+1317641728,1317642863,IE
+1317642864,1317642879,GB
+1317642880,1317642975,IE
1317642976,1317642991,GB
1317642992,1317645407,IE
1317645408,1317645823,GB
@@ -26905,8 +27645,8 @@
1317649920,1317650023,IE
1317650024,1317650031,GB
1317650032,1317650047,IE
-1317650048,1317650111,GB
-1317650112,1317650135,IE
+1317650048,1317650095,GB
+1317650096,1317650135,IE
1317650136,1317650143,GB
1317650144,1317650431,IE
1317650432,1317666815,RU
@@ -26928,25 +27668,22 @@
1317667040,1317667047,GH
1317667048,1317667055,A2
1317667056,1317667063,LR
-1317667064,1317667071,A2
-1317667072,1317667079,AO
-1317667080,1317667103,A2
+1317667064,1317667103,A2
1317667104,1317667111,NG
-1317667112,1317667119,GH
-1317667120,1317667135,A2
+1317667112,1317667135,A2
1317667136,1317667143,AO
1317667144,1317667151,A2
1317667152,1317667159,NG
1317667160,1317667167,AO
1317667168,1317667175,NG
-1317667176,1317667183,GH
-1317667184,1317667191,A2
+1317667176,1317667191,A2
1317667192,1317667231,NG
1317667232,1317667239,GH
1317667240,1317667247,NG
1317667248,1317667263,A2
1317667264,1317667271,GB
-1317667272,1317667295,NG
+1317667272,1317667279,A2
+1317667280,1317667295,NG
1317667296,1317667303,A2
1317667304,1317667335,NG
1317667336,1317667343,A2
@@ -26965,15 +27702,15 @@
1317667496,1317667503,NG
1317667504,1317667551,A2
1317667552,1317667567,NG
-1317667568,1317667583,A2
-1317667584,1317667719,NG
+1317667568,1317667711,A2
+1317667712,1317667719,NG
1317667720,1317667735,A2
1317667736,1317667743,NG
1317667744,1317667751,A2
1317667752,1317667759,NG
1317667760,1317667767,FR
1317667768,1317667775,ZA
-1317667776,1317667783,A2
+1317667776,1317667783,US
1317667784,1317667823,NG
1317667824,1317668095,A2
1317668096,1317668103,GH
@@ -26992,8 +27729,7 @@
1317668248,1317668255,NG
1317668256,1317668271,A2
1317668272,1317668279,SL
-1317668280,1317668295,A2
-1317668296,1317668303,CD
+1317668280,1317668303,A2
1317668304,1317668311,NG
1317668312,1317668319,IQ
1317668320,1317668343,A2
@@ -27032,8 +27768,7 @@
1317668672,1317668703,NG
1317668704,1317668727,A2
1317668728,1317668735,NG
-1317668736,1317668759,A2
-1317668760,1317668767,IQ
+1317668736,1317668767,A2
1317668768,1317668775,LR
1317668776,1317668791,NG
1317668792,1317668807,A2
@@ -27045,18 +27780,18 @@
1317668856,1317668863,A2
1317668864,1317668871,LR
1317668872,1317668911,A2
-1317668912,1317668927,NG
-1317668928,1317668935,A2
+1317668912,1317668919,NG
+1317668920,1317668935,A2
1317668936,1317668943,NG
1317668944,1317668959,A2
1317668960,1317668983,NG
1317668984,1317668999,A2
1317669000,1317669007,CD
-1317669008,1317669023,NG
-1317669024,1317669055,A2
+1317669008,1317669015,NG
+1317669016,1317669055,A2
1317669056,1317669079,NG
-1317669080,1317669087,A2
-1317669088,1317669103,NG
+1317669080,1317669095,A2
+1317669096,1317669103,NG
1317669104,1317669111,A2
1317669112,1317669119,NG
1317669120,1317669375,GE
@@ -27072,8 +27807,7 @@
1317670016,1317670063,A2
1317670064,1317670103,NG
1317670104,1317670111,A2
-1317670112,1317670135,NG
-1317670136,1317670143,A2
+1317670112,1317670143,NG
1317670144,1317670175,SL
1317670176,1317670215,A2
1317670216,1317670223,NG
@@ -27082,13 +27816,12 @@
1317670240,1317670247,NG
1317670248,1317670255,A2
1317670256,1317670263,NG
-1317670264,1317670407,A2
-1317670408,1317670415,CD
-1317670416,1317670423,A2
+1317670264,1317670423,A2
1317670424,1317670431,NG
1317670432,1317670447,A2
1317670448,1317670455,IQ
-1317670456,1317670471,NG
+1317670456,1317670463,A2
+1317670464,1317670471,NG
1317670472,1317670479,CO
1317670480,1317670511,A2
1317670512,1317670519,CI
@@ -27115,7 +27848,7 @@
1317670776,1317670783,A2
1317670784,1317670791,GH
1317670792,1317670807,NG
-1317670808,1317670815,AO
+1317670808,1317670815,A2
1317670816,1317670823,NG
1317670824,1317670847,A2
1317670848,1317670855,NG
@@ -27126,9 +27859,7 @@
1317670897,1317670911,NG
1317670912,1317671175,A2
1317671176,1317671191,NG
-1317671192,1317671199,A2
-1317671200,1317671207,CI
-1317671208,1317671231,A2
+1317671192,1317671231,A2
1317671232,1317671239,NG
1317671240,1317671247,CI
1317671248,1317671255,NG
@@ -27137,22 +27868,21 @@
1317671272,1317671279,A2
1317671280,1317671311,NG
1317671312,1317671319,A2
-1317671320,1317671335,NG
+1317671320,1317671327,NG
+1317671328,1317671335,A2
1317671336,1317671343,BW
-1317671344,1317671351,CD
-1317671352,1317671359,A2
+1317671344,1317671359,A2
1317671360,1317671367,NG
1317671368,1317671375,A2
1317671376,1317671383,NG
1317671384,1317671391,CI
1317671392,1317671399,NG
1317671400,1317671407,IQ
-1317671408,1317671415,A2
+1317671408,1317671415,UG
1317671416,1317671423,NG
1317671424,1317671439,A2
1317671440,1317671487,NG
-1317671488,1317671503,AO
-1317671504,1317671527,A2
+1317671488,1317671527,A2
1317671528,1317671543,NG
1317671544,1317671551,GH
1317671552,1317671567,NG
@@ -27196,9 +27926,7 @@
1317672624,1317672655,A2
1317672656,1317672663,CD
1317672664,1317672679,NG
-1317672680,1317672703,A2
-1317672704,1317672711,NG
-1317672712,1317672727,A2
+1317672680,1317672727,A2
1317672728,1317672735,NG
1317672736,1317672743,LR
1317672744,1317672759,A2
@@ -27211,20 +27939,20 @@
1317672832,1317672839,A2
1317672840,1317672847,NG
1317672848,1317672863,A2
-1317672864,1317672895,NG
+1317672864,1317672871,NG
+1317672872,1317672879,A2
+1317672880,1317672895,NG
1317672896,1317672903,A2
1317672904,1317672919,CI
1317672920,1317672927,GH
1317672928,1317672951,NG
1317672952,1317672959,A2
-1317672960,1317673239,NG
-1317673240,1317673255,A2
-1317673256,1317673271,NG
+1317672960,1317673247,NG
+1317673248,1317673263,A2
+1317673264,1317673271,UG
1317673272,1317673279,A2
1317673280,1317673287,NG
-1317673288,1317673311,A2
-1317673312,1317673319,NG
-1317673320,1317673335,A2
+1317673288,1317673335,A2
1317673336,1317673343,GH
1317673344,1317673359,A2
1317673360,1317673375,NG
@@ -27264,8 +27992,8 @@
1317673744,1317673751,IQ
1317673752,1317673815,A2
1317673816,1317673823,LR
-1317673824,1317673855,A2
-1317673856,1317673871,NG
+1317673824,1317673863,A2
+1317673864,1317673871,NG
1317673872,1317673903,A2
1317673904,1317673911,NG
1317673912,1317673919,AO
@@ -27280,11 +28008,11 @@
1317674256,1317674263,CM
1317674264,1317674271,A2
1317674272,1317674279,NG
-1317674280,1317674287,CD
+1317674280,1317674287,A2
1317674288,1317674295,GH
1317674296,1317674303,AO
-1317674304,1317674319,NG
-1317674320,1317674351,A2
+1317674304,1317674335,NG
+1317674336,1317674351,A2
1317674352,1317674359,NG
1317674360,1317674383,A2
1317674384,1317674399,NG
@@ -27309,42 +28037,43 @@
1317674632,1317674639,A2
1317674640,1317674647,NG
1317674648,1317674655,A2
-1317674656,1317674671,NG
-1317674672,1317674687,A2
+1317674656,1317674679,NG
+1317674680,1317674687,A2
1317674688,1317674703,NG
1317674704,1317674711,A2
1317674712,1317674735,NG
1317674736,1317674743,AO
1317674744,1317674751,IQ
-1317674752,1317674791,NG
+1317674752,1317674759,NG
+1317674760,1317674767,A2
+1317674768,1317674791,NG
1317674792,1317674799,A2
1317674800,1317674807,NG
1317674808,1317674823,A2
-1317674824,1317674863,NG
+1317674824,1317674839,NG
+1317674840,1317674847,A2
+1317674848,1317674863,NG
1317674864,1317674879,A2
1317674880,1317674887,NG
-1317674888,1317674895,AO
-1317674896,1317674911,A2
+1317674888,1317674911,A2
1317674912,1317674927,NG
1317674928,1317674935,A2
1317674936,1317674943,NG
1317674944,1317674951,GA
1317674952,1317674959,NG
1317674960,1317674967,GH
-1317674968,1317674975,NG
-1317674976,1317674991,A2
+1317674968,1317674983,NG
+1317674984,1317674991,A2
1317674992,1317675007,NG
1317675008,1317675023,A2
-1317675024,1317675031,NG
-1317675032,1317675039,A2
-1317675040,1317675047,NG
+1317675024,1317675047,NG
1317675048,1317675055,A2
1317675056,1317675063,NG
1317675064,1317675071,AO
1317675072,1317675095,NG
-1317675096,1317675119,A2
-1317675120,1317675127,NG
-1317675128,1317675183,A2
+1317675096,1317675103,A2
+1317675104,1317675111,CD
+1317675112,1317675183,A2
1317675184,1317675199,CM
1317675200,1317675223,NG
1317675224,1317675231,A2
@@ -27394,47 +28123,210 @@
1317675696,1317675703,NG
1317675704,1317675711,A2
1317675712,1317675719,CM
-1317675720,1317675735,NG
+1317675720,1317675727,A2
+1317675728,1317675735,NG
1317675736,1317675743,A2
1317675744,1317675751,GH
1317675752,1317675759,NG
1317675760,1317675775,GH
1317675776,1317675783,NG
-1317675784,1317675815,A2
-1317675816,1317675831,NG
-1317675832,1317675911,A2
-1317675912,1317675927,NG
-1317675928,1317675951,A2
-1317675952,1317675967,NG
-1317675968,1317676287,A2
-1317676288,1317676543,LR
-1317676544,1317676583,A2
+1317675784,1317675799,A2
+1317675800,1317675807,NG
+1317675808,1317675815,A2
+1317675816,1317675839,NG
+1317675840,1317675855,A2
+1317675856,1317675863,NG
+1317675864,1317675887,A2
+1317675888,1317675895,CD
+1317675896,1317675911,A2
+1317675912,1317675935,NG
+1317675936,1317675943,A2
+1317675944,1317675975,NG
+1317675976,1317675983,A2
+1317675984,1317675991,LR
+1317675992,1317675999,A2
+1317676000,1317676007,GN
+1317676008,1317676015,GH
+1317676016,1317676023,SD
+1317676024,1317676031,GQ
+1317676032,1317676039,NG
+1317676040,1317676047,CD
+1317676048,1317676063,A2
+1317676064,1317676071,CM
+1317676072,1317676079,A2
+1317676080,1317676087,AO
+1317676088,1317676095,NG
+1317676096,1317676103,NE
+1317676104,1317676111,NG
+1317676112,1317676127,A2
+1317676128,1317676135,NG
+1317676136,1317676151,A2
+1317676152,1317676159,CM
+1317676160,1317676167,TG
+1317676168,1317676175,ML
+1317676176,1317676191,A2
+1317676192,1317676207,SD
+1317676208,1317676215,A2
+1317676216,1317676223,GH
+1317676224,1317676231,AO
+1317676232,1317676239,NG
+1317676240,1317676247,SD
+1317676248,1317676255,NG
+1317676256,1317676263,CD
+1317676264,1317676271,NG
+1317676272,1317676279,A2
+1317676280,1317676287,NG
+1317676288,1317676551,LR
+1317676552,1317676559,AO
+1317676560,1317676567,NG
+1317676568,1317676583,A2
1317676584,1317676591,NG
-1317676592,1317676655,A2
+1317676592,1317676599,AO
+1317676600,1317676607,UG
+1317676608,1317676615,NG
+1317676616,1317676623,A2
+1317676624,1317676631,CM
+1317676632,1317676639,A2
+1317676640,1317676647,LR
+1317676648,1317676655,A2
1317676656,1317676671,NG
-1317676672,1317676823,A2
+1317676672,1317676687,A2
+1317676688,1317676695,LR
+1317676696,1317676711,A2
+1317676712,1317676719,NG
+1317676720,1317676727,GQ
+1317676728,1317676751,A2
+1317676752,1317676759,ML
+1317676760,1317676767,LR
+1317676768,1317676775,A2
+1317676776,1317676783,UG
+1317676784,1317676799,A2
+1317676800,1317676807,CD
+1317676808,1317676815,NG
+1317676816,1317676823,LR
1317676824,1317676831,NG
-1317676832,1317676895,A2
-1317676896,1317676919,NG
-1317676920,1317676991,A2
+1317676832,1317676847,A2
+1317676848,1317676855,NG
+1317676856,1317676863,A2
+1317676864,1317676871,TG
+1317676872,1317676879,NG
+1317676880,1317676903,A2
+1317676904,1317676927,NG
+1317676928,1317676943,A2
+1317676944,1317676959,CM
+1317676960,1317676983,A2
+1317676984,1317676991,NG
1317676992,1317676999,LR
1317677000,1317677007,IQ
-1317677008,1317677015,IT
-1317677016,1317677023,A2
+1317677008,1317677015,CD
+1317677016,1317677023,GH
1317677024,1317677031,NG
-1317677032,1317677079,A2
+1317677032,1317677047,A2
+1317677048,1317677055,NG
+1317677056,1317677071,A2
+1317677072,1317677079,NG
1317677080,1317677087,SD
1317677088,1317677143,A2
1317677144,1317677151,SD
-1317677152,1317677199,A2
+1317677152,1317677191,A2
+1317677192,1317677199,SD
1317677200,1317677207,NG
1317677208,1317677223,A2
1317677224,1317677231,NG
-1317677232,1317677247,A2
-1317677248,1317677255,NG
-1317677256,1317677303,A2
-1317677304,1317677311,NG
-1317677312,1317683199,A2
+1317677232,1317677239,UG
+1317677240,1317677247,A2
+1317677248,1317677271,NG
+1317677272,1317677295,A2
+1317677296,1317677311,NG
+1317677312,1317677319,A2
+1317677320,1317677327,AO
+1317677328,1317677335,CD
+1317677336,1317677343,A2
+1317677344,1317677351,NG
+1317677352,1317677367,CD
+1317677368,1317677375,NG
+1317677376,1317677399,A2
+1317677400,1317677407,NG
+1317677408,1317677415,CD
+1317677416,1317677423,A2
+1317677424,1317677431,CD
+1317677432,1317677439,A2
+1317677440,1317677455,CD
+1317677456,1317677463,AO
+1317677464,1317677471,A2
+1317677472,1317677479,NG
+1317677480,1317677487,AO
+1317677488,1317677495,A2
+1317677496,1317677503,CD
+1317677504,1317677511,NG
+1317677512,1317677519,CD
+1317677520,1317677527,NG
+1317677528,1317677535,GQ
+1317677536,1317677543,A2
+1317677544,1317677551,CD
+1317677552,1317677591,NG
+1317677592,1317677599,A2
+1317677600,1317677711,NG
+1317677712,1317677719,A2
+1317677720,1317677735,NG
+1317677736,1317677743,A2
+1317677744,1317677775,NG
+1317677776,1317677791,A2
+1317677792,1317677823,NG
+1317677824,1317677831,AO
+1317677832,1317677839,A2
+1317677840,1317677847,LR
+1317677848,1317677855,NG
+1317677856,1317677895,A2
+1317677896,1317677903,GN
+1317677904,1317677959,A2
+1317677960,1317677967,NG
+1317677968,1317678007,A2
+1317678008,1317678015,NG
+1317678016,1317678047,A2
+1317678048,1317678055,IQ
+1317678056,1317678143,A2
+1317678144,1317678151,CD
+1317678152,1317678167,A2
+1317678168,1317678175,NG
+1317678176,1317678207,A2
+1317678208,1317678215,NG
+1317678216,1317678231,A2
+1317678232,1317678239,BF
+1317678240,1317678335,A2
+1317678336,1317678343,NG
+1317678344,1317678375,A2
+1317678376,1317678383,NG
+1317678384,1317678439,A2
+1317678440,1317678447,CD
+1317678448,1317678455,A2
+1317678456,1317678463,CD
+1317678464,1317678471,A2
+1317678472,1317678479,AO
+1317678480,1317678487,A2
+1317678488,1317678495,NG
+1317678496,1317679615,A2
+1317679616,1317679631,AO
+1317679632,1317679639,A2
+1317679640,1317679647,ZW
+1317679648,1317679663,A2
+1317679664,1317679671,AO
+1317679672,1317679679,NG
+1317679680,1317679695,A2
+1317679696,1317679703,LU
+1317679704,1317679711,A2
+1317679712,1317679719,NG
+1317679720,1317679727,A2
+1317679728,1317679735,GN
+1317679736,1317679743,A2
+1317679744,1317679751,AO
+1317679752,1317679767,NG
+1317679768,1317679783,A2
+1317679784,1317679799,NG
+1317679800,1317679831,A2
+1317679832,1317679839,CD
+1317679840,1317679847,NG
+1317679848,1317683199,A2
1317683200,1317683839,DE
1317683840,1317683855,CH
1317683856,1317683863,DE
@@ -27476,14 +28368,15 @@
1317839680,1317839695,CZ
1317839696,1317841407,NL
1317841408,1317841439,SC
-1317841440,1317841727,NL
+1317841440,1317841663,NL
+1317841664,1317841727,HK
1317841728,1317841855,CY
1317841856,1317842943,NL
1317842944,1317843071,CY
1317843072,1317843135,HK
1317843136,1317843199,CY
-1317843200,1317843327,US
-1317843328,1317847039,NL
+1317843200,1317843391,US
+1317843392,1317847039,NL
1317847040,1317863423,RU
1317863424,1317879807,GB
1317879808,1317896191,SK
@@ -27509,7 +28402,9 @@
1318006272,1318006783,NL
1318006784,1318007999,DE
1318008000,1318008031,NL
-1318008032,1318009423,DE
+1318008032,1318008703,DE
+1318008704,1318008767,NL
+1318008768,1318009423,DE
1318009424,1318009471,NL
1318009472,1318010527,DE
1318010528,1318010879,NL
@@ -27549,8 +28444,8 @@
1318708524,1318708527,GB
1318708528,1318708599,FR
1318708600,1318708607,GB
-1318708608,1318708631,FR
-1318708632,1318708731,GB
+1318708608,1318708639,FR
+1318708640,1318708731,GB
1318708732,1318708735,FR
1318708736,1318708991,GB
1318708992,1318711647,FR
@@ -27681,7 +28576,6 @@
1331881984,1331883007,GB
1331883008,1331883263,SE
1331883264,1331886079,GB
-1331886080,1331888127,ES
1331888128,1331890175,SE
1331890176,1331892223,IT
1331892224,1331894271,RU
@@ -27713,13 +28607,19 @@
1331937584,1331937599,ZA
1331937600,1331938111,GB
1331938112,1331938127,AE
-1331938128,1331938191,GB
+1331938128,1331938135,SA
+1331938136,1331938191,GB
1331938192,1331938207,AE
1331938208,1331938375,GB
1331938376,1331938383,AE
-1331938384,1331938823,GB
+1331938384,1331938399,IE
+1331938400,1331938823,GB
1331938824,1331938831,US
-1331938832,1331939327,GB
+1331938832,1331938839,NG
+1331938840,1331938847,IE
+1331938848,1331938879,GB
+1331938880,1331938895,NG
+1331938896,1331939327,GB
1331939328,1331941375,BE
1331941376,1331943423,ES
1331943424,1331945471,RU
@@ -27781,9 +28681,7 @@
1334083584,1334091775,DE
1334091776,1334099967,LT
1334099968,1334108159,IR
-1334108160,1334109807,BE
-1334109808,1334109811,NL
-1334109812,1334113527,BE
+1334108160,1334113527,BE
1334113528,1334113535,NL
1334113536,1334116351,BE
1334116352,1334124543,AX
@@ -27792,6 +28690,7 @@
1334165504,1334173695,PL
1334173696,1334181887,LT
1334181888,1334190079,RU
+1334190080,1334198271,BG
1334198272,1334206463,RU
1334206464,1334214655,FI
1334214656,1334222847,JO
@@ -27806,9 +28705,7 @@
1334288384,1334296575,PL
1334296576,1334304767,UA
1334304768,1334312959,RU
-1334312960,1334316031,SE
-1334316032,1334316543,NO
-1334316544,1334343047,SE
+1334312960,1334343047,SE
1334343048,1334343055,NO
1334343056,1334345727,SE
1334345728,1334378495,RU
@@ -27824,9 +28721,7 @@
1334542336,1334575103,RU
1334575104,1334579199,UA
1334579200,1334583295,RU
-1334583296,1334583311,DE
-1334583312,1334583319,US
-1334583320,1334583535,DE
+1334583296,1334583535,DE
1334583536,1334583543,US
1334583544,1334583807,DE
1334583808,1334584063,CH
@@ -27838,7 +28733,9 @@
1334585000,1334585007,US
1334585008,1334585111,DE
1334585112,1334585119,AT
-1334585120,1334591487,DE
+1334585120,1334585471,DE
+1334585472,1334585503,AT
+1334585504,1334591487,DE
1334591488,1334595583,RU
1334595584,1334596351,IT
1334596352,1334596607,GR
@@ -27869,7 +28766,9 @@
1334640640,1334644735,FR
1334644736,1334644991,LU
1334644992,1334645247,A2
-1334645248,1334648319,IQ
+1334645248,1334647807,IQ
+1334647808,1334648063,LB
+1334648064,1334648319,IQ
1334648320,1334648831,A2
1334648832,1334650959,GB
1334650960,1334650975,NL
@@ -27928,6 +28827,7 @@
1334730744,1334734847,RU
1334734848,1334738943,LT
1334738944,1334743039,CH
+1334743040,1334747135,CZ
1334747136,1334751231,RU
1334751232,1334755327,BH
1334755328,1334759423,UA
@@ -28042,7 +28942,9 @@
1336885248,1336901631,RS
1336901632,1336911103,IR
1336911104,1336911359,SE
-1336911360,1336918015,IR
+1336911360,1336911749,IR
+1336911750,1336911759,AE
+1336911760,1336918015,IR
1336918016,1336934399,PL
1336934400,1337458687,IL
1337458688,1337982975,PL
@@ -28164,25 +29066,29 @@
1346501152,1346501247,IM
1346501248,1346501343,GB
1346501344,1346501375,IM
-1346501376,1346501743,GB
-1346501744,1346501751,IM
-1346501752,1346501795,GB
+1346501376,1346501695,GB
+1346501696,1346501727,IM
+1346501728,1346501743,GB
+1346501744,1346501775,IM
+1346501776,1346501795,GB
1346501796,1346501823,IM
-1346501824,1346501848,GB
-1346501849,1346501879,IM
-1346501880,1346502319,GB
+1346501824,1346501847,GB
+1346501848,1346501879,IM
+1346501880,1346502223,GB
+1346502224,1346502239,IM
+1346502240,1346502319,GB
1346502320,1346502323,IM
-1346502324,1346502463,GB
-1346502464,1346502527,IM
-1346502528,1346502559,GB
-1346502560,1346502591,IM
-1346502592,1346502655,GB
+1346502324,1346502399,GB
+1346502400,1346502527,IM
+1346502528,1346502655,GB
1346502656,1346510847,DE
1346510848,1346519039,AT
1346519040,1346527231,RU
1346527232,1346531327,DE
1346531328,1346535423,ES
-1346535424,1346537983,BE
+1346535424,1346537335,BE
+1346537336,1346537343,GB
+1346537344,1346537983,BE
1346537984,1346537988,AT
1346537989,1346537991,BE
1346537992,1346537999,AT
@@ -28353,11 +29259,14 @@
1347133440,1347141631,EG
1347141632,1347145727,CH
1347145728,1347146239,GB
-1347146240,1347147263,FR
+1347146240,1347147007,FR
+1347147008,1347147263,DE
1347147264,1347147775,GB
1347147776,1347148287,DE
1347148288,1347148543,GB
-1347148544,1347149823,FR
+1347148544,1347148799,FR
+1347148800,1347149055,NO
+1347149056,1347149823,FR
1347149824,1347153919,HU
1347153920,1347158015,AT
1347158016,1347162111,CH
@@ -28380,7 +29289,6 @@
1347211112,1347211119,IE
1347211120,1347215359,GB
1347215360,1347219455,RU
-1347219456,1347223551,KW
1347223552,1347223807,EG
1347223808,1347224063,HK
1347224064,1347224183,US
@@ -28391,15 +29299,21 @@
1347226624,1347227135,EG
1347227136,1347227391,HK
1347227392,1347227647,EG
-1347227648,1347229311,DE
+1347227648,1347228055,DE
+1347228056,1347228063,GR
+1347228064,1347229311,DE
1347229312,1347229343,AT
-1347229344,1347231071,DE
+1347229344,1347229895,DE
+1347229896,1347229903,GR
+1347229904,1347231071,DE
1347231072,1347231087,AT
1347231088,1347231095,GR
1347231096,1347231743,DE
1347231744,1347235839,UA
1347235840,1347239935,GE
-1347239936,1347244031,DK
+1347239936,1347240943,DK
+1347240944,1347240959,GB
+1347240960,1347244031,DK
1347244032,1347247359,GB
1347247360,1347247871,RU
1347247872,1347248127,US
@@ -28501,9 +29415,7 @@
1347293928,1347293935,US
1347293936,1347293943,NG
1347293944,1347293951,A2
-1347293952,1347293959,NG
-1347293960,1347293967,GN
-1347293968,1347293975,NG
+1347293952,1347293975,NG
1347293976,1347293983,GN
1347293984,1347293991,US
1347293992,1347293999,NG
@@ -28605,13 +29517,16 @@
1347342336,1347346431,SE
1347346432,1347350527,BG
1347350528,1347354623,RU
+1347354624,1347358719,GR
1347358720,1347362815,CZ
1347362816,1347366911,NL
1347366912,1347371007,IT
1347371008,1347375103,RU
1347375104,1347379199,GB
1347379200,1347383295,NL
-1347383296,1347387391,EE
+1347383296,1347386751,EE
+1347386752,1347386815,MY
+1347386816,1347387391,EE
1347387392,1347391487,GB
1347391488,1347395583,LB
1347395584,1347399679,SE
@@ -28691,7 +29606,9 @@
1347571712,1347575807,RU
1347575808,1347579903,DK
1347579904,1347588095,GB
-1347588096,1347592191,CZ
+1347588096,1347590911,CZ
+1347590912,1347591167,SK
+1347591168,1347592191,CZ
1347592192,1347600383,RU
1347600384,1347604479,IT
1347604480,1347608575,DE
@@ -28774,7 +29691,9 @@
1347756032,1347760127,NL
1347760128,1347764223,HU
1347764224,1347772415,GB
-1347772416,1347776511,MT
+1347772416,1347775953,MT
+1347775954,1347775954,GB
+1347775955,1347776511,MT
1347776512,1347780607,SE
1347780608,1347784703,NL
1347784704,1347788799,RU
@@ -28812,14 +29731,12 @@
1347855960,1347855967,DE
1347855968,1347855999,EU
1347856000,1347856063,DE
-1347856064,1347856079,EU
-1347856080,1347856239,DE
+1347856064,1347856095,EU
+1347856096,1347856239,DE
1347856240,1347856255,EU
1347856256,1347856383,DE
1347856384,1347856391,EU
-1347856392,1347856415,DE
-1347856416,1347856423,EU
-1347856424,1347856431,DE
+1347856392,1347856431,DE
1347856432,1347856447,EU
1347856448,1347856639,DE
1347856640,1347856895,AT
@@ -28852,9 +29769,7 @@
1347861944,1347861951,DE
1347861952,1347862111,EU
1347862112,1347862143,DE
-1347862144,1347862279,EU
-1347862280,1347862287,DE
-1347862288,1347862303,EU
+1347862144,1347862303,EU
1347862304,1347862431,DE
1347862432,1347862463,EU
1347862464,1347862527,DE
@@ -28888,8 +29803,8 @@
1347977600,1347977607,NG
1347977608,1347978007,A2
1347978008,1347978015,NG
-1347978016,1347978023,A2
-1347978024,1347978039,NG
+1347978016,1347978031,A2
+1347978032,1347978039,NG
1347978040,1347978191,A2
1347978192,1347978199,NG
1347978200,1347978263,A2
@@ -28905,8 +29820,10 @@
1347978408,1347978447,A2
1347978448,1347978463,NG
1347978464,1347978575,A2
-1347978576,1347978655,NG
-1347978656,1347978727,A2
+1347978576,1347978623,NG
+1347978624,1347978631,A2
+1347978632,1347978647,NG
+1347978648,1347978727,A2
1347978728,1347978735,NG
1347978736,1347978775,A2
1347978776,1347978783,NG
@@ -28932,16 +29849,14 @@
1347979584,1347979591,NG
1347979592,1347979743,A2
1347979744,1347979751,NG
-1347979752,1347980079,A2
-1347980080,1347980095,GH
-1347980096,1347980111,NG
+1347979752,1347980111,A2
1347980112,1347980127,GN
1347980128,1347980167,A2
1347980168,1347980175,NG
1347980176,1347980223,A2
1347980224,1347980271,NG
-1347980272,1347980287,DK
-1347980288,1347980415,A2
+1347980272,1347980279,DK
+1347980280,1347980415,A2
1347980416,1347980479,NG
1347980480,1347980543,A2
1347980544,1347980559,DK
@@ -28949,9 +29864,7 @@
1347981008,1347981015,NG
1347981016,1347981023,A2
1347981024,1347981031,NG
-1347981032,1347981183,A2
-1347981184,1347981191,NG
-1347981192,1347981239,A2
+1347981032,1347981239,A2
1347981240,1347981247,NG
1347981248,1347981255,A2
1347981256,1347981263,DK
@@ -28963,9 +29876,7 @@
1347982224,1347982231,NG
1347982232,1347982279,A2
1347982280,1347982287,NG
-1347982288,1347982887,A2
-1347982888,1347982895,NG
-1347982896,1347982911,A2
+1347982288,1347982911,A2
1347982912,1347982919,NG
1347982920,1347982927,A2
1347982928,1347982943,NG
@@ -28981,9 +29892,7 @@
1347983304,1347983311,NG
1347983312,1347983423,A2
1347983424,1347983487,NG
-1347983488,1347983527,A2
-1347983528,1347983535,NG
-1347983536,1347983567,A2
+1347983488,1347983567,A2
1347983568,1347983575,NG
1347983576,1347983903,A2
1347983904,1347983911,NG
@@ -29034,9 +29943,7 @@
1348076032,1348076287,LV
1348076288,1348076543,RU
1348076544,1348083711,LV
-1348083712,1348086535,LU
-1348086536,1348086543,NL
-1348086544,1348091903,LU
+1348083712,1348091903,LU
1348091904,1348095999,RU
1348096000,1348100095,AL
1348100096,1348104191,DE
@@ -29103,8 +30010,7 @@
1348274800,1348274815,IL
1348274816,1348274927,IE
1348274928,1348274935,IL
-1348274936,1348274943,IE
-1348274944,1348275199,CH
+1348274936,1348275199,CH
1348275200,1348275711,GB
1348275712,1348275967,CH
1348275968,1348280319,IE
@@ -29227,7 +30133,9 @@
1352011448,1352011455,IT
1352011456,1352038695,DE
1352038696,1352038699,US
-1352038700,1352139671,DE
+1352038700,1352041471,DE
+1352041472,1352041727,US
+1352041728,1352139671,DE
1352139672,1352139679,IT
1352139680,1352144519,DE
1352144520,1352144527,IT
@@ -29256,7 +30164,9 @@
1352149456,1352149487,FR
1352149488,1352277535,DE
1352277536,1352277567,IT
-1352277568,1352402791,DE
+1352277568,1352287399,DE
+1352287400,1352287407,NL
+1352287408,1352402791,DE
1352402792,1352402799,BE
1352402800,1352404599,DE
1352404600,1352404607,NL
@@ -29264,7 +30174,9 @@
1352445688,1352445703,NL
1352445704,1352663039,DE
1352663040,1353187327,DK
-1353187328,1353253663,GB
+1353187328,1353252991,GB
+1353252992,1353253023,FR
+1353253024,1353253663,GB
1353253664,1353253671,NL
1353253672,1353253791,GB
1353253792,1353253823,FR
@@ -29288,94 +30200,74 @@
1353258504,1353258639,SE
1353258640,1353258783,GB
1353258784,1353258807,SE
-1353258808,1353265943,GB
+1353258808,1353259271,GB
+1353259272,1353259279,DE
+1353259280,1353264167,GB
+1353264168,1353264175,FR
+1353264176,1353265375,GB
+1353265376,1353265383,IE
+1353265384,1353265943,GB
1353265944,1353265951,IE
1353265952,1353266959,GB
1353266960,1353266975,IE
1353266976,1353267455,GB
1353267456,1353268223,IE
1353268224,1353268479,GB
-1353268480,1353268551,BE
-1353268552,1353268559,GB
-1353268560,1353269247,BE
+1353268480,1353269247,BE
1353269248,1353270527,GB
1353270528,1353270783,IE
1353270784,1353271295,GB
1353271296,1353271423,IE
-1353271424,1353271807,GB
-1353271808,1353271831,ES
+1353271424,1353271815,GB
+1353271816,1353271831,ES
1353271832,1353271839,GB
-1353271840,1353271847,ES
-1353271848,1353271895,GB
-1353271896,1353271919,ES
-1353271920,1353271927,GB
-1353271928,1353272031,ES
+1353271840,1353272031,ES
1353272032,1353272039,FR
1353272040,1353272047,GB
1353272048,1353272055,ES
1353272056,1353272063,GB
1353272064,1353272245,ES
-1353272246,1353272255,GB
-1353272256,1353272647,ES
-1353272648,1353272655,GB
-1353272656,1353272691,ES
+1353272246,1353272247,GB
+1353272248,1353272691,ES
1353272692,1353272695,GB
-1353272696,1353272727,ES
-1353272728,1353272735,GB
-1353272736,1353272783,ES
-1353272784,1353272799,GB
-1353272800,1353272807,ES
+1353272696,1353272807,ES
1353272808,1353272815,GB
-1353272816,1353272847,ES
-1353272848,1353272879,GB
-1353272880,1353273047,ES
-1353273048,1353273055,GB
-1353273056,1353273343,ES
+1353272816,1353273343,ES
1353273344,1353273631,BE
1353273632,1353273639,ES
1353273640,1353273711,BE
1353273712,1353273719,GB
1353273720,1353274367,BE
-1353274368,1353274671,ES
-1353274672,1353274679,GB
-1353274680,1353274687,ES
-1353274688,1353274703,GB
-1353274704,1353274759,ES
+1353274368,1353274759,ES
1353274760,1353274767,GB
1353274768,1353274791,ES
1353274792,1353274799,GB
-1353274800,1353274831,ES
-1353274832,1353274839,GB
-1353274840,1353274863,ES
-1353274864,1353274879,GB
-1353274880,1353274895,ES
+1353274800,1353274895,ES
1353274896,1353274911,GB
-1353274912,1353274919,ES
-1353274920,1353274927,GB
-1353274928,1353275023,ES
-1353275024,1353275039,GB
-1353275040,1353275087,ES
-1353275088,1353275103,GB
-1353275104,1353275231,ES
-1353275232,1353275255,GB
-1353275256,1353275263,ES
-1353275264,1353275279,GB
-1353275280,1353275335,ES
-1353275336,1353275343,GB
-1353275344,1353275391,ES
+1353274912,1353275007,ES
+1353275008,1353275015,GB
+1353275016,1353275111,ES
+1353275112,1353275119,GB
+1353275120,1353275391,ES
1353275392,1353277439,GB
1353277440,1353279487,CH
1353279488,1353279743,IT
1353279744,1353279751,GB
1353279752,1353279759,IT
1353279760,1353279763,GB
-1353279764,1353280119,IT
+1353279764,1353280079,IT
+1353280080,1353280087,GB
+1353280088,1353280119,IT
1353280120,1353280127,GB
1353280128,1353280143,IT
1353280144,1353280151,GB
-1353280152,1353280559,IT
-1353280560,1353280575,GB
-1353280576,1353281023,IT
+1353280152,1353280279,IT
+1353280280,1353280287,GB
+1353280288,1353280567,IT
+1353280568,1353280575,GB
+1353280576,1353280663,IT
+1353280664,1353280671,GB
+1353280672,1353281023,IT
1353281024,1353281535,BE
1353281536,1353282047,GB
1353282048,1353282559,IT
@@ -29384,7 +30276,9 @@
1353283328,1353287327,GB
1353287328,1353287359,IE
1353287360,1353287679,GB
-1353287680,1353288031,IE
+1353287680,1353287935,IE
+1353287936,1353287943,GB
+1353287944,1353288031,IE
1353288032,1353288063,GB
1353288064,1353288151,IE
1353288152,1353288159,GB
@@ -29400,16 +30294,16 @@
1353288520,1353288527,GB
1353288528,1353288607,IE
1353288608,1353288639,GB
-1353288640,1353288663,IE
-1353288664,1353288671,GB
-1353288672,1353288831,IE
+1353288640,1353288831,IE
1353288832,1353288839,GB
1353288840,1353288847,IE
1353288848,1353288855,GB
1353288856,1353288879,IE
1353288880,1353288895,GB
1353288896,1353288959,IE
-1353288960,1353289087,GB
+1353288960,1353288975,GB
+1353288976,1353288991,IE
+1353288992,1353289087,GB
1353289088,1353289247,IE
1353289248,1353289255,GB
1353289256,1353289279,IE
@@ -29439,7 +30333,8 @@
1353298720,1353298751,DE
1353298752,1353298815,SE
1353298816,1353298831,PT
-1353298832,1353298879,GB
+1353298832,1353298839,SE
+1353298840,1353298879,GB
1353298880,1353298881,SE
1353298882,1353298887,GB
1353298888,1353299647,SE
@@ -29460,15 +30355,10 @@
1353301096,1353301103,US
1353301104,1353306111,GB
1353306112,1353306623,ES
-1353306624,1353306624,BE
-1353306625,1353306687,GB
-1353306688,1353306695,BE
-1353306696,1353306703,GB
-1353306704,1353306735,BE
+1353306624,1353306687,GB
+1353306688,1353306735,BE
1353306736,1353306751,GB
-1353306752,1353306831,BE
-1353306832,1353306847,GB
-1353306848,1353307135,BE
+1353306752,1353307135,BE
1353307136,1353307143,IT
1353307144,1353308159,GB
1353308160,1353309183,FR
@@ -29478,12 +30368,14 @@
1353310608,1353310719,ES
1353310720,1353311175,IT
1353311176,1353311183,ES
-1353311184,1353311207,IT
-1353311208,1353311215,GB
+1353311184,1353311199,IT
+1353311200,1353311215,GB
1353311216,1353311231,IT
1353311232,1353312255,GB
1353312256,1353312767,CH
-1353312768,1353313111,IT
+1353312768,1353312815,IT
+1353312816,1353312823,GB
+1353312824,1353313111,IT
1353313112,1353313119,GB
1353313120,1353313191,IT
1353313192,1353313199,GB
@@ -29614,9 +30506,7 @@
1354682772,1354682775,RS
1354682776,1354682895,DE
1354682896,1354682911,AE
-1354682912,1354682939,DE
-1354682940,1354682943,MC
-1354682944,1354683095,DE
+1354682912,1354683095,DE
1354683096,1354683103,IT
1354683104,1354683391,DE
1354683392,1354683903,PL
@@ -29702,7 +30592,7 @@
1357332480,1357333247,DE
1357333248,1357333503,GB
1357333504,1357333759,IR
-1357333760,1357333823,EU
+1357333760,1357333823,FR
1357333824,1357333855,GB
1357333856,1357334015,ES
1357334016,1357334271,TZ
@@ -29728,19 +30618,18 @@
1357342720,1357348863,EU
1357348864,1357349119,DE
1357349120,1357349375,LU
-1357349376,1357349887,EU
+1357349376,1357349887,GB
1357349888,1357350399,ES
1357350400,1357350911,QA
1357350912,1357351167,GB
1357351168,1357351423,PL
-1357351424,1357351935,EU
-1357351936,1357352959,GB
+1357351424,1357352959,GB
1357352960,1357355007,EU
1357355008,1357355263,NL
1357355264,1357355775,FR
1357355776,1357356031,GB
1357356032,1357356543,ES
-1357356544,1357357055,EU
+1357356544,1357357055,PT
1357357056,1357357567,ES
1357357568,1357358079,DE
1357358080,1357358335,ES
@@ -29776,7 +30665,8 @@
1357366880,1357366911,GB
1357366912,1357367039,EU
1357367040,1357367295,GB
-1357367296,1357367807,EU
+1357367296,1357367551,FR
+1357367552,1357367807,EU
1357367808,1357368063,GB
1357368064,1357368831,GN
1357368832,1357369343,ES
@@ -29787,7 +30677,7 @@
1357370368,1357370879,EU
1357370880,1357371391,LY
1357371392,1357371647,GB
-1357371648,1357371903,EU
+1357371648,1357371903,FR
1357371904,1357372159,RU
1357372160,1357372415,GB
1357372416,1357372927,EU
@@ -29876,8 +30766,10 @@
1357883552,1357883583,EU
1357883584,1357883727,FR
1357883728,1357883759,EU
-1357883760,1357883935,FR
-1357883936,1357883999,EU
+1357883760,1357883775,FR
+1357883776,1357883807,EU
+1357883808,1357883903,FR
+1357883904,1357883999,EU
1357884000,1357884031,FR
1357884032,1357884095,RU
1357884096,1357884159,EU
@@ -29934,8 +30826,8 @@
1357899016,1357899023,EU
1357899024,1357899039,DE
1357899040,1357899047,EU
-1357899048,1357899055,DE
-1357899056,1357899071,EU
+1357899048,1357899063,DE
+1357899064,1357899071,EU
1357899072,1357899199,DE
1357899200,1357899279,EU
1357899280,1357899287,RU
@@ -30028,7 +30920,6 @@
1358012416,1358016511,IT
1358016512,1358020607,GE
1358020608,1358024703,DE
-1358024704,1358028799,EE
1358028800,1358032895,IT
1358032896,1358036991,GE
1358036992,1358041087,IR
@@ -30083,22 +30974,25 @@
1358223360,1358223631,GB
1358223632,1358223663,DE
1358223664,1358223671,GB
-1358223672,1358223727,DE
-1358223728,1358223775,GB
+1358223672,1358223719,DE
+1358223720,1358223775,GB
1358223776,1358223843,DE
1358223844,1358223871,GB
-1358223872,1358223911,DE
+1358223872,1358223887,NL
+1358223888,1358223911,DE
1358223912,1358223927,NL
-1358223928,1358223967,DE
-1358223968,1358224055,NL
-1358224056,1358224511,DE
+1358223928,1358223975,DE
+1358223976,1358223991,NL
+1358223992,1358223999,DE
+1358224000,1358224079,NL
+1358224080,1358224511,DE
1358224512,1358224519,BE
1358224520,1358224611,DE
1358224612,1358224651,BE
1358224652,1358224655,DE
1358224656,1358224719,BE
-1358224720,1358224927,DE
-1358224928,1358225127,IT
+1358224720,1358224959,DE
+1358224960,1358225127,IT
1358225128,1358225407,DE
1358225408,1358229503,RU
1358229504,1358229631,DE
@@ -30142,9 +31036,7 @@
1358295040,1358299135,RU
1358299136,1358303231,DZ
1358303232,1358307327,RU
-1358307328,1358313215,DE
-1358313216,1358313727,ES
-1358313728,1358315519,DE
+1358307328,1358315519,DE
1358315520,1358323711,RU
1358323712,1358327807,LU
1358327808,1358328671,DE
@@ -30275,7 +31167,7 @@
1358524416,1358528511,DE
1358528512,1358536703,RU
1358536704,1358540799,HU
-1358540800,1358544895,RU
+1358540800,1358548991,RU
1358548992,1358553087,JO
1358553088,1358557183,UA
1358557184,1358559503,IE
@@ -30303,7 +31195,7 @@
1358667776,1358668067,PT
1358668068,1358668071,GB
1358668072,1358668271,PT
-1358668272,1358668279,GB
+1358668272,1358668279,ES
1358668280,1358668359,PT
1358668360,1358668367,GB
1358668368,1358668463,PT
@@ -30317,23 +31209,23 @@
1358668928,1358668959,ES
1358668960,1358669351,PT
1358669352,1358669359,GB
-1358669360,1358669431,PT
-1358669432,1358669439,GB
-1358669440,1358669455,PT
-1358669456,1358669471,GB
+1358669360,1358669463,PT
+1358669464,1358669471,GB
1358669472,1358669503,PT
1358669504,1358669519,GB
1358669520,1358669543,PT
1358669544,1358669551,GB
1358669552,1358669975,PT
-1358669976,1358669999,GB
+1358669976,1358669983,GB
+1358669984,1358669991,PT
+1358669992,1358669999,GB
1358670000,1358670015,PT
1358670016,1358670023,GB
1358670024,1358670071,PT
1358670072,1358670079,GB
1358670080,1358670183,PT
-1358670184,1358670207,GB
-1358670208,1358671415,PT
+1358670184,1358670191,GB
+1358670192,1358671415,PT
1358671416,1358671423,GB
1358671424,1358671431,PT
1358671432,1358671439,GB
@@ -30435,9 +31327,7 @@
1358785088,1358785151,NL
1358785152,1358786559,GB
1358786560,1358787071,NL
-1358787072,1358789167,GB
-1358789168,1358789183,IE
-1358789184,1358790655,GB
+1358787072,1358790655,GB
1358790656,1358798847,IR
1358798848,1358799359,DE
1358799360,1358802943,HR
@@ -30457,12 +31347,9 @@
1358860288,1358861311,GB
1358861312,1358861823,DE
1358861824,1358862335,FR
-1358862336,1358862591,US
-1358862592,1358862847,GB
-1358862848,1358863103,DK
-1358863104,1358863359,GB
-1358863360,1358863615,US
-1358863616,1358864383,GB
+1358862336,1358862847,US
+1358862848,1358863359,DK
+1358863360,1358864383,US
1358864384,1358864399,CH
1358864400,1358864407,IN
1358864408,1358864535,CH
@@ -30693,7 +31580,9 @@
1359467776,1359467815,US
1359467816,1359467903,DE
1359467904,1359468031,US
-1359468032,1359468639,DE
+1359468032,1359468575,DE
+1359468576,1359468583,SG
+1359468584,1359468639,DE
1359468640,1359468655,SG
1359468656,1359468671,JP
1359468672,1359468695,SG
@@ -30863,7 +31752,7 @@
1360351232,1360355327,AZ
1360355328,1360359423,EG
1360359424,1360363519,AT
-1360363520,1360367615,IT
+1360363520,1360365567,IT
1360367616,1360371711,IE
1360371712,1360375807,TR
1360375808,1360379903,NL
@@ -30913,6 +31802,7 @@
1360556032,1360564223,RU
1360564224,1360568319,AT
1360568320,1360572415,ES
+1360572416,1360576511,RU
1360576512,1360580607,GB
1360580608,1360584703,UA
1360584704,1360588799,IT
@@ -30924,7 +31814,9 @@
1360613376,1360617471,SE
1360617472,1360621567,IT
1360621568,1360625663,ES
-1360625664,1360627455,DE
+1360625664,1360626687,DE
+1360626688,1360627199,LB
+1360627200,1360627455,DE
1360627456,1360627743,LB
1360627744,1360627967,DE
1360627968,1360628095,IQ
@@ -31432,6 +32324,7 @@
1361038312,1361038319,NL
1361038320,1361038335,US
1361038336,1361039359,NL
+1361039360,1361043455,PL
1361043456,1361051647,NO
1361051648,1362100223,ES
1362100224,1362395135,FR
@@ -31642,9 +32535,13 @@
1365042048,1365042055,GB
1365042056,1365042175,LU
1365042176,1365044479,FR
-1365044480,1365044655,LU
+1365044480,1365044607,LU
+1365044608,1365044639,BE
+1365044640,1365044655,LU
1365044656,1365044719,FR
-1365044720,1365044895,LU
+1365044720,1365044815,LU
+1365044816,1365044831,BE
+1365044832,1365044895,LU
1365044896,1365044911,FR
1365044912,1365044959,LU
1365044960,1365044975,BE
@@ -31742,7 +32639,9 @@
1365159936,1365164031,HU
1365164032,1365166255,GB
1365166256,1365166271,IE
-1365166272,1365172223,GB
+1365166272,1365166303,GB
+1365166304,1365166311,BD
+1365166312,1365172223,GB
1365172224,1365176319,LV
1365176320,1365180415,HU
1365180416,1365183231,DE
@@ -31755,9 +32654,27 @@
1365204992,1365209087,CZ
1365209088,1365213183,BE
1365213184,1365217279,RU
-1365217280,1365217791,GB
-1365217792,1365217823,US
-1365217824,1365218047,GB
+1365217280,1365217567,GB
+1365217568,1365217575,PT
+1365217576,1365217591,GB
+1365217592,1365217599,EG
+1365217600,1365217631,GB
+1365217632,1365217671,US
+1365217672,1365217687,IL
+1365217688,1365217695,KW
+1365217696,1365217703,GB
+1365217704,1365217711,AU
+1365217712,1365217791,GB
+1365217792,1365217807,BD
+1365217808,1365217815,US
+1365217816,1365217831,GB
+1365217832,1365217839,TR
+1365217840,1365217879,GB
+1365217880,1365217919,US
+1365217920,1365217975,GB
+1365217976,1365218031,US
+1365218032,1365218039,CA
+1365218040,1365218047,GB
1365218048,1365218303,US
1365218304,1365218311,CA
1365218312,1365218319,AR
@@ -31770,11 +32687,11 @@
1365218408,1365218415,IN
1365218416,1365218431,GB
1365218432,1365218439,EG
-1365218440,1365218447,GB
+1365218440,1365218447,ZA
1365218448,1365218455,CA
1365218456,1365218459,GB
1365218460,1365218463,US
-1365218464,1365218471,EG
+1365218464,1365218471,HK
1365218472,1365218479,GB
1365218480,1365218511,GR
1365218512,1365218519,AU
@@ -31791,8 +32708,7 @@
1365218928,1365218943,BR
1365218944,1365218951,IN
1365218952,1365218959,NL
-1365218960,1365218967,GB
-1365218968,1365218975,US
+1365218960,1365218975,US
1365218976,1365219007,CN
1365219008,1365219023,US
1365219024,1365219031,DK
@@ -31858,8 +32774,7 @@
1365219984,1365219991,IT
1365219992,1365220007,EE
1365220008,1365220015,ES
-1365220016,1365220023,GB
-1365220024,1365220031,US
+1365220016,1365220031,US
1365220032,1365220127,CN
1365220128,1365220143,TR
1365220144,1365220151,IL
@@ -31885,10 +32800,7 @@
1365220440,1365220471,GB
1365220472,1365220479,US
1365220480,1365220487,AU
-1365220488,1365220495,GB
-1365220496,1365220503,US
-1365220504,1365220511,GB
-1365220512,1365220523,US
+1365220488,1365220523,US
1365220524,1365220527,GB
1365220528,1365220535,IS
1365220536,1365220551,GB
@@ -31898,7 +32810,8 @@
1365220584,1365220599,TR
1365220600,1365220607,GR
1365220608,1365220615,TR
-1365220616,1365220631,US
+1365220616,1365220623,US
+1365220624,1365220631,KW
1365220632,1365220639,GR
1365220640,1365220663,GB
1365220664,1365220679,US
@@ -31907,35 +32820,35 @@
1365220728,1365220735,JO
1365220736,1365220767,US
1365220768,1365220775,GR
-1365220776,1365220783,JO
+1365220776,1365220783,US
1365220784,1365220791,IN
1365220792,1365220799,KW
1365220800,1365220807,RU
-1365220808,1365220815,GB
-1365220816,1365220823,IN
+1365220808,1365220815,US
+1365220816,1365220823,KW
1365220824,1365220831,GB
1365220832,1365220847,IT
1365220848,1365220855,AU
-1365220856,1365220895,US
-1365220896,1365220903,GR
+1365220856,1365220903,US
1365220904,1365220911,CA
-1365220912,1365220919,GB
+1365220912,1365220919,US
1365220920,1365220927,KW
1365220928,1365220935,IT
1365220936,1365220939,AR
1365220940,1365220943,US
-1365220944,1365220975,GB
+1365220944,1365220959,GB
+1365220960,1365220967,US
+1365220968,1365220975,GB
1365220976,1365220979,US
1365220980,1365220983,GB
1365220984,1365220991,BR
1365220992,1365220999,ZA
-1365221000,1365221007,TR
-1365221008,1365221023,US
+1365221000,1365221023,US
1365221024,1365221031,TR
1365221032,1365221047,IL
1365221048,1365221055,GB
1365221056,1365221063,KW
-1365221064,1365221071,GB
+1365221064,1365221071,MY
1365221072,1365221087,ES
1365221088,1365221119,US
1365221120,1365221375,GB
@@ -31956,6 +32869,7 @@
1369559040,1369563135,RU
1369563136,1369567231,PL
1369567232,1369571327,BG
+1369636864,1369702399,DE
1369702400,1369833471,BE
1369833472,1369964543,NO
1369964544,1369997311,GB
@@ -32147,21 +33061,29 @@
1372651520,1372684287,FI
1372684288,1372684415,DE
1372684416,1372684543,EU
-1372684544,1372685631,DE
-1372685632,1372685655,EU
+1372684544,1372685567,DE
+1372685568,1372685655,EU
1372685656,1372685663,DE
1372685664,1372685695,EU
1372685696,1372685823,DE
1372685824,1372685887,EU
1372685888,1372686335,DE
1372686336,1372687359,EU
-1372687360,1372687711,DE
+1372687360,1372687487,DE
+1372687488,1372687551,EU
+1372687552,1372687615,DE
+1372687616,1372687679,EU
+1372687680,1372687711,DE
1372687712,1372687719,EU
1372687720,1372687727,DE
-1372687728,1372687735,EU
-1372687736,1372688199,DE
+1372687728,1372687743,EU
+1372687744,1372688199,DE
1372688200,1372688223,EU
-1372688224,1372689839,DE
+1372688224,1372688351,DE
+1372688352,1372688383,EU
+1372688384,1372689695,DE
+1372689696,1372689791,EU
+1372689792,1372689839,DE
1372689840,1372689855,EU
1372689856,1372691455,DE
1372691456,1372691711,US
@@ -32180,7 +33102,8 @@
1372694816,1372694831,EU
1372694832,1372695039,DE
1372695040,1372695167,EU
-1372695168,1372695551,DE
+1372695168,1372695423,DE
+1372695424,1372695551,EU
1372695552,1372695807,CZ
1372695808,1372696007,DK
1372696008,1372696063,EU
@@ -32217,7 +33140,7 @@
1372717056,1372749823,PL
1372749824,1372782591,DE
1372782592,1372815359,RU
-1372815360,1372848127,IT
+1372815360,1372848127,SE
1372848128,1373110271,TR
1373110272,1373175807,SE
1373175808,1373241343,AT
@@ -32304,7 +33227,9 @@
1382154240,1382170623,FR
1382170624,1382171776,DE
1382171777,1382171791,CH
-1382171792,1382173663,DE
+1382171792,1382172215,DE
+1382172216,1382172223,CH
+1382172224,1382173663,DE
1382173664,1382173671,GB
1382173672,1382173675,DE
1382173676,1382173679,CH
@@ -32314,9 +33239,7 @@
1382177984,1382178303,LI
1382178304,1382179247,DE
1382179248,1382179279,GB
-1382179280,1382179839,DE
-1382179840,1382180863,CN
-1382180864,1382182327,DE
+1382179280,1382182327,DE
1382182328,1382182335,GB
1382182336,1382182547,DE
1382182548,1382182551,CH
@@ -32350,12 +33273,13 @@
1382212224,1382212239,FR
1382212240,1382212287,EU
1382212288,1382212351,NL
-1382212352,1382212479,FR
-1382212480,1382212607,EU
+1382212352,1382212607,EU
1382212608,1382212863,FR
1382212864,1382213183,NL
1382213184,1382213199,EU
-1382213200,1382214079,NL
+1382213200,1382213375,NL
+1382213376,1382213631,EU
+1382213632,1382214079,NL
1382214080,1382214111,GB
1382214112,1382214879,NL
1382214880,1382214895,GB
@@ -32363,9 +33287,7 @@
1382216832,1382216895,GB
1382216896,1382216959,NL
1382216960,1382217215,GB
-1382217216,1382217727,NL
-1382217728,1382217983,GB
-1382217984,1382218399,NL
+1382217216,1382218399,NL
1382218400,1382218447,GB
1382218448,1382218455,NL
1382218456,1382218495,GB
@@ -32376,7 +33298,9 @@
1382218912,1382218959,NL
1382218960,1382218991,GB
1382218992,1382219775,NL
-1382219776,1382223551,SE
+1382219776,1382223327,SE
+1382223328,1382223359,FI
+1382223360,1382223551,SE
1382223552,1382223615,NO
1382223616,1382224287,SE
1382224288,1382224319,NO
@@ -32441,9 +33365,10 @@
1383098112,1383098367,DE
1383098368,1383099391,GB
1383099392,1383099903,DE
-1383099904,1383100159,GB
-1383100160,1383100287,FR
-1383100288,1383100831,GB
+1383099904,1383099967,FR
+1383099968,1383100159,GB
+1383100160,1383100415,FR
+1383100416,1383100831,GB
1383100832,1383100847,IE
1383100848,1383100879,GB
1383100880,1383100895,IE
@@ -32455,9 +33380,7 @@
1383104016,1383104023,ES
1383104024,1383104255,GB
1383104256,1383104511,FR
-1383104512,1383111695,JE
-1383111696,1383111727,GB
-1383111728,1383112703,JE
+1383104512,1383112703,JE
1383112704,1383120895,GE
1383120896,1383129031,IT
1383129032,1383129039,ES
@@ -32477,38 +33400,20 @@
1383202816,1383211007,RU
1383211008,1383219199,CY
1383219200,1383220223,AL
-1383220224,1383222415,RS
-1383222416,1383222431,AL
-1383222432,1383222440,RS
-1383222441,1383222455,AL
-1383222456,1383222459,RS
-1383222460,1383222471,AL
-1383222472,1383222479,RS
-1383222480,1383222487,AL
-1383222488,1383223119,RS
-1383223120,1383223123,AL
-1383223124,1383223131,RS
-1383223132,1383223135,AL
-1383223136,1383223191,RS
-1383223192,1383223199,AL
-1383223200,1383223208,RS
-1383223209,1383223215,AL
-1383223216,1383223231,RS
-1383223232,1383223239,AL
-1383223240,1383223551,RS
-1383223552,1383223567,AL
-1383223568,1383223583,RS
-1383223584,1383223615,AL
-1383223616,1383223631,RS
-1383223632,1383223663,AL
-1383223664,1383223695,RS
+1383220224,1383222447,RS
+1383222448,1383222455,AL
+1383222456,1383223695,RS
1383223696,1383223703,AL
-1383223704,1383223711,RS
-1383223712,1383223727,AL
-1383223728,1383223759,RS
-1383223760,1383223807,AL
-1383223808,1383225599,RS
-1383225600,1383226623,AL
+1383223704,1383225759,RS
+1383225760,1383225771,AL
+1383225772,1383225807,RS
+1383225808,1383225808,AL
+1383225809,1383225819,RS
+1383225820,1383225827,AL
+1383225828,1383226091,RS
+1383226092,1383226095,AL
+1383226096,1383226271,RS
+1383226272,1383226623,AL
1383226624,1383226751,RS
1383226752,1383226815,AL
1383226816,1383227391,RS
@@ -32818,6 +33723,8 @@
1385259008,1385267199,IT
1385267200,1385275391,SE
1385275392,1385283583,IT
+1385287680,1385289727,IS
+1385289728,1385291775,NO
1385291776,1385299967,TR
1385299968,1385308159,BG
1385308160,1385309439,BE
@@ -32940,8 +33847,8 @@
1386348544,1386414079,RU
1386414080,1386479615,GB
1386479616,1386545151,NO
-1386545152,1386582015,DE
-1386582016,1386594303,US
+1386545152,1386586111,DE
+1386586112,1386594303,US
1386594304,1386602495,DE
1386602496,1386610687,US
1386610688,1386676223,IL
@@ -32979,18 +33886,16 @@
1388371968,1388380159,CH
1388380160,1388388895,IT
1388388896,1388388927,NG
-1388388928,1388388935,IT
-1388388936,1388388991,NG
-1388388992,1388389119,IT
-1388389120,1388389135,NG
-1388389136,1388389447,IT
-1388389448,1388389471,NG
-1388389472,1388389567,IT
+1388388928,1388388943,IT
+1388388944,1388388959,NG
+1388388960,1388388967,IT
+1388388968,1388388991,NG
+1388388992,1388389447,IT
+1388389448,1388389455,NG
+1388389456,1388389567,IT
1388389568,1388389631,NG
-1388389632,1388389903,IT
-1388389904,1388389911,NG
-1388389912,1388389919,IT
-1388389920,1388390015,NG
+1388389632,1388389927,IT
+1388389928,1388390015,NG
1388390016,1388390143,IT
1388390144,1388394495,NG
1388394496,1388395519,IT
@@ -33079,6 +33984,7 @@
1388642304,1388650495,FI
1388650496,1388658687,PL
1388658688,1388666879,GB
+1388666880,1388675071,FR
1388675072,1388675327,NL
1388675328,1388675583,EU
1388675584,1388676863,DE
@@ -33102,12 +34008,13 @@
1388691456,1388699647,NL
1388699648,1388707839,SE
1388707840,1388708863,RU
-1388708864,1388709119,LB
+1388708864,1388709119,LT
1388709120,1388712191,RU
1388712192,1388712703,LT
1388712704,1388713215,LB
-1388713216,1388713727,TJ
-1388713728,1388714239,LB
+1388713216,1388713727,RU
+1388713728,1388713983,LT
+1388713984,1388714239,LB
1388714240,1388714495,LT
1388714496,1388714751,RU
1388714752,1388715007,IQ
@@ -33140,18 +34047,26 @@
1388740608,1388740623,GB
1388740624,1388740719,IE
1388740720,1388740735,GB
-1388740736,1388741745,IE
+1388740736,1388741375,IE
+1388741376,1388741443,GB
+1388741444,1388741535,IE
+1388741536,1388741631,GB
+1388741632,1388741659,IE
+1388741660,1388741723,GB
+1388741724,1388741745,IE
1388741746,1388741747,GB
1388741748,1388741751,IE
1388741752,1388741759,GB
-1388741760,1388741767,IE
-1388741768,1388741787,GB
-1388741788,1388741795,IE
-1388741796,1388741819,GB
-1388741820,1388741859,IE
+1388741760,1388741775,IE
+1388741776,1388741787,GB
+1388741788,1388741799,IE
+1388741800,1388741800,GB
+1388741801,1388741807,IE
+1388741808,1388741815,GB
+1388741816,1388741859,IE
1388741860,1388741863,GB
-1388741864,1388742007,IE
-1388742008,1388742015,GB
+1388741864,1388742011,IE
+1388742012,1388742015,GB
1388742016,1388742019,IE
1388742020,1388742023,GB
1388742024,1388742024,IE
@@ -33159,12 +34074,14 @@
1388742032,1388742655,IE
1388742656,1388742719,GB
1388742720,1388742731,IE
-1388742732,1388742739,GB
-1388742740,1388743043,IE
+1388742732,1388742735,IR
+1388742736,1388743043,IE
1388743044,1388743055,GB
-1388743056,1388743435,IE
-1388743436,1388743439,GB
-1388743440,1388744087,IE
+1388743056,1388743439,IE
+1388743440,1388743451,GB
+1388743452,1388743919,IE
+1388743920,1388743935,GB
+1388743936,1388744087,IE
1388744088,1388744095,GB
1388744096,1388744117,IE
1388744118,1388744127,GB
@@ -33178,27 +34095,27 @@
1388745216,1388745343,GB
1388745344,1388745499,IE
1388745500,1388745503,GB
-1388745504,1388745651,IE
+1388745504,1388745559,IE
+1388745560,1388745563,GB
+1388745564,1388745651,IE
1388745652,1388745663,GB
1388745664,1388745683,IE
1388745684,1388745727,GB
-1388745728,1388745915,IE
-1388745916,1388745919,GB
+1388745728,1388745911,IE
+1388745912,1388745919,GB
1388745920,1388745927,IE
1388745928,1388745935,GB
-1388745936,1388745971,IE
-1388745972,1388745975,GB
-1388745976,1388746155,IE
+1388745936,1388746155,IE
1388746156,1388746159,GB
-1388746160,1388746171,IE
-1388746172,1388746239,GB
+1388746160,1388746175,IE
+1388746176,1388746239,GB
1388746240,1388746659,IE
1388746660,1388746671,GB
-1388746672,1388746703,IE
+1388746672,1388746675,IE
+1388746676,1388746695,GB
+1388746696,1388746703,IE
1388746704,1388746719,GB
-1388746720,1388746859,IE
-1388746860,1388746863,GB
-1388746864,1388746895,IE
+1388746720,1388746895,IE
1388746896,1388746903,GB
1388746904,1388746959,IE
1388746960,1388746975,GB
@@ -33215,16 +34132,18 @@
1388747792,1388747835,IE
1388747836,1388747839,GB
1388747840,1388747859,IE
-1388747860,1388747863,GB
-1388747864,1388747891,IE
+1388747860,1388747875,GB
+1388747876,1388747891,IE
1388747892,1388747895,GB
1388747896,1388747983,IE
-1388747984,1388748031,GB
-1388748032,1388748179,IE
-1388748180,1388748183,GB
-1388748184,1388748223,IE
-1388748224,1388748319,GB
-1388748320,1388748349,IE
+1388747984,1388747987,GB
+1388747988,1388747999,IE
+1388748000,1388748031,GB
+1388748032,1388748223,IE
+1388748224,1388748255,GB
+1388748256,1388748287,IE
+1388748288,1388748295,GB
+1388748296,1388748349,IE
1388748350,1388748351,GB
1388748352,1388748799,IE
1388748800,1388756991,RU
@@ -33232,12 +34151,16 @@
1388765184,1388773375,GB
1388773376,1388781567,NO
1388781568,1388789759,ES
-1388789760,1388789887,NL
-1388789888,1388789951,GB
-1388789952,1388797951,NL
+1388789760,1388797951,NL
1388797952,1388806143,RU
-1388806144,1388814335,DE
-1388814336,1388821119,AX
+1388806144,1388807679,DE
+1388807680,1388807711,BZ
+1388807712,1388814335,DE
+1388814336,1388815103,AX
+1388815104,1388815231,FI
+1388815232,1388818687,AX
+1388818688,1388818815,FI
+1388818816,1388821119,AX
1388821120,1388821150,SE
1388821151,1388821247,AX
1388821248,1388822527,SE
@@ -33345,7 +34268,8 @@
1389213208,1389213215,LY
1389213216,1389213311,A2
1389213312,1389213343,LY
-1389213344,1389215743,A2
+1389213344,1389214719,A2
+1389214720,1389215743,LY
1389215744,1389217791,AF
1389217792,1389218303,A2
1389218304,1389219839,AF
@@ -33658,13 +34582,8 @@
1389562880,1389563135,IT
1389563136,1389563391,DE
1389563392,1389563647,IT
-1389563648,1389564159,DE
-1389564160,1389564415,BR
-1389564416,1389576191,DE
+1389563648,1389576191,DE
1389576192,1389592575,GB
-1389592576,1389592831,A2
-1389592832,1389593087,CY
-1389593088,1389608959,A2
1389608960,1389625343,DK
1389625344,1389641727,DE
1389641728,1389658111,JO
@@ -33676,7 +34595,9 @@
1389756416,1389772799,SE
1389772800,1389780991,SI
1389780992,1389782527,HR
-1389782528,1389783039,SI
+1389782528,1389782543,SI
+1389782544,1389782559,HR
+1389782560,1389783039,SI
1389783040,1389784063,BA
1389784064,1389788671,SI
1389788672,1389789183,RS
@@ -33744,7 +34665,9 @@
1398896640,1398898687,CH
1398898688,1398931455,ES
1398931456,1398964223,GB
-1398964224,1398965503,NL
+1398964224,1398964543,NL
+1398964544,1398964559,US
+1398964560,1398965503,NL
1398965504,1398965759,US
1398965760,1398966015,DE
1398966016,1398966839,NL
@@ -33789,13 +34712,17 @@
1399717888,1399848959,AE
1399848960,1400111103,FR
1400111104,1400373247,NL
-1400373248,1400705279,DE
+1400373248,1400635391,DE
+1400635392,1400700927,EU
+1400700928,1400705279,DE
1400705280,1400706047,EU
1400706048,1400707071,DE
1400707072,1400709119,EU
1400709120,1400710143,DE
1400710144,1400710399,EU
-1400710400,1400712703,DE
+1400710400,1400712191,DE
+1400712192,1400712447,EU
+1400712448,1400712703,DE
1400712704,1400712959,EU
1400712960,1400716287,DE
1400716288,1400717311,EU
@@ -33917,15 +34844,15 @@
1401565184,1401567231,RU
1401567232,1401569279,GB
1401569280,1401585663,DE
-1401585664,1401599167,GB
-1401599168,1401599231,IE
-1401599232,1401602047,GB
+1401585664,1401602047,GB
1401602048,1401618431,ES
1401618432,1401634815,AM
1401634816,1401651199,HR
1401651200,1401667583,RU
1401667584,1401683967,IT
-1401683968,1401684479,SE
+1401683968,1401684067,SE
+1401684068,1401684071,NO
+1401684072,1401684479,SE
1401684480,1401684511,DK
1401684512,1401684543,SE
1401684544,1401684607,DK
@@ -33961,7 +34888,9 @@
1401709312,1401709567,GB
1401709568,1401714047,SE
1401714048,1401714063,FR
-1401714064,1401717759,SE
+1401714064,1401715455,SE
+1401715456,1401715459,US
+1401715460,1401717759,SE
1401717760,1401718015,NL
1401718016,1401719935,SE
1401719936,1401719951,DK
@@ -33990,7 +34919,8 @@
1401743344,1401743359,GB
1401743360,1401745439,SE
1401745440,1401745443,GB
-1401745444,1401745487,SE
+1401745444,1401745447,US
+1401745448,1401745487,SE
1401745488,1401745503,ES
1401745504,1401745919,SE
1401745920,1401745935,IT
@@ -34321,7 +35251,8 @@
1404198912,1404200959,SE
1404200960,1404203007,NL
1404203008,1404204800,HR
-1404204801,1404207103,SE
+1404204801,1404205055,SE
+1404205056,1404207103,HR
1404207104,1404210175,NO
1404210176,1404212223,LV
1404212224,1404215295,SE
@@ -34351,10 +35282,14 @@
1404645376,1404645887,HR
1404645888,1404764159,SE
1404764160,1404768511,NL
-1404768512,1404802047,SE
+1404768512,1404768767,SE
+1404768768,1404769279,NL
+1404769280,1404770303,SE
+1404770304,1404772351,NL
+1404772352,1404802047,SE
1404802048,1404803071,EE
-1404803072,1404803583,LV
-1404803584,1404805119,SE
+1404803072,1404804095,LV
+1404804096,1404805119,SE
1404805120,1404813311,AT
1404813312,1404829695,SE
1404829696,1404870655,RU
@@ -34389,7 +35324,10 @@
1406705664,1406708735,IT
1406708736,1406709759,A2
1406709760,1406710015,IT
-1406710016,1406713855,A2
+1406710016,1406711295,A2
+1406711296,1406712063,IT
+1406712064,1406713343,A2
+1406713344,1406713855,IT
1406713856,1406714879,AT
1406714880,1406715391,NL
1406715392,1406715519,AT
@@ -34463,7 +35401,7 @@
1406935040,1406951423,RU
1406951424,1406959615,PL
1406959616,1406964287,DE
-1406964288,1406964319,CH
+1406964288,1406964319,NL
1406964320,1406964327,DE
1406964328,1406964351,NL
1406964352,1406964735,DE
@@ -34540,9 +35478,10 @@
1407517384,1407517391,CD
1407517392,1407517415,A2
1407517416,1407517423,NG
-1407517424,1407517431,A2
+1407517424,1407517431,ZW
1407517432,1407517439,NG
-1407517440,1407517887,A2
+1407517440,1407517695,A2
+1407517696,1407517887,NG
1407517888,1407517919,CD
1407517920,1407517951,A2
1407517952,1407518015,SL
@@ -34551,10 +35490,9 @@
1407518040,1407518047,CD
1407518048,1407518063,NG
1407518064,1407518079,A2
-1407518080,1407518111,FR
-1407518112,1407518119,A2
-1407518120,1407518127,NG
-1407518128,1407518135,KE
+1407518080,1407518111,LR
+1407518112,1407518127,NG
+1407518128,1407518135,ZW
1407518136,1407518143,GH
1407518144,1407518151,A2
1407518152,1407518159,ZA
@@ -34565,9 +35503,10 @@
1407518192,1407518199,A2
1407518200,1407518207,AE
1407518208,1407518215,ZW
-1407518216,1407518231,A2
-1407518232,1407518247,NG
-1407518248,1407518263,A2
+1407518216,1407518239,A2
+1407518240,1407518247,NG
+1407518248,1407518255,A2
+1407518256,1407518263,CD
1407518264,1407518269,GH
1407518270,1407518335,A2
1407518336,1407518343,CG
@@ -34575,11 +35514,12 @@
1407518352,1407518359,A2
1407518360,1407518367,NG
1407518368,1407518375,ZA
-1407518376,1407518783,A2
+1407518376,1407518383,CD
+1407518384,1407518783,A2
1407518784,1407518815,CD
1407518816,1407518831,A2
1407518832,1407518847,NG
-1407518848,1407518911,A2
+1407518848,1407518911,FR
1407518912,1407518943,NG
1407518944,1407518975,A2
1407518976,1407518983,NG
@@ -34587,7 +35527,7 @@
1407518992,1407518999,NG
1407519000,1407519015,A2
1407519016,1407519023,AO
-1407519024,1407519031,NG
+1407519024,1407519031,A2
1407519032,1407519039,AO
1407519040,1407519047,NG
1407519048,1407519055,A2
@@ -34613,13 +35553,49 @@
1407519232,1407519615,NG
1407519616,1407519751,A2
1407519752,1407519767,NG
-1407519768,1407519783,A2
-1407519784,1407519791,NG
-1407519792,1407519839,A2
+1407519768,1407519775,GN
+1407519776,1407519783,A2
+1407519784,1407519823,NG
+1407519824,1407519831,A2
+1407519832,1407519839,SD
1407519840,1407519855,NG
-1407519856,1407519863,A2
+1407519856,1407519863,GN
1407519864,1407519871,NG
-1407519872,1407520271,A2
+1407519872,1407519879,A2
+1407519880,1407519895,NG
+1407519896,1407519903,GN
+1407519904,1407519911,NG
+1407519912,1407519919,GN
+1407519920,1407519943,A2
+1407519944,1407519951,NG
+1407519952,1407519959,A2
+1407519960,1407519983,NG
+1407519984,1407519991,A2
+1407519992,1407519999,NG
+1407520000,1407520007,CD
+1407520008,1407520023,NG
+1407520024,1407520031,A2
+1407520032,1407520039,GN
+1407520040,1407520047,A2
+1407520048,1407520063,ZW
+1407520064,1407520071,A2
+1407520072,1407520079,CM
+1407520080,1407520087,NG
+1407520088,1407520103,GN
+1407520104,1407520111,SD
+1407520112,1407520119,GN
+1407520120,1407520127,NE
+1407520128,1407520151,GN
+1407520152,1407520152,A2
+1407520153,1407520159,GN
+1407520160,1407520167,IL
+1407520168,1407520175,GN
+1407520176,1407520207,A2
+1407520208,1407520215,NG
+1407520216,1407520223,NE
+1407520224,1407520231,SD
+1407520232,1407520239,NG
+1407520240,1407520271,A2
1407520272,1407520279,NG
1407520280,1407520303,A2
1407520304,1407520327,NG
@@ -34629,7 +35605,9 @@
1407520360,1407520367,CD
1407520368,1407520375,A2
1407520376,1407520397,NG
-1407520398,1407520439,A2
+1407520398,1407520415,A2
+1407520416,1407520423,AO
+1407520424,1407520439,A2
1407520440,1407520447,CD
1407520448,1407520463,NG
1407520464,1407520519,A2
@@ -34638,8 +35616,10 @@
1407520544,1407520551,A2
1407520552,1407520559,NG
1407520560,1407520567,SL
-1407520568,1407520575,NG
-1407520576,1407520607,A2
+1407520568,1407520583,NG
+1407520584,1407520591,A2
+1407520592,1407520599,NG
+1407520600,1407520607,A2
1407520608,1407520615,AO
1407520616,1407520623,A2
1407520624,1407520631,NG
@@ -34650,85 +35630,146 @@
1407520688,1407520695,NG
1407520696,1407520711,A2
1407520712,1407520719,NG
-1407520720,1407520759,A2
+1407520720,1407520735,A2
+1407520736,1407520743,LR
+1407520744,1407520751,NG
+1407520752,1407520759,A2
1407520760,1407520767,CD
1407520768,1407520775,ZW
-1407520776,1407520783,A2
+1407520776,1407520783,CD
1407520784,1407520791,SD
-1407520792,1407520847,A2
+1407520792,1407520807,A2
+1407520808,1407520815,CI
+1407520816,1407520823,GQ
+1407520824,1407520831,CI
+1407520832,1407520839,NG
+1407520840,1407520847,A2
1407520848,1407520855,ZM
1407520856,1407520863,A2
-1407520864,1407520871,NG
-1407520872,1407520895,A2
+1407520864,1407520871,TZ
+1407520872,1407520879,CD
+1407520880,1407520887,ZM
+1407520888,1407520895,CD
1407520896,1407520903,AO
1407520904,1407520911,NG
1407520912,1407520919,ZW
1407520920,1407520927,IQ
-1407520928,1407520951,A2
-1407520952,1407520959,ZW
+1407520928,1407520935,A2
+1407520936,1407520943,CD
+1407520944,1407520951,A2
+1407520952,1407520959,ZM
1407520960,1407520967,TZ
-1407520968,1407520975,CD
-1407520976,1407520983,A2
-1407520984,1407520991,ZM
-1407520992,1407521023,A2
-1407521024,1407521031,ZW
-1407521032,1407521055,A2
+1407520968,1407520975,A2
+1407520976,1407520991,ZM
+1407520992,1407520999,IQ
+1407521000,1407521023,CD
+1407521024,1407521031,ZM
+1407521032,1407521047,A2
+1407521048,1407521055,NG
1407521056,1407521063,KE
-1407521064,1407521127,A2
+1407521064,1407521071,A2
+1407521072,1407521079,NG
+1407521080,1407521087,UG
+1407521088,1407521095,NG
+1407521096,1407521103,A2
+1407521104,1407521111,MZ
+1407521112,1407521119,SL
+1407521120,1407521127,A2
1407521128,1407521135,NG
-1407521136,1407521215,A2
+1407521136,1407521143,CD
+1407521144,1407521151,ZM
+1407521152,1407521159,NG
+1407521160,1407521167,ZW
+1407521168,1407521175,SD
+1407521176,1407521183,IQ
+1407521184,1407521199,CD
+1407521200,1407521207,A2
+1407521208,1407521215,IQ
1407521216,1407521223,NG
-1407521224,1407521415,A2
+1407521224,1407521231,TZ
+1407521232,1407521239,LR
+1407521240,1407521247,A2
+1407521248,1407521279,GH
+1407521280,1407521415,A2
1407521416,1407521423,LR
1407521424,1407522319,A2
-1407522320,1407522327,BF
+1407522320,1407522327,TG
1407522328,1407522335,NG
1407522336,1407522351,SO
1407522352,1407522359,CD
1407522360,1407522367,NG
-1407522368,1407522375,A2
-1407522376,1407522383,LR
-1407522384,1407522407,A2
-1407522408,1407522415,LR
-1407522416,1407522431,A2
+1407522368,1407522383,GQ
+1407522384,1407522391,A2
+1407522392,1407522407,NG
+1407522408,1407522415,ZW
+1407522416,1407522423,NG
+1407522424,1407522431,A2
1407522432,1407522439,IQ
1407522440,1407522440,NG
-1407522441,1407522463,A2
+1407522441,1407522447,A2
+1407522448,1407522455,UG
+1407522456,1407522463,ML
1407522464,1407522479,NG
-1407522480,1407522495,A2
+1407522480,1407522487,TZ
+1407522488,1407522495,ZW
1407522496,1407522503,NG
-1407522504,1407522535,A2
-1407522536,1407522559,NG
-1407522560,1407522567,A2
+1407522504,1407522527,A2
+1407522528,1407522535,ZM
+1407522536,1407522551,NG
+1407522552,1407522559,UG
+1407522560,1407522567,MZ
1407522568,1407522575,NG
1407522576,1407522583,A2
1407522584,1407522591,NG
-1407522592,1407522615,A2
-1407522616,1407522623,NG
-1407522624,1407522639,A2
+1407522592,1407522599,A2
+1407522600,1407522607,ZM
+1407522608,1407522615,A2
+1407522616,1407522631,NG
+1407522632,1407522639,MW
1407522640,1407522647,GQ
1407522648,1407522655,NG
-1407522656,1407522671,A2
+1407522656,1407522663,CI
+1407522664,1407522671,A2
1407522672,1407522679,ZM
1407522680,1407522687,IQ
-1407522688,1407522695,LR
-1407522696,1407522703,A2
-1407522704,1407522711,NG
-1407522712,1407522727,A2
-1407522728,1407522735,CD
-1407522736,1407522775,A2
+1407522688,1407522711,NG
+1407522712,1407522719,BJ
+1407522720,1407522727,A2
+1407522728,1407522735,ZW
+1407522736,1407522751,NG
+1407522752,1407522767,ZM
+1407522768,1407522775,A2
1407522776,1407522791,NG
1407522792,1407522799,A2
1407522800,1407522807,ZM
-1407522808,1407522815,A2
-1407522816,1407523071,ZW
-1407523072,1407523279,A2
+1407522808,1407522815,NG
+1407522816,1407522831,A2
+1407522832,1407522839,IQ
+1407522840,1407522871,A2
+1407522872,1407522879,IQ
+1407522880,1407522991,A2
+1407522992,1407522999,CD
+1407523000,1407523071,A2
+1407523072,1407523088,NG
+1407523089,1407523095,A2
+1407523096,1407523103,NG
+1407523104,1407523111,UG
+1407523112,1407523119,ZW
+1407523120,1407523127,CD
+1407523128,1407523135,A2
+1407523136,1407523143,BJ
+1407523144,1407523159,A2
+1407523160,1407523167,LR
+1407523168,1407523183,UG
+1407523184,1407523215,NG
+1407523216,1407523223,BI
+1407523224,1407523247,AO
+1407523248,1407523279,NG
1407523280,1407523287,MZ
-1407523288,1407523295,NG
-1407523296,1407523327,A2
+1407523288,1407523311,NG
+1407523312,1407523327,BJ
1407523328,1407523335,MW
-1407523336,1407523343,A2
-1407523344,1407523351,NG
+1407523336,1407523351,A2
1407523352,1407523359,LU
1407523360,1407523367,ZW
1407523368,1407523391,A2
@@ -34738,54 +35779,130 @@
1407523536,1407523551,NG
1407523552,1407523559,CM
1407523560,1407523567,KE
-1407523568,1407523575,A2
-1407523576,1407523583,MW
-1407523584,1407523839,A2
+1407523568,1407523839,A2
1407523840,1407524351,MW
1407524352,1407524607,GB
1407524608,1407524615,ZW
1407524616,1407524623,CM
-1407524624,1407524631,NG
-1407524632,1407524639,A2
-1407524640,1407524647,NG
+1407524624,1407524631,A2
+1407524632,1407524647,NG
1407524648,1407524655,CD
-1407524656,1407524663,NG
-1407524664,1407524687,A2
+1407524656,1407524671,NG
+1407524672,1407524679,A2
+1407524680,1407524687,LR
1407524688,1407524703,MZ
-1407524704,1407524735,A2
-1407524736,1407524743,NG
-1407524744,1407524783,A2
+1407524704,1407524711,A2
+1407524712,1407524719,CD
+1407524720,1407524727,A2
+1407524728,1407524751,NG
+1407524752,1407524759,A2
+1407524760,1407524767,CM
+1407524768,1407524775,BW
+1407524776,1407524783,A2
1407524784,1407524791,ZW
-1407524792,1407524967,A2
+1407524792,1407524799,LR
+1407524800,1407524839,A2
+1407524840,1407524847,LR
+1407524848,1407524855,A2
+1407524856,1407524863,CD
+1407524864,1407524879,A2
+1407524880,1407524887,NG
+1407524888,1407524895,A2
+1407524896,1407524903,LR
+1407524904,1407524927,NG
+1407524928,1407524935,A2
+1407524936,1407524951,NG
+1407524952,1407524959,CM
+1407524960,1407524967,TZ
1407524968,1407524975,NG
-1407524976,1407525071,A2
-1407525072,1407525079,NG
-1407525080,1407525247,A2
-1407525248,1407525255,CD
+1407524976,1407524991,A2
+1407524992,1407524999,TZ
+1407525000,1407525007,A2
+1407525008,1407525015,TZ
+1407525016,1407525023,BI
+1407525024,1407525031,NG
+1407525032,1407525039,A2
+1407525040,1407525047,ZA
+1407525048,1407525055,NG
+1407525056,1407525063,A2
+1407525064,1407525079,NG
+1407525080,1407525087,A2
+1407525088,1407525095,MW
+1407525096,1407525111,NG
+1407525112,1407525119,ZA
+1407525120,1407525127,NG
+1407525128,1407525135,SD
+1407525136,1407525143,CD
+1407525144,1407525151,A2
+1407525152,1407525167,CD
+1407525168,1407525175,A2
+1407525176,1407525183,CD
+1407525184,1407525191,ZW
+1407525192,1407525207,A2
+1407525208,1407525215,CD
+1407525216,1407525231,A2
+1407525232,1407525255,CD
1407525256,1407525263,NG
-1407525264,1407529023,A2
+1407525264,1407525287,CD
+1407525288,1407525303,A2
+1407525304,1407525319,CD
+1407525320,1407525327,A2
+1407525328,1407525343,CD
+1407525344,1407525471,A2
+1407525472,1407525479,UG
+1407525480,1407526711,A2
+1407526712,1407526719,GN
+1407526720,1407529023,A2
1407529024,1407529087,NG
1407529088,1407529095,A2
1407529096,1407529103,ZW
1407529104,1407529111,NG
1407529112,1407529127,A2
1407529128,1407529135,ZW
-1407529136,1407529143,US
+1407529136,1407529143,A2
1407529144,1407529151,ZW
1407529152,1407529183,A2
1407529184,1407529191,NG
-1407529192,1407529207,A2
+1407529192,1407529199,A2
+1407529200,1407529207,IQ
1407529208,1407529215,NG
1407529216,1407531007,A2
1407531008,1407531519,NG
-1407531520,1407532543,A2
+1407531520,1407531551,CD
+1407531552,1407531559,SD
+1407531560,1407531567,NG
+1407531568,1407531575,CD
+1407531576,1407531583,UG
+1407531584,1407531591,CD
+1407531592,1407531599,A2
+1407531600,1407531607,NG
+1407531608,1407531631,CD
+1407531632,1407531639,ZM
+1407531640,1407531647,CD
+1407531648,1407531655,A2
+1407531656,1407531663,CD
+1407531664,1407531671,MZ
+1407531672,1407531687,CD
+1407531688,1407531695,A2
+1407531696,1407531703,CD
+1407531704,1407531711,IQ
+1407531712,1407531719,A2
+1407531720,1407531735,CD
+1407531736,1407531743,ZW
+1407531744,1407531751,A2
+1407531752,1407531759,GQ
+1407531760,1407531767,ZW
+1407531768,1407531775,SD
+1407531776,1407532543,A2
1407532544,1407532551,UG
1407532552,1407532559,AO
1407532560,1407532583,A2
1407532584,1407532591,ZW
1407532592,1407532615,A2
1407532616,1407532623,KG
-1407532624,1407532663,A2
+1407532624,1407532639,A2
+1407532640,1407532647,NG
+1407532648,1407532663,A2
1407532664,1407532671,TZ
1407532672,1407532799,A2
1407532800,1407532927,SO
@@ -34818,14 +35935,15 @@
1407533816,1407533823,NG
1407533824,1407534079,A2
1407534080,1407534335,AE
-1407534336,1407534359,A2
+1407534336,1407534343,CM
+1407534344,1407534359,A2
1407534360,1407534383,NG
1407534384,1407534391,A2
1407534392,1407534399,AO
1407534400,1407534407,NG
1407534408,1407534415,CI
-1407534416,1407534447,A2
-1407534448,1407534463,NG
+1407534416,1407534455,A2
+1407534456,1407534463,NG
1407534464,1407534543,A2
1407534544,1407534559,GH
1407534560,1407534567,NG
@@ -34840,11 +35958,26 @@
1407534792,1407534847,A2
1407534848,1407535103,CM
1407535104,1407535615,GA
-1407535616,1407535711,A2
+1407535616,1407535623,CD
+1407535624,1407535631,IQ
+1407535632,1407535639,SD
+1407535640,1407535647,A2
+1407535648,1407535663,NG
+1407535664,1407535671,A2
+1407535672,1407535679,SD
+1407535680,1407535687,GN
+1407535688,1407535711,A2
1407535712,1407535719,GB
1407535720,1407535735,A2
1407535736,1407535743,NG
-1407535744,1407536127,A2
+1407535744,1407535775,A2
+1407535776,1407535783,GN
+1407535784,1407535815,A2
+1407535816,1407535823,NG
+1407535824,1407535831,A2
+1407535832,1407535839,GB
+1407535840,1407535847,NG
+1407535848,1407536127,A2
1407536128,1407536639,GA
1407536640,1407536895,CD
1407536896,1407536903,A2
@@ -34871,34 +36004,43 @@
1407537184,1407537191,NG
1407537192,1407537199,A2
1407537200,1407537207,NG
-1407537208,1407537231,A2
+1407537208,1407537215,BE
+1407537216,1407537231,A2
1407537232,1407537255,NG
1407537256,1407537263,A2
1407537264,1407537279,NG
1407537280,1407537287,A2
1407537288,1407537295,NG
-1407537296,1407537335,A2
+1407537296,1407537303,UG
+1407537304,1407537335,A2
1407537336,1407537351,NG
1407537352,1407537367,A2
1407537368,1407537383,NG
-1407537384,1407537431,A2
+1407537384,1407537399,A2
+1407537400,1407537407,BF
+1407537408,1407537415,A2
+1407537416,1407537423,GH
+1407537424,1407537431,A2
1407537432,1407537455,NG
-1407537456,1407537479,A2
+1407537456,1407537463,AO
+1407537464,1407537479,A2
1407537480,1407537487,CM
1407537488,1407537495,GH
-1407537496,1407537511,NG
+1407537496,1407537503,A2
+1407537504,1407537511,NG
1407537512,1407537519,LR
1407537520,1407537535,A2
1407537536,1407537543,LR
-1407537544,1407537559,A2
+1407537544,1407537551,AO
+1407537552,1407537559,A2
1407537560,1407537567,NG
1407537568,1407537575,A2
1407537576,1407537599,NG
-1407537600,1407537623,A2
+1407537600,1407537607,A2
+1407537608,1407537615,CM
+1407537616,1407537623,A2
1407537624,1407537639,NG
-1407537640,1407537663,A2
-1407537664,1407537671,AO
-1407537672,1407537679,A2
+1407537640,1407537679,A2
1407537680,1407537687,IQ
1407537688,1407537703,A2
1407537704,1407537735,NG
@@ -34906,35 +36048,61 @@
1407537752,1407537847,NG
1407537848,1407537855,A2
1407537856,1407537863,NG
-1407537864,1407537871,A2
+1407537864,1407537871,TG
1407537872,1407537879,IQ
-1407537880,1407537887,A2
-1407537888,1407537895,NG
+1407537880,1407537895,A2
1407537896,1407537903,IQ
-1407537904,1407537935,A2
+1407537904,1407537911,TG
+1407537912,1407537927,A2
+1407537928,1407537935,SL
1407537936,1407537943,GH
-1407537944,1407537951,A2
-1407537952,1407537959,NG
-1407537960,1407537967,A2
-1407537968,1407537991,NG
+1407537944,1407537951,TG
+1407537952,1407537959,A2
+1407537960,1407537967,TG
+1407537968,1407537975,NG
+1407537976,1407537983,A2
+1407537984,1407537991,NG
1407537992,1407537999,IQ
1407538000,1407538023,NG
-1407538024,1407538047,A2
+1407538024,1407538031,A2
+1407538032,1407538039,NG
+1407538040,1407538047,CD
1407538048,1407538055,NG
1407538056,1407538071,LU
1407538072,1407538079,NG
-1407538080,1407538087,A2
+1407538080,1407538087,LR
1407538088,1407538095,AO
-1407538096,1407538111,A2
+1407538096,1407538103,CD
+1407538104,1407538111,A2
1407538112,1407538119,LR
-1407538120,1407538127,NG
-1407538128,1407538143,A2
+1407538120,1407538135,NG
+1407538136,1407538143,A2
1407538144,1407538151,GN
1407538152,1407538167,A2
1407538168,1407538175,IQ
-1407538176,1407538295,A2
+1407538176,1407538183,A2
+1407538184,1407538191,NG
+1407538192,1407538199,A2
+1407538200,1407538207,NG
+1407538208,1407538208,A2
+1407538209,1407538271,NG
+1407538272,1407538279,CO
+1407538280,1407538287,A2
+1407538288,1407538295,NG
1407538296,1407538303,AO
-1407538304,1407538439,A2
+1407538304,1407538311,NG
+1407538312,1407538319,CD
+1407538320,1407538327,NG
+1407538328,1407538335,CD
+1407538336,1407538343,A2
+1407538344,1407538351,CD
+1407538352,1407538383,A2
+1407538384,1407538391,CM
+1407538392,1407538407,A2
+1407538408,1407538415,NG
+1407538416,1407538423,A2
+1407538424,1407538431,NG
+1407538432,1407538439,A2
1407538440,1407538447,NG
1407538448,1407538463,A2
1407538464,1407538471,ZM
@@ -34943,8 +36111,7 @@
1407538664,1407538679,NG
1407538680,1407538751,A2
1407538752,1407538783,NG
-1407538784,1407538847,A2
-1407538848,1407538863,NG
+1407538784,1407538863,A2
1407538864,1407538879,GE
1407538880,1407538887,A2
1407538888,1407538895,NG
@@ -34969,9 +36136,25 @@
1407539176,1407539183,GH
1407539184,1407539199,NG
1407539200,1407539455,GE
-1407539456,1407540119,A2
+1407539456,1407539967,A2
+1407539968,1407539975,CD
+1407539976,1407540007,A2
+1407540008,1407540015,NG
+1407540016,1407540055,A2
+1407540056,1407540063,NG
+1407540064,1407540071,A2
+1407540072,1407540079,NG
+1407540080,1407540111,A2
+1407540112,1407540119,TG
1407540120,1407540127,NG
-1407540128,1407541471,A2
+1407540128,1407540135,A2
+1407540136,1407540143,NG
+1407540144,1407540159,A2
+1407540160,1407540167,CD
+1407540168,1407540183,A2
+1407540184,1407540199,NG
+1407540200,1407540215,CD
+1407540216,1407541471,A2
1407541472,1407541495,NG
1407541496,1407541535,A2
1407541536,1407541543,CM
@@ -35024,7 +36207,10 @@
1407543280,1407543287,NG
1407543288,1407546367,A2
1407546368,1407546495,AE
-1407546496,1407546879,A2
+1407546496,1407546799,A2
+1407546800,1407546815,GH
+1407546816,1407546863,A2
+1407546864,1407546879,LR
1407546880,1407547135,ZW
1407547136,1407547143,A2
1407547144,1407547151,GH
@@ -35065,7 +36251,9 @@
1407548144,1407548151,A2
1407548152,1407548415,NG
1407548416,1407548543,GE
-1407548544,1407549183,A2
+1407548544,1407548711,A2
+1407548712,1407548719,CD
+1407548720,1407549183,A2
1407549184,1407549439,GE
1407549440,1407582207,RU
1407582208,1407614975,PL
@@ -35112,21 +36300,21 @@
1407705760,1407705791,FR
1407705792,1407706367,GB
1407706368,1407706423,FR
-1407706424,1407707703,GB
+1407706424,1407706431,GB
+1407706432,1407706463,FR
+1407706464,1407707703,GB
1407707704,1407707839,CH
1407707840,1407707903,GB
1407707904,1407707935,CH
1407707936,1407709183,GB
-1407709184,1407709631,DE
-1407709632,1407710207,GB
+1407709184,1407709695,DE
+1407709696,1407710207,GB
1407710208,1407710239,ES
1407710240,1407710975,GB
1407710976,1407711319,FR
1407711320,1407711327,GB
-1407711328,1407711623,FR
-1407711624,1407711631,GB
-1407711632,1407711727,FR
-1407711728,1407712207,GB
+1407711328,1407711743,FR
+1407711744,1407712207,GB
1407712208,1407712223,FR
1407712224,1407712767,GB
1407712768,1407712831,DE
@@ -35228,11 +36416,10 @@
1410010824,1410010831,IR
1410010832,1410010879,DE
1410010880,1410011135,IR
-1410011136,1410011903,DE
-1410011904,1410011919,US
-1410011920,1410012159,DE
+1410011136,1410012159,DE
1410012160,1410012415,IQ
-1410012416,1410013183,DE
+1410012416,1410012447,AF
+1410012448,1410013183,DE
1410013184,1410013439,ES
1410013440,1410013471,IR
1410013472,1410013535,AE
@@ -35302,8 +36489,8 @@
1410017120,1410017279,DE
1410017280,1410017407,IR
1410017408,1410017791,DE
-1410017792,1410018079,IR
-1410018080,1410018303,DE
+1410017792,1410018047,IR
+1410018048,1410018303,DE
1410018304,1410018559,AE
1410018560,1410018591,DE
1410018592,1410018607,IR
@@ -35323,9 +36510,7 @@
1410022592,1410022655,IR
1410022656,1410022911,DE
1410022912,1410023423,IR
-1410023424,1410024191,DE
-1410024192,1410024223,AE
-1410024224,1410024287,DE
+1410023424,1410024287,DE
1410024288,1410024319,IR
1410024320,1410024447,DE
1410024448,1410025087,IR
@@ -35382,7 +36567,9 @@
1410036192,1410036207,PA
1410036208,1410036735,DE
1410036736,1410036751,PA
-1410036752,1410037759,DE
+1410036752,1410036991,DE
+1410036992,1410037247,LB
+1410037248,1410037759,DE
1410037760,1410038015,US
1410038016,1410039807,DE
1410039808,1410041855,AE
@@ -35392,7 +36579,9 @@
1410043904,1410044415,JO
1410044416,1410044927,DE
1410044928,1410045183,VG
-1410045184,1410072319,DE
+1410045184,1410045439,DE
+1410045440,1410045695,LB
+1410045696,1410072319,DE
1410072320,1410072575,AE
1410072576,1410203647,GB
1410203648,1410204439,FR
@@ -35405,11 +36594,15 @@
1410212864,1410213119,GB
1410213120,1410221663,FR
1410221664,1410221671,GB
-1410221672,1410250551,FR
+1410221672,1410234839,FR
+1410234840,1410234847,A2
+1410234848,1410250551,FR
1410250552,1410250559,GB
1410250560,1410261007,FR
1410261008,1410261015,GB
-1410261016,1410262799,FR
+1410261016,1410261663,FR
+1410261664,1410261671,GB
+1410261672,1410262799,FR
1410262800,1410262815,DE
1410262816,1410267039,FR
1410267040,1410267055,ES
@@ -35475,9 +36668,14 @@
1410573408,1410573439,RU
1410573440,1410573695,DE
1410573696,1410573711,RU
-1410573712,1410573815,DE
+1410573712,1410573759,DE
+1410573760,1410573775,BA
+1410573776,1410573807,DE
+1410573808,1410573815,IT
1410573816,1410573823,RU
-1410573824,1410574559,DE
+1410573824,1410574527,DE
+1410574528,1410574543,IT
+1410574544,1410574559,DE
1410574560,1410574575,RU
1410574576,1410574583,DE
1410574584,1410574591,RU
@@ -35571,7 +36769,9 @@
1410756736,1410756863,DE
1410756864,1410757119,AQ
1410757120,1410758655,DE
-1410758656,1410760191,AQ
+1410758656,1410759423,AQ
+1410759424,1410759679,GB
+1410759680,1410760191,AQ
1410760192,1410760455,DE
1410760456,1410760471,AQ
1410760472,1410760479,SC
@@ -35691,13 +36891,15 @@
1411919872,1411923967,DE
1411923968,1411940351,BG
1411940352,1411973119,PL
-1411973120,1411999767,SI
+1411973120,1411999743,SI
+1411999744,1411999759,BA
+1411999760,1411999767,SI
1411999768,1411999783,BA
1411999784,1411999791,SI
1411999792,1411999799,BA
1411999800,1411999807,SI
-1411999808,1411999839,BA
-1411999840,1411999871,SI
+1411999808,1411999847,BA
+1411999848,1411999871,SI
1411999872,1412000767,BA
1412000768,1412000783,SI
1412000784,1412000791,BA
@@ -35705,7 +36907,9 @@
1412000864,1412000879,BA
1412000880,1412000903,SI
1412000904,1412000911,BA
-1412000912,1412001311,SI
+1412000912,1412001023,SI
+1412001024,1412001279,BA
+1412001280,1412001311,SI
1412001312,1412001319,DE
1412001320,1412001807,SI
1412001808,1412001855,RO
@@ -35744,12 +36948,17 @@
1412003528,1412003535,SI
1412003536,1412003551,BA
1412003552,1412003583,SI
-1412003584,1412003839,BA
+1412003584,1412003599,BA
+1412003600,1412003623,SI
+1412003624,1412003631,BA
+1412003632,1412003639,SI
+1412003640,1412003839,BA
1412003840,1412003855,SI
1412003856,1412003903,BG
1412003904,1412003935,SI
-1412003936,1412004607,BG
-1412004608,1412005887,SI
+1412003936,1412004351,BG
+1412004352,1412004863,BA
+1412004864,1412005887,SI
1412005888,1412038655,NL
1412038656,1412071423,RU
1412071424,1412104191,CZ
@@ -35779,8 +36988,7 @@
1412628480,1412641791,TR
1412641792,1412642815,DE
1412642816,1412644863,TR
-1412644864,1412653055,UA
-1412653056,1412661247,RU
+1412644864,1412661247,RU
1412661248,1412677631,GB
1412677632,1412685823,RU
1412685824,1412686239,IE
@@ -35833,21 +37041,20 @@
1422393344,1422393599,DE
1422393600,1422393855,IT
1422393856,1422399103,DE
-1422399104,1422399231,IT
-1422399232,1422399999,DE
+1422399104,1422399135,IT
+1422399136,1422399999,DE
1422400000,1422400255,IT
1422400256,1422400511,DE
1422400512,1422400767,BR
-1422400768,1422401087,DE
-1422401088,1422401151,GB
-1422401152,1422462207,DE
+1422400768,1422406399,DE
+1422406400,1422406463,GB
+1422406464,1422462207,DE
1422462208,1422462463,TR
1422462464,1422468671,DE
1422468672,1422468735,IT
1422468736,1422479615,DE
1422479616,1422479871,BE
1422479872,1422491647,DE
-1422491648,1422508031,GB
1422508032,1422512127,BG
1422512128,1422516223,PL
1422516224,1422520319,BY
@@ -35869,7 +37076,9 @@
1422853920,1422854143,EU
1422854144,1422854151,FR
1422854152,1422856319,EU
-1422856320,1422856575,FR
+1422856320,1422856447,FR
+1422856448,1422856511,EU
+1422856512,1422856575,FR
1422856576,1422856703,EU
1422856704,1422857855,FR
1422857856,1422857919,EU
@@ -36039,9 +37248,7 @@
1424609272,1424609279,DE
1424609280,1424609395,CH
1424609396,1424609399,GB
-1424609400,1424609727,CH
-1424609728,1424609743,GB
-1424609744,1424609791,CH
+1424609400,1424609791,CH
1424609792,1424610303,GB
1424610304,1424610559,TZ
1424610560,1424610815,PL
@@ -36105,9 +37312,7 @@
1424618016,1424618239,IT
1424618240,1424618495,NL
1424618496,1424618751,GB
-1424618752,1424618943,FR
-1424618944,1424618951,GB
-1424618952,1424619007,FR
+1424618752,1424619007,FR
1424619008,1424619775,IT
1424619776,1424619807,BE
1424619808,1424619815,GB
@@ -36115,7 +37320,9 @@
1424619824,1424619839,GB
1424619840,1424619915,BE
1424619916,1424619919,GB
-1424619920,1424620031,BE
+1424619920,1424619951,BE
+1424619952,1424619967,GB
+1424619968,1424620031,BE
1424620032,1424621055,GB
1424621056,1424621567,IT
1424621568,1424625663,PL
@@ -36227,6 +37434,7 @@
1425426432,1425428479,KW
1425428480,1425430527,GB
1425430528,1425432575,SE
+1425432576,1425434623,HR
1425434624,1425436671,FR
1425436672,1425438719,GB
1425438720,1425439271,DE
@@ -36314,9 +37522,7 @@
1425966721,1425966728,BJ
1425966729,1425966735,A2
1425966736,1425966751,BJ
-1425966752,1425966784,A2
-1425966785,1425966808,BJ
-1425966809,1425966815,A2
+1425966752,1425966815,A2
1425966816,1425966847,BJ
1425966848,1425966852,A2
1425966853,1425966896,DE
@@ -36521,7 +37727,11 @@
1426685952,1426702335,TJ
1426702336,1426703103,LV
1426703104,1426703167,RU
-1426703168,1426718719,LV
+1426703168,1426703214,LV
+1426703215,1426703217,RU
+1426703218,1426716159,LV
+1426716160,1426716415,RU
+1426716416,1426718719,LV
1426718720,1426731007,SI
1426731008,1426735103,HR
1426735104,1426751487,BE
@@ -36638,9 +37848,7 @@
1427668992,1427701759,SE
1427701760,1427723391,DE
1427723392,1427723519,LI
-1427723520,1427728383,DE
-1427728384,1427728415,US
-1427728416,1427728479,DE
+1427723520,1427728479,DE
1427728480,1427728511,CY
1427728512,1427728543,BR
1427728544,1427728671,DE
@@ -36651,8 +37859,7 @@
1427728896,1427728927,DE
1427728928,1427728959,IL
1427728960,1427728991,RU
-1427728992,1427729023,DE
-1427729024,1427729055,AT
+1427728992,1427729055,DE
1427729056,1427729087,CA
1427729088,1427729119,DE
1427729120,1427729151,RO
@@ -36660,9 +37867,7 @@
1427729312,1427729343,GR
1427729344,1427742719,DE
1427742720,1427742751,IO
-1427742752,1427742847,DE
-1427742848,1427742879,CZ
-1427742880,1427743231,DE
+1427742752,1427743231,DE
1427743232,1427743263,GR
1427743264,1427743327,DE
1427743328,1427743359,NL
@@ -36672,16 +37877,18 @@
1427743616,1427743647,DK
1427743648,1427743775,DE
1427743776,1427743807,ZA
-1427743808,1427744159,DE
+1427743808,1427743839,DE
+1427743840,1427743871,RU
+1427743872,1427743935,DE
+1427743936,1427743967,RU
+1427743968,1427744159,DE
1427744160,1427744191,RU
1427744192,1427744255,DE
1427744256,1427744287,US
1427744288,1427744319,TR
1427744320,1427744351,DE
1427744352,1427744383,UA
-1427744384,1427744511,DE
-1427744512,1427744543,BE
-1427744544,1427744639,DE
+1427744384,1427744639,DE
1427744640,1427744671,TR
1427744672,1427744703,DE
1427744704,1427744735,CA
@@ -36713,7 +37920,11 @@
1427746368,1427746399,SE
1427746400,1427747839,DE
1427747840,1427747871,FI
-1427747872,1427748543,DE
+1427747872,1427748063,DE
+1427748064,1427748095,NL
+1427748096,1427748479,DE
+1427748480,1427748511,TR
+1427748512,1427748543,DE
1427748544,1427748575,MX
1427748576,1427749503,DE
1427749504,1427749535,UA
@@ -36723,9 +37934,7 @@
1427749632,1427749663,US
1427749664,1427749951,DE
1427749952,1427749983,RU
-1427749984,1427750143,DE
-1427750144,1427750175,TR
-1427750176,1427750239,DE
+1427749984,1427750239,DE
1427750240,1427750271,NL
1427750272,1427750303,DE
1427750304,1427750335,GB
@@ -36737,7 +37946,8 @@
1427760192,1427760223,TR
1427760224,1427760255,US
1427760256,1427760319,BR
-1427760320,1427760383,DE
+1427760320,1427760351,DE
+1427760352,1427760383,RU
1427760384,1427760415,TR
1427760416,1427760799,DE
1427760800,1427760831,NL
@@ -36757,7 +37967,8 @@
1427761504,1427761535,PL
1427761536,1427761567,US
1427761568,1427761599,RU
-1427761600,1427767295,DE
+1427761600,1427761631,EG
+1427761632,1427767295,DE
1427767296,1427800063,BE
1427800064,1427823615,RU
1427823616,1427824639,KG
@@ -36773,6 +37984,7 @@
1427980288,1427996671,FI
1427996672,1428013055,KZ
1428013056,1428029439,EE
+1428029440,1428045823,SE
1428045824,1428062207,MK
1428062208,1428078591,SE
1428078592,1428094975,RU
@@ -36783,7 +37995,7 @@
1428111360,1428119551,A2
1428119552,1428121599,LV
1428121600,1428123647,FR
-1428123648,1428126975,RU
+1428125696,1428126975,RU
1428126976,1428127231,TR
1428127232,1428127743,RU
1428127744,1428129791,ES
@@ -36802,19 +38014,16 @@
1428147596,1428147711,GB
1428147712,1428147855,FR
1428147856,1428147871,US
-1428147872,1428147895,FR
-1428147896,1428147903,GB
-1428147904,1428148039,FR
+1428147872,1428148039,FR
1428148040,1428148047,GB
1428148048,1428148175,FR
1428148176,1428148191,CH
-1428148192,1428148223,GB
-1428148224,1428150735,FR
+1428148192,1428150735,FR
1428150736,1428150751,GB
1428150752,1428151007,FR
1428151008,1428151039,GB
1428151040,1428151231,FR
-1428151232,1428151295,GB
+1428151232,1428151295,CH
1428151296,1428152127,FR
1428152128,1428152319,GB
1428152320,1428160511,PL
@@ -36897,16 +38106,14 @@
1432133632,1432150015,GB
1432150016,1432158207,BA
1432158208,1432159042,DE
-1432159043,1432159046,IR
+1432159043,1432159046,US
1432159047,1432159311,DE
-1432159312,1432159321,IR
+1432159312,1432159321,US
1432159322,1432159743,DE
1432159744,1432159871,PL
1432159872,1432160255,DE
1432160256,1432160511,CH
-1432160512,1432162907,DE
-1432162908,1432162914,IR
-1432162915,1432165247,DE
+1432160512,1432165247,DE
1432165248,1432165375,PL
1432165376,1432166399,DE
1432166400,1432174591,RU
@@ -36940,8 +38147,7 @@
1433410560,1433411071,ES
1433411072,1433411327,US
1433411328,1433411343,ES
-1433411344,1433411359,TR
-1433411360,1433411375,ES
+1433411344,1433411375,TR
1433411376,1433411407,US
1433411408,1433411455,TR
1433411456,1433411519,US
@@ -37027,7 +38233,9 @@
1433860096,1433862143,DE
1433862144,1433862751,CH
1433862752,1433862783,MC
-1433862784,1433863423,CH
+1433862784,1433862975,CH
+1433862976,1433862991,GB
+1433862992,1433863423,CH
1433863424,1433863487,US
1433863488,1433864191,CH
1433864192,1433866239,HU
@@ -37063,8 +38271,8 @@
1433911296,1433913343,ES
1433913344,1433913875,NL
1433913876,1433913879,DE
-1433913880,1433914111,NL
-1433914112,1433915135,DE
+1433913880,1433914047,NL
+1433914048,1433915135,DE
1433915136,1433915391,NL
1433915392,1433917439,DE
1433917440,1433919487,BE
@@ -37086,17 +38294,21 @@
1434681856,1434682111,MY
1434682112,1434682303,DE
1434682304,1434682367,NL
-1434682368,1434683103,DE
-1434683104,1434683135,NL
-1434683136,1434683263,DE
-1434683264,1434683391,NL
-1434683392,1434684415,DE
-1434684416,1434684671,NL
-1434684672,1434685439,DE
+1434682368,1434683119,DE
+1434683120,1434683135,NL
+1434683136,1434683327,DE
+1434683328,1434683391,MY
+1434683392,1434685439,DE
1434685440,1434687231,NL
1434687232,1434687359,DE
1434687360,1434687487,NL
-1434687488,1434694655,DE
+1434687488,1434688207,DE
+1434688208,1434688223,NL
+1434688224,1434689887,DE
+1434689888,1434689919,NL
+1434689920,1434692607,DE
+1434692608,1434692671,NL
+1434692672,1434694655,DE
1434694656,1434694719,NL
1434694720,1434702463,DE
1434702464,1434702591,NL
@@ -37258,9 +38470,7 @@
1438869648,1438869651,LV
1438869652,1438869655,US
1438869656,1438869663,UA
-1438869664,1438869671,DE
-1438869672,1438869679,CY
-1438869680,1438873119,DE
+1438869664,1438873119,DE
1438873120,1438873127,PA
1438873128,1438873671,DE
1438873672,1438873679,PA
@@ -37281,7 +38491,7 @@
1438875256,1438875257,CH
1438875258,1438875647,DE
1438875648,1438876159,RU
-1438876160,1438876415,LB
+1438876160,1438876415,LT
1438876416,1438876927,RU
1438876928,1438877183,IQ
1438877184,1438877439,LT
@@ -37299,8 +38509,7 @@
1438884352,1438884607,LB
1438884608,1438884863,IQ
1438884864,1438885887,RU
-1438885888,1438889983,LT
-1438889984,1438890239,LB
+1438885888,1438890239,LT
1438890240,1438890495,RU
1438890496,1438890751,IQ
1438890752,1438892031,RU
@@ -37465,7 +38674,11 @@
1441388672,1441388799,CA
1441388800,1441389055,FR
1441389056,1441389119,IE
-1441389120,1441390591,FR
+1441389120,1441389223,FR
+1441389224,1441389231,LU
+1441389232,1441389567,FR
+1441389568,1441389599,LU
+1441389600,1441390591,FR
1441390592,1441398783,DK
1441398784,1441415167,RU
1441415168,1441423359,GB
@@ -37513,10 +38726,7 @@
1441583104,1441587199,DE
1441587200,1441594879,AT
1441594880,1441595135,DE
-1441595136,1441596415,AT
-1441596416,1441602815,SK
-1441602816,1441603071,AT
-1441603072,1441603583,SK
+1441595136,1441603583,AT
1441603584,1441611775,RU
1441611776,1441619967,DE
1441619968,1441620271,FR
@@ -37669,25 +38879,1019 @@
1446862080,1446862591,HR
1446862592,1446871039,SI
1446871040,1446903807,CZ
-1446903808,1446904071,A2
-1446904072,1446904079,CY
+1446903808,1446904063,A2
+1446904064,1446904071,CY
+1446904072,1446904079,IQ
1446904080,1446904095,BH
-1446904096,1446904111,SA
-1446904112,1446904119,BH
-1446904120,1446904127,A2
+1446904096,1446904103,SD
+1446904104,1446904111,SA
+1446904112,1446904119,LY
+1446904120,1446904127,SD
1446904128,1446904135,SA
1446904136,1446904143,IQ
-1446904144,1446904151,SA
+1446904144,1446904151,ER
1446904152,1446904159,IR
1446904160,1446904167,ES
1446904168,1446904175,IQ
-1446904176,1446904831,A2
-1446904832,1446904835,LY
-1446904836,1446904931,A2
+1446904176,1446904183,A2
+1446904184,1446904191,IQ
+1446904192,1446904215,A2
+1446904216,1446904223,IQ
+1446904224,1446904231,LY
+1446904232,1446904247,A2
+1446904248,1446904255,AF
+1446904256,1446904263,CY
+1446904264,1446904279,A2
+1446904280,1446904287,IQ
+1446904288,1446904295,AF
+1446904296,1446904303,IQ
+1446904304,1446904311,A2
+1446904312,1446904319,AF
+1446904320,1446904335,AE
+1446904336,1446904351,A2
+1446904352,1446904367,AE
+1446904368,1446904527,A2
+1446904528,1446904543,ZM
+1446904544,1446904575,A2
+1446904576,1446904591,SD
+1446904592,1446904599,NG
+1446904600,1446904607,A2
+1446904608,1446904623,SD
+1446904624,1446904631,IQ
+1446904632,1446904751,A2
+1446904752,1446904759,NG
+1446904760,1446904799,A2
+1446904800,1446904807,SD
+1446904808,1446904815,A2
+1446904816,1446904823,ZM
+1446904824,1446904831,A2
+1446904832,1446904839,IQ
+1446904840,1446904843,A2
+1446904844,1446904847,CG
+1446904848,1446904851,A2
+1446904852,1446904859,IQ
+1446904860,1446904871,A2
+1446904872,1446904875,IQ
+1446904876,1446904879,ZM
+1446904880,1446904887,IQ
+1446904888,1446904895,A2
+1446904896,1446904907,IQ
+1446904908,1446904915,A2
+1446904916,1446904919,ZM
+1446904920,1446904927,IQ
+1446904928,1446904931,A2
1446904932,1446904935,ZM
-1446904936,1446908539,A2
+1446904936,1446904939,LY
+1446904940,1446904947,IQ
+1446904948,1446904951,A2
+1446904952,1446904955,AF
+1446904956,1446904959,A2
+1446904960,1446904963,IQ
+1446904964,1446904975,A2
+1446904976,1446904979,CG
+1446904980,1446904987,IQ
+1446904988,1446904991,A2
+1446904992,1446905007,IQ
+1446905008,1446905011,CG
+1446905012,1446905015,A2
+1446905016,1446905019,NG
+1446905020,1446905023,LY
+1446905024,1446905031,IQ
+1446905032,1446905035,A2
+1446905036,1446905039,IQ
+1446905040,1446905043,AF
+1446905044,1446905051,IQ
+1446905052,1446905055,LY
+1446905056,1446905063,IQ
+1446905064,1446905067,NG
+1446905068,1446905071,IQ
+1446905072,1446905083,A2
+1446905084,1446905095,AF
+1446905096,1446905103,BJ
+1446905104,1446905107,IQ
+1446905108,1446905111,A2
+1446905112,1446905115,BJ
+1446905116,1446905119,A2
+1446905120,1446905123,GN
+1446905124,1446905127,AF
+1446905128,1446905135,A2
+1446905136,1446905143,IQ
+1446905144,1446905147,A2
+1446905148,1446905151,LY
+1446905152,1446905155,AF
+1446905156,1446905167,IQ
+1446905168,1446905171,A2
+1446905172,1446905175,IQ
+1446905176,1446905179,AF
+1446905180,1446905191,LY
+1446905192,1446905195,A2
+1446905196,1446905199,AF
+1446905200,1446905203,NG
+1446905204,1446905207,AF
+1446905208,1446905211,ER
+1446905212,1446905215,IQ
+1446905216,1446905223,A2
+1446905224,1446905227,IQ
+1446905228,1446905235,NG
+1446905236,1446905251,A2
+1446905252,1446905255,IQ
+1446905256,1446905259,A2
+1446905260,1446905263,IQ
+1446905264,1446905267,LY
+1446905268,1446905271,NG
+1446905272,1446905275,IQ
+1446905276,1446905279,A2
+1446905280,1446905283,IQ
+1446905284,1446905287,A2
+1446905288,1446905295,IQ
+1446905296,1446905303,ZM
+1446905304,1446905307,CF
+1446905308,1446905315,A2
+1446905316,1446905319,NG
+1446905320,1446905323,A2
+1446905324,1446905327,IQ
+1446905328,1446905331,A2
+1446905332,1446905339,IQ
+1446905340,1446905343,A2
+1446905344,1446905351,LY
+1446905352,1446905367,A2
+1446905368,1446905375,LY
+1446905376,1446905383,A2
+1446905384,1446905391,SD
+1446905392,1446905583,A2
+1446905584,1446905591,AF
+1446905592,1446905599,A2
+1446905600,1446905603,ZM
+1446905604,1446905615,IQ
+1446905616,1446905619,A2
+1446905620,1446905623,ZM
+1446905624,1446905627,A2
+1446905628,1446905631,AF
+1446905632,1446905635,LY
+1446905636,1446905639,IQ
+1446905640,1446905643,A2
+1446905644,1446905655,IQ
+1446905656,1446905659,AF
+1446905660,1446905663,ER
+1446905664,1446905667,LY
+1446905668,1446905671,A2
+1446905672,1446905675,AF
+1446905676,1446905679,LY
+1446905680,1446905683,ZM
+1446905684,1446905691,A2
+1446905692,1446905695,ZM
+1446905696,1446905699,LY
+1446905700,1446905703,ZM
+1446905704,1446905719,A2
+1446905720,1446905723,AF
+1446905724,1446905727,A2
+1446905728,1446905731,IQ
+1446905732,1446905735,AF
+1446905736,1446905743,A2
+1446905744,1446905747,LY
+1446905748,1446905751,A2
+1446905752,1446905755,IQ
+1446905756,1446905759,A2
+1446905760,1446905763,ML
+1446905764,1446905767,LY
+1446905768,1446905779,A2
+1446905780,1446905783,LY
+1446905784,1446905787,A2
+1446905788,1446905791,LY
+1446905792,1446905795,TD
+1446905796,1446905803,A2
+1446905804,1446905807,IQ
+1446905808,1446905815,A2
+1446905816,1446905823,LY
+1446905824,1446905827,A2
+1446905828,1446905831,LY
+1446905832,1446905835,NG
+1446905836,1446905839,A2
+1446905840,1446905843,IQ
+1446905844,1446905847,A2
+1446905848,1446905851,IQ
+1446905852,1446905855,AF
+1446905856,1446905856,A2
+1446905857,1446905863,LY
+1446905864,1446905871,SD
+1446905872,1446905911,A2
+1446905912,1446905943,SD
+1446905944,1446906023,A2
+1446906024,1446906031,SD
+1446906032,1446906039,A2
+1446906040,1446906047,SD
+1446906048,1446906071,A2
+1446906072,1446906079,CY
+1446906080,1446906115,A2
+1446906116,1446906119,ZM
+1446906120,1446906123,SD
+1446906124,1446906131,IQ
+1446906132,1446906135,LY
+1446906136,1446906139,IQ
+1446906140,1446906143,A2
+1446906144,1446906151,ZM
+1446906152,1446906167,AF
+1446906168,1446906171,A2
+1446906172,1446906179,AF
+1446906180,1446906187,A2
+1446906188,1446906191,AF
+1446906192,1446906195,A2
+1446906196,1446906203,IQ
+1446906204,1446906211,A2
+1446906212,1446906215,AF
+1446906216,1446906219,A2
+1446906220,1446906223,BG
+1446906224,1446906231,IQ
+1446906232,1446906239,AF
+1446906240,1446906243,IQ
+1446906244,1446906247,A2
+1446906248,1446906259,IQ
+1446906260,1446906263,AF
+1446906264,1446906283,A2
+1446906284,1446906303,IQ
+1446906304,1446906307,ZM
+1446906308,1446906311,A2
+1446906312,1446906327,IQ
+1446906328,1446906331,A2
+1446906332,1446906335,IQ
+1446906336,1446906339,ZM
+1446906340,1446906343,A2
+1446906344,1446906347,NG
+1446906348,1446906351,ZM
+1446906352,1446906359,A2
+1446906360,1446906363,SD
+1446906364,1446906367,IQ
+1446906368,1446906391,A2
+1446906392,1446906399,CY
+1446906400,1446906567,A2
+1446906568,1446906591,KW
+1446906592,1446906599,IQ
+1446906600,1446906615,KW
+1446906616,1446906623,A2
+1446906624,1446906631,LY
+1446906632,1446906639,A2
+1446906640,1446906655,LY
+1446906656,1446906663,NG
+1446906664,1446906863,A2
+1446906864,1446906871,ZM
+1446906872,1446906879,A2
+1446906880,1446906883,IQ
+1446906884,1446906887,AF
+1446906888,1446906891,IQ
+1446906892,1446906895,A2
+1446906896,1446906899,IQ
+1446906900,1446906907,A2
+1446906908,1446906919,IQ
+1446906920,1446906923,A2
+1446906924,1446906927,IQ
+1446906928,1446906931,SA
+1446906932,1446906935,IQ
+1446906936,1446906943,LY
+1446906944,1446906947,IQ
+1446906948,1446906951,A2
+1446906952,1446906955,IQ
+1446906956,1446906963,A2
+1446906964,1446906967,AF
+1446906968,1446906971,A2
+1446906972,1446906983,IQ
+1446906984,1446906987,NG
+1446906988,1446906995,IQ
+1446906996,1446906999,AF
+1446907000,1446907007,A2
+1446907008,1446907011,AF
+1446907012,1446907015,IQ
+1446907016,1446907019,ZM
+1446907020,1446907023,AF
+1446907024,1446907027,IQ
+1446907028,1446907031,ZM
+1446907032,1446907039,A2
+1446907040,1446907043,ZM
+1446907044,1446907047,CG
+1446907048,1446907055,IQ
+1446907056,1446907067,A2
+1446907068,1446907071,AF
+1446907072,1446907075,A2
+1446907076,1446907079,IQ
+1446907080,1446907083,AF
+1446907084,1446907087,IQ
+1446907088,1446907091,LY
+1446907092,1446907095,IQ
+1446907096,1446907099,NG
+1446907100,1446907103,IQ
+1446907104,1446907123,A2
+1446907124,1446907131,IQ
+1446907132,1446907135,AF
+1446907136,1446907147,A2
+1446907148,1446907151,IQ
+1446907152,1446907155,A2
+1446907156,1446907159,LY
+1446907160,1446907163,AF
+1446907164,1446907167,IQ
+1446907168,1446907171,LY
+1446907172,1446907175,IQ
+1446907176,1446907187,LY
+1446907188,1446907191,CG
+1446907192,1446907199,IQ
+1446907200,1446907203,A2
+1446907204,1446907207,IQ
+1446907208,1446907211,A2
+1446907212,1446907215,IQ
+1446907216,1446907223,A2
+1446907224,1446907227,ZM
+1446907228,1446907231,A2
+1446907232,1446907243,IQ
+1446907244,1446907247,NG
+1446907248,1446907255,A2
+1446907256,1446907259,GA
+1446907260,1446907279,IQ
+1446907280,1446907283,GA
+1446907284,1446907287,A2
+1446907288,1446907291,AF
+1446907292,1446907303,A2
+1446907304,1446907307,IQ
+1446907308,1446907311,AF
+1446907312,1446907315,A2
+1446907316,1446907319,IQ
+1446907320,1446907323,AF
+1446907324,1446907327,A2
+1446907328,1446907331,IQ
+1446907332,1446907335,A2
+1446907336,1446907339,IQ
+1446907340,1446907347,LY
+1446907348,1446907355,ZM
+1446907356,1446907371,A2
+1446907372,1446907375,AF
+1446907376,1446907379,ZM
+1446907380,1446907383,IQ
+1446907384,1446907387,CI
+1446907388,1446907391,A2
+1446907392,1446907395,AF
+1446907396,1446907399,IQ
+1446907400,1446907403,A2
+1446907404,1446907407,IQ
+1446907408,1446907411,A2
+1446907412,1446907419,IQ
+1446907420,1446907423,A2
+1446907424,1446907427,ZM
+1446907428,1446907439,A2
+1446907440,1446907443,AF
+1446907444,1446907451,A2
+1446907452,1446907463,IQ
+1446907464,1446907475,A2
+1446907476,1446907479,LY
+1446907480,1446907483,A2
+1446907484,1446907487,IQ
+1446907488,1446907491,A2
+1446907492,1446907495,TD
+1446907496,1446907503,IQ
+1446907504,1446907507,LY
+1446907508,1446907511,IQ
+1446907512,1446907523,A2
+1446907524,1446907527,LY
+1446907528,1446907531,A2
+1446907532,1446907539,IQ
+1446907540,1446907543,LY
+1446907544,1446907547,IQ
+1446907548,1446907551,A2
+1446907552,1446907559,IQ
+1446907560,1446907571,A2
+1446907572,1446907575,AF
+1446907576,1446907579,A2
+1446907580,1446907583,GH
+1446907584,1446907615,A2
+1446907616,1446907619,TD
+1446907620,1446907631,A2
+1446907632,1446907635,LY
+1446907636,1446907647,IQ
+1446907648,1446907659,A2
+1446907660,1446907663,ZM
+1446907664,1446907667,NG
+1446907668,1446907671,A2
+1446907672,1446907675,IQ
+1446907676,1446907679,LY
+1446907680,1446907691,A2
+1446907692,1446907695,IQ
+1446907696,1446907699,LY
+1446907700,1446907703,IQ
+1446907704,1446907715,A2
+1446907716,1446907719,AF
+1446907720,1446907723,A2
+1446907724,1446907731,IQ
+1446907732,1446907735,LY
+1446907736,1446907739,A2
+1446907740,1446907743,IQ
+1446907744,1446907747,A2
+1446907748,1446907755,AF
+1446907756,1446907759,A2
+1446907760,1446907763,IQ
+1446907764,1446907767,A2
+1446907768,1446907771,IQ
+1446907772,1446907775,A2
+1446907776,1446907779,LY
+1446907780,1446907783,IQ
+1446907784,1446907787,A2
+1446907788,1446907791,IQ
+1446907792,1446907799,A2
+1446907800,1446907803,ZM
+1446907804,1446907807,IQ
+1446907808,1446907823,A2
+1446907824,1446907827,LY
+1446907828,1446907831,A2
+1446907832,1446907839,LY
+1446907840,1446907855,A2
+1446907856,1446907859,AF
+1446907860,1446907863,A2
+1446907864,1446907871,LY
+1446907872,1446907875,A2
+1446907876,1446907883,IQ
+1446907884,1446907887,A2
+1446907888,1446907891,SD
+1446907892,1446907895,AF
+1446907896,1446907899,IQ
+1446907900,1446907903,LY
+1446907904,1446907911,IQ
+1446907912,1446907919,A2
+1446907920,1446907927,LY
+1446907928,1446908103,A2
+1446908104,1446908111,NG
+1446908112,1446908143,A2
+1446908144,1446908151,AE
+1446908152,1446908159,SD
+1446908160,1446908163,AF
+1446908164,1446908167,A2
+1446908168,1446908175,IQ
+1446908176,1446908187,A2
+1446908188,1446908191,GH
+1446908192,1446908235,A2
+1446908236,1446908243,IQ
+1446908244,1446908247,A2
+1446908248,1446908251,AF
+1446908252,1446908255,A2
+1446908256,1446908259,SZ
+1446908260,1446908267,A2
+1446908268,1446908271,AF
+1446908272,1446908275,LY
+1446908276,1446908279,A2
+1446908280,1446908283,IQ
+1446908284,1446908287,AF
+1446908288,1446908299,A2
+1446908300,1446908303,IQ
+1446908304,1446908307,AF
+1446908308,1446908311,A2
+1446908312,1446908315,LY
+1446908316,1446908323,A2
+1446908324,1446908327,ZM
+1446908328,1446908331,A2
+1446908332,1446908335,NG
+1446908336,1446908359,A2
+1446908360,1446908363,LY
+1446908364,1446908367,A2
+1446908368,1446908371,IQ
+1446908372,1446908383,A2
+1446908384,1446908391,IQ
+1446908392,1446908419,A2
+1446908420,1446908423,IQ
+1446908424,1446908427,A2
+1446908428,1446908431,IQ
+1446908432,1446908435,A2
+1446908436,1446908443,AF
+1446908444,1446908447,A2
+1446908448,1446908451,ZM
+1446908452,1446908455,A2
+1446908456,1446908459,LB
+1446908460,1446908479,A2
+1446908480,1446908483,IQ
+1446908484,1446908487,A2
+1446908488,1446908491,IQ
+1446908492,1446908515,A2
+1446908516,1446908519,IQ
+1446908520,1446908531,A2
+1446908532,1446908535,IQ
+1446908536,1446908539,A2
1446908540,1446908543,ZM
-1446908544,1446920191,A2
+1446908544,1446908591,A2
+1446908592,1446908595,IQ
+1446908596,1446908599,A2
+1446908600,1446908603,ZM
+1446908604,1446908607,CG
+1446908608,1446908631,A2
+1446908632,1446908635,IQ
+1446908636,1446908651,A2
+1446908652,1446908663,IQ
+1446908664,1446908683,A2
+1446908684,1446908687,SD
+1446908688,1446908691,IQ
+1446908692,1446908707,A2
+1446908708,1446908711,IQ
+1446908712,1446908715,A2
+1446908716,1446908719,CM
+1446908720,1446908727,A2
+1446908728,1446908731,AF
+1446908732,1446908735,A2
+1446908736,1446908739,IQ
+1446908740,1446908743,A2
+1446908744,1446908747,GN
+1446908748,1446908751,A2
+1446908752,1446908759,IQ
+1446908760,1446908775,A2
+1446908776,1446908779,IQ
+1446908780,1446908787,A2
+1446908788,1446908791,NG
+1446908792,1446908811,A2
+1446908812,1446908815,IQ
+1446908816,1446908835,A2
+1446908836,1446908843,IQ
+1446908844,1446908855,A2
+1446908856,1446908859,ZM
+1446908860,1446908863,A2
+1446908864,1446908871,AF
+1446908872,1446908875,A2
+1446908876,1446908879,AF
+1446908880,1446908907,A2
+1446908908,1446908911,IQ
+1446908912,1446908919,A2
+1446908920,1446908923,IQ
+1446908924,1446908927,A2
+1446908928,1446908931,IQ
+1446908932,1446908935,ZM
+1446908936,1446908951,A2
+1446908952,1446908955,IQ
+1446908956,1446908959,LY
+1446908960,1446908971,A2
+1446908972,1446908975,AF
+1446908976,1446908979,GA
+1446908980,1446908983,AF
+1446908984,1446908987,LY
+1446908988,1446908999,A2
+1446909000,1446909003,IQ
+1446909004,1446909007,LY
+1446909008,1446909019,IQ
+1446909020,1446909083,A2
+1446909084,1446909087,CG
+1446909088,1446909091,IQ
+1446909092,1446909095,A2
+1446909096,1446909099,TD
+1446909100,1446909111,A2
+1446909112,1446909115,IQ
+1446909116,1446909163,A2
+1446909164,1446909167,IQ
+1446909168,1446909171,A2
+1446909172,1446909173,IQ
+1446909174,1446909195,A2
+1446909196,1446909199,IQ
+1446909200,1446909203,A2
+1446909204,1446909207,IQ
+1446909208,1446909211,LY
+1446909212,1446909215,A2
+1446909216,1446909219,LY
+1446909220,1446909223,IQ
+1446909224,1446909271,A2
+1446909272,1446909275,IQ
+1446909276,1446909295,A2
+1446909296,1446909299,IQ
+1446909300,1446909303,A2
+1446909304,1446909319,IQ
+1446909320,1446909327,A2
+1446909328,1446909331,IQ
+1446909332,1446909335,A2
+1446909336,1446909339,GH
+1446909340,1446909351,A2
+1446909352,1446909359,IQ
+1446909360,1446909363,A2
+1446909364,1446909367,IQ
+1446909368,1446909391,A2
+1446909392,1446909395,ZM
+1446909396,1446909401,NG
+1446909402,1446909423,A2
+1446909424,1446909435,AF
+1446909436,1446909443,A2
+1446909444,1446909447,NG
+1446909448,1446909471,A2
+1446909472,1446909475,IQ
+1446909476,1446909491,A2
+1446909492,1446909495,IQ
+1446909496,1446909499,A2
+1446909500,1446909507,IQ
+1446909508,1446909519,A2
+1446909520,1446909523,CG
+1446909524,1446909539,A2
+1446909540,1446909543,IQ
+1446909544,1446909555,A2
+1446909556,1446909559,IQ
+1446909560,1446909563,A2
+1446909564,1446909567,NG
+1446909568,1446909575,A2
+1446909576,1446909579,AF
+1446909580,1446909599,A2
+1446909600,1446909603,AF
+1446909604,1446909615,A2
+1446909616,1446909623,IQ
+1446909624,1446909647,A2
+1446909648,1446909651,NG
+1446909652,1446909655,A2
+1446909656,1446909659,AF
+1446909660,1446909667,A2
+1446909668,1446909671,IQ
+1446909672,1446909683,A2
+1446909684,1446909687,IQ
+1446909688,1446909691,AF
+1446909692,1446909699,A2
+1446909700,1446909703,IQ
+1446909704,1446909731,A2
+1446909732,1446909735,IQ
+1446909736,1446909739,ZM
+1446909740,1446909743,AF
+1446909744,1446909755,A2
+1446909756,1446909763,ZM
+1446909764,1446909787,A2
+1446909788,1446909791,IQ
+1446909792,1446909803,A2
+1446909804,1446909807,AF
+1446909808,1446909815,A2
+1446909816,1446909819,AF
+1446909820,1446909827,IQ
+1446909828,1446909851,A2
+1446909852,1446909855,LY
+1446909856,1446909859,A2
+1446909860,1446909863,IQ
+1446909864,1446909867,A2
+1446909868,1446909871,LY
+1446909872,1446909879,A2
+1446909880,1446909883,LY
+1446909884,1446909887,A2
+1446909888,1446909891,LY
+1446909892,1446909907,A2
+1446909908,1446909911,IQ
+1446909912,1446909955,A2
+1446909956,1446909959,IQ
+1446909960,1446909967,A2
+1446909968,1446909971,LY
+1446909972,1446909975,A2
+1446909976,1446909991,LY
+1446909992,1446909999,IQ
+1446910000,1446910003,AF
+1446910004,1446910011,A2
+1446910012,1446910015,IQ
+1446910016,1446910019,A2
+1446910020,1446910027,IQ
+1446910028,1446910031,A2
+1446910032,1446910035,LY
+1446910036,1446910039,A2
+1446910040,1446910043,IQ
+1446910044,1446910055,A2
+1446910056,1446910059,ZM
+1446910060,1446910063,IQ
+1446910064,1446910071,A2
+1446910072,1446910075,IQ
+1446910076,1446910083,A2
+1446910084,1446910095,IQ
+1446910096,1446910103,A2
+1446910104,1446910107,IQ
+1446910108,1446910111,A2
+1446910112,1446910115,IQ
+1446910116,1446910119,A2
+1446910120,1446910123,IQ
+1446910124,1446910159,A2
+1446910160,1446910163,ZM
+1446910164,1446910167,NG
+1446910168,1446910175,A2
+1446910176,1446910179,ZM
+1446910180,1446910191,IQ
+1446910192,1446910195,A2
+1446910196,1446910199,AF
+1446910200,1446910203,A2
+1446910204,1446910207,ZM
+1446910208,1446910211,A2
+1446910212,1446910220,IQ
+1446910221,1446910223,A2
+1446910224,1446910227,IQ
+1446910228,1446910231,A2
+1446910232,1446910239,IQ
+1446910240,1446910247,A2
+1446910248,1446910251,LY
+1446910252,1446910255,IQ
+1446910256,1446910263,A2
+1446910264,1446910267,IQ
+1446910268,1446910271,AF
+1446910272,1446910275,A2
+1446910276,1446910279,IQ
+1446910280,1446910283,A2
+1446910284,1446910291,IQ
+1446910292,1446910295,A2
+1446910296,1446910307,IQ
+1446910308,1446910311,AF
+1446910312,1446910323,A2
+1446910324,1446910327,IQ
+1446910328,1446910331,A2
+1446910332,1446910335,IQ
+1446910336,1446910339,AF
+1446910340,1446910343,IQ
+1446910344,1446910347,LY
+1446910348,1446910351,GA
+1446910352,1446910355,A2
+1446910356,1446910359,IQ
+1446910360,1446910363,AF
+1446910364,1446910371,A2
+1446910372,1446910379,AF
+1446910380,1446910427,A2
+1446910428,1446910431,IQ
+1446910432,1446910439,A2
+1446910440,1446910443,IQ
+1446910444,1446910455,A2
+1446910456,1446910459,IQ
+1446910460,1446910463,A2
+1446910464,1446910479,LY
+1446910480,1446910495,A2
+1446910496,1446910503,NG
+1446910504,1446910527,A2
+1446910528,1446910535,AF
+1446910536,1446910599,A2
+1446910600,1446910615,NG
+1446910616,1446910623,A2
+1446910624,1446910631,AF
+1446910632,1446910695,A2
+1446910696,1446910711,SD
+1446910712,1446910719,AE
+1446910720,1446910723,A2
+1446910724,1446910727,IQ
+1446910728,1446910731,AF
+1446910732,1446910739,A2
+1446910740,1446910747,AF
+1446910748,1446910751,A2
+1446910752,1446910755,LY
+1446910756,1446910767,IQ
+1446910768,1446910771,A2
+1446910772,1446910775,AF
+1446910776,1446910779,IQ
+1446910780,1446910787,A2
+1446910788,1446910791,IQ
+1446910792,1446910799,A2
+1446910800,1446910807,IQ
+1446910808,1446910815,A2
+1446910816,1446910819,IQ
+1446910820,1446910823,AF
+1446910824,1446910835,A2
+1446910836,1446910839,AF
+1446910840,1446910843,A2
+1446910844,1446910847,NG
+1446910848,1446910855,IQ
+1446910856,1446910883,A2
+1446910884,1446910887,IQ
+1446910888,1446910899,A2
+1446910900,1446910903,IQ
+1446910904,1446910907,A2
+1446910908,1446910911,IQ
+1446910912,1446910927,A2
+1446910928,1446910931,NG
+1446910932,1446910935,A2
+1446910936,1446910943,IQ
+1446910944,1446910947,A2
+1446910948,1446910955,IQ
+1446910956,1446910963,A2
+1446910964,1446910967,AF
+1446910968,1446910971,IQ
+1446910972,1446910975,AF
+1446910976,1446910979,IQ
+1446910980,1446910991,AF
+1446910992,1446910999,IQ
+1446911000,1446911003,A2
+1446911004,1446911007,IQ
+1446911008,1446911011,LY
+1446911012,1446911015,A2
+1446911016,1446911023,IQ
+1446911024,1446911027,LY
+1446911028,1446911035,AF
+1446911036,1446911039,LY
+1446911040,1446911043,A2
+1446911044,1446911047,IQ
+1446911048,1446911051,LY
+1446911052,1446911055,AF
+1446911056,1446911059,A2
+1446911060,1446911067,IQ
+1446911068,1446911075,A2
+1446911076,1446911079,IQ
+1446911080,1446911087,LY
+1446911088,1446911091,A2
+1446911092,1446911095,IQ
+1446911096,1446911099,NG
+1446911100,1446911103,IQ
+1446911104,1446911111,SD
+1446911112,1446911115,A2
+1446911116,1446911135,SD
+1446911136,1446911143,A2
+1446911144,1446911147,TD
+1446911148,1446911163,A2
+1446911164,1446911171,IQ
+1446911172,1446911175,A2
+1446911176,1446911179,IQ
+1446911180,1446911191,A2
+1446911192,1446911203,IQ
+1446911204,1446911207,A2
+1446911208,1446911219,IQ
+1446911220,1446911223,A2
+1446911224,1446911227,AF
+1446911228,1446911231,LY
+1446911232,1446911239,IQ
+1446911240,1446911243,A2
+1446911244,1446911247,LY
+1446911248,1446911251,A2
+1446911252,1446911255,IQ
+1446911256,1446911259,A2
+1446911260,1446911263,AF
+1446911264,1446911267,IQ
+1446911268,1446911271,AF
+1446911272,1446911283,A2
+1446911284,1446911287,IQ
+1446911288,1446911291,LY
+1446911292,1446911295,IQ
+1446911296,1446911299,GH
+1446911300,1446911303,IQ
+1446911304,1446911311,A2
+1446911312,1446911315,LY
+1446911316,1446911319,IQ
+1446911320,1446911323,A2
+1446911324,1446911327,IQ
+1446911328,1446911331,NG
+1446911332,1446911335,ZM
+1446911336,1446911339,IQ
+1446911340,1446911343,AF
+1446911344,1446911347,A2
+1446911348,1446911351,LY
+1446911352,1446911355,IQ
+1446911356,1446911359,A2
+1446911360,1446911363,IQ
+1446911364,1446911367,A2
+1446911368,1446911371,LY
+1446911372,1446911375,A2
+1446911376,1446911379,LY
+1446911380,1446911387,A2
+1446911388,1446911395,LY
+1446911396,1446911399,A2
+1446911400,1446911403,LY
+1446911404,1446911407,AF
+1446911408,1446911415,A2
+1446911416,1446911423,IQ
+1446911424,1446911427,AF
+1446911428,1446911435,A2
+1446911436,1446911439,SD
+1446911440,1446911447,A2
+1446911448,1446911459,IQ
+1446911460,1446911463,A2
+1446911464,1446911467,IQ
+1446911468,1446911475,A2
+1446911476,1446911479,ER
+1446911480,1446911483,CG
+1446911484,1446911503,A2
+1446911504,1446911507,IQ
+1446911508,1446911515,A2
+1446911516,1446911523,IQ
+1446911524,1446911527,A2
+1446911528,1446911531,IQ
+1446911532,1446911539,A2
+1446911540,1446911543,IQ
+1446911544,1446911547,AF
+1446911548,1446911551,LY
+1446911552,1446911559,AF
+1446911560,1446911567,A2
+1446911568,1446911571,IQ
+1446911572,1446911575,LY
+1446911576,1446911579,IQ
+1446911580,1446911587,A2
+1446911588,1446911591,IQ
+1446911592,1446911595,A2
+1446911596,1446911597,LY
+1446911598,1446911615,A2
+1446911616,1446911619,LY
+1446911620,1446911623,GH
+1446911624,1446911627,IQ
+1446911628,1446911631,AF
+1446911632,1446911635,A2
+1446911636,1446911639,IQ
+1446911640,1446911647,A2
+1446911648,1446911651,ZM
+1446911652,1446911655,A2
+1446911656,1446911659,IQ
+1446911660,1446911671,A2
+1446911672,1446911675,LY
+1446911676,1446911679,IQ
+1446911680,1446911683,SD
+1446911684,1446911687,A2
+1446911688,1446911691,LY
+1446911692,1446911695,AF
+1446911696,1446911699,A2
+1446911700,1446911707,LY
+1446911708,1446911711,IQ
+1446911712,1446911715,LY
+1446911716,1446911719,IQ
+1446911720,1446911723,LY
+1446911724,1446911727,IQ
+1446911728,1446911739,LY
+1446911740,1446911747,A2
+1446911748,1446911751,IQ
+1446911752,1446911759,LY
+1446911760,1446911763,IQ
+1446911764,1446911767,A2
+1446911768,1446911771,AF
+1446911772,1446911779,IQ
+1446911780,1446911783,AF
+1446911784,1446911787,LY
+1446911788,1446911791,AF
+1446911792,1446911795,LY
+1446911796,1446911803,A2
+1446911804,1446911811,LY
+1446911812,1446911815,IQ
+1446911816,1446911819,LY
+1446911820,1446911827,IQ
+1446911828,1446911835,A2
+1446911836,1446911843,IQ
+1446911844,1446911847,A2
+1446911848,1446911851,IQ
+1446911852,1446911855,A2
+1446911856,1446911859,AF
+1446911860,1446911863,A2
+1446911864,1446911867,IQ
+1446911868,1446911871,LY
+1446911872,1446911879,A2
+1446911880,1446911883,IQ
+1446911884,1446911887,NG
+1446911888,1446911891,IQ
+1446911892,1446911895,A2
+1446911896,1446911899,IQ
+1446911900,1446911903,A2
+1446911904,1446911907,AF
+1446911908,1446911911,IQ
+1446911912,1446911923,A2
+1446911924,1446911927,IQ
+1446911928,1446911935,A2
+1446911936,1446911939,IQ
+1446911940,1446911943,A2
+1446911944,1446911955,IQ
+1446911956,1446911959,A2
+1446911960,1446911967,IQ
+1446911968,1446911975,A2
+1446911976,1446911987,IQ
+1446911988,1446911991,AF
+1446911992,1446911995,A2
+1446911996,1446911999,IQ
+1446912000,1446912003,BJ
+1446912004,1446912007,AF
+1446912008,1446912011,IQ
+1446912012,1446912015,A2
+1446912016,1446912019,BJ
+1446912020,1446912023,ZM
+1446912024,1446912027,A2
+1446912028,1446912031,AF
+1446912032,1446912035,IQ
+1446912036,1446912039,AF
+1446912040,1446912047,A2
+1446912048,1446912051,IQ
+1446912052,1446912055,ER
+1446912056,1446912059,A2
+1446912060,1446912063,NG
+1446912064,1446912067,AF
+1446912068,1446912071,IQ
+1446912072,1446912075,AE
+1446912076,1446912079,A2
+1446912080,1446912083,IQ
+1446912084,1446912087,A2
+1446912088,1446912091,IQ
+1446912092,1446912095,LY
+1446912096,1446912099,AF
+1446912100,1446912107,IQ
+1446912108,1446912111,A2
+1446912112,1446912115,IQ
+1446912116,1446912119,LY
+1446912120,1446912123,A2
+1446912124,1446912127,LY
+1446912128,1446912139,A2
+1446912140,1446912143,IQ
+1446912144,1446912147,AF
+1446912148,1446912151,IQ
+1446912152,1446912163,A2
+1446912164,1446912167,IQ
+1446912168,1446912179,A2
+1446912180,1446912183,ZM
+1446912184,1446912187,AF
+1446912188,1446912195,IQ
+1446912196,1446912211,A2
+1446912212,1446912219,IQ
+1446912220,1446912223,LY
+1446912224,1446912235,IQ
+1446912236,1446912243,A2
+1446912244,1446912247,IQ
+1446912248,1446912251,AF
+1446912252,1446912255,A2
+1446912256,1446912263,AF
+1446912264,1446912295,IQ
+1446912296,1446912303,AF
+1446912304,1446912319,A2
+1446912320,1446912335,IQ
+1446912336,1446912343,KW
+1446912344,1446912367,IQ
+1446912368,1446912375,A2
+1446912376,1446912391,AF
+1446912392,1446912399,GA
+1446912400,1446920191,A2
1446920192,1446936575,RU
1446936576,1446952959,NO
1446952960,1446969343,QA
@@ -37706,9 +39910,7 @@
1449459712,1449525247,HU
1449525248,1449590783,RU
1449590784,1449656319,DE
-1449656320,1449717759,RO
-1449717760,1449718783,MD
-1449718784,1449808639,RO
+1449656320,1449808639,RO
1449808640,1449808895,UA
1449808896,1449840639,RO
1449840640,1449852927,MD
@@ -37727,17 +39929,9 @@
1450057728,1450065919,EE
1450065920,1450074111,DE
1450074112,1450082303,RU
-1450082304,1450083327,IT
-1450083328,1450083583,A2
-1450083584,1450083839,IT
-1450083840,1450084351,A2
-1450084352,1450085375,IT
-1450085376,1450085383,A2
-1450085384,1450085549,IT
-1450085550,1450085551,A2
-1450085552,1450085679,IT
-1450085680,1450085751,A2
-1450085752,1450090495,IT
+1450082304,1450084351,IT
+1450084352,1450085119,A2
+1450085120,1450090495,IT
1450090496,1450106879,RU
1450106880,1450115071,SK
1450115072,1450123263,RU
@@ -37801,7 +39995,9 @@
1466265600,1466269695,HU
1466269696,1466302463,SA
1466302464,1466335231,GB
-1466335232,1466367999,CH
+1466335232,1466367631,CH
+1466367632,1466367639,AT
+1466367640,1466367999,CH
1466368000,1466400767,PT
1466400768,1466433535,RU
1466433536,1466499071,DK
@@ -37812,7 +40008,9 @@
1466592256,1466592511,FR
1466592512,1466592767,GB
1466592768,1466593279,FR
-1466593280,1466606847,DE
+1466593280,1466604799,DE
+1466604800,1466605055,ES
+1466605056,1466606847,DE
1466606848,1466607103,FR
1466607104,1466613759,DE
1466613760,1466615807,ES
@@ -37839,9 +40037,7 @@
1467318272,1467334655,RU
1467334656,1467340959,GB
1467340960,1467340991,TR
-1467340992,1467344127,GB
-1467344128,1467344383,CA
-1467344384,1467344639,GB
+1467340992,1467344639,GB
1467344640,1467344895,ZA
1467344896,1467347903,GB
1467347904,1467347935,SE
@@ -37857,7 +40053,9 @@
1467367904,1467367935,DE
1467367936,1467368191,SI
1467368192,1467368319,DK
-1467368320,1467369519,DE
+1467368320,1467368447,DE
+1467368448,1467368703,DK
+1467368704,1467369519,DE
1467369520,1467369535,RU
1467369536,1467369599,DE
1467369600,1467369663,IT
@@ -38000,11 +40198,14 @@
1475175056,1475176447,NL
1475176448,1475178495,RO
1475178496,1475180543,RU
-1475180544,1475181455,DE
+1475180544,1475181343,DE
+1475181344,1475181375,LU
+1475181376,1475181455,DE
1475181456,1475181471,SC
1475181472,1475181519,DE
1475181520,1475181535,GB
-1475181536,1475184639,DE
+1475181536,1475181551,ES
+1475181552,1475184639,DE
1475184640,1475186687,RU
1475186688,1475188735,ES
1475188736,1475190783,SE
@@ -38053,10 +40254,8 @@
1475223552,1475229695,NO
1475229696,1475229759,SE
1475229760,1475229951,NO
-1475229952,1475230003,SE
-1475230004,1475230015,NO
-1475230016,1475230047,SE
-1475230048,1475233791,NO
+1475229952,1475230071,SE
+1475230072,1475233791,NO
1475233792,1475234303,GB
1475234304,1475234559,IE
1475234560,1475235839,GB
@@ -38179,9 +40378,7 @@
1475636400,1475636415,JE
1475636416,1475636431,GB
1475636432,1475636447,JE
-1475636448,1475637287,GB
-1475637288,1475637295,JE
-1475637296,1475637479,GB
+1475636448,1475637479,GB
1475637480,1475637487,JE
1475637488,1475637503,GB
1475637504,1475638783,JE
@@ -38196,8 +40393,8 @@
1475639272,1475639295,JE
1475639296,1475639343,GB
1475639344,1475639351,JE
-1475639352,1475639367,GB
-1475639368,1475639383,JE
+1475639352,1475639375,GB
+1475639376,1475639383,JE
1475639384,1475639527,GB
1475639528,1475639543,JE
1475639544,1475639595,GB
@@ -38217,11 +40414,14 @@
1475706880,1475723263,RU
1475723264,1475725311,CY
1475725312,1475725951,RU
-1475725952,1475727103,GB
+1475725952,1475726591,GB
+1475726592,1475726719,RU
+1475726720,1475727103,GB
1475727104,1475727167,RU
1475727168,1475727343,GB
1475727344,1475727359,RU
-1475727360,1475729407,GB
+1475727360,1475727391,FI
+1475727392,1475729407,GB
1475729408,1475731455,UA
1475731456,1475739647,GB
1475739648,1475756031,BG
@@ -38279,8 +40479,8 @@
1476075520,1476077911,NL
1476077912,1476077919,DE
1476077920,1476079551,NL
-1476079552,1476079567,DE
-1476079568,1476083711,NL
+1476079552,1476079571,DE
+1476079572,1476083711,NL
1476083712,1476116479,RU
1476116480,1476124671,SE
1476124672,1476132863,PL
@@ -38289,7 +40489,26 @@
1476135168,1476141055,FR
1476141056,1476149247,GB
1476149248,1476157439,NO
-1476157440,1476165375,BH
+1476157440,1476157535,BH
+1476157536,1476157631,BR
+1476157632,1476157695,BH
+1476157696,1476157823,BR
+1476157824,1476157855,BH
+1476157856,1476157887,BR
+1476157888,1476157951,BH
+1476157952,1476157983,BR
+1476157984,1476158079,BH
+1476158080,1476158399,BR
+1476158400,1476158463,BH
+1476158464,1476158975,BR
+1476158976,1476159231,BH
+1476159232,1476159487,JO
+1476159488,1476159695,GB
+1476159696,1476159727,BH
+1476159728,1476159951,GB
+1476159952,1476159983,BH
+1476159984,1476165119,GB
+1476165120,1476165375,BH
1476165376,1476165631,JO
1476165632,1476173823,HR
1476173824,1476182015,BG
@@ -38332,9 +40551,7 @@
1481679776,1481680639,SE
1481680640,1481680643,GB
1481680644,1481687039,SE
-1481687040,1481691071,DE
-1481691072,1481691135,ES
-1481691136,1481695231,DE
+1481687040,1481695231,DE
1481695232,1481703423,SK
1481703424,1481711615,SA
1481711616,1481719807,RU
@@ -38402,9 +40619,7 @@
1482060920,1482060927,SK
1482060928,1482063871,CZ
1482063872,1482072063,FI
-1482072064,1482076159,IT
-1482076160,1482076223,CH
-1482076224,1482076383,IT
+1482072064,1482076383,IT
1482076384,1482076415,MT
1482076416,1482080255,IT
1482080256,1482088447,RU
@@ -38476,9 +40691,7 @@
1486295040,1486297087,ES
1486297088,1486299135,IE
1486299136,1486301183,NL
-1486301184,1486301951,DK
-1486301952,1486302719,SE
-1486302720,1486302863,DK
+1486301184,1486302863,DK
1486302864,1486302879,SE
1486302880,1486303231,DK
1486303232,1486305023,IS
@@ -38497,7 +40710,7 @@
1486321856,1486321887,NL
1486321888,1486321919,US
1486321920,1486323199,EU
-1486323200,1486323215,GU
+1486323200,1486323215,US
1486323216,1486323231,NL
1486323232,1486323239,GB
1486323240,1486323447,EU
@@ -38559,8 +40772,8 @@
1489646848,1489647103,IT
1489647104,1489647359,A2
1489647360,1489648639,IT
-1489648640,1489649407,A2
-1489649408,1489650687,FR
+1489648640,1489649663,A2
+1489649664,1489650687,FR
1489650688,1489651199,A2
1489651200,1489653759,IT
1489653760,1489657855,A2
@@ -38587,7 +40800,8 @@
1490028544,1490029055,UA
1490029056,1490040839,NL
1490040840,1490041855,UA
-1490041856,1490049879,CZ
+1490041856,1490042879,NL
+1490042880,1490049879,CZ
1490049880,1490049887,AT
1490049888,1490049919,CZ
1490049920,1490049983,PL
@@ -38618,13 +40832,9 @@
1490196960,1490197247,IE
1490197248,1490206719,GB
1490206720,1490223103,GE
-1490223104,1490226047,GB
-1490226048,1490226175,FR
-1490226176,1490230719,GB
+1490223104,1490230719,GB
1490230720,1490230751,FR
-1490230752,1490235263,GB
-1490235264,1490235391,FR
-1490235392,1490255871,GB
+1490230752,1490255871,GB
1490255872,1490272255,NL
1490272256,1490288639,GB
1490288640,1490305023,SK
@@ -38769,7 +40979,9 @@
1495070720,1495072767,RU
1495072768,1495105535,CZ
1495105536,1495138303,ES
-1495138304,1495139327,FR
+1495138304,1495139095,FR
+1495139096,1495139103,IT
+1495139104,1495139327,FR
1495139328,1495139583,EU
1495139584,1495139591,GB
1495139592,1495139711,EU
@@ -38870,7 +41082,9 @@
1495326720,1495330815,MD
1495330816,1495334911,RO
1495334912,1495335935,MD
-1495335936,1495399935,RO
+1495335936,1495339007,RO
+1495339008,1495343103,MD
+1495343104,1495399935,RO
1495399936,1495400191,MD
1495400192,1495623679,RO
1495623680,1495623935,MD
@@ -38918,9 +41132,13 @@
1500106528,1500106559,DE
1500106560,1500107415,NL
1500107416,1500107423,DE
-1500107424,1500107775,NL
+1500107424,1500107439,NL
+1500107440,1500107455,DE
+1500107456,1500107775,NL
1500107776,1500107903,DE
-1500107904,1500110847,NL
+1500107904,1500107943,NL
+1500107944,1500107951,DE
+1500107952,1500110847,NL
1500110848,1500119039,UA
1500119040,1500127231,TR
1500127232,1500135423,FI
@@ -39001,9 +41219,13 @@
1500231680,1500233727,DE
1500233728,1500237823,RU
1500237824,1500241919,SE
-1500241920,1500242483,TR
+1500241920,1500241960,TR
+1500241961,1500241966,US
+1500241967,1500242483,TR
1500242484,1500242485,US
-1500242486,1500242801,TR
+1500242486,1500242784,TR
+1500242785,1500242793,GB
+1500242794,1500242801,TR
1500242802,1500242814,US
1500242815,1500243008,TR
1500243009,1500243038,GB
@@ -39090,8 +41312,8 @@
1502975744,1502975775,IE
1502975776,1502975999,FR
1502976000,1502977055,US
-1502977056,1502977279,FR
-1502977280,1502979071,US
+1502977056,1502977151,FR
+1502977152,1502979071,US
1502979072,1502979103,FR
1502979104,1502979111,ES
1502979112,1502979119,FR
@@ -39151,13 +41373,13 @@
1503789056,1503821823,NO
1503821824,1503854591,UA
1503854592,1503887359,RU
-1503887360,1503895607,DE
-1503895608,1503895615,NL
-1503895616,1503895631,DE
+1503887360,1503895631,DE
1503895632,1503895639,AT
-1503895640,1503895671,DE
+1503895640,1503895647,GR
+1503895648,1503895671,DE
1503895672,1503895679,PL
-1503895680,1503895767,DE
+1503895680,1503895687,IT
+1503895688,1503895767,DE
1503895768,1503895783,IT
1503895784,1503895799,DE
1503895800,1503895807,CA
@@ -39168,14 +41390,11 @@
1503896360,1503896367,CH
1503896368,1503896375,DE
1503896376,1503896383,CH
-1503896384,1503896415,DE
-1503896416,1503896423,GR
-1503896424,1503896439,DE
+1503896384,1503896439,DE
1503896440,1503896447,NO
1503896448,1503896543,DE
1503896544,1503896551,FR
-1503896552,1503896559,AT
-1503896560,1503897303,DE
+1503896552,1503897303,DE
1503897304,1503897311,BE
1503897312,1503897367,DE
1503897368,1503897375,BE
@@ -39211,7 +41430,9 @@
1503898360,1503898415,DE
1503898416,1503898423,BE
1503898424,1503898431,CH
-1503898432,1503908351,DE
+1503898432,1503898567,DE
+1503898568,1503898575,NL
+1503898576,1503908351,DE
1503908352,1503909375,IT
1503909376,1503920127,DE
1503920128,1503985663,HR
@@ -39269,29 +41490,23 @@
1505273088,1505273095,NZ
1505273096,1505279999,NL
1505280000,1505280007,IR
-1505280008,1505280255,AE
-1505280256,1505280271,IR
-1505280272,1505284095,AE
+1505280008,1505284095,AE
1505284096,1505284607,IR
1505284608,1505284863,AE
1505284864,1505288191,IR
1505288192,1505296383,RU
1505296384,1505304575,UA
-1505304576,1505305198,FR
-1505305199,1505305199,DK
-1505305200,1505305200,BE
-1505305201,1505305201,NL
-1505305202,1505305202,GB
-1505305203,1505305203,CA
-1505305204,1505305204,FR
-1505305205,1505305205,CH
-1505305206,1505305206,DE
-1505305207,1505305207,AT
-1505305208,1505305208,IT
-1505305209,1505305209,ES
-1505305210,1505305210,SE
-1505305211,1505305211,NO
-1505305212,1505305878,FR
+1505304576,1505305351,FR
+1505305352,1505305359,GB
+1505305360,1505305367,BE
+1505305368,1505305375,ES
+1505305376,1505305383,NL
+1505305384,1505305391,DE
+1505305392,1505305399,IT
+1505305400,1505305407,PT
+1505305408,1505305415,US
+1505305416,1505305423,CH
+1505305424,1505305878,FR
1505305879,1505305879,US
1505305880,1505305880,ES
1505305881,1505305899,FR
@@ -39318,7 +41533,11 @@
1505321984,1505322287,AT
1505322288,1505322415,DE
1505322416,1505322879,AT
-1505322880,1505325055,DE
+1505322880,1505324335,DE
+1505324336,1505324351,AT
+1505324352,1505324791,DE
+1505324792,1505324799,AT
+1505324800,1505325055,DE
1505325056,1505329151,AT
1505329152,1505329215,GB
1505329216,1505329375,IE
@@ -39327,7 +41546,9 @@
1505332992,1505332999,GB
1505333000,1505333623,IE
1505333624,1505333631,GB
-1505333632,1505336063,IE
+1505333632,1505333887,IE
+1505333888,1505333951,GB
+1505333952,1505336063,IE
1505336064,1505336071,GB
1505336072,1505336576,IE
1505336577,1505336639,GB
@@ -39382,7 +41603,10 @@
1505456640,1505456895,US
1505456896,1505456927,GB
1505456928,1505456935,US
-1505456936,1505458175,GB
+1505456936,1505456983,GB
+1505456984,1505456987,IL
+1505456988,1505456991,US
+1505456992,1505458175,GB
1505458176,1505458431,US
1505458432,1505458463,GB
1505458464,1505458495,US
@@ -39444,7 +41668,14 @@
1506342912,1506344959,UA
1506344960,1506377727,LV
1506377728,1506410495,HR
-1506410496,1506427663,DE
+1506410496,1506418687,DE
+1506418688,1506418695,CY
+1506418696,1506418703,DE
+1506418704,1506418719,CA
+1506418720,1506422655,DE
+1506422656,1506422687,CY
+1506422688,1506422703,CA
+1506422704,1506427663,DE
1506427664,1506427679,GB
1506427680,1506428223,DE
1506428224,1506428239,US
@@ -39548,26 +41779,22 @@
1506444288,1506445311,DE
1506445312,1506445337,FR
1506445338,1506445343,GB
-1506445344,1506445375,FR
-1506445376,1506445407,GB
-1506445408,1506445519,FR
+1506445344,1506445519,FR
1506445520,1506445527,GB
1506445528,1506445703,FR
1506445704,1506445711,NL
1506445712,1506445719,GB
1506445720,1506445759,FR
1506445760,1506445767,GB
-1506445768,1506445775,FR
-1506445776,1506445791,GB
-1506445792,1506445807,FR
-1506445808,1506445823,GB
-1506445824,1506446159,FR
-1506446160,1506446175,GB
-1506446176,1506446335,FR
+1506445768,1506445815,FR
+1506445816,1506445823,GB
+1506445824,1506446335,FR
1506446336,1506447359,NL
1506447360,1506447423,IT
1506447424,1506447455,GB
-1506447456,1506448383,IT
+1506447456,1506448255,IT
+1506448256,1506448287,GB
+1506448288,1506448383,IT
1506448384,1506448639,AT
1506448640,1506448647,GB
1506448648,1506448663,AT
@@ -39606,7 +41833,8 @@
1506453424,1506453439,SE
1506453440,1506453447,GB
1506453448,1506453471,SE
-1506453472,1506453503,GB
+1506453472,1506453487,GB
+1506453488,1506453503,SE
1506453504,1506453759,DE
1506453760,1506454015,FR
1506454016,1506454271,AT
@@ -39654,9 +41882,7 @@
1506462624,1506462719,FR
1506462720,1506463231,IT
1506463232,1506463487,SE
-1506463488,1506463527,DE
-1506463528,1506463535,GB
-1506463536,1506463999,DE
+1506463488,1506463999,DE
1506464000,1506464767,GB
1506464768,1506465279,NL
1506465280,1506465791,GB
@@ -39683,13 +41909,15 @@
1506472448,1506472703,GB
1506472704,1506473215,IT
1506473216,1506473471,GB
-1506473472,1506474271,IT
+1506473472,1506473783,IT
+1506473784,1506473791,GB
+1506473792,1506474271,IT
1506474272,1506474303,SE
1506474304,1506474495,IT
1506474496,1506474751,FR
1506474752,1506474887,IT
-1506474888,1506475007,GB
-1506475008,1506475519,IT
+1506474888,1506474911,GB
+1506474912,1506475519,IT
1506475520,1506475527,AT
1506475528,1506476031,GB
1506476032,1506508799,KW
@@ -39730,6 +41958,7 @@
1506781888,1506781951,AU
1506781952,1506783231,GB
1506783232,1506785279,RU
+1506785280,1506787327,BE
1506787328,1506789375,ME
1506789376,1506791423,DE
1506791424,1506793471,GB
@@ -39829,12 +42058,12 @@
1508642816,1508646911,SE
1508646912,1508646927,DK
1508646928,1508646935,SE
-1508646936,1508647031,DK
-1508647032,1508648447,SE
+1508646936,1508647039,DK
+1508647040,1508648447,SE
1508648448,1508648703,DK
1508648704,1508650751,SE
-1508650752,1508650815,DK
-1508650816,1508650879,SE
+1508650752,1508650823,DK
+1508650824,1508650879,SE
1508650880,1508651263,DK
1508651264,1508652543,SE
1508652544,1508654079,DK
@@ -39980,8 +42209,10 @@
1515468288,1515468415,NL
1515468416,1515486975,FR
1515486976,1515487231,CD
-1515487232,1515487359,HK
-1515487360,1515487999,FR
+1515487232,1515487495,HK
+1515487496,1515487739,FR
+1515487740,1515487775,HK
+1515487776,1515487999,FR
1515488000,1515488255,HK
1515488256,1515519743,FR
1515519744,1515519999,ES
@@ -39992,8 +42223,8 @@
1518452736,1518460927,AT
1518460928,1518501887,SE
1518501888,1518503935,EE
-1518503936,1518508543,LT
-1518508544,1518510079,SE
+1518503936,1518508799,LT
+1518508800,1518510079,SE
1518510080,1518516479,LV
1518516480,1518665727,SE
1518665728,1518727167,RU
@@ -40007,8 +42238,8 @@
1518962688,1518964735,NO
1518964736,1518966783,HR
1518966784,1518967807,SE
-1518967808,1518969855,HR
-1518969856,1518993407,SE
+1518967808,1518970367,HR
+1518970368,1518993407,SE
1518993408,1519190015,RU
1519190016,1519321087,SE
1519321088,1519386623,RU
@@ -40163,19 +42394,21 @@
1519976448,1520009215,DE
1520009216,1520041983,SY
1520041984,1520074751,RU
-1520074752,1520099327,BG
-1520099328,1520099583,A2
-1520099584,1520107519,BG
+1520074752,1520107519,BG
1520107520,1520138167,GB
1520138168,1520138175,IE
-1520138176,1520140287,GB
+1520138176,1520138611,GB
+1520138612,1520138615,IE
+1520138616,1520139399,GB
+1520139400,1520139407,IE
+1520139408,1520140287,GB
1520140288,1520173055,RU
1520173056,1520205823,PL
1520205824,1520230399,RU
1520230400,1520230911,NL
1520230912,1520231935,RU
-1520231936,1520232191,NL
-1520232192,1520232959,RU
+1520231936,1520232447,NL
+1520232448,1520232959,RU
1520232960,1520233471,NL
1520233472,1520271359,RU
1520271360,1520304127,SI
@@ -40319,7 +42552,10 @@
1534711808,1534712831,BE
1534712832,1534713855,FR
1534713856,1534713887,PL
-1534713888,1534713935,FR
+1534713888,1534713919,FR
+1534713920,1534713927,IT
+1534713928,1534713931,GB
+1534713932,1534713935,FI
1534713936,1534713943,CH
1534713944,1534713947,DE
1534713948,1534713951,PL
@@ -40357,8 +42593,9 @@
1534714352,1534714367,CH
1534714368,1534714383,GB
1534714384,1534714399,FR
-1534714400,1534714415,ES
-1534714416,1534714431,GB
+1534714400,1534714403,GB
+1534714404,1534714407,PL
+1534714408,1534714431,GB
1534714432,1534714463,FR
1534714464,1534714495,GB
1534714496,1534714511,FR
@@ -40381,8 +42618,8 @@
1534714848,1534714855,GB
1534714856,1534714863,CH
1534714864,1534714871,FR
-1534714872,1534714875,DE
-1534714876,1534714879,FR
+1534714872,1534714875,ES
+1534714876,1534714879,DE
1534714880,1534714895,PL
1534714896,1534714911,FR
1534714912,1534714927,DE
@@ -40392,19 +42629,20 @@
1534715040,1534715055,GB
1534715056,1534715071,PL
1534715072,1534715135,FR
-1534715136,1534715139,PL
-1534715140,1534715143,GB
-1534715144,1534715151,NL
-1534715152,1534715167,FR
+1534715136,1534715143,PL
+1534715144,1534715167,FR
1534715168,1534715183,NL
1534715184,1534715199,FR
-1534715200,1534715203,DE
+1534715200,1534715203,GB
1534715204,1534715207,FR
1534715208,1534715215,BE
1534715216,1534715263,FR
1534715264,1534715279,ES
1534715280,1534715295,FR
-1534715296,1534715311,ES
+1534715296,1534715299,ES
+1534715300,1534715303,FR
+1534715304,1534715307,ES
+1534715308,1534715311,DE
1534715312,1534715315,FR
1534715316,1534715319,ES
1534715320,1534715327,PL
@@ -40414,29 +42652,37 @@
1534715372,1534715375,GB
1534715376,1534715391,ES
1534715392,1534715407,PL
-1534715408,1534715423,ES
+1534715408,1534715423,DE
1534715424,1534715439,PL
1534715440,1534715447,ES
1534715448,1534715451,FR
1534715452,1534715487,PL
-1534715488,1534715503,ES
+1534715488,1534715495,IT
+1534715496,1534715503,CZ
1534715504,1534715519,CH
1534715520,1534715551,FR
1534715552,1534715583,ES
1534715584,1534715599,GB
1534715600,1534715615,BE
-1534715616,1534715631,FR
-1534715632,1534715647,ES
+1534715616,1534715639,FR
+1534715640,1534715647,DE
1534715648,1534715663,PL
-1534715664,1534715679,ES
+1534715664,1534715667,FR
+1534715668,1534715675,PL
+1534715676,1534715679,GB
1534715680,1534715711,FR
1534715712,1534715727,PT
1534715728,1534715731,FR
1534715732,1534715735,GB
1534715736,1534715759,PL
-1534715760,1534715807,ES
+1534715760,1534715775,ES
+1534715776,1534715783,PL
+1534715784,1534715791,BE
+1534715792,1534715807,ES
1534715808,1534715871,FR
-1534715872,1534715887,DE
+1534715872,1534715879,FI
+1534715880,1534715883,CH
+1534715884,1534715887,PL
1534715888,1534715919,FR
1534715920,1534715935,ES
1534715936,1534715999,FR
@@ -40490,7 +42736,8 @@
1534716992,1534717007,DE
1534717008,1534717023,FR
1534717024,1534717055,PL
-1534717056,1534717103,FR
+1534717056,1534717071,GB
+1534717072,1534717103,FR
1534717104,1534717119,PL
1534717120,1534717135,IT
1534717136,1534717139,CH
@@ -40498,8 +42745,8 @@
1534717144,1534717147,FR
1534717148,1534717151,IT
1534717152,1534717263,FR
-1534717264,1534717279,ES
-1534717280,1534717315,FR
+1534717264,1534717267,PL
+1534717268,1534717315,FR
1534717316,1534717319,IE
1534717320,1534717323,GB
1534717324,1534717343,FR
@@ -40531,7 +42778,10 @@
1534717908,1534717911,GB
1534717912,1534717915,FR
1534717916,1534717919,DE
-1534717920,1534717935,ES
+1534717920,1534717923,PL
+1534717924,1534717927,ES
+1534717928,1534717931,DE
+1534717932,1534717935,FR
1534717936,1534717951,IT
1534717952,1534717967,BE
1534717968,1534717983,IT
@@ -40573,8 +42823,7 @@
1534718832,1534718847,FR
1534718848,1534718911,BE
1534718912,1534718927,IT
-1534718928,1534718943,FR
-1534718944,1534718959,DE
+1534718928,1534718959,FR
1534718960,1534718975,ES
1534718976,1534719039,FR
1534719040,1534719167,BE
@@ -40593,7 +42842,7 @@
1534719424,1534719439,DE
1534719440,1534719455,PL
1534719456,1534719471,FR
-1534719472,1534719487,GB
+1534719472,1534719487,IE
1534719488,1534719631,FR
1534719632,1534719639,ES
1534719640,1534719643,GB
@@ -40617,7 +42866,8 @@
1534719952,1534719967,DE
1534719968,1534719983,PL
1534719984,1534720003,FR
-1534720004,1534720015,PL
+1534720004,1534720007,ES
+1534720008,1534720015,PL
1534720016,1534720031,GB
1534720032,1534720047,DE
1534720048,1534720063,ES
@@ -40625,14 +42875,15 @@
1534720080,1534720095,GB
1534720096,1534720111,FR
1534720112,1534720127,ES
-1534720128,1534720207,FR
-1534720208,1534720223,GB
+1534720128,1534720211,FR
+1534720212,1534720215,PL
+1534720216,1534720223,FR
1534720224,1534720239,DE
1534720240,1534720255,BE
1534720256,1534720287,PL
1534720288,1534720351,FR
1534720352,1534720367,ES
-1534720368,1534720383,IT
+1534720368,1534720383,PL
1534720384,1534720431,FR
1534720432,1534720435,DE
1534720436,1534720439,FR
@@ -40650,12 +42901,13 @@
1534720528,1534720535,FR
1534720536,1534720539,PL
1534720540,1534720543,FI
-1534720544,1534720575,FR
-1534720576,1534720591,ES
+1534720544,1534720559,FR
+1534720560,1534720583,IT
+1534720584,1534720591,BE
1534720592,1534720607,FR
1534720608,1534720623,GB
-1534720624,1534720655,FR
-1534720656,1534720671,PL
+1534720624,1534720639,FR
+1534720640,1534720671,PL
1534720672,1534720739,FR
1534720740,1534720743,PL
1534720744,1534720747,NL
@@ -40673,7 +42925,9 @@
1534720896,1534720899,ES
1534720900,1534720903,GB
1534720904,1534720959,FR
-1534720960,1534720975,ES
+1534720960,1534720967,IT
+1534720968,1534720971,DE
+1534720972,1534720975,FR
1534720976,1534720979,NL
1534720980,1534720983,FR
1534720984,1534720991,PL
@@ -40730,11 +42984,9 @@
1534721712,1534721727,ES
1534721728,1534721743,FR
1534721744,1534721747,PL
-1534721748,1534721751,IT
+1534721748,1534721751,GB
1534721752,1534721755,DE
-1534721756,1534721775,FR
-1534721776,1534721791,ES
-1534721792,1534721823,FR
+1534721756,1534721823,FR
1534721824,1534721827,PL
1534721828,1534721831,FR
1534721832,1534721835,PL
@@ -40749,19 +43001,19 @@
1534721956,1534721959,PL
1534721960,1534721963,IE
1534721964,1534721967,CH
-1534721968,1534721975,DE
+1534721968,1534721971,DE
+1534721972,1534721975,PL
1534721976,1534721979,ES
1534721980,1534721983,GB
1534721984,1534722007,PL
1534722008,1534722011,PT
-1534722012,1534722015,DE
-1534722016,1534722031,FR
-1534722032,1534722039,GB
+1534722012,1534722015,ES
+1534722016,1534722039,FR
1534722040,1534722043,BE
1534722044,1534722047,FR
1534722048,1534787583,RU
1534787584,1534791679,RO
-1534791680,1534795775,UA
+1534791680,1534795775,RU
1534795776,1534803967,NO
1534803968,1534808063,LV
1534808064,1534812159,RU
@@ -40769,7 +43021,7 @@
1534816256,1534820351,FR
1534820352,1534824447,FI
1534824448,1534828543,UA
-1534828544,1534832639,PL
+1534828544,1534836735,PL
1534836736,1534840831,SE
1534840832,1534844927,PL
1534844928,1534849023,IE
@@ -40929,7 +43181,9 @@
1536659760,1536659775,BI
1536659776,1536659791,DE
1536659792,1536659823,SD
-1536659824,1536659991,DE
+1536659824,1536659943,DE
+1536659944,1536659951,SD
+1536659952,1536659991,DE
1536659992,1536659999,EG
1536660000,1536660003,DE
1536660004,1536660007,SO
@@ -40946,9 +43200,7 @@
1536662320,1536662335,LB
1536662336,1536662351,DE
1536662352,1536662359,TD
-1536662360,1536662367,DE
-1536662368,1536662399,IQ
-1536662400,1536662415,DE
+1536662360,1536662415,DE
1536662416,1536662431,GN
1536662432,1536662463,IQ
1536662464,1536662783,DE
@@ -40957,8 +43209,8 @@
1536663296,1536663311,LB
1536663312,1536663319,DE
1536663320,1536663327,LB
-1536663328,1536663359,DE
-1536663360,1536663391,IQ
+1536663328,1536663343,DE
+1536663344,1536663391,IQ
1536663392,1536663423,DE
1536663424,1536663551,KW
1536663552,1536667647,SA
@@ -41046,10 +43298,7 @@
1539049312,1539049327,LY
1539049328,1539049335,IT
1539049336,1539049343,LY
-1539049344,1539050335,IT
-1539050336,1539050351,TR
-1539050352,1539050359,IT
-1539050360,1539050367,TR
+1539049344,1539050367,IT
1539050368,1539050375,FR
1539050376,1539050383,IT
1539050384,1539050399,FR
@@ -41110,13 +43359,13 @@
1539212544,1539213311,CZ
1539213312,1539215359,SE
1539215360,1539219455,DE
-1539221504,1539222287,FR
-1539222288,1539222303,HK
-1539222304,1539222527,FR
+1539219456,1539221503,GG
+1539221504,1539222527,FR
1539222528,1539222783,HK
1539222784,1539223551,FR
1539223552,1539225599,DE
1539225600,1539227647,HU
+1539227648,1539229695,FI
1539229696,1539231743,DE
1539231744,1539233791,BE
1539233792,1539235839,GR
@@ -41162,6 +43411,7 @@
1539336192,1539336703,UA
1539336704,1539337215,EE
1539337216,1539338239,ES
+1539338240,1539339263,SE
1539339264,1539340287,NL
1539340288,1539341311,PL
1539341312,1539342335,IT
@@ -41240,7 +43490,7 @@
1539421184,1539422207,GB
1539422208,1539423231,PL
1539423232,1539424255,IE
-1539424256,1539425279,UA
+1539424256,1539425279,LV
1539425280,1539426303,PL
1539426304,1539427327,BG
1539427328,1539428351,UA
@@ -41741,7 +43991,8 @@
1539744256,1539744511,RO
1539744512,1539744767,DE
1539744768,1539745023,SE
-1539745024,1539745535,GB
+1539745024,1539745279,GB
+1539745280,1539745535,GI
1539745536,1539745791,CH
1539745792,1539746303,DK
1539746304,1539746815,RU
@@ -41788,6 +44039,7 @@
1539757568,1539757823,SI
1539757824,1539758079,UA
1539758080,1539758335,HR
+1539758336,1539758591,EU
1539758592,1539758847,NL
1539758848,1539759103,BA
1539759104,1539759359,DK
@@ -42159,7 +44411,7 @@
1539947520,1539948543,UA
1539948544,1539949567,RO
1539949568,1539950591,MD
-1539950592,1539951615,KZ
+1539950592,1539951103,KZ
1539951616,1539953663,RU
1539953664,1539954687,UA
1539954688,1539956735,RO
@@ -42237,7 +44489,7 @@
1540047872,1540048895,LV
1540048896,1540049919,GB
1540049920,1540050943,UA
-1540050944,1540051967,RU
+1540050944,1540052991,RU
1540052992,1540054052,UA
1540054053,1540054062,MD
1540054063,1540055039,UA
@@ -42357,10 +44609,11 @@
1540199424,1540200447,CH
1540200448,1540201471,IL
1540201472,1540202495,UA
+1540202496,1540203519,RU
1540203520,1540204543,UA
1540204544,1540205567,RU
1540205568,1540206591,DE
-1540206592,1540207615,RU
+1540206592,1540208639,RU
1540208640,1540209663,NO
1540209664,1540211711,RU
1540211712,1540212735,DE
@@ -42508,6 +44761,7 @@
1540303872,1540304895,UA
1540304896,1540305407,PL
1540305408,1540305919,GB
+1540305920,1540306431,PL
1540306432,1540306943,UA
1540306944,1540307455,GB
1540307456,1540307967,RU
@@ -42974,6 +45228,7 @@
1540464384,1540464895,DE
1540464896,1540465407,GB
1540465408,1540465663,ES
+1540465664,1540465919,NL
1540465920,1540466175,UA
1540466176,1540466431,DK
1540466432,1540466687,RU
@@ -43448,7 +45703,6 @@
1540701952,1540702207,GB
1540702208,1540702463,PL
1540702464,1540702719,PT
-1540702720,1540702975,AT
1540702976,1540703231,RU
1540703232,1540703487,MH
1540703488,1540703743,NL
@@ -43500,8 +45754,7 @@
1540716800,1540717055,UA
1540717056,1540717311,CZ
1540717312,1540717823,PL
-1540717824,1540718079,UA
-1540718080,1540718335,CR
+1540717824,1540718335,UA
1540718336,1540718591,DE
1540718592,1540718847,CH
1540718848,1540719103,IT
@@ -43753,6 +46006,7 @@
1540891136,1540891391,NL
1540891392,1540891647,DE
1540891648,1540891903,CH
+1540891904,1540892159,GB
1540892160,1540892415,IT
1540892416,1540892671,UA
1540892672,1540892927,GB
@@ -43779,6 +46033,7 @@
1540898304,1540898559,SE
1540898560,1540898815,ES
1540898816,1540899071,PL
+1540899072,1540899327,SE
1540899328,1540899583,RU
1540899584,1540899839,FR
1540899840,1540900351,RU
@@ -43999,11 +46254,15 @@
1540974080,1540974591,RU
1540974592,1540975103,PL
1540975104,1540975615,UA
-1540976128,1540976639,RU
+1540975616,1540976639,RU
1540976640,1540977151,UA
1540977152,1540977663,PL
1540977664,1540978175,FI
1540978176,1540978687,AT
+1540978688,1540979199,RU
+1540979200,1540979711,SI
+1540979712,1540980223,RU
+1540980224,1540980735,SI
1540980736,1540980991,CH
1540980992,1540981247,RU
1540981248,1540981503,RO
@@ -44103,7 +46362,6 @@
1541007616,1541007871,RU
1541007872,1541008127,FR
1541008128,1541008383,NL
-1541008384,1541008639,UA
1541008640,1541008895,GB
1541008896,1541009151,TR
1541009152,1541009407,RU
@@ -44116,8 +46374,7 @@
1541010944,1541011199,CY
1541011200,1541011455,CH
1541011456,1541011711,FI
-1541011712,1541011967,UA
-1541011968,1541012223,RU
+1541011712,1541012223,RU
1541012224,1541012479,DE
1541012480,1541012735,FI
1541012736,1541013247,UA
@@ -44190,6 +46447,293 @@
1541093376,1541094399,RU
1541094400,1541095423,UA
1541095424,1541096447,RU
+1541096448,1541097471,AT
+1541097472,1541098495,RU
+1541098496,1541099519,NL
+1541099520,1541100543,UA
+1541100544,1541101567,HU
+1541101568,1541102591,RU
+1541102592,1541103615,RO
+1541103616,1541105663,RU
+1541105664,1541106687,PL
+1541106688,1541107711,NL
+1541107712,1541108735,PL
+1541108736,1541109759,ES
+1541109760,1541110783,PL
+1541110784,1541111807,RU
+1541111808,1541112831,PL
+1541112832,1541113855,SK
+1541113856,1541115903,RU
+1541115904,1541116927,UA
+1541116928,1541117951,RU
+1541117952,1541118975,DK
+1541118976,1541122047,RU
+1541123072,1541124095,FI
+1541124096,1541126143,RU
+1541126144,1541127167,PL
+1541127168,1541129215,RU
+1541129216,1541130239,UA
+1541130240,1541132287,RU
+1541132288,1541133311,PL
+1541133312,1541134335,RO
+1541134336,1541135359,SE
+1541135360,1541136383,UA
+1541136384,1541138431,RU
+1541138432,1541139455,UA
+1541139456,1541140479,HU
+1541140480,1541142527,CZ
+1541142528,1541143551,RU
+1541143552,1541144575,UA
+1541144576,1541144831,LV
+1541144832,1541145087,RU
+1541145088,1541145343,AT
+1541145344,1541145599,UA
+1541145600,1541145855,IT
+1541145856,1541146111,RU
+1541146112,1541146367,UA
+1541146368,1541146623,DK
+1541146624,1541146879,AT
+1541146880,1541147135,IL
+1541147136,1541147391,PL
+1541147392,1541147903,RU
+1541147904,1541148159,EU
+1541148160,1541148415,RO
+1541148416,1541148671,GB
+1541148672,1541148927,RU
+1541148928,1541149439,PL
+1541149440,1541149695,SE
+1541149696,1541149951,LT
+1541149952,1541150207,NL
+1541150208,1541150463,IL
+1541150464,1541150719,CH
+1541150720,1541151231,GB
+1541151232,1541151487,RO
+1541151488,1541151743,FR
+1541151744,1541151999,NL
+1541152000,1541152255,HU
+1541152256,1541152511,NL
+1541152512,1541152767,RU
+1541152768,1541153023,PL
+1541153024,1541153279,RU
+1541153280,1541153535,DE
+1541153536,1541153791,UA
+1541153792,1541154047,DE
+1541154048,1541154303,NL
+1541154304,1541154559,RU
+1541154560,1541154815,PL
+1541154816,1541155071,CH
+1541155072,1541155327,CY
+1541155328,1541155583,GB
+1541155584,1541155839,RU
+1541155840,1541156095,PL
+1541156096,1541156351,IE
+1541156352,1541156607,RU
+1541156608,1541156863,SE
+1541156864,1541157119,RO
+1541157120,1541157375,DE
+1541157376,1541157631,TR
+1541157632,1541157887,KZ
+1541157888,1541158143,GB
+1541158144,1541158399,NL
+1541158400,1541158655,PL
+1541158656,1541158911,SI
+1541158912,1541159167,DE
+1541159168,1541159423,RU
+1541159424,1541159679,SE
+1541159680,1541159935,LT
+1541159936,1541160447,UA
+1541160448,1541160703,RU
+1541160704,1541160959,MD
+1541160960,1541161215,CH
+1541161216,1541161471,TR
+1541161472,1541161727,ES
+1541161728,1541161983,DE
+1541161984,1541162239,BE
+1541162240,1541162495,RU
+1541162496,1541162751,GB
+1541162752,1541163007,DE
+1541163008,1541163263,RO
+1541163264,1541163519,PL
+1541163520,1541163775,DE
+1541163776,1541164031,RO
+1541164032,1541164287,RU
+1541164288,1541164543,HR
+1541164544,1541164799,SI
+1541164800,1541165055,IR
+1541165056,1541165311,UA
+1541165312,1541165567,RU
+1541165568,1541165823,NL
+1541165824,1541166079,GB
+1541166080,1541166335,RU
+1541166336,1541166591,FR
+1541166592,1541166847,RO
+1541166848,1541167103,RU
+1541167104,1541167359,NL
+1541167360,1541167615,AT
+1541167616,1541167871,RU
+1541167872,1541168127,UA
+1541168128,1541168383,RU
+1541168640,1541168895,MD
+1541168896,1541169151,MK
+1541169152,1541169407,RO
+1541169408,1541169663,PL
+1541169664,1541169919,SE
+1541169920,1541170431,CH
+1541170432,1541170687,UA
+1541170688,1541170943,BE
+1541170944,1541171199,PL
+1541171200,1541171455,UA
+1541171456,1541171711,PL
+1541171712,1541171967,UA
+1541171968,1541172223,SI
+1541172224,1541172479,GR
+1541172480,1541172735,RU
+1541172736,1541172991,RO
+1541172992,1541173247,BE
+1541173248,1541173503,RU
+1541173504,1541173759,UA
+1541173760,1541174015,LT
+1541174016,1541174271,DE
+1541174272,1541174527,FR
+1541174528,1541174783,SE
+1541174784,1541175039,GB
+1541175040,1541175295,SI
+1541175296,1541175551,RU
+1541175552,1541175807,RO
+1541175808,1541176063,CZ
+1541176064,1541176319,NL
+1541176320,1541176575,AM
+1541176576,1541176831,DE
+1541176832,1541177087,RU
+1541177088,1541177343,GB
+1541177344,1541177599,CH
+1541177600,1541177855,DE
+1541177856,1541178111,RO
+1541178112,1541178367,RU
+1541178368,1541178623,GB
+1541178624,1541178879,RU
+1541178880,1541179135,DE
+1541179136,1541179391,RU
+1541179392,1541179647,BE
+1541179648,1541179903,RU
+1541179904,1541180159,IS
+1541180160,1541180415,MT
+1541180416,1541180671,UA
+1541180672,1541180927,GB
+1541180928,1541181183,IT
+1541181184,1541181439,NO
+1541181440,1541181695,MD
+1541181696,1541182207,RU
+1541182208,1541182463,NL
+1541182464,1541182719,DE
+1541182720,1541182975,RO
+1541182976,1541183231,SE
+1541183232,1541183487,UA
+1541183488,1541183743,RU
+1541183744,1541183999,DE
+1541184000,1541184255,BE
+1541184256,1541184511,RU
+1541184512,1541184767,SI
+1541184768,1541185023,DE
+1541185024,1541185279,ES
+1541185280,1541185535,DE
+1541185536,1541185791,GB
+1541185792,1541186047,UA
+1541186048,1541186303,CH
+1541186304,1541186559,UA
+1541186560,1541186815,PL
+1541186816,1541187071,NO
+1541187072,1541187327,RU
+1541187328,1541187583,RO
+1541187584,1541187839,IT
+1541187840,1541188351,RU
+1541188352,1541188607,FR
+1541188608,1541188863,HU
+1541188864,1541189119,RU
+1541189120,1541189375,UA
+1541189376,1541189631,GB
+1541189632,1541189887,BG
+1541189888,1541190143,PL
+1541190144,1541190399,GB
+1541190400,1541190655,AT
+1541190656,1541190911,GB
+1541190912,1541191167,RU
+1541191168,1541191423,TR
+1541191424,1541191679,RO
+1541191680,1541192191,NL
+1541210112,1541210623,RU
+1541210624,1541211135,CZ
+1541211136,1541211647,SK
+1541211648,1541212159,RU
+1541212160,1541212671,DE
+1541212672,1541213183,MT
+1541213184,1541213695,DE
+1541213696,1541214207,UA
+1541214208,1541215743,RU
+1541215744,1541216255,SA
+1541216256,1541216767,RU
+1541216768,1541217279,PL
+1541217280,1541218303,RU
+1541218304,1541218815,IT
+1541218816,1541219839,RU
+1541219840,1541220351,CZ
+1541220352,1541221375,RU
+1541221376,1541221887,PL
+1541221888,1541222399,CZ
+1541222400,1541222911,RU
+1541222912,1541223423,DK
+1541223424,1541223935,UA
+1541223936,1541224447,GB
+1541224448,1541224959,RU
+1541224960,1541225471,DE
+1541225472,1541225983,RU
+1541225984,1541226495,LV
+1541226496,1541227007,UA
+1541227008,1541227519,FI
+1541227520,1541228031,GB
+1541228032,1541228543,RU
+1541228544,1541229055,CZ
+1541229056,1541229567,UA
+1541229568,1541230079,RU
+1541230080,1541230591,RO
+1541230592,1541231103,RU
+1541231104,1541231615,GB
+1541231616,1541232127,UA
+1541232128,1541232639,RU
+1541232640,1541233151,PL
+1541233152,1541233663,RU
+1541233664,1541234175,SK
+1541234176,1541234687,RO
+1541234688,1541235199,NL
+1541235200,1541235711,LV
+1541235712,1541236223,AT
+1541236224,1541236735,RU
+1541236736,1541237247,DE
+1541237248,1541237759,RU
+1541237760,1541238271,CZ
+1541238272,1541238783,ES
+1541238784,1541239295,SK
+1541239296,1541239807,PL
+1541239808,1541240319,RU
+1541240320,1541240831,CH
+1541240832,1541241343,DE
+1541241344,1541241855,PL
+1541241856,1541242367,UA
+1541242368,1541242879,PL
+1541242880,1541243391,KW
+1541243392,1541243903,NO
+1541243904,1541244415,UA
+1541244416,1541244927,RS
+1541275648,1541276671,UA
+1541276672,1541277695,RS
+1541277696,1541278719,ES
+1541278720,1541280767,UA
+1541280768,1541281791,BG
+1541281792,1541282815,PL
+1541282816,1541283839,RU
+1541283840,1541286911,UA
+1541286912,1541287935,DE
+1541287936,1541288959,UA
1543503872,1545601023,GB
1545601024,1545863167,SE
1545863168,1545895935,RU
@@ -44253,6 +46797,7 @@
1546270720,1546272767,GB
1546272768,1546274815,NO
1546274816,1546276863,SE
+1546276864,1546278911,IT
1546278912,1546280959,RU
1546280960,1546283007,IT
1546283008,1546285055,CH
@@ -44316,17 +46861,13 @@
1546649600,1546665983,SA
1546665984,1546673823,GB
1546673824,1546673839,RS
-1546673840,1546677503,GB
-1546677504,1546677551,IN
+1546673840,1546677535,GB
+1546677536,1546677551,IN
1546677552,1546677555,GB
1546677556,1546677557,IN
1546677558,1546677559,GB
1546677560,1546677561,IN
-1546677562,1546677567,GB
-1546677568,1546677569,IN
-1546677570,1546677571,GB
-1546677572,1546677573,IN
-1546677574,1546677679,GB
+1546677562,1546677679,GB
1546677680,1546677695,IN
1546677696,1546678863,GB
1546678864,1546678871,RS
@@ -44351,6 +46892,7 @@
1546895360,1546911743,IE
1546911744,1546928127,SK
1546928128,1546944511,GB
+1546944512,1546960895,UA
1546960896,1546977279,HU
1546977280,1546993663,MK
1546993664,1547010047,RU
@@ -44560,8 +47102,8 @@
1559314432,1559322623,GE
1559322624,1559330815,RU
1559330816,1559339007,BA
-1559339008,1559339711,RU
-1559339712,1559339775,A1
+1559339008,1559339743,RU
+1559339744,1559339775,MH
1559339776,1559341695,RU
1559341696,1559341703,ES
1559341704,1559347199,RU
@@ -44640,8 +47182,8 @@
1566101504,1566105599,RU
1566105600,1566109695,DE
1566109696,1566111231,CH
-1566111232,1566111295,FR
-1566111296,1566113791,CH
+1566111232,1566111487,FR
+1566111488,1566113791,CH
1566113792,1566117887,DE
1566117888,1566121983,TR
1566121984,1566126079,NO
@@ -44724,7 +47266,6 @@
1566363648,1566365695,GB
1566365696,1566367743,RU
1566367744,1566371839,ES
-1566371840,1566373887,RU
1566373888,1566375935,RS
1566375936,1566377983,DE
1566377984,1566380031,BG
@@ -44799,18 +47340,22 @@
1566468896,1566469391,BE
1566469392,1566469407,HU
1566469408,1566470143,BE
-1566470144,1566470320,IE
-1566470321,1566470343,GB
+1566470144,1566470159,IE
+1566470160,1566470171,GB
+1566470172,1566470239,IE
+1566470240,1566470343,GB
1566470344,1566470351,IE
1566470352,1566470367,GB
-1566470368,1566470719,IE
+1566470368,1566470511,IE
+1566470512,1566470655,GB
+1566470656,1566470719,IE
1566470720,1566470727,GB
1566470728,1566470739,IE
1566470740,1566470743,GB
-1566470744,1566470747,IE
-1566470748,1566470767,GB
-1566470768,1566470847,IE
-1566470848,1566470911,GB
+1566470744,1566470847,IE
+1566470848,1566470879,GB
+1566470880,1566470895,IR
+1566470896,1566470911,GB
1566470912,1566472191,IE
1566472192,1566474239,GB
1566474240,1566476287,DE
@@ -44856,7 +47401,9 @@
1566564352,1566566399,IS
1566566400,1566568447,FR
1566568448,1566570495,KZ
-1566570496,1566572543,NL
+1566570496,1566570943,NL
+1566570944,1566570951,DE
+1566570952,1566572543,NL
1566572544,1566703615,GB
1566703616,1566769151,SA
1566769152,1566773759,CZ
@@ -44937,6 +47484,7 @@
1570504704,1570570239,ES
1570570240,1570572287,NL
1570572288,1570574335,UA
+1570574336,1570576383,RU
1570576384,1570578431,UA
1570578432,1570580479,CH
1570580480,1570582527,RU
@@ -44948,6 +47496,7 @@
1570596864,1570598911,UA
1570598912,1570600959,PL
1570600960,1570603007,RU
+1570603008,1570605055,CZ
1570605056,1570607103,NL
1570607104,1570609151,RU
1570609152,1570611199,PL
@@ -45055,7 +47604,9 @@
1570667524,1570667527,IT
1570667528,1570667531,NO
1570667532,1570667535,GB
-1570667536,1570667711,SE
+1570667536,1570667587,SE
+1570667588,1570667591,US
+1570667592,1570667711,SE
1570667712,1570667727,FR
1570667728,1570667743,NL
1570667744,1570667775,SE
@@ -45080,6 +47631,7 @@
1570717696,1570725887,HR
1570725888,1570734079,DE
1570734080,1570750463,PL
+1570750464,1570752511,AL
1570752512,1570754559,GB
1570754560,1570756607,ES
1570756608,1570764799,RU
@@ -45087,7 +47639,13 @@
1570766848,1571291135,DK
1571291136,1571422207,RO
1571422208,1571426303,RU
-1571426304,1571553279,CZ
+1571426304,1571428351,CZ
+1571428352,1571428863,UA
+1571428864,1571430399,CZ
+1571430400,1571435519,UA
+1571435520,1571446783,CZ
+1571446784,1571448831,KZ
+1571448832,1571553279,CZ
1571553280,1571684351,IL
1571684352,1571686399,ES
1571686400,1571688447,GB
@@ -45224,7 +47782,8 @@
1572504320,1572504575,DE
1572504576,1572504703,RO
1572504704,1572504831,TR
-1572504832,1572507199,IT
+1572504832,1572505087,SG
+1572505088,1572507199,IT
1572507200,1572507207,GB
1572507208,1572507647,IT
1572507648,1572511743,GB
@@ -45250,7 +47809,6 @@
1572542000,1572542207,GB
1572542208,1572542463,FR
1572542464,1572544511,IT
-1572544512,1572546559,HR
1572546560,1572548607,FR
1572548608,1572550655,GB
1572550656,1572552703,DE
@@ -45313,7 +47871,13 @@
1572661248,1572663295,NO
1572663296,1572665343,DE
1572665344,1572667391,NL
-1572667392,1572669439,GB
+1572667392,1572668303,GB
+1572668304,1572668311,SA
+1572668312,1572668415,GB
+1572668416,1572668431,SA
+1572668432,1572668463,GB
+1572668464,1572668471,SA
+1572668472,1572669439,GB
1572669440,1572673535,RU
1572673536,1572675583,AT
1572675584,1572677631,ES
@@ -45386,13 +47950,12 @@
1572800512,1572804607,RU
1572804608,1572808703,GB
1572808704,1572810751,FR
-1572810752,1572812031,DE
-1572812032,1572812543,RO
-1572812544,1572812799,DE
+1572810752,1572812799,DE
1572812800,1572814847,RU
1572814848,1572816895,KW
1572816896,1572818943,RU
1572818944,1572820991,FR
+1572820992,1572823039,CH
1572823040,1572825087,BY
1572825088,1572827135,RU
1572827136,1572829183,NO
@@ -45413,9 +47976,10 @@
1572849664,1572851711,GB
1572851712,1572853759,DE
1572853760,1572854015,BE
-1572854016,1572854527,LU
+1572854016,1572854271,LU
+1572854272,1572854527,BE
1572854528,1572855551,EU
-1572855552,1572855807,LU
+1572855552,1572855807,BE
1572855808,1572857855,KZ
1572857856,1572859903,SE
1572859904,1572861951,IT
@@ -45443,8 +48007,8 @@
1578590304,1578590311,IT
1578590312,1578590319,FR
1578590320,1578590335,CH
-1578590336,1578590343,FR
-1578590344,1578590351,GB
+1578590336,1578590347,FR
+1578590348,1578590351,PL
1578590352,1578590415,FR
1578590416,1578590431,PL
1578590432,1578590447,BE
@@ -45477,7 +48041,7 @@
1578590928,1578590935,DE
1578590936,1578590943,ES
1578590944,1578590959,CH
-1578590960,1578590975,NL
+1578590960,1578590975,FR
1578590976,1578590991,GB
1578590992,1578590999,IT
1578591000,1578591007,FR
@@ -45497,18 +48061,17 @@
1578591248,1578591263,PL
1578591264,1578591279,FR
1578591280,1578591287,ES
-1578591288,1578591291,DE
+1578591288,1578591291,NL
1578591292,1578591295,ES
1578591296,1578591327,FR
1578591328,1578591343,PL
-1578591344,1578591359,FR
-1578591360,1578591375,PL
-1578591376,1578591391,FR
+1578591344,1578591391,FR
1578591392,1578591407,CH
-1578591408,1578591423,GB
+1578591408,1578591411,ES
+1578591412,1578591415,FR
+1578591416,1578591423,ES
1578591424,1578591431,PL
-1578591432,1578591435,DE
-1578591436,1578591439,ES
+1578591432,1578591439,ES
1578591440,1578591463,FR
1578591464,1578591487,PL
1578591488,1578591503,FR
@@ -45533,14 +48096,16 @@
1578591808,1578591823,DE
1578591824,1578591887,FR
1578591888,1578591891,DE
-1578591892,1578591903,FR
+1578591892,1578591899,FR
+1578591900,1578591903,GB
1578591904,1578591919,PL
1578591920,1578591939,ES
1578591940,1578591951,FR
1578591952,1578591967,PT
1578591968,1578591983,FR
1578591984,1578592031,PL
-1578592032,1578592047,IT
+1578592032,1578592039,PT
+1578592040,1578592047,ES
1578592048,1578592079,FR
1578592080,1578592095,PL
1578592096,1578592111,FR
@@ -45555,9 +48120,9 @@
1578592192,1578592199,BE
1578592200,1578592207,CH
1578592208,1578592223,FR
-1578592224,1578592255,ES
-1578592256,1578592271,FR
-1578592272,1578592279,NL
+1578592224,1578592239,ES
+1578592240,1578592275,FR
+1578592276,1578592279,FI
1578592280,1578592283,BE
1578592284,1578592287,NL
1578592288,1578592303,DE
@@ -45580,16 +48145,17 @@
1578592536,1578592543,NL
1578592544,1578592559,FR
1578592560,1578592575,NL
-1578592576,1578592687,FR
-1578592688,1578592719,ES
+1578592576,1578592591,GB
+1578592592,1578592687,FR
+1578592688,1578592695,DE
+1578592696,1578592719,ES
1578592720,1578592735,CH
1578592736,1578592751,FR
1578592752,1578592783,DE
1578592784,1578592799,FR
1578592800,1578592815,GB
1578592816,1578592823,PL
-1578592824,1578592827,FR
-1578592828,1578592831,IE
+1578592824,1578592831,FR
1578592832,1578592847,PL
1578592848,1578592851,BE
1578592852,1578592855,DE
@@ -45667,7 +48233,11 @@
1578594312,1578594315,PL
1578594316,1578594319,FR
1578594320,1578594335,PL
-1578594336,1578594375,FR
+1578594336,1578594355,GB
+1578594356,1578594359,FR
+1578594360,1578594363,PT
+1578594364,1578594367,IT
+1578594368,1578594375,FR
1578594376,1578594383,PT
1578594384,1578594399,FR
1578594400,1578594431,PL
@@ -45676,7 +48246,7 @@
1578594464,1578594479,FR
1578594480,1578594495,ES
1578594496,1578594511,FR
-1578594512,1578594515,DE
+1578594512,1578594515,PL
1578594516,1578594519,FR
1578594520,1578594523,PL
1578594524,1578594543,FR
@@ -45693,7 +48263,7 @@
1578594712,1578594715,IT
1578594716,1578594751,FR
1578594752,1578594767,ES
-1578594768,1578594771,DE
+1578594768,1578594771,GB
1578594772,1578594775,FR
1578594776,1578594783,ES
1578594784,1578594799,FR
@@ -45730,8 +48300,8 @@
1578595388,1578595391,PL
1578595392,1578595423,CH
1578595424,1578595455,LT
-1578595456,1578595463,DE
-1578595464,1578595487,FR
+1578595456,1578595459,DE
+1578595460,1578595487,FR
1578595488,1578595503,DE
1578595504,1578595519,PL
1578595520,1578595607,FR
@@ -45740,7 +48310,12 @@
1578595616,1578595647,PL
1578595648,1578595679,FR
1578595680,1578595695,BE
-1578595696,1578595763,FR
+1578595696,1578595711,FR
+1578595712,1578595743,GB
+1578595744,1578595747,IT
+1578595748,1578595751,FR
+1578595752,1578595759,ES
+1578595760,1578595763,FR
1578595764,1578595775,ES
1578595776,1578595807,CH
1578595808,1578595983,FR
@@ -45750,7 +48325,9 @@
1578596096,1578596099,DE
1578596100,1578596103,GB
1578596104,1578596111,FR
-1578596112,1578596127,ES
+1578596112,1578596115,DE
+1578596116,1578596123,PT
+1578596124,1578596127,ES
1578596128,1578596143,PL
1578596144,1578596147,DE
1578596148,1578596151,FR
@@ -45778,14 +48355,18 @@
1578610688,1578610943,FR
1578610944,1578610975,ES
1578610976,1578611039,PL
-1578611040,1578611071,FR
+1578611040,1578611043,ES
+1578611044,1578611047,CZ
+1578611048,1578611051,ES
+1578611052,1578611055,PL
+1578611056,1578611071,FR
1578611072,1578611075,DE
1578611076,1578611079,FR
1578611080,1578611087,NL
1578611088,1578611119,DE
1578611120,1578611135,FR
1578611136,1578611151,CH
-1578611152,1578611167,FR
+1578611152,1578611167,DE
1578611168,1578611183,ES
1578611184,1578611199,FR
1578611200,1578611215,NL
@@ -45805,7 +48386,7 @@
1578611400,1578611403,BE
1578611404,1578611407,ES
1578611408,1578611423,IT
-1578611424,1578611439,FR
+1578611424,1578611439,GB
1578611440,1578611455,IT
1578611456,1578611711,FR
1578611712,1578611775,CH
@@ -45820,12 +48401,11 @@
1578611952,1578611967,FR
1578611968,1578612159,GB
1578612160,1578612223,PL
-1578612224,1578612239,DE
+1578612224,1578612239,GB
1578612240,1578612255,FR
1578612256,1578612259,PL
1578612260,1578612263,IT
-1578612264,1578612271,FR
-1578612272,1578612287,ES
+1578612264,1578612287,FR
1578612288,1578612303,BE
1578612304,1578612319,DE
1578612320,1578612383,FR
@@ -45838,7 +48418,8 @@
1578612704,1578612863,FR
1578612864,1578612895,NL
1578612896,1578612911,PL
-1578612912,1578612975,ES
+1578612912,1578612959,ES
+1578612960,1578612975,GB
1578612976,1578612991,FR
1578612992,1578613247,DE
1578613248,1578613503,FR
@@ -45889,7 +48470,9 @@
1579091840,1579091855,US
1579091856,1579091967,GB
1579091968,1579092223,DE
-1579092224,1579104511,GB
+1579092224,1579093759,GB
+1579093760,1579094015,NL
+1579094016,1579104511,GB
1579104512,1579104767,NL
1579104768,1579105023,GB
1579105024,1579105151,NL
@@ -45910,7 +48493,9 @@
1580015616,1580048383,UA
1580048384,1580064767,RU
1580064768,1580072959,DE
-1580072960,1580134399,PT
+1580072960,1580085247,PT
+1580085248,1580089343,MZ
+1580089344,1580134399,PT
1580134400,1580136447,ES
1580136448,1580138495,PT
1580138496,1580204031,IT
@@ -46028,7 +48613,9 @@
1583813736,1583813743,DE
1583813744,1583813808,NL
1583813809,1583813815,US
-1583813816,1583816703,NL
+1583813816,1583815167,NL
+1583815168,1583815199,US
+1583815200,1583816703,NL
1583816704,1583820799,TR
1583820800,1583824895,LV
1583824896,1583828991,SI
@@ -46043,7 +48630,13 @@
1583848704,1583848735,NL
1583848736,1583848799,BE
1583848800,1583849471,NL
-1583849472,1583853567,DE
+1583849472,1583850751,DE
+1583850752,1583850943,AT
+1583850944,1583850951,DE
+1583850952,1583850959,AT
+1583850960,1583850999,DE
+1583851000,1583851007,AT
+1583851008,1583853567,DE
1583853568,1583857663,RU
1583857664,1583861759,SE
1583861760,1583865855,LU
@@ -46097,7 +48690,9 @@
1585265696,1585265727,IM
1585265728,1585265767,FR
1585265768,1585265775,IM
-1585265776,1585266111,FR
+1585265776,1585265919,FR
+1585265920,1585265935,IM
+1585265936,1585266111,FR
1585266112,1585266687,IM
1585266688,1585270783,DE
1585270784,1585272831,IT
@@ -46207,14 +48802,15 @@
1585991684,1585991687,US
1585991688,1585991935,SE
1585991936,1585991939,US
-1585991940,1585995775,SE
+1585991940,1585994499,SE
+1585994500,1585994503,RU
+1585994504,1585995775,SE
1585995776,1586003967,AT
1586003968,1586012159,SK
1586012160,1586020351,DE
1586020352,1586028543,RU
1586028544,1586036735,GB
-1586036736,1586061311,RU
-1586061312,1586069503,HR
+1586036736,1586069503,RU
1586069504,1586077695,DE
1586077696,1586085887,GE
1586085888,1586110463,RU
@@ -46281,6 +48877,7 @@
1586438144,1586446335,RU
1586446336,1586448383,NO
1586448384,1586450431,ES
+1586450432,1586452479,FR
1586452480,1586454527,CH
1586454528,1586456575,IT
1586456576,1586458623,GB
@@ -46325,7 +48922,9 @@
1588068352,1588592639,GB
1588592640,1588621311,RO
1588621312,1588625407,MD
-1588625408,1588723711,RO
+1588625408,1588670463,RO
+1588670464,1588674559,MD
+1588674560,1588723711,RO
1588723712,1588854783,UA
1588854784,1588985855,RU
1588985856,1589182463,IR
@@ -46453,14 +49052,15 @@
1592069888,1592074239,RU
1592074240,1592078335,SK
1592078336,1592082431,NL
-1592082432,1592086527,GB
+1592082432,1592085023,GB
+1592085024,1592085039,ES
+1592085040,1592086527,GB
1592086528,1592087295,CZ
1592087296,1592088063,PL
1592088064,1592090623,CZ
1592090624,1592094719,RU
1592094720,1592098815,RS
1592098816,1592102911,GB
-1592102912,1592107007,PT
1592107008,1592111103,GB
1592111104,1592115199,DE
1592115200,1592119295,ES
@@ -46501,6 +49101,7 @@
1592287232,1592289279,RO
1592289280,1592291327,RU
1592291328,1592293375,NL
+1592293376,1592295423,LT
1592295424,1592299519,RU
1592299520,1592303615,PL
1592303616,1592305663,NL
@@ -46551,7 +49152,9 @@
1593180160,1593196543,NO
1593196544,1593196783,SE
1593196784,1593196799,GB
-1593196800,1593203455,SE
+1593196800,1593202687,SE
+1593202688,1593202815,NO
+1593202816,1593203455,SE
1593203456,1593203487,NO
1593203488,1593204159,SE
1593204160,1593204223,DK
@@ -46561,9 +49164,7 @@
1593206084,1593206095,DK
1593206096,1593206103,FI
1593206104,1593206111,GB
-1593206112,1593206207,SE
-1593206208,1593206271,FI
-1593206272,1593209151,SE
+1593206112,1593209151,SE
1593209152,1593209155,GR
1593209156,1593209159,HU
1593209160,1593209163,FI
@@ -46620,9 +49221,7 @@
1593606144,1593638911,SY
1593638912,1593671679,RU
1593671680,1593704447,HR
-1593704448,1593704959,SE
-1593704960,1593705471,NO
-1593705472,1593737215,SE
+1593704448,1593737215,SE
1593737216,1593769983,PL
1593769984,1593802751,RU
1593802752,1593835519,SE
@@ -46665,9 +49264,16 @@
1599078400,1599094783,SE
1599094784,1599111167,RU
1599111168,1599127551,IR
-1599127552,1599143935,CZ
+1599127552,1599133695,CZ
+1599133696,1599133823,SK
+1599133824,1599134207,CZ
+1599134208,1599134463,AT
+1599134464,1599143935,CZ
+1599143936,1599160319,UA
1599160320,1599176703,IR
-1599176704,1599193087,FR
+1599176704,1599188991,FR
+1599188992,1599189263,DE
+1599189264,1599193087,FR
1599193088,1599209471,RU
1599209472,1599242239,IR
1599242240,1599258623,CZ
@@ -46753,7 +49359,9 @@
1602271232,1602273279,MK
1602273280,1602273535,FR
1602273536,1602273791,GB
-1602273792,1602275327,FR
+1602273792,1602274559,IN
+1602274560,1602274815,IE
+1602274816,1602275327,FR
1602275328,1602275615,DE
1602275616,1602275647,CY
1602275648,1602279423,DE
@@ -46781,8 +49389,10 @@
1602314240,1602316287,CZ
1602316288,1602318335,GB
1602318336,1602320383,ES
-1602320384,1602324479,NL
-1602324480,1602326527,RU
+1602320384,1602322687,NL
+1602322688,1602322703,IE
+1602322704,1602324479,NL
+1602324480,1602328575,RU
1602328576,1602330623,ES
1602330624,1602336767,RU
1602336768,1602338815,GB
@@ -46856,7 +49466,9 @@
1602453504,1602455551,SK
1602455552,1602456015,FR
1602456016,1602456023,ES
-1602456024,1602457599,FR
+1602456024,1602456175,FR
+1602456176,1602456183,ES
+1602456184,1602457599,FR
1602457600,1602459647,RU
1602459648,1602461695,GB
1602461696,1602465791,ES
@@ -46942,9 +49554,7 @@
1603170304,1603174399,IE
1603174400,1603178495,TR
1603178496,1603182591,DK
-1603182592,1603184639,FR
-1603184640,1603185663,GB
-1603185664,1603186687,FR
+1603182592,1603186687,FR
1603186688,1603190783,IT
1603190784,1603194879,RU
1603194880,1603198975,IT
@@ -46963,8 +49573,18 @@
1603223937,1603223951,GB
1603223952,1603224319,FR
1603224320,1603224575,GB
-1603224576,1603224735,FR
-1603224736,1603226623,GB
+1603224576,1603224775,FR
+1603224776,1603224783,GB
+1603224784,1603224799,FR
+1603224800,1603225599,GB
+1603225600,1603225607,ES
+1603225608,1603225615,GB
+1603225616,1603225623,DE
+1603225624,1603225631,IT
+1603225632,1603225639,US
+1603225640,1603225647,CN
+1603225648,1603225855,FR
+1603225856,1603226623,GB
1603226624,1603227391,FR
1603227392,1603227647,GB
1603227648,1603231743,AT
@@ -47056,7 +49676,11 @@
1604894464,1604894719,DE
1604894720,1604895487,CZ
1604895488,1604895491,SK
-1604895492,1604902911,CZ
+1604895492,1604895607,CZ
+1604895608,1604895611,SK
+1604895612,1604900351,CZ
+1604900352,1604900383,SC
+1604900384,1604902911,CZ
1604902912,1604911103,BG
1604911104,1604919295,UA
1604919296,1604927487,NO
@@ -47083,18 +49707,22 @@
1605099520,1605107711,RU
1605107712,1605115903,GB
1605115904,1605124095,RU
-1605124096,1605124351,US
-1605124352,1605125263,GB
+1605124096,1605124607,US
+1605124608,1605124671,GB
+1605124672,1605124735,US
+1605124736,1605125263,GB
1605125264,1605125287,US
1605125288,1605125311,GB
1605125312,1605125319,US
1605125320,1605125327,GB
-1605125328,1605125335,US
-1605125336,1605125375,GB
+1605125328,1605125343,US
+1605125344,1605125375,GB
1605125376,1605125631,US
1605125632,1605126143,DE
1605126144,1605127679,US
-1605127680,1605132287,GB
+1605127680,1605130239,GB
+1605130240,1605130271,US
+1605130272,1605132287,GB
1605132288,1605148671,RU
1605148672,1605156863,PT
1605156864,1605165055,JO
@@ -47179,7 +49807,9 @@
1607947264,1607948287,RU
1607948288,1607949311,GB
1607949312,1607950335,UA
+1607950336,1607952383,RU
1607952384,1607953407,UA
+1607954432,1607956479,UA
1607956480,1607957503,ES
1607957504,1607958527,UA
1607958528,1607959551,PS
@@ -47192,9 +49822,9 @@
1607967744,1607968767,UA
1607968768,1607969791,SE
1607969792,1607971839,RU
+1607972864,1607974911,NL
1607974912,1607975935,LV
1607976960,1607977983,KZ
-1607977984,1607979007,NL
1607979008,1607980031,RU
1607980032,1607981055,DE
1607981056,1607982079,UA
@@ -47231,8 +49861,8 @@
1613471744,1613479935,JM
1613479936,1613488127,US
1613488128,1613492223,CA
-1613496320,1613504511,US
-1613512704,1613529087,CA
+1613492224,1613504511,US
+1613504512,1613529087,CA
1613529088,1613536191,US
1613536192,1613536223,TW
1613536224,1613536255,US
@@ -47286,8 +49916,11 @@
1613570048,1613574143,CA
1613574144,1613586431,US
1613586432,1613590527,CA
-1613590528,1613606911,US
-1613606912,1613615103,CA
+1613590528,1613602815,US
+1613606912,1613607423,CA
+1613607424,1613607679,GB
+1613607680,1613607935,US
+1613607936,1613615103,CA
1613615104,1613635583,US
1613635584,1613639679,CA
1613639680,1613676543,US
@@ -47322,7 +49955,9 @@
1632355512,1632355519,US
1632355520,1632355583,CA
1632355584,1632355599,US
-1632355600,1632362495,CA
+1632355600,1632357439,CA
+1632357440,1632357447,US
+1632357448,1632362495,CA
1632362496,1634414591,US
1634414592,1634418687,CA
1634418688,1634447359,US
@@ -47924,7 +50559,9 @@
1652681520,1653534719,US
1653534720,1653538815,CA
1653538816,1653555199,US
-1653555200,1653567487,CA
+1653555200,1653560319,CA
+1653560320,1653560327,US
+1653560328,1653567487,CA
1653567488,1653571583,US
1653571584,1653575679,CA
1653575680,1653592063,US
@@ -47936,9 +50573,12 @@
1654546432,1654550527,VG
1654550528,1654554623,US
1654554624,1654558719,CA
-1654558720,1654597631,US
-1654597632,1654597887,CA
-1654597888,1654648831,US
+1654558720,1654583071,US
+1654583072,1654583103,TR
+1654583104,1654583135,CA
+1654583136,1654599455,US
+1654599456,1654599471,CA
+1654599472,1654648831,US
1654648832,1654652927,CA
1654652928,1665833175,US
1665833176,1665833183,A2
@@ -48060,15 +50700,19 @@
1697775616,1697776639,AP
1700790272,1702887679,AU
1711210496,1711276031,AP
-1795162112,1796210687,US
-1811939328,1828716543,US
+1795162112,1815822335,US
+1815822336,1815826431,CA
+1815826432,1815846911,US
+1815871488,1815879679,CA
+1816133632,1822425087,US
1828716544,1830813695,FR
1830813696,1831337983,NL
1831337984,1831862271,DE
1831862272,1832124415,PT
1832124416,1832386559,IT
1832386560,1832517631,DK
-1832517632,1832648703,SE
+1832517632,1832615935,SE
+1832615936,1832648703,DK
1832648704,1832681471,HR
1832681472,1832714239,RU
1832714240,1832747007,HU
@@ -48244,7 +50888,6 @@
1833504768,1833508863,DE
1833508864,1833512959,RU
1833512960,1833517055,DE
-1833517056,1833521151,ES
1833521152,1833525247,IT
1833525248,1833529343,LV
1833529344,1833533439,GB
@@ -48329,7 +50972,7 @@
1834960896,1834964991,RU
1834964992,1834967039,PL
1834967040,1834971135,RU
-1834971136,1834973183,KZ
+1834971136,1834973183,UA
1834973184,1834975231,RU
1834975232,1834977279,IL
1834977280,1834983423,PL
@@ -48493,7 +51136,9 @@
1839801280,1839801311,VG
1839801312,1839801343,GB
1839801344,1839801471,CN
-1839801472,1839801599,GB
+1839801472,1839801551,GB
+1839801552,1839801567,US
+1839801568,1839801599,GB
1839801600,1839801855,US
1839801856,1839802111,GB
1839802112,1839802239,RO
@@ -48543,13 +51188,14 @@
1841629184,1841635327,RU
1841635328,1841639423,PL
1841639424,1841641471,RU
-1841641472,1841643519,PL
+1841641472,1841645567,PL
1841645568,1841647615,RU
1841647616,1841649663,RO
1841649664,1841651711,RU
1841651712,1841653759,PL
1841653760,1841655807,FR
1841655808,1841668095,RU
+1841668096,1841670143,RO
1841670144,1841672191,PL
1841672192,1841674239,FR
1841674240,1841676287,PL
@@ -48578,13 +51224,22 @@
1841827088,1841827231,GB
1841827232,1841827263,BR
1841827264,1841827279,BD
-1841827280,1841831935,GB
+1841827280,1841827463,GB
+1841827464,1841827471,BD
+1841827472,1841827479,ES
+1841827480,1841827695,GB
+1841827696,1841827703,ES
+1841827704,1841828879,GB
+1841828880,1841828895,MT
+1841828896,1841831935,GB
1841831936,1841840127,MT
1841840128,1841848319,PL
1841848320,1841856511,RU
1841856512,1841864703,UA
1841864704,1841872895,YE
-1841872896,1841881087,NL
+1841872896,1841879807,NL
+1841879808,1841880063,GB
+1841880064,1841881087,JP
1841881088,1841889279,UA
1841889280,1841897471,IR
1841897472,1841905663,RO
@@ -48693,12 +51348,15 @@
1843707904,1843724287,TR
1843724288,1843732479,UA
1843732480,1843765247,RU
+1843765248,1843773439,KZ
1843773440,1843781631,LV
1843781632,1843789823,RU
1843789824,1843806207,SK
1843806208,1843822591,IR
1843822592,1843838975,RU
-1843838976,1843855359,DE
+1843838976,1843849215,DE
+1843849216,1843850239,GB
+1843850240,1843855359,DE
1843855360,1843871743,PL
1843871744,1843888127,GB
1843888128,1843904511,CZ
@@ -48820,9 +51478,11 @@
1844162560,1844164607,CZ
1844164608,1844166655,RU
1844166656,1844168703,AZ
-1844168704,1844169727,LB
-1844169728,1844170387,DE
-1844170388,1844170751,GI
+1844168704,1844169487,SE
+1844169488,1844169503,IQ
+1844169504,1844169983,SE
+1844169984,1844170387,DE
+1844170388,1844170751,SE
1844170752,1844174847,RU
1844174848,1844178943,DE
1844178944,1844180991,EE
@@ -48834,7 +51494,25 @@
1844181953,1844181958,GB
1844181959,1844181984,TR
1844181985,1844181990,GB
-1844181991,1844183039,TR
+1844181991,1844182271,TR
+1844182272,1844182302,US
+1844182303,1844182309,TR
+1844182310,1844182329,US
+1844182330,1844182343,TR
+1844182344,1844182403,US
+1844182404,1844182416,TR
+1844182417,1844182417,US
+1844182418,1844182424,TR
+1844182425,1844182426,US
+1844182427,1844182432,TR
+1844182433,1844182442,US
+1844182443,1844182459,TR
+1844182460,1844182480,US
+1844182481,1844182485,TR
+1844182486,1844182489,US
+1844182490,1844182501,TR
+1844182502,1844182511,US
+1844182512,1844183039,TR
1844183040,1844191231,IT
1844191232,1844195327,AL
1844195328,1844203519,RU
@@ -48854,6 +51532,7 @@
1844256768,1844260863,BA
1844260864,1844264959,CH
1844264960,1844269055,NL
+1844269056,1844273151,UA
1844273152,1844277247,RU
1844277248,1844281343,AZ
1844281344,1844285439,DE
@@ -49013,7 +51692,6 @@
1851590656,1851591679,AU
1851592704,1851594751,AU
1851594752,1851596799,KR
-1851596800,1851604991,IN
1851604992,1851613183,PH
1851613184,1851617279,JP
1851617280,1851637759,KR
@@ -49189,7 +51867,6 @@
1877706752,1877707775,SG
1877707776,1877709823,AU
1877710848,1877711871,AP
-1877711872,1877712895,BD
1877712896,1877721087,CN
1877721088,1877737471,TW
1877737472,1877999615,JP
@@ -49450,12 +52127,12 @@
1916272640,1916534783,ID
1916534784,1917124607,CN
1917124608,1917169663,JP
-1917169664,1917177855,NC
+1917169664,1917181951,NC
1917181952,1917190143,IN
1917190144,1917321215,KR
1917321216,1917779967,AU
1917779968,1917796351,ID
-1917796352,1917845503,IN
+1917812736,1917845503,IN
1917845504,1919680511,CN
1919680512,1919729663,KR
1919729664,1919746047,PH
@@ -49510,6 +52187,8 @@
1921867776,1921871871,AU
1921875968,1921892351,CN
1921892352,1921896447,AU
+1921896448,1921898495,SG
+1921898496,1921900543,PH
1921900544,1921908735,KR
1921908736,1921943551,JP
1921943552,1921945599,IN
@@ -50495,7 +53174,9 @@
2038423552,2038431743,HK
2038431744,2042626047,KR
2042626048,2043150335,CN
-2043150336,2043166719,AU
+2043150336,2043162623,AU
+2043162624,2043165695,IN
+2043165696,2043166719,BD
2043166720,2043183103,KR
2043183104,2043199487,JP
2043199488,2043201535,BD
@@ -50561,7 +53242,7 @@
2053521408,2053529599,CN
2053529600,2053533695,AU
2053533696,2053534719,VN
-2053535744,2053537791,IN
+2053534720,2053537791,IN
2053537792,2053636095,JP
2053636096,2054160383,AU
2054160384,2054422527,CN
@@ -50751,7 +53432,6 @@
2066882560,2066890751,TW
2066890752,2066907135,PF
2066907136,2066915327,AU
-2066915328,2066923519,IN
2066923520,2066939903,JP
2066939904,2066972671,AU
2066972672,2067005439,TW
@@ -51109,6 +53789,7 @@
2110832640,2110865407,KR
2110865408,2110881791,PK
2110881792,2110898175,AU
+2110898176,2110914559,KR
2110914560,2111045631,CN
2111045632,2111078399,PH
2111078400,2111111167,VN
@@ -51477,7 +54158,8 @@
2194604032,2194669567,US
2194669568,2194735103,IS
2194735104,2194800639,GB
-2194800640,2195193855,US
+2194800640,2194866175,US
+2194931712,2195193855,US
2195193856,2195324927,NZ
2195324928,2195455999,US
2195456000,2195521535,AU
@@ -51680,7 +54362,9 @@
2249457664,2249523199,US
2249523200,2249588735,CH
2249588736,2249654271,CA
-2249654272,2249781247,US
+2249654272,2249724671,US
+2249724672,2249724927,CA
+2249724928,2249781247,US
2249781248,2249781255,FR
2249781256,2249785343,US
2249785344,2249850879,SE
@@ -52251,7 +54935,10 @@
2329673728,2329739263,US
2329739264,2329804799,CH
2329804800,2329870335,DE
-2329870336,2330132479,CH
+2329870336,2329935871,CH
+2329935872,2330001407,DE
+2330001408,2330066943,CH
+2330066944,2330132479,US
2330132480,2330198015,SE
2330198016,2330263551,CH
2330263552,2330394623,US
@@ -52549,11 +55236,11 @@
2382102528,2382168063,NL
2382168064,2382233599,BE
2382233600,2382299135,US
-2382364672,2385430319,CA
-2385430320,2385430335,US
-2385430336,2385430655,CA
+2382364672,2385430655,CA
2385430656,2385430687,US
-2385430688,2386067455,CA
+2385430688,2385903615,CA
+2385903616,2385969151,US
+2385969152,2386067455,CA
2386067456,2386083839,US
2386083840,2386624511,CA
2386624512,2386690047,US
@@ -52565,7 +55252,10 @@
2387410944,2387476479,US
2387476480,2387542015,CA
2387542016,2387607551,US
-2387607552,2394947583,CA
+2387607552,2390818815,CA
+2390884352,2390995455,CA
+2390995456,2391015423,US
+2391015424,2394947583,CA
2394947584,2395013119,US
2395013120,2395209727,CA
2395340800,2399141887,CA
@@ -52956,9 +55646,7 @@
2467233792,2468020223,US
2468020224,2468085759,GR
2468085760,2468151295,JP
-2468151296,2468174847,DK
-2468174848,2468175359,NO
-2468175360,2468189663,DK
+2468151296,2468189663,DK
2468189664,2468189695,GB
2468189696,2468216831,DK
2468216832,2468282367,EU
@@ -53418,7 +56106,9 @@
2601451520,2601517055,CA
2601517056,2602565631,US
2602565632,2602631167,NZ
-2602631168,2604007423,US
+2602631168,2603417599,US
+2603417600,2603483135,DE
+2603483136,2604007423,US
2604007424,2604072959,ES
2604072960,2604138495,NO
2604138496,2604204031,DE
@@ -53598,7 +56288,8 @@
2642280448,2642411519,US
2642411520,2642477055,AU
2642477056,2642542591,FI
-2642542592,2642935807,US
+2642542592,2642608127,US
+2642673664,2642935807,US
2642935808,2643001343,FR
2643001344,2643066879,US
2643066880,2643132415,IT
@@ -54685,9 +57376,7 @@
2816014272,2816015319,IL
2816015320,2816015327,US
2816015328,2816015335,IL
-2816015336,2816015343,US
-2816015344,2816015359,IL
-2816015360,2816015423,US
+2816015336,2816015423,US
2816015424,2816016383,IL
2816016384,2816671743,US
2816671744,2816737279,CA
@@ -54915,35 +57604,25 @@
2904555520,2904817663,CA
2904817664,2905376767,US
2905376768,2905377535,CA
-2905377536,2905377791,US
-2905377792,2905378047,CA
-2905378048,2905378303,US
+2905377536,2905378303,US
2905378304,2905378815,CA
2905378816,2905379071,US
2905379072,2905379583,CA
-2905379584,2905380863,US
-2905380864,2905381119,CA
-2905381120,2905381887,US
+2905379584,2905381887,US
2905381888,2905382016,CA
-2905382017,2905384191,US
-2905384192,2905385471,CA
-2905385472,2905386239,US
-2905386240,2905386495,CA
-2905386496,2905388031,US
+2905382017,2905384959,US
+2905384960,2905385471,CA
+2905385472,2905388031,US
2905388032,2905388287,CA
-2905388288,2905391871,US
-2905391872,2905392127,CA
-2905392128,2905392895,US
-2905392896,2905394943,CA
+2905388288,2905392895,US
+2905392896,2905393151,CA
+2905393152,2905394175,US
+2905394176,2905394943,CA
2905394944,2905395455,US
2905395456,2905396991,CA
-2905396992,2905397759,US
-2905397760,2905398271,CA
-2905398272,2905399039,US
+2905396992,2905399039,US
2905399040,2905399295,CA
-2905399296,2905404671,US
-2905404672,2905405183,CA
-2905405184,2905407743,US
+2905399296,2905407743,US
2905407744,2905407999,TW
2905408000,2905428967,US
2905428968,2905428975,AE
@@ -55245,28 +57924,21 @@
2915811136,2915811199,IN
2915811200,2915958783,US
2915958784,2916024319,CA
-2916024320,2916091903,US
-2916091904,2916092159,IN
-2916092160,2916092927,US
-2916092928,2916093183,IN
-2916093184,2916093695,US
-2916093696,2916093951,IN
-2916093952,2916110623,US
+2916024320,2916110623,US
2916110624,2916110639,CA
2916110640,2916163583,US
2916163584,2916171775,CA
-2916171776,2916188159,US
-2916188160,2916196351,CA
-2916196352,2916200447,US
-2916204544,2916253695,US
+2916171776,2916184063,US
+2916184064,2916196351,CA
+2916196352,2916253695,US
2916253696,2916286463,CA
2916286464,2916319231,US
2916319232,2916335615,PR
2916352000,2916368383,US
2916368384,2916401151,CA
2916401152,2916417535,US
-2916417536,2916434495,CA
-2916434496,2916434559,US
+2916417536,2916434431,CA
+2916434432,2916434559,US
2916434560,2916434591,CA
2916434592,2916437503,US
2916437504,2916437567,CA
@@ -55274,7 +57946,11 @@
2916440064,2916440095,CA
2916440096,2916440143,US
2916440144,2916440159,CA
-2916440160,2916441343,US
+2916440160,2916440175,US
+2916440176,2916440191,CA
+2916440192,2916441119,US
+2916441120,2916441151,CA
+2916441152,2916441343,US
2916441344,2916442111,CA
2916442112,2916442623,US
2916442624,2916442879,CA
@@ -55285,11 +57961,7 @@
2916443904,2916444159,CA
2916444160,2916444927,US
2916444928,2916445951,CA
-2916445952,2916447231,US
-2916447232,2916448031,CA
-2916448032,2916448063,US
-2916448064,2916448255,CA
-2916448256,2916449279,US
+2916445952,2916449279,US
2916449280,2916450303,CA
2916450304,2916515839,US
2916548608,2916581375,US
@@ -55330,6 +58002,7 @@
2917580800,2917597439,US
2917597440,2917597695,GB
2917597696,2917621759,US
+2917621760,2917629951,CA
2917629952,2917646335,US
2917662720,2917663231,US
2917663232,2917663487,CA
@@ -55341,33 +58014,31 @@
2917675264,2917675775,CA
2917675776,2917676031,US
2917676032,2917677055,CA
-2917677056,2917677567,US
-2917677568,2917678335,CA
-2917678336,2917680895,US
+2917677056,2917680895,US
2917680896,2917681407,CA
2917681408,2917681919,US
2917681920,2917682175,CA
-2917682176,2917685247,US
-2917685248,2917686015,CA
+2917682176,2917682431,US
+2917682432,2917683455,CA
+2917683456,2917685503,US
+2917685504,2917686015,CA
2917686016,2917690367,US
2917690368,2917690879,CA
2917690880,2917693183,US
2917693184,2917693951,CA
2917693952,2917695231,US
2917695232,2917695487,CA
-2917695488,2917701119,US
-2917701120,2917701375,CA
-2917701376,2917702399,US
-2917702400,2917707519,CA
-2917707520,2917711871,US
-2917711872,2917714431,CA
+2917695488,2917695743,US
+2917695744,2917696255,CA
+2917696256,2917702399,US
+2917702400,2917707007,CA
+2917707008,2917714175,US
+2917714176,2917714431,CA
2917714432,2917718527,US
2917718528,2917719039,CA
-2917719040,2917719295,US
-2917719296,2917719551,CA
-2917719552,2917722367,US
-2917722368,2917722879,CA
-2917722880,2917842175,US
+2917719040,2917722367,US
+2917722368,2917722623,CA
+2917722624,2917842175,US
2917842176,2917842431,CA
2917842432,2918055935,US
2918055936,2918121471,CA
@@ -55381,7 +58052,9 @@
2918260736,2918264831,CA
2918264832,2918277119,US
2918277120,2918281215,CA
-2918281216,2918286879,US
+2918281216,2918286335,US
+2918286336,2918286719,CA
+2918286720,2918286879,US
2918286880,2918286895,GB
2918286896,2918287103,US
2918287104,2918287359,CR
@@ -55410,12 +58083,22 @@
2918612992,2918760447,US
2918760448,2918776831,CA
2918776832,2918813695,US
-2918825984,2918838271,US
+2918825984,2918828031,US
+2918828032,2918828543,UA
+2918828544,2918829055,ES
+2918829056,2918829183,US
+2918829184,2918829311,PL
+2918829312,2918829439,CA
+2918829440,2918829567,JM
+2918829568,2918829695,GR
+2918829696,2918829823,DE
+2918829824,2918830079,CN
+2918830080,2918834175,CA
+2918834176,2918838271,US
2918838272,2918875135,CA
2918875136,2918973439,US
2918973440,2918989823,CA
-2919006208,2919071743,US
-2919170048,2919174143,US
+2919006208,2919174143,US
2919174144,2919178239,CA
2919178240,2919186431,US
2919186432,2919190527,CA
@@ -55427,30 +58110,17 @@
2921496896,2921496903,IN
2921496904,2921496967,US
2921496968,2921496975,IN
-2921496976,2921497375,US
-2921497376,2921497407,IN
-2921497408,2921497415,US
+2921496976,2921497415,US
2921497416,2921497423,IN
2921497424,2921497471,US
2921497472,2921497599,IN
2921497600,2921503607,US
2921503608,2921503615,GB
2921503616,2921503695,US
-2921503696,2921503703,GB
-2921503704,2921508095,US
-2921508096,2921508103,IN
-2921508104,2921508319,US
-2921508320,2921508351,IN
-2921508352,2921508639,US
-2921508640,2921508671,IN
-2921508672,2921508679,US
-2921508680,2921508719,IN
+2921503696,2921503703,ID
+2921503704,2921508719,US
2921508720,2921508727,SE
-2921508728,2921511351,US
-2921511352,2921511359,IN
-2921511360,2921511743,US
-2921511744,2921511759,BE
-2921511760,2921512703,US
+2921508728,2921512703,US
2921512704,2921512959,CA
2921512960,2921562111,US
2921562112,2921594879,CA
@@ -55458,7 +58128,55 @@
2925002752,2925527039,CA
2925527040,2926575615,US
2926575616,2927099903,CA
-2927099904,2928218127,US
+2927099904,2928173103,US
+2928173104,2928173119,PH
+2928173120,2928173151,US
+2928173152,2928173159,RU
+2928173160,2928173343,US
+2928173344,2928173351,NL
+2928173352,2928173519,US
+2928173520,2928173527,GB
+2928173528,2928173551,US
+2928173552,2928173559,CA
+2928173560,2928173679,US
+2928173680,2928173695,JP
+2928173696,2928173711,US
+2928173712,2928173727,JP
+2928173728,2928173775,US
+2928173776,2928173783,IE
+2928173784,2928173855,US
+2928173856,2928173871,AU
+2928173872,2928173903,US
+2928173904,2928173919,NZ
+2928173920,2928173959,US
+2928173960,2928173967,CA
+2928173968,2928174095,US
+2928174096,2928174103,CA
+2928174104,2928174575,US
+2928174576,2928174583,AU
+2928174584,2928174911,US
+2928174912,2928174919,AU
+2928174920,2928175055,US
+2928175056,2928175063,MX
+2928175064,2928175791,US
+2928175792,2928175799,CA
+2928175800,2928175839,US
+2928175840,2928175847,SE
+2928175848,2928175967,US
+2928175968,2928175975,ZA
+2928175976,2928176223,US
+2928176224,2928176231,JP
+2928176232,2928176383,US
+2928176384,2928176391,ES
+2928176392,2928176575,US
+2928176576,2928176591,MQ
+2928176592,2928176783,US
+2928176784,2928176799,MX
+2928176800,2928176895,US
+2928176896,2928176903,CA
+2928176904,2928177151,US
+2928177152,2928181247,CA
+2928181248,2928218127,US
2928218128,2928218143,CA
2928218144,2928218623,US
2928218624,2928219135,CA
@@ -55746,7 +58464,9 @@
2928279024,2928279551,CA
2928279552,2928312319,US
2928312320,2928316415,CA
-2928316416,2928321311,US
+2928316416,2928318719,US
+2928318720,2928318975,DO
+2928318976,2928321311,US
2928321312,2928321327,GB
2928321328,2928321343,CN
2928321344,2928323135,US
@@ -56387,6 +59107,7 @@
2948135936,2948136959,IN
2948136960,2948595711,CN
2948595712,2952790015,KR
+2969567232,2971664383,BR
2986344448,2987393023,DE
2987393024,2987397119,IM
2987397120,2987401215,LV
@@ -56400,7 +59121,9 @@
2987433216,2987433235,KZ
2987433236,2987433239,RU
2987433240,2987433287,KZ
-2987433288,2987433983,RU
+2987433288,2987433295,RU
+2987433296,2987433331,KZ
+2987433332,2987433983,RU
2987433984,2987438079,FR
2987438080,2987442175,FI
2987442176,2987446271,IE
@@ -56435,6 +59158,7 @@
2987548672,2987552767,RU
2987552768,2987556863,GB
2987556864,2987560959,NL
+2987560960,2987565055,DE
2987565056,2987569151,AT
2987569152,2987573247,FR
2987573248,2987577343,TR
@@ -56450,8 +59174,8 @@
2987585848,2987585855,SE
2987585856,2987585863,RU
2987585864,2987585871,GB
-2987585872,2987585879,IT
-2987585880,2987585887,FR
+2987585872,2987585879,MX
+2987585880,2987585887,BR
2987585888,2987585895,PL
2987585896,2987589631,DE
2987589632,2987593727,FR
@@ -56472,8 +59196,8 @@
2987655168,2987658367,DE
2987658368,2987658383,AT
2987658384,2987659263,DE
-2987659264,2987659519,BA
-2987659520,2987661311,SI
+2987659264,2987660799,BA
+2987660800,2987661311,SI
2987661312,2987663359,GB
2987663360,2987665407,IT
2987665408,2987667455,RU
@@ -56610,9 +59334,9 @@
2988441888,2988441895,FR
2988441896,2988441903,PL
2988441904,2988441911,IT
-2988441912,2988441983,FR
-2988441984,2988441999,NL
-2988442000,2988442003,FR
+2988441912,2988441991,FR
+2988441992,2988441995,ES
+2988441996,2988442003,FR
2988442004,2988442007,ES
2988442008,2988442047,FR
2988442048,2988442063,GB
@@ -56635,7 +59359,8 @@
2988442920,2988442923,LT
2988442924,2988442927,GB
2988442928,2988442975,FR
-2988442976,2988443023,GB
+2988442976,2988443007,GB
+2988443008,2988443023,PT
2988443024,2988443027,FR
2988443028,2988443031,BE
2988443032,2988443035,GB
@@ -56661,7 +59386,11 @@
2988443564,2988443567,PL
2988443568,2988443583,FR
2988443584,2988443647,GB
-2988443648,2988444167,FR
+2988443648,2988443903,FR
+2988443904,2988443919,BE
+2988443920,2988443923,FR
+2988443924,2988443927,PL
+2988443928,2988444167,FR
2988444168,2988444171,CZ
2988444172,2988444199,FR
2988444200,2988444203,DE
@@ -56691,7 +59420,9 @@
2988446272,2988446275,IT
2988446276,2988446287,FR
2988446288,2988446303,GB
-2988446304,2988446323,FR
+2988446304,2988446307,FR
+2988446308,2988446319,PL
+2988446320,2988446323,FR
2988446324,2988446327,LT
2988446328,2988446335,NL
2988446336,2988446399,PL
@@ -56716,10 +59447,11 @@
2988448256,2988448511,DE
2988448512,2988448519,FR
2988448520,2988448543,PL
-2988448544,2988448559,FR
+2988448544,2988448551,FR
+2988448552,2988448559,PL
2988448560,2988448563,DE
-2988448564,2988448567,ES
-2988448568,2988448607,FR
+2988448564,2988448575,ES
+2988448576,2988448607,FR
2988448608,2988448639,ES
2988448640,2988448671,GB
2988448672,2988448691,IT
@@ -56748,7 +59480,11 @@
2988449136,2988449151,FR
2988449152,2988449279,PL
2988449280,2988449535,GB
-2988449536,2988449663,PL
+2988449536,2988449579,FR
+2988449580,2988449583,PL
+2988449584,2988449631,FR
+2988449632,2988449647,ES
+2988449648,2988449663,GB
2988449664,2988449695,DE
2988449696,2988449727,IT
2988449728,2988449743,BE
@@ -56759,9 +59495,12 @@
2988453888,2988457983,GB
2988457984,2988457987,FR
2988457988,2988457991,PL
-2988457992,2988458031,FR
+2988457992,2988457995,CH
+2988457996,2988457999,FR
+2988458000,2988458015,GB
+2988458016,2988458031,FR
2988458032,2988458047,IT
-2988458048,2988458055,FR
+2988458048,2988458055,PL
2988458056,2988458063,CH
2988458064,2988458067,ES
2988458068,2988458075,FR
@@ -56831,7 +59570,20 @@
2988459736,2988459743,PL
2988459744,2988459747,ES
2988459748,2988459751,PL
-2988459752,2988460031,FR
+2988459752,2988459759,FR
+2988459760,2988459767,GB
+2988459768,2988459771,NL
+2988459772,2988459775,GB
+2988459776,2988459839,FR
+2988459840,2988459855,GB
+2988459856,2988459863,FR
+2988459864,2988459867,ES
+2988459868,2988459871,GB
+2988459872,2988459887,FR
+2988459888,2988459895,PL
+2988459896,2988459967,FR
+2988459968,2988459999,ES
+2988460000,2988460031,FR
2988460032,2988460063,DE
2988460064,2988460095,FR
2988460096,2988460103,ES
@@ -56843,7 +59595,9 @@
2988460128,2988460131,PL
2988460132,2988460135,CZ
2988460136,2988460143,FR
-2988460144,2988460159,ES
+2988460144,2988460147,GB
+2988460148,2988460151,FR
+2988460152,2988460159,ES
2988460160,2988460191,GB
2988460192,2988460195,FR
2988460196,2988460199,CZ
@@ -56867,7 +59621,9 @@
2988460552,2988460575,PL
2988460576,2988460591,PT
2988460592,2988460607,GB
-2988460608,2988460679,FR
+2988460608,2988460615,IT
+2988460616,2988460623,PL
+2988460624,2988460679,FR
2988460680,2988460683,GB
2988460684,2988460687,DE
2988460688,2988460719,FR
@@ -56876,18 +59632,21 @@
2988460760,2988460763,PT
2988460764,2988460767,FR
2988460768,2988460799,PL
-2988460800,2988460863,CH
+2988460800,2988460863,DE
2988460864,2988460927,FR
2988460928,2988460931,DE
2988460932,2988460943,PL
2988460944,2988460959,DE
2988460960,2988460991,GB
-2988460992,2988461055,FR
-2988461056,2988461119,IE
+2988460992,2988461087,FR
+2988461088,2988461103,PL
+2988461104,2988461119,FR
2988461120,2988461151,NL
2988461152,2988461247,GB
2988461248,2988461255,FR
-2988461256,2988461295,IT
+2988461256,2988461263,GB
+2988461264,2988461279,PL
+2988461280,2988461295,IT
2988461296,2988461299,PL
2988461300,2988461307,FR
2988461308,2988461311,PL
@@ -56947,8 +59706,8 @@
2988461904,2988461911,ES
2988461912,2988461935,FR
2988461936,2988461951,GB
-2988461952,2988462079,PL
-2988462080,2988462095,CZ
+2988461952,2988462087,PL
+2988462088,2988462095,DE
2988462096,2988462127,FR
2988462128,2988462131,ES
2988462132,2988462143,FR
@@ -56976,7 +59735,8 @@
2988462604,2988462607,BE
2988462608,2988462735,FR
2988462736,2988462743,IT
-2988462744,2988462767,FR
+2988462744,2988462751,FR
+2988462752,2988462767,PL
2988462768,2988462775,GB
2988462776,2988462779,PL
2988462780,2988462783,FR
@@ -57005,7 +59765,8 @@
2988463228,2988463231,CH
2988463232,2988463263,NL
2988463264,2988463279,PL
-2988463280,2988463315,FR
+2988463280,2988463283,GB
+2988463284,2988463315,FR
2988463316,2988463319,DE
2988463320,2988463323,FR
2988463324,2988463331,DE
@@ -57041,7 +59802,11 @@
2988463952,2988463999,FR
2988464000,2988464007,IE
2988464008,2988464015,LT
-2988464016,2988464055,FR
+2988464016,2988464019,PT
+2988464020,2988464023,IT
+2988464024,2988464027,GB
+2988464028,2988464031,PL
+2988464032,2988464055,FR
2988464056,2988464059,ES
2988464060,2988464063,FR
2988464064,2988464095,PL
@@ -57056,7 +59821,8 @@
2988464512,2988464519,PT
2988464520,2988464527,FR
2988464528,2988464543,DE
-2988464544,2988464575,IT
+2988464544,2988464551,FR
+2988464552,2988464575,ES
2988464576,2988464607,FR
2988464608,2988464611,DE
2988464612,2988464615,PL
@@ -57088,14 +59854,19 @@
2988465296,2988465299,IT
2988465300,2988465343,FR
2988465344,2988465363,DE
-2988465364,2988465371,PL
-2988465372,2988465375,FR
+2988465364,2988465367,PL
+2988465368,2988465375,FR
2988465376,2988465391,IT
-2988465392,2988465407,FR
+2988465392,2988465395,ES
+2988465396,2988465399,GB
+2988465400,2988465403,PT
+2988465404,2988465407,DE
2988465408,2988465423,CH
2988465424,2988465439,PT
2988465440,2988465471,GB
-2988465472,2988465503,FR
+2988465472,2988465479,FR
+2988465480,2988465483,NL
+2988465484,2988465503,FR
2988465504,2988465507,DE
2988465508,2988465511,PL
2988465512,2988465515,PT
@@ -57106,7 +59877,8 @@
2988465532,2988465535,GB
2988465536,2988465539,FR
2988465540,2988465543,GB
-2988465544,2988465551,FR
+2988465544,2988465547,CZ
+2988465548,2988465551,IT
2988465552,2988465559,ES
2988465560,2988465567,GB
2988465568,2988465571,ES
@@ -57183,7 +59955,10 @@
2988507640,2988507643,FR
2988507644,2988507647,IT
2988507648,2988507711,DE
-2988507712,2988507775,IT
+2988507712,2988507743,FR
+2988507744,2988507759,IE
+2988507760,2988507767,FR
+2988507768,2988507775,PL
2988507776,2988507839,IE
2988507840,2988507855,FR
2988507856,2988507859,BE
@@ -57207,7 +59982,10 @@
2988507980,2988507983,DE
2988507984,2988507999,FR
2988508000,2988508031,NL
-2988508032,2988508063,DE
+2988508032,2988508039,PL
+2988508040,2988508047,FR
+2988508048,2988508055,GB
+2988508056,2988508063,ES
2988508064,2988508067,FR
2988508068,2988508071,PL
2988508072,2988508079,FR
@@ -57219,11 +59997,15 @@
2988508144,2988508151,FR
2988508152,2988508155,ES
2988508156,2988508159,PL
-2988508160,2988508219,FR
+2988508160,2988508207,FR
+2988508208,2988508211,DE
+2988508212,2988508215,PL
+2988508216,2988508219,FR
2988508220,2988508223,DE
2988508224,2988508287,FR
2988508288,2988508303,PL
-2988508304,2988508315,FR
+2988508304,2988508307,CZ
+2988508308,2988508315,FR
2988508316,2988508319,ES
2988508320,2988508343,FR
2988508344,2988508367,ES
@@ -57268,7 +60050,7 @@
2988509024,2988509055,ES
2988509056,2988509119,IT
2988509120,2988509151,GB
-2988509152,2988509183,ES
+2988509152,2988509183,PL
2988509184,2988509279,FR
2988509280,2988509283,DE
2988509284,2988509287,IT
@@ -57330,7 +60112,8 @@
2988509920,2988509931,FR
2988509932,2988509951,PL
2988509952,2988509955,IT
-2988509956,2988509963,DE
+2988509956,2988509959,PL
+2988509960,2988509963,FR
2988509964,2988509967,GB
2988509968,2988509983,ES
2988509984,2988509995,FR
@@ -57339,7 +60122,10 @@
2988510016,2988510023,ES
2988510024,2988510031,FR
2988510032,2988510079,PL
-2988510080,2988510111,NL
+2988510080,2988510095,ES
+2988510096,2988510099,FR
+2988510100,2988510103,GB
+2988510104,2988510111,BE
2988510112,2988510143,CZ
2988510144,2988510175,NL
2988510176,2988510207,ES
@@ -57353,7 +60139,7 @@
2988510288,2988510303,PL
2988510304,2988510307,ES
2988510308,2988510311,FR
-2988510312,2988510319,BE
+2988510312,2988510319,GB
2988510320,2988510323,FR
2988510324,2988510327,GB
2988510328,2988510399,FR
@@ -57380,7 +60166,8 @@
2988511084,2988511087,PL
2988511088,2988511103,FR
2988511104,2988511167,PL
-2988511168,2988511183,FR
+2988511168,2988511175,IE
+2988511176,2988511183,FR
2988511184,2988511191,GB
2988511192,2988511487,FR
2988511488,2988511551,PL
@@ -57400,9 +60187,7 @@
2988511700,2988511703,IT
2988511704,2988511711,PL
2988511712,2988511719,DE
-2988511720,2988511723,FR
-2988511724,2988511727,GB
-2988511728,2988511735,FR
+2988511720,2988511735,FR
2988511736,2988511739,DE
2988511740,2988511743,FR
2988511744,2988511747,PL
@@ -57437,9 +60222,12 @@
2988512152,2988512155,ES
2988512156,2988512159,FR
2988512160,2988512191,GB
-2988512192,2988512199,FR
+2988512192,2988512195,FR
+2988512196,2988512199,DE
2988512200,2988512207,ES
-2988512208,2988512239,FR
+2988512208,2988512223,FR
+2988512224,2988512227,BE
+2988512228,2988512239,FR
2988512240,2988512247,LT
2988512248,2988512251,GB
2988512252,2988512255,ES
@@ -57489,16 +60277,21 @@
2988512832,2988512835,FR
2988512836,2988512839,ES
2988512840,2988512847,DE
-2988512848,2988512879,FR
+2988512848,2988512851,ES
+2988512852,2988512855,DE
+2988512856,2988512879,FR
2988512880,2988512895,DE
2988512896,2988512899,PL
-2988512900,2988512907,GB
+2988512900,2988512903,GB
+2988512904,2988512907,ES
2988512908,2988512911,LT
2988512912,2988512943,FR
2988512944,2988512951,GB
2988512952,2988512955,FR
2988512956,2988512959,LT
-2988512960,2988512975,BE
+2988512960,2988512967,ES
+2988512968,2988512971,GB
+2988512972,2988512975,NL
2988512976,2988512995,FR
2988512996,2988512999,GB
2988513000,2988513003,FR
@@ -57515,7 +60308,9 @@
2988513208,2988513219,FR
2988513220,2988513223,CZ
2988513224,2988513227,NL
-2988513228,2988513271,FR
+2988513228,2988513235,FR
+2988513236,2988513239,ES
+2988513240,2988513271,FR
2988513272,2988513275,DE
2988513276,2988513279,CH
2988513280,2988513283,FR
@@ -57523,14 +60318,14 @@
2988513288,2988513307,FR
2988513308,2988513311,PL
2988513312,2988513327,PT
-2988513328,2988513331,ES
+2988513328,2988513331,PL
2988513332,2988513335,FR
2988513336,2988513343,GB
-2988513344,2988513351,ES
+2988513344,2988513351,FR
2988513352,2988513359,IT
2988513360,2988513375,GB
-2988513376,2988513391,IT
-2988513392,2988513407,GB
+2988513376,2988513383,FR
+2988513384,2988513407,GB
2988513408,2988513471,PL
2988513472,2988513503,FR
2988513504,2988513507,CH
@@ -57570,8 +60365,7 @@
2988514024,2988514027,PT
2988514028,2988514111,FR
2988514112,2988514115,DE
-2988514116,2988514119,FR
-2988514120,2988514127,PT
+2988514116,2988514127,FR
2988514128,2988514131,IE
2988514132,2988514139,IT
2988514140,2988514143,PL
@@ -57615,7 +60409,7 @@
2988514736,2988514739,FR
2988514740,2988514743,ES
2988514744,2988514747,BE
-2988514748,2988514751,IT
+2988514748,2988514751,GB
2988514752,2988514815,FI
2988514816,2988514823,FR
2988514824,2988514827,PL
@@ -57636,11 +60430,13 @@
2988515328,2988517375,DE
2988517376,2988519423,FR
2988519424,2988521471,PL
-2988521472,2988539935,FR
+2988521472,2988535807,FR
+2988535808,2988537855,ES
+2988537856,2988539935,FR
2988539936,2988539967,GB
2988539968,2988539971,ES
2988539972,2988539975,IT
-2988539976,2988539983,DE
+2988539976,2988539983,FR
2988539984,2988540003,PL
2988540004,2988540007,CZ
2988540008,2988540023,FR
@@ -57728,13 +60524,15 @@
2988541244,2988541247,GB
2988541248,2988541279,FR
2988541280,2988541311,NL
-2988541312,2988541327,DE
+2988541312,2988541315,DE
+2988541316,2988541319,CH
+2988541320,2988541327,DE
2988541328,2988541335,PL
2988541336,2988541375,FR
2988541376,2988541391,BE
2988541392,2988541407,FR
2988541408,2988541423,BE
-2988541424,2988541439,PL
+2988541424,2988541439,DE
2988541440,2988541443,IT
2988541444,2988541463,FR
2988541464,2988541467,ES
@@ -57745,7 +60543,7 @@
2988541552,2988541583,FR
2988541584,2988541587,ES
2988541588,2988541591,FR
-2988541592,2988541599,PL
+2988541592,2988541599,GB
2988541600,2988541603,FR
2988541604,2988541607,NL
2988541608,2988541611,GB
@@ -57781,9 +60579,9 @@
2988541824,2988541855,LT
2988541856,2988541887,IE
2988541888,2988541895,DE
-2988541896,2988541899,FR
+2988541896,2988541899,PL
2988541900,2988541903,BE
-2988541904,2988541907,DE
+2988541904,2988541907,CZ
2988541908,2988541911,GB
2988541912,2988541935,PL
2988541936,2988541939,FR
@@ -57799,8 +60597,9 @@
2988542020,2988542023,FR
2988542024,2988542027,NL
2988542028,2988542031,PL
-2988542032,2988542055,FR
-2988542056,2988542063,BE
+2988542032,2988542047,FR
+2988542048,2988542055,PL
+2988542056,2988542063,FR
2988542064,2988542067,GB
2988542068,2988542071,ES
2988542072,2988542367,FR
@@ -57808,7 +60607,8 @@
2988542400,2988542407,FR
2988542408,2988542415,PL
2988542416,2988542431,FR
-2988542432,2988542443,ES
+2988542432,2988542439,PL
+2988542440,2988542443,ES
2988542444,2988542447,FR
2988542448,2988542455,PL
2988542456,2988542459,FR
@@ -57818,14 +60618,14 @@
2988542528,2988542535,DE
2988542536,2988542539,NL
2988542540,2988542543,LT
-2988542544,2988542551,NL
+2988542544,2988542551,DE
2988542552,2988542559,ES
2988542560,2988542591,FR
2988542592,2988542595,PT
2988542596,2988542599,FI
2988542600,2988542603,GB
-2988542604,2988542615,FR
-2988542616,2988542623,DE
+2988542604,2988542611,FR
+2988542612,2988542623,DE
2988542624,2988542655,FR
2988542656,2988542719,BE
2988542720,2988542783,CH
@@ -57838,7 +60638,11 @@
2988542964,2988542967,CH
2988542968,2988542971,NL
2988542972,2988542975,DE
-2988542976,2988543039,FR
+2988542976,2988543007,FR
+2988543008,2988543011,PL
+2988543012,2988543015,GB
+2988543016,2988543023,CH
+2988543024,2988543039,DE
2988543040,2988543043,CZ
2988543044,2988543047,ES
2988543048,2988543051,IE
@@ -57915,13 +60719,418 @@
2988544800,2988544831,FI
2988544832,2988544863,FR
2988544864,2988544895,PL
-2988544896,2988572671,FR
+2988544896,2988544927,FR
+2988544928,2988544931,DE
+2988544932,2988544935,FR
+2988544936,2988544943,IT
+2988544944,2988544951,PL
+2988544952,2988544959,GB
+2988544960,2988544979,ES
+2988544980,2988544983,FR
+2988544984,2988544991,IE
+2988544992,2988544995,PL
+2988544996,2988544999,FR
+2988545000,2988545003,DE
+2988545004,2988545007,ES
+2988545008,2988545011,FR
+2988545012,2988545019,DE
+2988545020,2988545031,FR
+2988545032,2988545039,PL
+2988545040,2988545047,ES
+2988545048,2988545051,FR
+2988545052,2988545055,PL
+2988545056,2988545063,FR
+2988545064,2988545067,GB
+2988545068,2988545071,ES
+2988545072,2988545151,FR
+2988545152,2988545167,GB
+2988545168,2988545171,DE
+2988545172,2988545175,FR
+2988545176,2988545179,GB
+2988545180,2988545183,PL
+2988545184,2988545215,FR
+2988545216,2988545247,ES
+2988545248,2988545287,PL
+2988545288,2988545291,FR
+2988545292,2988545295,DE
+2988545296,2988545311,FR
+2988545312,2988545327,CH
+2988545328,2988545335,IT
+2988545336,2988545343,DE
+2988545344,2988545407,FR
+2988545408,2988545439,IE
+2988545440,2988545471,FR
+2988545472,2988545503,ES
+2988545504,2988545507,FR
+2988545508,2988545511,DE
+2988545512,2988545515,IT
+2988545516,2988545531,PL
+2988545532,2988545535,FR
+2988545536,2988545567,BE
+2988545568,2988545663,FR
+2988545664,2988545695,ES
+2988545696,2988545727,DE
+2988545728,2988545791,FR
+2988545792,2988545807,DE
+2988545808,2988545815,FR
+2988545816,2988545823,NL
+2988545824,2988545831,FR
+2988545832,2988545835,GB
+2988545836,2988545839,DE
+2988545840,2988545855,FR
+2988545856,2988545859,ES
+2988545860,2988545867,FR
+2988545868,2988545871,PL
+2988545872,2988545919,FR
+2988545920,2988545923,GB
+2988545924,2988545927,PL
+2988545928,2988545931,BE
+2988545932,2988545943,FR
+2988545944,2988545967,NL
+2988545968,2988545983,GB
+2988545984,2988545987,FR
+2988545988,2988545991,PL
+2988545992,2988545995,LT
+2988545996,2988545999,FI
+2988546000,2988546015,GB
+2988546016,2988546031,FR
+2988546032,2988546035,ES
+2988546036,2988546039,BE
+2988546040,2988546043,FR
+2988546044,2988546047,ES
+2988546048,2988546111,PL
+2988546112,2988546115,ES
+2988546116,2988546119,FR
+2988546120,2988546123,IE
+2988546124,2988546127,ES
+2988546128,2988546143,GB
+2988546144,2988546159,PL
+2988546160,2988546175,ES
+2988546176,2988546239,GB
+2988546240,2988546271,LT
+2988546272,2988546279,IT
+2988546280,2988546283,GB
+2988546284,2988546287,BE
+2988546288,2988546291,GB
+2988546292,2988546295,ES
+2988546296,2988546303,PL
+2988546304,2988546307,ES
+2988546308,2988546311,NL
+2988546312,2988546315,IT
+2988546316,2988546319,FR
+2988546320,2988546327,CH
+2988546328,2988546335,ES
+2988546336,2988546351,PT
+2988546352,2988546367,ES
+2988546368,2988546431,FR
+2988546432,2988546463,DE
+2988546464,2988546527,FR
+2988546528,2988546535,BE
+2988546536,2988546539,IE
+2988546540,2988546547,ES
+2988546548,2988546559,FR
+2988546560,2988546567,NL
+2988546568,2988546575,FR
+2988546576,2988546579,ES
+2988546580,2988546583,GB
+2988546584,2988546591,FR
+2988546592,2988546599,DE
+2988546600,2988546603,PT
+2988546604,2988546615,GB
+2988546616,2988546619,FI
+2988546620,2988546623,FR
+2988546624,2988546687,FI
+2988546688,2988546695,PL
+2988546696,2988546699,FR
+2988546700,2988546703,IT
+2988546704,2988546727,FR
+2988546728,2988546735,ES
+2988546736,2988546751,FR
+2988546752,2988546783,ES
+2988546784,2988546831,FR
+2988546832,2988546835,DE
+2988546836,2988546839,ES
+2988546840,2988546847,IE
+2988546848,2988546879,FR
+2988546880,2988546947,ES
+2988546948,2988546951,DE
+2988546952,2988546959,FR
+2988546960,2988546967,DE
+2988546968,2988546971,FR
+2988546972,2988546975,BE
+2988546976,2988546991,FI
+2988546992,2988546995,DE
+2988546996,2988546999,ES
+2988547000,2988547003,IT
+2988547004,2988547007,ES
+2988547008,2988547011,GB
+2988547012,2988547015,FR
+2988547016,2988547019,NL
+2988547020,2988547023,ES
+2988547024,2988547039,FR
+2988547040,2988547047,ES
+2988547048,2988547055,FR
+2988547056,2988547059,IT
+2988547060,2988547063,FR
+2988547064,2988547067,GB
+2988547068,2988547071,PL
+2988547072,2988547087,GB
+2988547088,2988547095,NL
+2988547096,2988547099,PL
+2988547100,2988547103,IE
+2988547104,2988547111,DE
+2988547112,2988547115,GB
+2988547116,2988547123,FR
+2988547124,2988547127,IT
+2988547128,2988547135,FR
+2988547136,2988547167,IT
+2988547168,2988547199,BE
+2988547200,2988547207,IE
+2988547208,2988547211,FR
+2988547212,2988547215,DE
+2988547216,2988547219,IT
+2988547220,2988547223,FR
+2988547224,2988547227,ES
+2988547228,2988547231,PT
+2988547232,2988547239,FR
+2988547240,2988547247,PL
+2988547248,2988547255,NL
+2988547256,2988547271,FR
+2988547272,2988547279,ES
+2988547280,2988547295,FR
+2988547296,2988547303,DE
+2988547304,2988547311,FR
+2988547312,2988547327,PL
+2988547328,2988547423,FR
+2988547424,2988547431,GB
+2988547432,2988547435,ES
+2988547436,2988547443,PL
+2988547444,2988547447,DE
+2988547448,2988547455,FR
+2988547456,2988547471,DE
+2988547472,2988547475,NL
+2988547476,2988547479,GB
+2988547480,2988547487,FR
+2988547488,2988547519,ES
+2988547520,2988547523,PL
+2988547524,2988547527,CZ
+2988547528,2988547531,IT
+2988547532,2988547535,ES
+2988547536,2988547539,FR
+2988547540,2988547543,DE
+2988547544,2988547547,IT
+2988547548,2988547551,PL
+2988547552,2988547567,FR
+2988547568,2988547583,DE
+2988547584,2988547599,ES
+2988547600,2988547615,FR
+2988547616,2988547647,PL
+2988547648,2988547655,FR
+2988547656,2988547663,PL
+2988547664,2988547679,IE
+2988547680,2988547711,CH
+2988547712,2988547727,PL
+2988547728,2988547751,FR
+2988547752,2988547775,DE
+2988547776,2988547807,ES
+2988547808,2988547871,FR
+2988547872,2988547903,GB
+2988547904,2988547935,FR
+2988547936,2988547967,LT
+2988547968,2988548047,FR
+2988548048,2988548055,ES
+2988548056,2988548059,PL
+2988548060,2988548063,DE
+2988548064,2988548095,ES
+2988548096,2988556287,FR
+2988556288,2988556295,PL
+2988556296,2988556303,FR
+2988556304,2988556311,PL
+2988556312,2988556319,FR
+2988556320,2988556351,GB
+2988556352,2988556359,DE
+2988556360,2988556383,FR
+2988556384,2988556415,DE
+2988556416,2988556447,FR
+2988556448,2988556451,NL
+2988556452,2988556479,FR
+2988556480,2988556495,IT
+2988556496,2988556511,FR
+2988556512,2988556543,DE
+2988556544,2988556799,FR
+2988556800,2988556839,DE
+2988556840,2988556847,FR
+2988556848,2988556855,ES
+2988556856,2988556863,GB
+2988556864,2988556879,FR
+2988556880,2988556883,ES
+2988556884,2988556887,DE
+2988556888,2988556895,FR
+2988556896,2988556911,PL
+2988556912,2988556919,NL
+2988556920,2988556959,PL
+2988556960,2988556963,ES
+2988556964,2988556967,FR
+2988556968,2988556975,BE
+2988556976,2988556979,FI
+2988556980,2988557023,FR
+2988557024,2988557039,IE
+2988557040,2988557047,FR
+2988557048,2988557055,PL
+2988557056,2988557071,FR
+2988557072,2988557075,PL
+2988557076,2988557079,FR
+2988557080,2988557087,FI
+2988557088,2988557119,DE
+2988557120,2988557151,NL
+2988557152,2988557215,FR
+2988557216,2988557247,BE
+2988557248,2988557251,FR
+2988557252,2988557255,ES
+2988557256,2988557279,GB
+2988557280,2988557295,ES
+2988557296,2988557299,BE
+2988557300,2988557303,PL
+2988557304,2988557311,CZ
+2988557312,2988557327,DE
+2988557328,2988557343,ES
+2988557344,2988557379,FR
+2988557380,2988557383,ES
+2988557384,2988557387,GB
+2988557388,2988557391,ES
+2988557392,2988557395,FR
+2988557396,2988557399,PL
+2988557400,2988557407,DE
+2988557408,2988557427,ES
+2988557428,2988557431,DE
+2988557432,2988557435,PL
+2988557436,2988557439,FR
+2988557440,2988557471,GB
+2988557472,2988557487,PL
+2988557488,2988557495,DE
+2988557496,2988557539,PL
+2988557540,2988557543,IE
+2988557544,2988557599,FR
+2988557600,2988557631,GB
+2988557632,2988557639,FR
+2988557640,2988557643,IE
+2988557644,2988557647,GB
+2988557648,2988557651,NL
+2988557652,2988557663,FR
+2988557664,2988557695,PL
+2988557696,2988557727,FR
+2988557728,2988557759,PL
+2988557760,2988557763,FR
+2988557764,2988557767,GB
+2988557768,2988557771,PL
+2988557772,2988557823,FR
+2988557824,2988557951,DE
+2988557952,2988557983,LT
+2988557984,2988557999,GB
+2988558000,2988558015,IE
+2988558016,2988558047,FR
+2988558048,2988558063,PL
+2988558064,2988558071,IT
+2988558072,2988558075,DE
+2988558076,2988558079,PL
+2988558080,2988558127,FR
+2988558128,2988558135,PL
+2988558136,2988558139,GB
+2988558140,2988558143,DE
+2988558144,2988558207,PL
+2988558208,2988558271,ES
+2988558272,2988558335,FI
+2988558336,2988558399,IE
+2988558400,2988558463,LT
+2988558464,2988558527,NL
+2988558528,2988558591,PL
+2988558592,2988558655,GB
+2988558656,2988558767,FR
+2988558768,2988558783,CH
+2988558784,2988558831,FR
+2988558832,2988558847,IT
+2988558848,2988558883,FR
+2988558884,2988558887,BE
+2988558888,2988558891,GB
+2988558892,2988558895,NL
+2988558896,2988558903,FR
+2988558904,2988558907,NL
+2988558908,2988558935,GB
+2988558936,2988558939,PL
+2988558940,2988558943,GB
+2988558944,2988558975,FR
+2988558976,2988559007,GB
+2988559008,2988559011,BE
+2988559012,2988559015,PL
+2988559016,2988559071,FR
+2988559072,2988559103,ES
+2988559104,2988559135,PL
+2988559136,2988559139,FR
+2988559140,2988559151,PL
+2988559152,2988559231,FR
+2988559232,2988559247,DE
+2988559248,2988559255,FR
+2988559256,2988559259,DE
+2988559260,2988559263,GB
+2988559264,2988559295,LT
+2988559296,2988559359,PL
+2988559360,2988559631,FR
+2988559632,2988559663,IE
+2988559664,2988559679,ES
+2988559680,2988559691,FR
+2988559692,2988559695,PL
+2988559696,2988559699,DE
+2988559700,2988559703,PL
+2988559704,2988559707,DE
+2988559708,2988559711,PL
+2988559712,2988559719,FR
+2988559720,2988559727,DE
+2988559728,2988559731,FR
+2988559732,2988559735,PL
+2988559736,2988559743,GB
+2988559744,2988559871,FR
+2988559872,2988560383,IT
+2988560384,2988560575,FR
+2988560576,2988560591,ES
+2988560592,2988560595,DE
+2988560596,2988560599,IT
+2988560600,2988560603,PL
+2988560604,2988560607,PT
+2988560608,2988560623,FR
+2988560624,2988560627,BE
+2988560628,2988560639,FR
+2988560640,2988560703,GB
+2988560704,2988560711,DE
+2988560712,2988560719,PL
+2988560720,2988560735,FR
+2988560736,2988560751,DE
+2988560752,2988560759,GB
+2988560760,2988560767,FI
+2988560768,2988560783,FR
+2988560784,2988560799,NL
+2988560800,2988560815,DE
+2988560816,2988560831,FR
+2988560832,2988560863,GB
+2988560864,2988560895,DE
+2988560896,2988560911,PL
+2988560912,2988560919,FR
+2988560920,2988560923,DE
+2988560924,2988560951,FR
+2988560952,2988560959,PL
+2988560960,2988561023,IE
+2988561024,2988561031,ES
+2988561032,2988561039,FR
+2988561040,2988561043,ES
+2988561044,2988561055,FR
+2988561056,2988561071,FI
+2988561072,2988572671,FR
2988572672,2988703743,RU
2988703744,2988834815,PL
2988834816,2988965887,CH
2988965888,2989096959,SK
2989096960,2989228031,PL
2989228032,2989490175,RU
+2989490176,2989555711,HU
2989555712,2989621247,RU
2989621248,2989752319,BE
2989752320,2989817855,SY
@@ -57961,139 +61170,139 @@
2991185952,2991185967,NL
2991185968,2991185983,DE
2991185984,2991185999,DK
-2991186000,2991186015,FI
+2991186000,2991186015,ES
2991186016,2991186175,SE
2991186176,2991186207,GB
2991186208,2991186223,NL
2991186224,2991186239,DE
2991186240,2991186255,DK
-2991186256,2991186271,FI
+2991186256,2991186271,ES
2991186272,2991186431,SE
2991186432,2991186463,GB
2991186464,2991186479,NL
2991186480,2991186495,DE
2991186496,2991186511,DK
-2991186512,2991186527,FI
+2991186512,2991186527,ES
2991186528,2991186687,SE
2991186688,2991186719,GB
2991186720,2991186735,NL
2991186736,2991186751,DE
2991186752,2991186767,DK
-2991186768,2991186783,FI
+2991186768,2991186783,ES
2991186784,2991186943,SE
2991186944,2991186975,GB
2991186976,2991186991,NL
2991186992,2991187007,DE
2991187008,2991187023,DK
-2991187024,2991187039,FI
+2991187024,2991187039,ES
2991187040,2991187199,SE
2991187200,2991187231,GB
2991187232,2991187247,NL
2991187248,2991187263,DE
2991187264,2991187279,DK
-2991187280,2991187295,FI
+2991187280,2991187295,ES
2991187296,2991187455,SE
2991187456,2991187487,GB
2991187488,2991187503,NL
2991187504,2991187519,DE
2991187520,2991187535,DK
-2991187536,2991187551,FI
+2991187536,2991187551,ES
2991187552,2991187711,SE
2991187712,2991187743,GB
2991187744,2991187759,NL
2991187760,2991187775,DE
2991187776,2991187791,DK
-2991187792,2991187807,FI
+2991187792,2991187807,ES
2991187808,2991187967,SE
2991187968,2991187999,GB
2991188000,2991188015,NL
2991188016,2991188031,DE
2991188032,2991188047,DK
-2991188048,2991188063,FI
+2991188048,2991188063,ES
2991188064,2991188223,SE
2991188224,2991188255,GB
2991188256,2991188271,NL
2991188272,2991188287,DE
2991188288,2991188303,DK
-2991188304,2991188319,FI
+2991188304,2991188319,ES
2991188320,2991188479,SE
2991188480,2991188511,GB
2991188512,2991188527,NL
2991188528,2991188543,DE
2991188544,2991188559,DK
-2991188560,2991188575,FI
+2991188560,2991188575,ES
2991188576,2991188735,SE
2991188736,2991188767,GB
2991188768,2991188783,NL
2991188784,2991188799,DE
2991188800,2991188815,DK
-2991188816,2991188831,FI
+2991188816,2991188831,ES
2991188832,2991188991,SE
2991188992,2991189023,GB
2991189024,2991189039,NL
2991189040,2991189055,DE
2991189056,2991189071,DK
-2991189072,2991189087,FI
+2991189072,2991189087,ES
2991189088,2991189247,SE
2991189248,2991189279,GB
2991189280,2991189295,NL
2991189296,2991189311,DE
2991189312,2991189327,DK
-2991189328,2991189343,FI
+2991189328,2991189343,ES
2991189344,2991189503,SE
2991189504,2991189535,GB
2991189536,2991189551,NL
2991189552,2991189567,DE
2991189568,2991189583,DK
-2991189584,2991189599,FI
+2991189584,2991189599,ES
2991189600,2991189759,SE
2991189760,2991189791,GB
2991189792,2991189807,NL
2991189808,2991189823,DE
2991189824,2991189839,DK
-2991189840,2991189855,FI
+2991189840,2991189855,ES
2991189856,2991190015,SE
2991190016,2991190047,GB
2991190048,2991190063,NL
2991190064,2991190079,DE
2991190080,2991190095,DK
-2991190096,2991190111,FI
+2991190096,2991190111,ES
2991190112,2991190271,SE
2991190272,2991190303,GB
2991190304,2991190319,NL
2991190320,2991190335,DE
2991190336,2991190351,DK
-2991190352,2991190367,FI
+2991190352,2991190367,ES
2991190368,2991190527,SE
2991190528,2991190559,GB
2991190560,2991190575,NL
2991190576,2991190591,DE
2991190592,2991190607,DK
-2991190608,2991190623,FI
+2991190608,2991190623,ES
2991190624,2991190783,SE
2991190784,2991190815,GB
2991190816,2991190831,NL
2991190832,2991190847,DE
2991190848,2991190863,DK
-2991190864,2991190879,FI
+2991190864,2991190879,ES
2991190880,2991191039,SE
2991191040,2991191071,GB
2991191072,2991191087,NL
2991191088,2991191103,DE
2991191104,2991191119,DK
-2991191120,2991191135,FI
+2991191120,2991191135,ES
2991191136,2991191295,SE
2991191296,2991191327,GB
2991191328,2991191343,NL
2991191344,2991191359,DE
2991191360,2991191375,DK
-2991191376,2991191391,FI
+2991191376,2991191391,ES
2991191392,2991191551,SE
2991191552,2991191583,GB
2991191584,2991191599,NL
2991191600,2991191615,DE
2991191616,2991191631,DK
-2991191632,2991191647,FI
+2991191632,2991191647,ES
2991191648,2991191807,SE
2991191808,2991192063,FI
2991192064,2991192319,DK
@@ -58127,15 +61336,7 @@
2991980808,2991980815,NA
2991980816,2991981063,UA
2991981064,2991981071,DE
-2991981072,2991981311,UA
-2991981312,2991981315,RU
-2991981316,2991981375,UA
-2991981376,2991981383,NA
-2991981384,2991981415,UA
-2991981416,2991981423,NA
-2991981424,2991981439,UA
-2991981440,2991981447,NA
-2991981448,2991981463,UA
+2991981072,2991981463,UA
2991981464,2991981471,NA
2991981472,2991981495,UA
2991981496,2991981503,NA
@@ -58147,13 +61348,15 @@
2991981840,2991981847,RU
2991981848,2991981911,UA
2991981912,2991981919,RU
-2991981920,2991981935,UA
-2991981936,2991981943,RU
-2991981944,2991982535,UA
+2991981920,2991982535,UA
2991982536,2991982543,GL
2991982544,2991982592,UA
-2991982593,2991982846,JP
-2991982847,2992111615,UA
+2991982593,2991982599,JP
+2991982600,2991982607,UA
+2991982608,2991982846,JP
+2991982847,2991983359,UA
+2991983360,2991983615,JP
+2991983616,2992111615,UA
2992111616,2992373759,KZ
2992373760,2992635903,UA
2992635904,2993684479,GB
@@ -58179,9 +61382,7 @@
2996174848,2996305919,UA
2996305920,2996436991,QA
2996436992,2996469759,BY
-2996469760,2996479487,RU
-2996479488,2996479495,US
-2996479496,2996535295,RU
+2996469760,2996535295,RU
2996535296,2996568063,DK
2996568064,2996600831,ES
2996600832,2996633599,RO
@@ -58189,6 +61390,7 @@
2996649984,2996666367,RO
2996666368,2996682751,RU
2996682752,2996699135,DK
+2996731904,2996748287,UA
2996764672,2996768767,NL
2996768768,2996772863,RU
2996772864,2996776959,UA
@@ -58199,14 +61401,15 @@
2996797440,2996801535,PL
2996801536,2996805631,RO
2996805632,2996809727,PL
+2996809728,2996813823,UA
+2996813824,2996817919,PL
+2996817920,2996826111,UA
+2996826112,2996830207,RU
2996830208,2996862975,HR
2996862976,2996895743,AM
2996895744,2996928511,KW
2996928512,2996994047,RU
-2996994048,2996994303,DE
-2996994304,2996994815,BY
-2996994816,2996994847,DE
-2996994848,2996994879,SC
+2996994048,2996994879,DE
2996994880,2996994943,UA
2996994944,2996995071,US
2996995072,2996995327,BZ
@@ -58214,8 +61417,7 @@
2996995648,2996995711,BZ
2996995712,2996995775,BY
2996995776,2996995839,RU
-2996995840,2996996095,UA
-2996996096,2996996127,DE
+2996995840,2996996127,DE
2996996128,2996996159,CA
2996996160,2996996287,DE
2996996288,2996996351,RU
@@ -58227,8 +61429,7 @@
2996996768,2996996831,RU
2996996832,2996996863,DE
2996996864,2996997119,CN
-2996997120,2996997631,DE
-2996997632,2996998143,BY
+2996997120,2996998143,DE
2996998144,2996998271,UA
2996998272,2996998463,DE
2996998464,2996998527,CA
@@ -58237,13 +61438,14 @@
2996998720,2996998911,RU
2996998912,2996999199,DE
2996999200,2996999231,AU
-2996999232,2996999359,IN
+2996999232,2996999359,DE
2996999360,2996999423,IL
2996999424,2996999551,IN
2996999552,2996999679,DE
2996999680,2996999935,GB
-2996999936,2997000063,DE
-2997000064,2997000447,CN
+2996999936,2996999967,DE
+2996999968,2996999999,AU
+2997000000,2997000447,DE
2997000448,2997000703,RU
2997000704,2997000767,DE
2997000768,2997000831,SC
@@ -58252,8 +61454,7 @@
2997000992,2997001119,RO
2997001120,2997001471,DE
2997001472,2997001727,BZ
-2997001728,2997001983,UA
-2997001984,2997003071,DE
+2997001728,2997003071,DE
2997003072,2997003135,RU
2997003136,2997003199,DE
2997003200,2997003263,RU
@@ -58281,7 +61482,8 @@
2997006592,2997006655,DE
2997006656,2997006719,TR
2997006720,2997006847,RU
-2997006848,2997008255,DE
+2997006848,2997008191,DE
+2997008192,2997008255,TR
2997008256,2997008383,LT
2997008384,2997008447,DE
2997008448,2997008511,RU
@@ -58296,18 +61498,23 @@
2997019648,2997019679,DE
2997019680,2997019711,AU
2997019712,2997019903,US
-2997019904,2997020159,IN
-2997020160,2997020415,DE
+2997019904,2997020415,DE
2997020416,2997020671,CA
-2997020672,2997020927,IR
-2997020928,2997021183,CN
+2997020672,2997021183,DE
2997021184,2997021695,GB
2997021696,2997021951,NL
2997021952,2997022015,DE
2997022016,2997022143,GB
-2997022144,2997022239,DE
+2997022144,2997022207,IN
+2997022208,2997022239,DE
2997022240,2997022303,NL
-2997022304,2997026815,DE
+2997022304,2997022367,SG
+2997022368,2997022783,DE
+2997022784,2997022847,IN
+2997022848,2997023231,BZ
+2997023232,2997024255,DE
+2997024256,2997024511,TR
+2997024512,2997026815,DE
2997026816,2997059583,RU
2997059584,2997092351,BY
2997092352,2997125119,NO
@@ -58321,7 +61528,9 @@
2997387264,2997420031,BY
2997420032,2997452799,RU
2997452800,2997485567,BG
-2997485568,2997518335,FR
+2997485568,2997486847,FR
+2997486848,2997486911,BH
+2997486912,2997518335,FR
2997518336,2997528063,RU
2997528064,2997528319,UA
2997528320,2997583871,RU
@@ -58347,8 +61556,8 @@
2999985712,2999985727,BE
2999985728,2999985743,CZ
2999985744,2999985759,NL
-2999985760,2999985919,BE
-2999985920,2999992319,NL
+2999985760,2999986687,BE
+2999986688,2999992319,NL
2999992320,3000000511,RU
3000000512,3000008703,DE
3000008704,3000016895,RU
@@ -58406,11 +61615,30 @@
3000317952,3000319999,PL
3000320000,3000322047,FR
3000322048,3000326143,RU
-3000326144,3000328191,PL
+3000326144,3000330239,PL
+3000330240,3000332287,UA
+3000332288,3000334335,RU
+3000334336,3000336383,PL
+3000336384,3000338431,AM
+3000338432,3000340479,PL
+3000340480,3000342527,RU
+3000342528,3000344575,CZ
+3000344576,3000346623,PL
+3000346624,3000348671,UA
+3000348672,3000350719,RO
+3000350720,3000352767,UA
+3000352768,3000358911,RU
+3000358912,3000360959,PL
+3000360960,3000363007,RU
+3000363008,3000365055,FI
+3000365056,3000369151,RU
3000369152,3000377343,PL
3000377344,3000385535,RU
3000385536,3000393727,PS
3000393728,3000401919,NL
+3000401920,3000410111,PL
+3000410112,3000426495,UA
+3000426496,3000434687,RU
3000434688,3000451071,IR
3000451072,3000467455,RU
3000467456,3000471551,GB
@@ -58437,6 +61665,7 @@
3000543232,3000545279,UA
3000545280,3000547327,RU
3000547328,3000549375,UA
+3000549376,3000551423,SE
3000551424,3000553471,RS
3000553472,3000555519,KG
3000555520,3000557567,RU
@@ -58486,7 +61715,6 @@
3000713216,3000717311,A2
3000717312,3000721407,UA
3000721408,3000729599,PL
-3000729600,3000733695,NL
3000733696,3000737791,RU
3000737792,3000741887,UA
3000741888,3000745983,RU
@@ -58511,12 +61739,17 @@
3001843712,3001845759,RU
3001845760,3001851903,GB
3001851904,3001855999,IT
-3001856000,3001858559,NL
-3001858560,3001859071,RO
+3001856000,3001859071,NL
3001859072,3001860095,MD
3001860096,3001864191,EE
3001864192,3001868287,RU
-3001868288,3001872383,FR
+3001868288,3001869312,FR
+3001869313,3001869599,SA
+3001869600,3001869600,FR
+3001869601,3001869696,IR
+3001869697,3001869823,YE
+3001869824,3001869887,IR
+3001869888,3001872383,FR
3001872384,3001876479,RU
3001876480,3001880575,IT
3001880576,3001884671,RU
@@ -58525,7 +61758,9 @@
3001885056,3001885087,US
3001885088,3001885439,NL
3001885440,3001886463,BE
-3001886464,3001888767,NL
+3001886464,3001886511,NL
+3001886512,3001886527,US
+3001886528,3001888767,NL
3001888768,3001892863,BH
3001892864,3001896959,AZ
3001896960,3001901055,CH
@@ -58552,22 +61787,88 @@
3001975608,3001975615,RU
3001975616,3001975623,US
3001975624,3001975631,RU
-3001975632,3001976575,GB
-3001976576,3001976607,TW
+3001975632,3001975655,GB
+3001975656,3001975663,RU
+3001975664,3001975671,US
+3001975672,3001975679,CN
+3001975680,3001975687,TW
+3001975688,3001975695,US
+3001975696,3001975703,GB
+3001975704,3001975711,DE
+3001975712,3001975719,MY
+3001975720,3001975727,US
+3001975728,3001975735,GB
+3001975736,3001975743,MY
+3001975744,3001975759,GB
+3001975760,3001975799,US
+3001975800,3001975815,GB
+3001975816,3001975823,US
+3001975824,3001975839,GB
+3001975840,3001975847,CN
+3001975848,3001975855,US
+3001975856,3001975863,GB
+3001975864,3001975871,AU
+3001975872,3001975879,US
+3001975880,3001975895,GB
+3001975896,3001975903,RU
+3001975904,3001976415,GB
+3001976416,3001976447,IL
+3001976448,3001976575,GB
+3001976576,3001976607,US
3001976608,3001976623,GB
3001976624,3001976639,CN
3001976640,3001976655,RU
-3001976656,3001976679,GB
+3001976656,3001976671,GB
+3001976672,3001976679,IN
3001976680,3001976687,US
-3001976688,3001976927,GB
+3001976688,3001976831,GB
+3001976832,3001976895,CN
+3001976896,3001976927,IL
3001976928,3001976959,RU
-3001976960,3001977215,GB
+3001976960,3001977087,GB
+3001977088,3001977103,IN
+3001977104,3001977119,RU
+3001977120,3001977135,GB
+3001977136,3001977151,AE
+3001977152,3001977167,GB
+3001977168,3001977183,LK
+3001977184,3001977199,GB
+3001977200,3001977215,DE
3001977216,3001977247,RU
3001977248,3001977311,GB
3001977312,3001977343,CN
-3001977344,3001977455,GB
+3001977344,3001977375,IL
+3001977376,3001977407,CA
+3001977408,3001977439,IL
+3001977440,3001977447,GB
+3001977448,3001977455,IT
3001977456,3001977463,US
-3001977464,3001982975,GB
+3001977464,3001977487,GB
+3001977488,3001977503,LK
+3001977504,3001977519,GB
+3001977520,3001977535,CN
+3001977536,3001977575,GB
+3001977576,3001977583,CA
+3001977584,3001977599,GB
+3001977600,3001977855,DK
+3001977856,3001978047,GB
+3001978048,3001978111,US
+3001978112,3001978303,GB
+3001978304,3001978367,IL
+3001978368,3001978495,US
+3001978496,3001978527,RU
+3001978528,3001978559,UA
+3001978560,3001978591,US
+3001978592,3001978607,AU
+3001978608,3001978623,GB
+3001978624,3001978687,CA
+3001978688,3001978751,EE
+3001978752,3001978783,RU
+3001978784,3001978815,US
+3001978816,3001978831,LK
+3001978832,3001978847,GB
+3001978848,3001978879,UA
+3001978880,3001982975,GB
3001982976,3001987071,CH
3001987072,3001991167,JO
3001991168,3001995263,IR
@@ -58578,7 +61879,15 @@
3002015744,3002019839,IT
3002019840,3002020095,NL
3002020096,3002020159,SG
-3002020160,3002023935,NL
+3002020160,3002020223,NL
+3002020224,3002020287,IL
+3002020288,3002020303,US
+3002020304,3002020319,BZ
+3002020320,3002021695,NL
+3002021696,3002021759,SG
+3002021760,3002022527,NL
+3002022528,3002022655,BZ
+3002022656,3002023935,NL
3002023936,3002028031,DE
3002028032,3002036223,GB
3002036224,3002040319,BG
@@ -58588,7 +61897,9 @@
3002052608,3002056703,IT
3002056704,3002060799,FI
3002060800,3002064895,ES
-3002064896,3002068991,BG
+3002064896,3002065407,BG
+3002065408,3002065663,RS
+3002065664,3002068991,BG
3002068992,3002073087,ES
3002073088,3002597375,TR
3002597376,3002599423,RU
@@ -58607,14 +61918,18 @@
3002619952,3002619967,GB
3002619968,3002619983,IT
3002619984,3002619991,GB
-3002619992,3002620023,IT
-3002620024,3002620031,GB
+3002619992,3002620015,IT
+3002620016,3002620031,GB
3002620032,3002620039,DE
3002620040,3002620047,IT
-3002620048,3002620071,GB
-3002620072,3002621951,IT
+3002620048,3002620095,GB
+3002620096,3002620103,IT
+3002620104,3002620111,GB
+3002620112,3002621951,IT
3002621952,3002623999,NO
-3002624000,3002628095,GB
+3002624000,3002626551,GB
+3002626552,3002626559,US
+3002626560,3002628095,GB
3002628096,3002630143,NO
3002630144,3002632191,GB
3002632192,3002634239,EE
@@ -58735,11 +62050,16 @@
3003056128,3003058175,DE
3003058176,3003058431,MT
3003058432,3003058687,FI
-3003058688,3003060223,EE
+3003058688,3003058943,EE
+3003058944,3003059135,PH
+3003059136,3003060223,EE
3003060224,3003062271,DE
3003062272,3003064319,NL
3003064320,3003066367,RO
-3003066368,3003068415,PL
+3003066368,3003066887,PL
+3003066888,3003066895,MX
+3003066896,3003066911,UA
+3003066912,3003068415,PL
3003068416,3003070463,NL
3003070464,3003074559,GB
3003074560,3003076607,IT
@@ -58787,7 +62107,6 @@
3025989632,3025993727,KR
3025993728,3026059263,VN
3026059264,3026067455,PH
-3026067456,3026068479,BD
3026068480,3026069503,PH
3026069504,3026071551,JP
3026071552,3026073599,AP
@@ -58826,12 +62145,10 @@
3029614592,3029622783,AU
3029630976,3029635071,VN
3029635072,3029637119,JP
-3029637120,3029639167,BD
3029639168,3029643263,JP
3029643264,3029644287,AU
3029645312,3029651455,JP
-3029651456,3029654527,BD
-3029654528,3029655551,IN
+3029651456,3029653503,BD
3029655552,3029663743,CN
3029663744,3029671935,BD
3029671936,3029680127,IN
@@ -58839,7 +62156,10 @@
3029696512,3029704703,CN
3029704704,3029712895,JP
3029712896,3029713919,AU
-3029714944,3029716991,JP
+3029714944,3029715199,JP
+3029715200,3029715455,AU
+3029715456,3029715967,AP
+3029715968,3029716991,JP
3029716992,3029721087,PK
3029721088,3029725183,AP
3029725184,3029727231,IN
@@ -58900,7 +62220,6 @@
3033268224,3033530367,TW
3033530368,3033661439,CN
3033661440,3033694207,KR
-3033694208,3033710591,BD
3033710592,3033712639,KR
3033712640,3033714687,SG
3033714688,3033715711,NZ
@@ -58933,7 +62252,7 @@
3034251264,3034316799,HK
3034316800,3034447871,JP
3034447872,3034456063,AU
-3034464256,3034465279,NZ
+3034464256,3034466303,NZ
3034466304,3034472447,JP
3034472448,3034480639,IN
3034480640,3034482687,SG
@@ -58964,8 +62283,8 @@
3035316224,3035324415,CN
3035324416,3035326463,JP
3035326464,3035327487,AU
-3035328512,3035332607,BD
3035332608,3035333631,AU
+3035333632,3035334655,HK
3035335680,3035337727,JP
3035337728,3035338751,ID
3035338752,3035339007,SG
@@ -59193,7 +62512,15 @@
3091726336,3093168127,US
3093168128,3093200895,CA
3093233664,3093237759,PR
-3093299200,3093954759,US
+3093299200,3093939167,US
+3093939168,3093939175,CN
+3093939176,3093941111,US
+3093941112,3093941119,MY
+3093941120,3093941199,US
+3093941200,3093941207,CN
+3093941208,3093942271,US
+3093942272,3093942527,CA
+3093942528,3093954759,US
3093954760,3093954767,AR
3093954768,3093954975,US
3093954976,3093954983,AU
@@ -59219,7 +62546,9 @@
3093955664,3093955679,CA
3093955680,3093956479,US
3093956480,3093956495,IE
-3093956496,3093956895,US
+3093956496,3093956567,US
+3093956568,3093956575,MX
+3093956576,3093956895,US
3093956896,3093956943,CA
3093956944,3093957103,US
3093957104,3093957119,CA
@@ -59249,13 +62578,35 @@
3093958746,3093958747,FR
3093958748,3093959559,US
3093959560,3093959567,CA
-3093959568,3093960191,US
+3093959568,3093959751,US
+3093959752,3093959759,GB
+3093959760,3093959911,US
+3093959912,3093959919,CA
+3093959920,3093960063,US
+3093960064,3093960095,CA
+3093960096,3093960191,US
3093960192,3093960207,CA
3093960208,3093960351,US
3093960352,3093960383,CA
-3093960384,3093962259,US
+3093960384,3093960447,US
+3093960448,3093960463,CA
+3093960464,3093962259,US
3093962260,3093962263,CA
-3093962264,3093986367,US
+3093962264,3093962287,US
+3093962288,3093962291,MX
+3093962292,3093962375,US
+3093962376,3093962379,CA
+3093962380,3093962475,US
+3093962476,3093962479,CA
+3093962480,3093962807,US
+3093962808,3093962815,AU
+3093962816,3093963359,US
+3093963360,3093963367,CA
+3093963368,3093963487,US
+3093963488,3093963495,IE
+3093963496,3093963599,US
+3093963600,3093963607,CA
+3093963608,3093986367,US
3093986368,3093986431,DE
3093986432,3093986463,US
3093986464,3093986495,GB
@@ -59267,7 +62618,12 @@
3097493504,3097755647,CA
3097755648,3098148863,US
3098148864,3098165247,JM
-3098542080,3103784959,US
+3098214400,3098263551,US
+3098263552,3098271743,CA
+3098271744,3098275839,US
+3098279936,3098476543,US
+3098476544,3098492927,CA
+3098492928,3103784959,US
3120562176,3120594943,CO
3120594944,3120599039,AR
3120599040,3120601087,EC
@@ -59296,7 +62652,7 @@
3121545216,3121610751,CR
3121610752,3121741823,PY
3121741824,3121872895,AR
-3121872896,3121938431,CL
+3121872896,3122003967,CL
3122003968,3122135039,AR
3122135040,3122331647,VE
3122331648,3122348031,BO
@@ -59336,6 +62692,11 @@
3132358656,3132424191,CO
3132489728,3132555263,AR
3132620800,3132751871,VE
+3132882944,3132915711,VE
+3132948480,3133014015,AR
+3133014016,3133046783,HT
+3133046784,3133054975,AR
+3133079552,3133145087,AR
3133145088,3145727999,BR
3145728000,3154116607,MX
3154116608,3154182143,EU
@@ -59497,12 +62858,9 @@
3158895424,3158895487,RU
3158895488,3158895551,MK
3158895552,3158895615,AE
-3158895616,3158895871,IN
-3158895872,3158896255,DE
+3158895616,3158896255,DE
3158896256,3158896383,IN
-3158896384,3158897151,DE
-3158897152,3158897407,BY
-3158897408,3158897503,DE
+3158896384,3158897503,DE
3158897504,3158897567,RU
3158897568,3158897631,DE
3158897632,3158897663,BZ
@@ -59510,8 +62868,7 @@
3158897728,3158897791,RU
3158897792,3158897855,DE
3158897856,3158897919,UA
-3158897920,3158898175,BY
-3158898176,3158898207,DE
+3158897920,3158898207,DE
3158898208,3158898271,CZ
3158898272,3158898335,RU
3158898336,3158898431,DE
@@ -59555,10 +62912,10 @@
3160186880,3160188927,EE
3160188928,3160190975,SE
3160190976,3160193023,RU
-3160193024,3160193279,IT
+3160193024,3160193279,A2
3160193280,3160193535,DE
-3160193536,3160193807,A2
-3160193808,3160193871,LY
+3160193536,3160193791,A2
+3160193792,3160193871,LY
3160193872,3160194047,A2
3160194048,3160194175,LY
3160194176,3160194543,A2
@@ -59658,14 +63015,13 @@
3160377344,3160379391,NL
3160379392,3160381439,TR
3160381440,3160383487,UA
-3160383488,3160385535,GB
3160385536,3160387583,NL
3160387584,3160389631,RS
3160389632,3160391679,RU
3160391680,3160395775,GB
3160395776,3160397823,EE
3160397824,3160399871,ES
-3160399872,3160403967,SE
+3160399872,3160401919,SE
3160403968,3160406015,NO
3160408064,3161456639,DE
3161456640,3161473023,PL
@@ -59715,10 +63071,14 @@
3162087424,3162095615,SK
3162095616,3162103807,GE
3162103808,3162104319,FR
-3162104320,3162111999,NL
+3162104320,3162108415,NL
+3162108416,3162108671,FR
+3162108672,3162108927,NL
+3162108928,3162109951,FR
+3162109952,3162111999,NL
3162112000,3162120191,PL
-3162120192,3162128895,GB
-3162128896,3162129407,NL
+3162120192,3162128383,GB
+3162128384,3162129407,NL
3162129408,3162129919,DE
3162129920,3162136575,NL
3162144768,3162152959,SE
@@ -59735,7 +63095,6 @@
3162234880,3162243071,RU
3162243072,3162251263,TR
3162251264,3162259455,RU
-3162259456,3162267647,CZ
3162267648,3162275839,RU
3162275840,3162284031,NO
3162284032,3162292223,PL
@@ -59743,9 +63102,10 @@
3162300416,3162308607,RU
3162308608,3162316799,HR
3162316800,3162324991,PL
-3162324992,3162327039,GB
-3162327040,3162327296,CH
-3162327297,3162332671,GB
+3162324992,3162327039,IR
+3162327040,3162329087,CH
+3162329088,3162331135,IR
+3162331136,3162332671,GB
3162332672,3162332927,NL
3162332928,3162333183,DE
3162333184,3162341375,IT
@@ -59777,9 +63137,7 @@
3162681344,3162682367,UA
3162682368,3162685439,RU
3162685440,3162697727,UA
-3162697728,3162700287,RU
-3162700288,3162700799,LV
-3162700800,3162701823,RU
+3162697728,3162701823,RU
3162701824,3162734591,MD
3162734592,3162767359,RU
3162767360,3162800127,SA
@@ -59803,27 +63161,24 @@
3163162144,3163162175,DE
3163162176,3163162207,US
3163162208,3163162239,TR
-3163162240,3163162271,CH
+3163162240,3163162271,DE
3163162272,3163162303,NL
3163162304,3163162431,DE
3163162432,3163162463,CY
3163162464,3163163871,DE
3163163872,3163163903,RU
-3163163904,3163163935,DE
+3163163904,3163163935,GR
3163163936,3163163967,VG
3163163968,3163164543,DE
3163164544,3163164575,RU
-3163164576,3163165695,DE
-3163165696,3163165727,TR
-3163165728,3163165759,DE
+3163164576,3163165759,DE
3163165760,3163165791,PL
-3163165792,3163166175,DE
+3163165792,3163165823,RU
+3163165824,3163166175,DE
3163166176,3163166207,US
-3163166208,3163166335,DE
-3163166336,3163166399,NL
-3163166400,3163166431,DE
-3163166432,3163166463,NL
-3163166464,3163166495,DE
+3163166208,3163166367,DE
+3163166368,3163166399,NL
+3163166400,3163166495,DE
3163166496,3163166527,RO
3163166528,3163166559,DE
3163166560,3163166591,HU
@@ -59833,15 +63188,12 @@
3163167840,3163167967,DE
3163167968,3163167999,TR
3163168000,3163168031,DE
-3163168032,3163168063,RU
-3163168064,3163168095,DE
+3163168032,3163168095,RU
3163168096,3163168127,TR
-3163168128,3163168159,IL
+3163168128,3163168159,SA
3163168160,3163168319,DE
3163168320,3163168351,DK
-3163168352,3163168415,DE
-3163168416,3163168447,CA
-3163168448,3163168575,DE
+3163168352,3163168575,DE
3163168576,3163168607,NL
3163168608,3163168671,DE
3163168672,3163168703,US
@@ -59857,21 +63209,23 @@
3163170208,3163170239,RU
3163170240,3163170303,DE
3163170304,3163170335,IT
-3163170336,3163170367,DE
-3163170368,3163170399,IR
-3163170400,3163170495,DE
+3163170336,3163170495,DE
3163170496,3163170527,BR
3163170528,3163170591,DE
3163170592,3163170623,BR
-3163170624,3163172127,DE
+3163170624,3163171871,DE
+3163171872,3163171903,RO
+3163171904,3163172127,DE
3163172128,3163172159,NL
3163172160,3163172191,RU
-3163172192,3163172223,DE
-3163172224,3163172255,NL
+3163172192,3163172255,DE
3163172256,3163172287,PL
-3163172288,3163172351,NL
+3163172288,3163172319,DE
+3163172320,3163172351,NL
3163172352,3163172383,GB
-3163172384,3163172607,DE
+3163172384,3163172447,DE
+3163172448,3163172479,TR
+3163172480,3163172607,DE
3163172608,3163172639,DK
3163172640,3163172735,DE
3163172736,3163172767,GR
@@ -59883,15 +63237,17 @@
3163174368,3163174591,DE
3163174592,3163174623,SE
3163174624,3163174655,GB
-3163174656,3163174687,DE
-3163174688,3163174719,US
+3163174656,3163174687,NL
+3163174688,3163174719,DE
3163174720,3163174751,NL
3163174752,3163174783,US
3163174784,3163176127,DE
3163176128,3163176159,NL
3163176160,3163176255,DE
3163176256,3163176287,UG
-3163176288,3163176479,DE
+3163176288,3163176319,DE
+3163176320,3163176351,US
+3163176352,3163176479,DE
3163176480,3163176543,GB
3163176544,3163176575,DE
3163176576,3163176607,GR
@@ -59935,7 +63291,7 @@
3164946496,3164946499,IT
3164946500,3164946503,GB
3164946504,3164946507,BE
-3164946508,3164946511,FR
+3164946508,3164946511,CZ
3164946512,3164946527,ES
3164946528,3164946559,GB
3164946560,3164946783,FR
@@ -59947,7 +63303,20 @@
3164947064,3164947067,NL
3164947068,3164947071,PL
3164947072,3164947199,DE
-3164947200,3164947743,FR
+3164947200,3164947455,FR
+3164947456,3164947519,PL
+3164947520,3164947551,ES
+3164947552,3164947583,DE
+3164947584,3164947599,FR
+3164947600,3164947615,GB
+3164947616,3164947627,FR
+3164947628,3164947635,ES
+3164947636,3164947639,DE
+3164947640,3164947643,IT
+3164947644,3164947647,FR
+3164947648,3164947651,BE
+3164947652,3164947655,PL
+3164947656,3164947743,FR
3164947744,3164947747,ES
3164947748,3164947751,BE
3164947752,3164947839,FR
@@ -59958,7 +63327,8 @@
3164949088,3164949095,FR
3164949096,3164949103,IT
3164949104,3164949119,GB
-3164949120,3164949131,DE
+3164949120,3164949123,PT
+3164949124,3164949131,DE
3164949132,3164949151,FR
3164949152,3164949155,NL
3164949156,3164949159,FR
@@ -59967,8 +63337,7 @@
3164949184,3164949215,DE
3164949216,3164949219,PL
3164949220,3164949223,FR
-3164949224,3164949227,PL
-3164949228,3164949231,GB
+3164949224,3164949231,PL
3164949232,3164949247,BE
3164949248,3164949279,FR
3164949280,3164949295,ES
@@ -59988,9 +63357,7 @@
3164950272,3164950399,DE
3164950400,3164950407,ES
3164950408,3164950411,FR
-3164950412,3164950415,CZ
-3164950416,3164950431,PL
-3164950432,3164950435,FR
+3164950412,3164950435,PL
3164950436,3164950439,ES
3164950440,3164950447,FR
3164950448,3164950451,PL
@@ -60002,7 +63369,8 @@
3164950496,3164950511,ES
3164950512,3164950515,GB
3164950516,3164950519,ES
-3164950520,3164950527,GB
+3164950520,3164950523,FR
+3164950524,3164950527,ES
3164950528,3164950543,BE
3164950544,3164950591,NL
3164950592,3164950623,FR
@@ -60085,16 +63453,15 @@
3164953392,3164953395,IT
3164953396,3164953399,NL
3164953400,3164953403,BE
-3164953404,3164953407,CH
+3164953404,3164953407,PL
3164953408,3164953423,BE
3164953424,3164953439,FR
-3164953440,3164953443,CZ
+3164953440,3164953443,PL
3164953444,3164953447,DE
3164953448,3164953451,ES
3164953452,3164953455,FR
-3164953456,3164953459,IE
-3164953460,3164953463,PT
-3164953464,3164953467,PL
+3164953456,3164953463,PL
+3164953464,3164953467,FR
3164953468,3164953471,GB
3164953472,3164953503,PL
3164953504,3164953511,FR
@@ -60133,8 +63500,7 @@
3164956544,3164958847,FR
3164958848,3164958911,IT
3164958912,3164958927,CH
-3164958928,3164958943,ES
-3164958944,3164958955,FR
+3164958928,3164958955,FR
3164958956,3164958959,GB
3164958960,3164959039,FR
3164959040,3164959135,DE
@@ -60158,12 +63524,34 @@
3164960000,3164960255,DE
3164960256,3164960511,FR
3164960512,3164960575,PL
-3164960576,3164960767,IT
+3164960576,3164960591,DE
+3164960592,3164960599,ES
+3164960600,3164960603,IT
+3164960604,3164960607,CZ
+3164960608,3164960639,BE
+3164960640,3164960643,LT
+3164960644,3164960647,FR
+3164960648,3164960651,CH
+3164960652,3164960659,IT
+3164960660,3164960671,PL
+3164960672,3164960675,ES
+3164960676,3164960679,GB
+3164960680,3164960699,PL
+3164960700,3164960703,ES
+3164960704,3164960719,GB
+3164960720,3164960723,CH
+3164960724,3164960727,DE
+3164960728,3164960735,GB
+3164960736,3164960767,ES
3164960768,3164960831,PL
3164960832,3164960895,FR
3164960896,3164960959,PT
3164960960,3164961023,CH
-3164961024,3164961279,FR
+3164961024,3164961151,FR
+3164961152,3164961167,DE
+3164961168,3164961175,PL
+3164961176,3164961247,FR
+3164961248,3164961279,NL
3164961280,3164961311,DE
3164961312,3164961319,FR
3164961320,3164961327,PL
@@ -60191,7 +63579,12 @@
3164961696,3164961727,GB
3164961728,3164961743,ES
3164961744,3164961759,PL
-3164961760,3164961855,FR
+3164961760,3164961763,ES
+3164961764,3164961767,IT
+3164961768,3164961775,BE
+3164961776,3164961783,FR
+3164961784,3164961791,ES
+3164961792,3164961855,FR
3164961856,3164961871,PL
3164961872,3164961887,IE
3164961888,3164961903,ES
@@ -60208,8 +63601,11 @@
3164962080,3164962095,ES
3164962096,3164962111,BE
3164962112,3164962143,GB
-3164962144,3164962175,FR
-3164962176,3164962239,NL
+3164962144,3164962203,FR
+3164962204,3164962207,PT
+3164962208,3164962211,GB
+3164962212,3164962215,PL
+3164962216,3164962239,FR
3164962240,3164962247,PL
3164962248,3164962251,FR
3164962252,3164962255,DE
@@ -60234,11 +63630,10 @@
3164962540,3164962543,CZ
3164962544,3164962623,FR
3164962624,3164962627,BE
-3164962628,3164962631,CH
+3164962628,3164962631,PL
3164962632,3164962655,FR
3164962656,3164962687,ES
-3164962688,3164962703,GB
-3164962704,3164962715,FR
+3164962688,3164962715,FR
3164962716,3164962719,NL
3164962720,3164962723,IT
3164962724,3164962727,ES
@@ -60246,7 +63641,7 @@
3164962752,3164964863,ES
3164964864,3164966911,FI
3164966912,3164967039,FR
-3164967040,3164967071,PL
+3164967040,3164967071,GB
3164967072,3164967087,FR
3164967088,3164967095,IT
3164967096,3164967103,PL
@@ -60256,7 +63651,7 @@
3164967160,3164967167,FR
3164967168,3164967295,ES
3164967296,3164967303,NL
-3164967304,3164967307,IT
+3164967304,3164967307,PT
3164967308,3164967311,DE
3164967312,3164967343,IT
3164967344,3164967351,ES
@@ -60290,10 +63685,10 @@
3164969136,3164969143,ES
3164969144,3164969147,PT
3164969148,3164969183,GB
-3164969184,3164969199,DE
+3164969184,3164969199,FR
3164969200,3164969203,LT
3164969204,3164969207,ES
-3164969208,3164969211,IT
+3164969208,3164969211,PL
3164969212,3164969471,FR
3164969472,3164969727,PL
3164969728,3164969983,GB
@@ -60304,7 +63699,13 @@
3164970212,3164970215,GB
3164970216,3164970219,PL
3164970220,3164970223,FR
-3164970224,3164970303,GB
+3164970224,3164970239,GB
+3164970240,3164970271,IE
+3164970272,3164970287,DE
+3164970288,3164970291,PL
+3164970292,3164970295,DE
+3164970296,3164970299,ES
+3164970300,3164970303,DE
3164970304,3164970335,ES
3164970336,3164970339,NL
3164970340,3164970343,BE
@@ -60345,7 +63746,9 @@
3164970832,3164970835,IT
3164970836,3164970839,PL
3164970840,3164970847,GB
-3164970848,3164970911,FR
+3164970848,3164970855,FR
+3164970856,3164970863,PL
+3164970864,3164970911,FR
3164970912,3164970915,ES
3164970916,3164970919,FR
3164970920,3164970923,GB
@@ -60355,8 +63758,7 @@
3164971008,3164971011,ES
3164971012,3164971015,FR
3164971016,3164971023,PL
-3164971024,3164971055,FR
-3164971056,3164971071,NL
+3164971024,3164971071,FR
3164971072,3164971135,DE
3164971136,3164971263,GB
3164971264,3164971455,DE
@@ -60389,8 +63791,7 @@
3164972352,3164972415,NL
3164972416,3164972479,BE
3164972480,3164972499,FR
-3164972500,3164972503,IT
-3164972504,3164972511,DE
+3164972500,3164972511,DE
3164972512,3164972527,GB
3164972528,3164972799,FR
3164972800,3164973311,ES
@@ -60404,12 +63805,10 @@
3164973884,3164973887,DE
3164973888,3164973919,ES
3164973920,3164973935,FR
-3164973936,3164973939,IT
+3164973936,3164973939,IE
3164973940,3164973943,FR
3164973944,3164973951,PL
-3164973952,3164974623,FR
-3164974624,3164974639,DE
-3164974640,3164974651,FR
+3164973952,3164974651,FR
3164974652,3164974655,DE
3164974656,3164974663,FR
3164974664,3164974667,GB
@@ -60428,16 +63827,15 @@
3164975104,3164975167,CH
3164975168,3164975231,GB
3164975232,3164975299,IT
-3164975300,3164975307,ES
-3164975308,3164975311,GB
+3164975300,3164975303,ES
+3164975304,3164975311,IT
3164975312,3164975343,ES
3164975344,3164975351,GB
3164975352,3164975355,NL
3164975356,3164975359,FR
3164975360,3164975615,ES
3164975616,3164976127,GB
-3164976128,3164976639,IT
-3164976640,3164976767,FR
+3164976128,3164976767,FR
3164976768,3164976783,DE
3164976784,3164976799,ES
3164976800,3164976815,DE
@@ -60525,7 +63923,9 @@
3166306304,3166437375,RU
3166437376,3166568447,BE
3166699520,3166961663,DE
-3167223808,3167748095,NL
+3167223808,3167594831,NL
+3167594832,3167594839,A2
+3167594840,3167748095,NL
3167748096,3167940095,RO
3167940096,3167940351,CY
3167940352,3168092159,RO
@@ -60622,6 +64022,10 @@
3187703808,3187711999,UY
3187712000,3187720191,AR
3187720192,3187728383,GT
+3187728384,3187730431,CR
+3187730432,3187732479,AR
+3187732480,3187734527,CO
+3187734528,3187736575,BO
3187736576,3187752959,AR
3187752960,3187761151,CO
3187769344,3187802111,CO
@@ -60710,8 +64114,7 @@
3188678656,3188686847,AR
3188686848,3188690943,EC
3188695040,3188703231,VE
-3188703232,3188711423,AR
-3188719616,3188981759,AR
+3188703232,3188981759,AR
3188981760,3189178367,CL
3189178368,3189211135,PY
3189243904,3189637119,CO
@@ -60825,6 +64228,10 @@
3194519552,3194535935,PY
3194552320,3194585087,AR
3194585088,3194589183,HN
+3194593280,3194595327,AR
+3194595328,3194596351,PA
+3194596352,3194597375,HT
+3194597376,3194601471,AR
3194601472,3194602495,AN
3194602496,3194605567,AR
3194609664,3194613759,AR
@@ -60861,12 +64268,14 @@
3194863616,3194871807,HN
3194880000,3194896383,DO
3194896384,3194904575,CO
-3194912768,3194920959,CL
+3194912768,3194929151,CL
3194929152,3194937343,EC
3194945536,3194953727,GT
3194961920,3194966015,EC
3194970112,3194974207,PA
3194974208,3194976255,AR
+3194976256,3194977279,VE
+3194977280,3194978303,AR
3194978304,3194994687,PA
3194994688,3195002879,AR
3195011072,3195023359,AR
@@ -60889,10 +64298,12 @@
3195207680,3195211775,GT
3195215872,3195224063,AR
3195224064,3195232255,PA
+3195240448,3195256831,HT
+3195256832,3195265023,AR
3195273216,3195535359,PE
3195535360,3195539455,SV
3195543552,3195547647,PE
-3195551744,3195555839,EC
+3195551744,3195559935,EC
3195559936,3195564031,AR
3195568128,3195572223,CO
3195572224,3195576319,AR
@@ -60961,14 +64372,14 @@
3198910464,3198926847,CL
3198943232,3199500799,AR
3199500800,3199501311,US
-3199501312,3199533055,AR
+3199501312,3199516671,AR
3199533056,3199549439,BO
3199565824,3199582207,NI
3199598592,3199631359,CO
3199664128,3199729663,AR
3199729664,3199762431,NI
3199795200,3199827967,AN
-3199827968,3199844351,AR
+3199827968,3199860735,AR
3199860736,3199926271,BO
3199926272,3199991807,PE
3199991808,3200516095,AR
@@ -60981,8 +64392,14 @@
3201302528,3201433599,CL
3201433600,3201499135,AR
3201499136,3201515519,CL
-3201531904,3201533951,AR
+3201531904,3201540095,AR
3201540096,3201544191,CL
+3201548288,3201556479,AR
+3201556480,3201560575,BO
+3201560576,3201561599,PY
+3201561600,3201562623,AR
+3201562624,3201563647,CL
+3201563648,3201564671,PA
3201564672,3201630207,NI
3201630208,3201695743,TT
3201695744,3201761279,EC
@@ -64670,7 +68087,7 @@
3238630400,3238630655,GR
3238630656,3238632959,GB
3238632960,3238633215,UA
-3238633216,3238657791,DK
+3238633216,3238653951,DK
3238657792,3238658047,AT
3238658048,3238675455,SE
3238675456,3238675711,DK
@@ -64949,6 +68366,7 @@
3239488256,3239488511,CH
3239488512,3239488767,KW
3239488768,3239489023,RO
+3239489024,3239489279,DE
3239489280,3239489535,PL
3239489536,3239501823,DE
3239501824,3239505919,BE
@@ -65098,6 +68516,7 @@
3239691776,3239692031,EU
3239692032,3239692287,AT
3239692288,3239697407,DE
+3239697408,3239697663,HR
3239697664,3239697919,RU
3239697920,3239698431,PL
3239698432,3239706367,DE
@@ -65154,12 +68573,12 @@
3239761408,3239761663,RU
3239761664,3239761919,PL
3239761920,3239762175,BG
+3239762176,3239762431,RU
3239762432,3239762687,DK
3239762688,3239762943,RO
3239763200,3239763455,SE
3239763456,3239763967,GB
3239763968,3239772159,DE
-3239772160,3239772415,UA
3239772416,3239772671,GB
3239772672,3239773183,DK
3239773184,3239773439,FR
@@ -65466,7 +68885,7 @@
3240199168,3240199679,HU
3240199680,3240200191,NL
3240200192,3240200703,RO
-3240200704,3240201215,GB
+3240200704,3240201215,SE
3240201216,3240201727,RO
3240201728,3240202239,CH
3240202240,3240202751,RU
@@ -65524,7 +68943,7 @@
3240232960,3240235007,RU
3240235008,3240236031,FR
3240236032,3240237055,UA
-3240237056,3240238079,DE
+3240237056,3240239103,DE
3240239104,3240240127,FR
3240240128,3240241151,US
3240241152,3240242175,FI
@@ -65545,6 +68964,7 @@
3240258560,3240259583,RO
3240259584,3240260607,PL
3240260608,3240262655,DE
+3240262656,3240263679,RU
3240263680,3240264191,UA
3240264192,3240264703,FR
3240264704,3240265215,TR
@@ -65588,11 +69008,10 @@
3240281600,3240281727,JO
3240281728,3240281855,PL
3240281856,3240281983,NL
-3240281984,3240282111,IT
3240282112,3240282239,DE
3240282240,3240282367,UA
3240282368,3240282495,RO
-3240282624,3240282879,SE
+3240282496,3240282879,SE
3240282880,3240283007,UA
3240283008,3240283135,PL
3240284160,3240285183,RU
@@ -65736,6 +69155,7 @@
3240706048,3240707071,BG
3240707072,3240707839,NL
3240707840,3240709119,FR
+3240709120,3240710143,RU
3240710144,3240710399,UA
3240710400,3240710655,LT
3240710656,3240710911,DE
@@ -65898,11 +69318,13 @@
3240859648,3240861183,CH
3240861184,3240861695,AT
3240861696,3240866815,IT
+3240866816,3240867071,RU
3240867072,3240867327,PL
3240867328,3240867583,RU
3240867584,3240867839,CH
3240867840,3240873983,IT
3240873984,3240874495,RU
+3240874496,3240875007,UA
3240875008,3240875519,AT
3240875520,3240876031,FR
3240876032,3240876543,DK
@@ -66137,6 +69559,7 @@
3241865728,3241865983,CH
3241865984,3241866239,RO
3241866240,3241866751,DE
+3241866752,3241867007,UA
3241867008,3241867263,FR
3241867264,3241867519,UA
3241867520,3241867775,PL
@@ -66381,12 +69804,13 @@
3244823296,3244823551,FR
3244823552,3244823807,GE
3244823808,3244824063,RO
-3244824064,3244824319,MT
+3244824064,3244824319,UA
3244824320,3244824575,SI
3244824576,3244824831,RU
3244824832,3244825087,GB
3244825088,3244825343,DE
-3244825344,3244826111,RU
+3244825344,3244825599,UA
+3244825600,3244826111,RU
3244826112,3244826367,RO
3244826368,3244826623,CH
3244826624,3244826879,DE
@@ -66459,7 +69883,6 @@
3244844800,3244845055,GB
3244845056,3244845311,NL
3244845312,3244845567,NO
-3244845568,3244845823,AD
3244845824,3244846335,GB
3244846336,3244846591,TR
3244846592,3244846847,CZ
@@ -66470,7 +69893,7 @@
3244847872,3244848127,IL
3244848128,3244848383,CH
3244848384,3244848639,IL
-3244848640,3244848895,HU
+3244848640,3244848895,DE
3244848896,3244849151,IL
3244849152,3244849407,AT
3244849408,3244849663,RO
@@ -66566,6 +69989,7 @@
3244875008,3244875263,PL
3244875264,3244875519,LI
3244875520,3244875775,IT
+3244875776,3244876799,BZ
3244876800,3244877055,GB
3244877056,3244877311,JO
3244877312,3244877567,RU
@@ -66594,7 +70018,7 @@
3244883200,3244883455,UA
3244883456,3244883711,CZ
3244883712,3244883967,NL
-3244883968,3244884223,MD
+3244883968,3244884223,UA
3244884224,3244884479,FR
3244884480,3244884735,IR
3244884736,3244884991,NL
@@ -66758,7 +70182,6 @@
3244927744,3244927999,US
3244928000,3244928255,GB
3244928256,3244928511,US
-3244928512,3244928767,UA
3244928768,3244929023,RU
3244929024,3244929535,RO
3244929536,3244929791,PL
@@ -66813,6 +70236,7 @@
3244942848,3244943103,DE
3244943104,3244943359,GB
3244943360,3244943615,FR
+3244943616,3244943871,NL
3244943872,3244944127,TR
3244944128,3244944639,RU
3244944640,3244944895,GE
@@ -66895,7 +70319,7 @@
3245024256,3245025279,BG
3245025280,3245026303,UA
3245026304,3245027327,GB
-3245027328,3245028351,RU
+3245027328,3245029375,RU
3245029376,3245030399,FR
3245030400,3245032447,RU
3245032448,3245033471,BG
@@ -67079,7 +70503,6 @@
3245168896,3245169151,RU
3245169152,3245169407,IT
3245169408,3245169919,PL
-3245169920,3245170175,UA
3245170176,3245170431,GB
3245170432,3245170687,CH
3245170688,3245171711,DE
@@ -67326,7 +70749,7 @@
3245319680,3245319935,PL
3245319936,3245320191,DE
3245320192,3245320447,GB
-3245320704,3245320959,DE
+3245320448,3245320959,DE
3245320960,3245321215,IE
3245321216,3245321471,NL
3245321472,3245321727,UA
@@ -67395,7 +70818,9 @@
3245904200,3245904207,GB
3245904208,3245906367,IE
3245906368,3245906431,GB
-3245906432,3245910831,IE
+3245906432,3245909567,IE
+3245909568,3245909631,US
+3245909632,3245910831,IE
3245910832,3245910847,GB
3245910848,3245921279,IE
3245921280,3245921535,BE
@@ -67534,6 +70959,7 @@
3247081472,3247083519,PL
3247083520,3247084543,UA
3247084544,3247085567,RU
+3247085568,3247086591,CZ
3247086592,3247087615,NL
3247087616,3247088639,IT
3247088640,3247089663,DE
@@ -67833,7 +71259,6 @@
3247347968,3247348223,HU
3247348224,3247348991,FI
3247348992,3247349247,DE
-3247349248,3247349759,FI
3247349760,3247353855,SE
3247353856,3247362047,FI
3247362048,3247362303,RO
@@ -67939,6 +71364,7 @@
3247918080,3247919103,PL
3247919104,3247920127,BG
3247920128,3247921151,FR
+3247921152,3247922175,UA
3247922176,3247923199,SE
3247923200,3247925247,PL
3247925248,3247926271,UA
@@ -67976,7 +71402,7 @@
3248488704,3248491519,NO
3248491520,3248492031,RU
3248492032,3248496895,NO
-3248496896,3248497151,IL
+3248496896,3248497151,US
3248497152,3248498431,NO
3248498432,3248498687,DE
3248498688,3248513279,NO
@@ -68183,7 +71609,7 @@
3249136128,3249137151,RU
3249137152,3249137663,FR
3249137664,3249138175,PL
-3249138176,3249138687,JM
+3249138176,3249138687,UA
3249139200,3249139711,RU
3249139712,3249140223,UA
3249140224,3249140735,IT
@@ -68232,7 +71658,8 @@
3249698560,3249698815,HU
3249698816,3249699839,GB
3249699840,3249700863,UA
-3249700864,3249701887,SE
+3249700864,3249701631,SE
+3249701632,3249701887,RU
3249701888,3249702143,PL
3249702144,3249702399,FI
3249702400,3249702655,FR
@@ -68303,7 +71730,9 @@
3249731584,3249732607,UA
3249732608,3249733631,IT
3249733632,3249799167,CZ
-3249799168,3249932031,SE
+3249799168,3249931007,SE
+3249931008,3249931263,GB
+3249931264,3249932031,SE
3249932032,3249934335,GB
3249934336,3250061311,SE
3250061312,3250061635,FI
@@ -68428,7 +71857,6 @@
3250416128,3250417663,DE
3250417664,3250418175,IT
3250418176,3250418687,DE
-3250418688,3250419199,PL
3250419200,3250419711,NO
3250419712,3250420223,RU
3250420224,3250420735,IR
@@ -68447,7 +71875,7 @@
3250425856,3250426111,LT
3250426112,3250426367,NO
3250426368,3250426623,AT
-3250426624,3250426879,BE
+3250426624,3250426879,FR
3250426880,3250427135,JO
3250427136,3250427391,NL
3250427392,3250429951,DE
@@ -68491,7 +71919,9 @@
3250601984,3250610175,GB
3250610176,3250618367,TR
3250618368,3250626559,RU
-3250626560,3250634751,PL
+3250626560,3250633983,PL
+3250633984,3250634239,US
+3250634240,3250634751,PL
3250634752,3250642943,GB
3250642944,3250651135,CH
3250651136,3250659327,IT
@@ -68809,6 +72239,7 @@
3251209216,3251210239,GB
3251210240,3251211263,PL
3251211264,3251212287,UA
+3251212288,3251212415,IE
3251212416,3251212671,FI
3251212672,3251212799,SE
3251212800,3251212927,FR
@@ -68921,6 +72352,7 @@
3251265536,3251267839,NL
3251267840,3251268351,GB
3251268352,3251268607,NL
+3251268608,3251268863,BG
3251268864,3251269119,NL
3251269120,3251269375,DK
3251269376,3251269631,FR
@@ -68987,6 +72419,7 @@
3251355648,3251356159,GB
3251356160,3251356671,AT
3251356672,3251357183,EE
+3251357184,3251357695,BG
3251357696,3251358207,ES
3251358208,3251358719,RU
3251358720,3251359231,RO
@@ -69129,14 +72562,15 @@
3252387328,3252387583,PL
3252387584,3252387839,RU
3252387840,3252404223,LT
-3252404224,3252406527,NO
-3252406528,3252407295,LT
+3252404224,3252406783,NO
+3252406784,3252407295,LT
3252407296,3252407583,NO
3252407584,3252407599,NG
3252407600,3252407615,BJ
3252407616,3252407711,NO
3252407712,3252407727,NG
-3252407728,3252407759,NO
+3252407728,3252407751,NO
+3252407752,3252407759,AO
3252407760,3252407767,NE
3252407768,3252407775,CD
3252407776,3252407791,GH
@@ -69145,10 +72579,9 @@
3252408000,3252408159,NO
3252408160,3252408191,GQ
3252408192,3252408319,NO
-3252408320,3252408335,LT
-3252408336,3252408343,GN
-3252408344,3252408351,LT
-3252408352,3252408367,GN
+3252408320,3252408327,MW
+3252408328,3252408335,LT
+3252408336,3252408367,GN
3252408368,3252408375,NG
3252408376,3252408383,LT
3252408384,3252408391,BI
@@ -69182,8 +72615,12 @@
3252409200,3252409207,TZ
3252409208,3252409215,LT
3252409216,3252409223,BW
-3252409224,3252409263,LT
-3252409264,3252409343,SO
+3252409224,3252409231,LT
+3252409232,3252409247,UG
+3252409248,3252409263,LT
+3252409264,3252409271,SO
+3252409272,3252409279,LT
+3252409280,3252409343,SO
3252409344,3252409375,TD
3252409376,3252409407,LT
3252409408,3252409471,BI
@@ -69195,15 +72632,20 @@
3252409600,3252409615,MA
3252409616,3252409631,LT
3252409632,3252409647,AO
-3252409648,3252410375,LT
+3252409648,3252409727,LT
+3252409728,3252409735,LR
+3252409736,3252410375,LT
3252410376,3252410391,BW
3252410392,3252410431,LT
3252410432,3252410463,BI
-3252410464,3252410623,LT
+3252410464,3252410495,LT
+3252410496,3252410623,BI
3252410624,3252410751,ZW
3252410752,3252411135,LT
3252411136,3252411167,IQ
-3252411168,3252411375,LT
+3252411168,3252411327,LT
+3252411328,3252411367,CD
+3252411368,3252411375,LT
3252411376,3252411391,CD
3252411392,3252411647,LT
3252411648,3252411679,BI
@@ -69225,7 +72667,8 @@
3252414512,3252414527,MR
3252414528,3252414591,LT
3252414592,3252414599,GH
-3252414600,3252414623,LT
+3252414600,3252414607,LT
+3252414608,3252414623,ER
3252414624,3252414639,TZ
3252414640,3252414647,GH
3252414648,3252414655,NE
@@ -69234,9 +72677,12 @@
3252414984,3252415007,IQ
3252415008,3252415015,LT
3252415016,3252415127,IQ
-3252415128,3252415551,LT
-3252415552,3252415567,NG
-3252415568,3252415743,LT
+3252415128,3252415135,LT
+3252415136,3252415167,IQ
+3252415168,3252415199,LT
+3252415200,3252415231,IQ
+3252415232,3252415487,LT
+3252415488,3252415743,IQ
3252415744,3252415775,GB
3252415776,3252415967,LT
3252415968,3252415999,CM
@@ -69246,8 +72692,8 @@
3252416960,3252417023,GN
3252417024,3252417279,LT
3252417280,3252417287,IQ
-3252417288,3252417359,AF
-3252417360,3252417791,LT
+3252417288,3252417375,AF
+3252417376,3252417791,LT
3252417792,3252417855,NG
3252417856,3252417919,LT
3252417920,3252417935,MW
@@ -69277,7 +72723,11 @@
3252419344,3252419359,LT
3252419360,3252419423,GH
3252419424,3252419839,LT
-3252419840,3252419911,IQ
+3252419840,3252419879,IQ
+3252419880,3252419887,LT
+3252419888,3252419895,IQ
+3252419896,3252419903,LT
+3252419904,3252419911,IQ
3252419912,3252419919,LT
3252419920,3252419927,IQ
3252419928,3252419935,LT
@@ -69297,16 +72747,10 @@
3252420240,3252420247,IQ
3252420248,3252420263,LT
3252420264,3252420271,IQ
-3252420272,3252420303,LT
-3252420304,3252420311,IQ
-3252420312,3252420327,LT
-3252420328,3252420335,IQ
-3252420336,3252420367,LT
+3252420272,3252420367,LT
3252420368,3252420415,IQ
3252420416,3252420431,GB
-3252420432,3252420447,IQ
-3252420448,3252420455,LT
-3252420456,3252420463,IQ
+3252420432,3252420463,IQ
3252420464,3252420471,AF
3252420472,3252420583,LT
3252420584,3252420591,IQ
@@ -69335,7 +72779,7 @@
3252427264,3252427519,NG
3252427520,3252427775,LT
3252427776,3252428287,MW
-3252428288,3252428351,NG
+3252428288,3252428351,LT
3252428352,3252428383,AO
3252428384,3252428415,LT
3252428416,3252428447,KE
@@ -69373,7 +72817,7 @@
3252435312,3252435319,LT
3252435320,3252435327,MZ
3252435328,3252435343,CD
-3252435344,3252435359,LT
+3252435344,3252435359,BF
3252435360,3252435375,CD
3252435376,3252435415,GN
3252435416,3252435423,CD
@@ -69396,13 +72840,16 @@
3252436320,3252436335,LT
3252436336,3252436351,ZM
3252436352,3252436383,GN
-3252436384,3252436447,LT
+3252436384,3252436399,LR
+3252436400,3252436407,SL
+3252436408,3252436415,ML
+3252436416,3252436447,LT
3252436448,3252436479,ER
3252436480,3252436991,LT
3252436992,3252437503,NG
3252437504,3252438015,LT
3252438016,3252438271,TR
-3252438272,3252438527,MD
+3252438272,3252438527,LT
3252438528,3252438783,CM
3252438784,3252439039,LT
3252439040,3252439055,BJ
@@ -69442,7 +72889,9 @@
3252450880,3252450911,NO
3252450912,3252451071,LT
3252451072,3252451327,CH
-3252451328,3252451839,LT
+3252451328,3252451583,LT
+3252451584,3252451599,GM
+3252451600,3252451839,LT
3252451840,3252451855,NO
3252451856,3252451967,LT
3252451968,3252451999,NO
@@ -69466,9 +72915,7 @@
3252452504,3252452511,SD
3252452512,3252452607,LT
3252452608,3252452735,TD
-3252452736,3252452863,LT
-3252452864,3252452879,TZ
-3252452880,3252453119,LT
+3252452736,3252453119,LT
3252453120,3252453151,NG
3252453152,3252453247,LT
3252453248,3252453271,NG
@@ -70045,7 +73492,11 @@
3254510564,3254510847,NE
3254510848,3254521855,FR
3254521856,3254522367,GB
-3254522368,3254550527,FR
+3254522368,3254523665,FR
+3254523666,3254523666,UG
+3254523667,3254523667,CH
+3254523668,3254523668,RO
+3254523669,3254550527,FR
3254550528,3254550783,US
3254550784,3254551039,IR
3254551040,3254551295,US
@@ -70099,7 +73550,7 @@
3254703616,3254704127,NL
3254704128,3254705663,UA
3254705664,3254706175,GR
-3254706176,3254706687,RU
+3254706176,3254707199,RU
3254707200,3254707711,TR
3254707712,3254708223,RO
3254708224,3254708735,UA
@@ -70129,6 +73580,8 @@
3254784000,3254784255,IT
3254784256,3254784511,CH
3254784512,3254785279,LT
+3254785280,3254785535,KZ
+3254785536,3254785791,DK
3254796288,3254797311,SE
3254797312,3254798335,RU
3254798336,3254799359,AT
@@ -70479,7 +73932,9 @@
3255249936,3255249951,LU
3255249952,3255250079,BE
3255250080,3255250111,LU
-3255250112,3255252487,BE
+3255250112,3255250815,BE
+3255250816,3255250879,LU
+3255250880,3255252487,BE
3255252488,3255252495,FR
3255252496,3255252527,BE
3255252528,3255252543,LU
@@ -70511,7 +73966,9 @@
3255262800,3255262815,LU
3255262816,3255263295,BE
3255263296,3255263327,US
-3255263328,3255270431,BE
+3255263328,3255265007,BE
+3255265008,3255265023,LU
+3255265024,3255270431,BE
3255270432,3255270463,FR
3255270464,3255273855,BE
3255273856,3255273887,LU
@@ -70549,7 +74006,9 @@
3255280048,3255280055,LU
3255280056,3255281407,BE
3255281408,3255281439,LU
-3255281440,3255283415,BE
+3255281440,3255281759,BE
+3255281760,3255281791,LU
+3255281792,3255283415,BE
3255283416,3255283423,LU
3255283424,3255283927,BE
3255283928,3255283931,LU
@@ -70632,6 +74091,7 @@
3255328768,3255336959,DE
3255336960,3255341055,RU
3255341056,3255342079,UA
+3255342080,3255343103,FR
3255343104,3255344127,RU
3255344128,3255345151,UA
3255345152,3255353343,RU
@@ -70812,7 +74272,7 @@
3255566336,3255574527,SE
3255574528,3255578623,CZ
3255578624,3255582719,SE
-3255590912,3255599103,UA
+3255582720,3255599103,UA
3255599104,3255615487,CH
3255615488,3255623679,DE
3255623680,3255631871,BG
@@ -70823,7 +74283,9 @@
3255666688,3255697407,NL
3255697408,3255739647,SE
3255739648,3255739903,GB
-3255739904,3255745535,SE
+3255739904,3255743231,SE
+3255743232,3255743487,IT
+3255743488,3255745535,SE
3255745536,3255746047,DK
3255746048,3255762943,SE
3255762944,3255799039,DE
@@ -70894,6 +74356,7 @@
3256414720,3256415231,DE
3256415232,3256415743,PL
3256415744,3256416255,UA
+3256416256,3256416767,RS
3256416768,3256417279,GB
3256417280,3256417791,NO
3256417792,3256418303,GB
@@ -70953,6 +74416,7 @@
3256643584,3256644607,MD
3256644608,3256645631,IT
3256645632,3256646655,SE
+3256646656,3256647679,GB
3256647680,3256648703,RS
3256648704,3256649727,UA
3256649728,3256650751,GB
@@ -71078,7 +74542,9 @@
3257011200,3257011455,BG
3257011456,3257058815,GB
3257058816,3257059071,PL
-3257059072,3257144831,GB
+3257059072,3257139199,GB
+3257139200,3257139455,DK
+3257139456,3257144831,GB
3257144832,3257145087,FR
3257145088,3257180159,GB
3257180160,3257180415,TR
@@ -71243,6 +74709,7 @@
3257561088,3257561599,UA
3257561600,3257562111,DE
3257562112,3257563647,PL
+3257563648,3257564159,NL
3257564160,3257564671,GB
3257564672,3257565183,RO
3257565184,3257570303,CY
@@ -72345,6 +75812,7 @@
3258903040,3258903295,FR
3258903296,3258903551,GB
3258903552,3258903807,DE
+3258903808,3258904063,AT
3258904064,3258941439,GB
3258941440,3258943487,PL
3258943488,3258944511,BG
@@ -72366,9 +75834,7 @@
3259032440,3259032443,ES
3259032444,3259032551,DE
3259032552,3259032559,IT
-3259032560,3259032831,DE
-3259032832,3259032879,GB
-3259032880,3259034319,DE
+3259032560,3259034319,DE
3259034320,3259034327,GB
3259034328,3259035447,DE
3259035448,3259035455,IT
@@ -72664,6 +76130,7 @@
3260481536,3260547071,RU
3260547072,3260547327,DE
3260547328,3260547583,UA
+3260547584,3260547839,NL
3260547840,3260548095,PL
3260548096,3260548351,IE
3260548352,3260548607,DK
@@ -72712,6 +76179,7 @@
3260600320,3260601343,RU
3260601344,3260601855,CH
3260601856,3260602367,PL
+3260602368,3260602879,DK
3260602880,3260603903,UA
3260603904,3260604415,FR
3260604416,3260604927,PL
@@ -72837,7 +76305,7 @@
3261767680,3261775871,RS
3261775872,3261776383,PL
3261776384,3261777407,RU
-3261777408,3261777919,KZ
+3261777664,3261777919,KZ
3261777920,3261778431,PL
3261778432,3261778943,RU
3261778944,3261779455,RO
@@ -72924,47 +76392,41 @@
3262027776,3262029823,FI
3262029824,3262030847,US
3262030848,3262031871,FR
-3262031872,3262033919,FI
-3262033920,3262033935,AX
-3262033936,3262033951,FI
-3262033952,3262033983,AX
-3262033984,3262033991,FI
-3262033992,3262033999,AX
-3262034000,3262034015,FI
-3262034016,3262034039,AX
-3262034040,3262034111,FI
-3262034112,3262034127,AX
-3262034128,3262034143,FI
-3262034144,3262034295,AX
-3262034296,3262034303,FI
-3262034304,3262034447,AX
-3262034448,3262034451,FI
-3262034452,3262034463,AX
-3262034464,3262034495,FI
-3262034496,3262034511,AX
-3262034512,3262034519,FI
-3262034520,3262034655,AX
-3262034656,3262034687,FI
-3262034688,3262034735,AX
-3262034736,3262034767,FI
-3262034768,3262034879,AX
-3262034880,3262034943,FI
-3262034944,3262035967,AX
-3262035968,3262036111,FI
-3262036112,3262036119,AX
-3262036120,3262036127,FI
-3262036128,3262036159,AX
-3262036160,3262036223,FI
-3262036224,3262036335,AX
-3262036336,3262036351,FI
-3262036352,3262036439,AX
-3262036440,3262036447,FI
-3262036448,3262036623,AX
-3262036624,3262036643,FI
-3262036644,3262036671,AX
-3262036672,3262036687,FI
-3262036688,3262036703,AX
-3262036704,3262036719,FI
+3262031872,3262034047,FI
+3262034048,3262034119,AX
+3262034120,3262034123,FI
+3262034124,3262034127,AX
+3262034128,3262034431,FI
+3262034432,3262034447,AX
+3262034448,3262034455,FI
+3262034456,3262034463,AX
+3262034464,3262034527,FI
+3262034528,3262034559,AX
+3262034560,3262034687,FI
+3262034688,3262034719,AX
+3262034720,3262034783,FI
+3262034784,3262034791,AX
+3262034792,3262034839,FI
+3262034840,3262034847,AX
+3262034848,3262034943,FI
+3262034944,3262035455,AX
+3262035456,3262035487,FI
+3262035488,3262035551,AX
+3262035552,3262036143,FI
+3262036144,3262036151,AX
+3262036152,3262036287,FI
+3262036288,3262036303,AX
+3262036304,3262036311,FI
+3262036312,3262036335,AX
+3262036336,3262036367,FI
+3262036368,3262036383,AX
+3262036384,3262036415,FI
+3262036416,3262036431,AX
+3262036432,3262036463,FI
+3262036464,3262036479,AX
+3262036480,3262036607,FI
+3262036608,3262036615,AX
+3262036616,3262036719,FI
3262036720,3262038015,AX
3262038016,3262038271,FR
3262038272,3262038527,RU
@@ -72977,8 +76439,7 @@
3262040064,3262040319,PL
3262040320,3262040575,ES
3262040576,3262040831,RU
-3262040832,3262041087,GB
-3262041088,3262041343,HU
+3262040832,3262041343,GB
3262041344,3262041599,BG
3262041600,3262041855,DK
3262041856,3262042367,FR
@@ -73018,23 +76479,35 @@
3262096128,3262096383,AX
3262096384,3262099199,FI
3262099200,3262099455,NL
-3262099456,3262106111,FI
-3262106112,3262106623,AX
-3262106624,3262108671,FI
+3262099456,3262108671,FI
3262108672,3262108927,RU
3262108928,3262114047,FI
3262114048,3262114303,SE
3262114304,3262115071,FI
3262115072,3262115327,RU
3262115328,3262119935,FI
-3262119936,3262122367,AX
-3262122368,3262122383,FI
-3262122384,3262122399,AX
-3262122400,3262122431,FI
-3262122432,3262123519,AX
-3262123520,3262123527,FI
-3262123528,3262123775,AX
-3262123776,3262124031,FI
+3262119936,3262120447,AX
+3262120448,3262120703,FI
+3262120704,3262121599,AX
+3262121600,3262121663,FI
+3262121664,3262121727,AX
+3262121728,3262121983,FI
+3262121984,3262122007,AX
+3262122008,3262122015,FI
+3262122016,3262122039,AX
+3262122040,3262122143,FI
+3262122144,3262122159,AX
+3262122160,3262122239,FI
+3262122240,3262122367,AX
+3262122368,3262122431,FI
+3262122432,3262122455,AX
+3262122456,3262122463,FI
+3262122464,3262122591,AX
+3262122592,3262122631,FI
+3262122632,3262122639,AX
+3262122640,3262122751,FI
+3262122752,3262122815,AX
+3262122816,3262124031,FI
3262124032,3262128127,DE
3262128128,3262136319,GB
3262136320,3262137599,EU
@@ -73158,15 +76631,14 @@
3262444544,3262445055,UA
3262445056,3262445567,RO
3262445568,3262446079,PL
-3262446080,3262446591,RU
3262446592,3262447103,PL
3262447104,3262447615,GB
3262447616,3262460415,PT
3262460416,3262460543,UA
3262460544,3262460671,RU
-3262460672,3262460799,AE
+3262460672,3262460927,AE
3262460928,3262461055,HU
-3262461056,3262461183,LV
+3262461056,3262461183,DK
3262461184,3262461311,SN
3262461312,3262461439,NO
3262461440,3262461567,DE
@@ -73197,7 +76669,9 @@
3262472336,3262472339,US
3262472340,3262472351,DE
3262472352,3262472355,NL
-3262472356,3262472359,ES
+3262472356,3262472356,ES
+3262472357,3262472358,CH
+3262472359,3262472359,ES
3262472360,3262472363,NL
3262472364,3262472367,GB
3262472368,3262472371,NL
@@ -73375,9 +76849,7 @@
3262473484,3262473484,VE
3262473485,3262473485,US
3262473486,3262473486,CA
-3262473487,3262473513,US
-3262473514,3262473514,PR
-3262473515,3262473516,US
+3262473487,3262473516,US
3262473517,3262473517,CN
3262473518,3262473526,US
3262473527,3262473527,CN
@@ -73878,7 +77350,7 @@
3262476456,3262476459,CA
3262476460,3262476463,DK
3262476464,3262476467,SK
-3262476468,3262476471,IT
+3262476468,3262476471,DE
3262476472,3262476475,CA
3262476476,3262476483,US
3262476484,3262476487,DE
@@ -74470,8 +77942,7 @@
3262478510,3262478513,DE
3262478514,3262478514,SE
3262478515,3262478515,PT
-3262478516,3262478516,ES
-3262478517,3262478519,DE
+3262478516,3262478519,DE
3262478520,3262478520,CH
3262478521,3262478521,NL
3262478522,3262478522,QA
@@ -74743,8 +78214,7 @@
3262478913,3262478913,FR
3262478914,3262478914,DE
3262478915,3262478915,NL
-3262478916,3262478919,DE
-3262478920,3262478920,ZA
+3262478916,3262478920,DE
3262478921,3262478921,AT
3262478922,3262478924,DE
3262478925,3262478925,NL
@@ -75112,8 +78582,7 @@
3262479427,3262479427,IT
3262479428,3262479429,FR
3262479430,3262479430,GB
-3262479431,3262479432,DE
-3262479433,3262479433,ZA
+3262479431,3262479433,DE
3262479434,3262479434,IT
3262479435,3262479437,DE
3262479438,3262479438,IT
@@ -75205,8 +78674,7 @@
3262479566,3262479566,NL
3262479567,3262479567,CH
3262479568,3262479568,NO
-3262479569,3262479572,DE
-3262479573,3262479573,IT
+3262479569,3262479573,DE
3262479574,3262479574,CH
3262479575,3262479575,DE
3262479576,3262479576,NL
@@ -76121,9 +79589,7 @@
3263774464,3263774719,BE
3263774720,3263792351,FI
3263792352,3263792367,SE
-3263792368,3263792383,FI
-3263792384,3263792639,AX
-3263792640,3263793151,FI
+3263792368,3263793151,FI
3263793152,3263793407,BE
3263793408,3263815123,FI
3263815124,3263815127,AX
@@ -76327,7 +79793,9 @@
3264431104,3264431615,LI
3264431616,3264446207,CH
3264446208,3264446463,FR
-3264446464,3264483071,CH
+3264446464,3264463871,CH
+3264463872,3264466943,LI
+3264466944,3264483071,CH
3264483072,3264483327,LI
3264483328,3264486527,CH
3264486528,3264486559,LI
@@ -76452,7 +79920,6 @@
3264665600,3264666111,RO
3264666112,3264666623,IL
3264666624,3264667135,UA
-3264667136,3264667647,SE
3264667648,3264668159,BE
3264668160,3264669183,DE
3264669184,3264669695,PL
@@ -76548,7 +80015,7 @@
3264846720,3264846847,RU
3264846848,3264846911,DK
3264846912,3264846975,SK
-3264847040,3264847103,GB
+3264846976,3264847103,GB
3264847104,3264847135,FR
3264847136,3264847167,ES
3264847168,3264847199,IE
@@ -76557,7 +80024,6 @@
3264847360,3264847487,FR
3264847488,3264847615,RU
3264847616,3264847679,PL
-3264847680,3264847743,LV
3264847744,3264847807,BE
3264847808,3264847871,SE
3264847872,3264849919,DE
@@ -76610,8 +80076,8 @@
3264906912,3264906919,GR
3264906920,3264906983,CY
3264906984,3264906995,GR
-3264906996,3264907135,CY
-3264907136,3264907143,GR
+3264906996,3264907139,CY
+3264907140,3264907143,GR
3264907144,3264907151,CY
3264907152,3264907155,GR
3264907156,3264907639,CY
@@ -76640,8 +80106,8 @@
3264907964,3264907971,GR
3264907972,3264907987,CY
3264907988,3264907991,GR
-3264907992,3264908011,CY
-3264908012,3264908019,GR
+3264907992,3264908007,CY
+3264908008,3264908019,GR
3264908020,3264908023,CY
3264908024,3264908031,GR
3264908032,3264908063,CY
@@ -76757,9 +80223,7 @@
3265219072,3265257471,GB
3265257472,3265259519,NL
3265259520,3265265663,GB
-3265265664,3265286463,SK
-3265286464,3265286527,SR
-3265286528,3265331199,SK
+3265265664,3265331199,SK
3265331200,3265340415,GB
3265340416,3265340671,DE
3265340672,3265340927,GB
@@ -76853,7 +80317,6 @@
3265604096,3265604351,SA
3265604352,3265604607,FR
3265604608,3265604863,CH
-3265604864,3265605119,FR
3265605120,3265605375,UA
3265605376,3265605631,CZ
3265605632,3265605887,PL
@@ -77067,9 +80530,7 @@
3266804736,3266804991,NL
3266804992,3266805503,GB
3266805504,3266805759,NL
-3266805760,3266809343,AT
-3266809344,3266809599,LI
-3266809600,3266813951,AT
+3266805760,3266813951,AT
3266813952,3266822143,UA
3266822144,3266830335,FR
3266830336,3266835151,BE
@@ -77452,9 +80913,7 @@
3267666448,3267666463,EU
3267666464,3267666543,GB
3267666544,3267666575,EU
-3267666576,3267666951,GB
-3267666952,3267666959,EU
-3267666960,3267667199,GB
+3267666576,3267667199,GB
3267667200,3267667455,NL
3267667456,3267667967,GB
3267667968,3267670015,EU
@@ -77656,8 +81115,8 @@
3268223232,3268224767,EU
3268224768,3268225023,US
3268225024,3268226367,EU
-3268226368,3268226639,GB
-3268226640,3268226687,EU
+3268226368,3268226655,GB
+3268226656,3268226687,EU
3268226688,3268226815,GB
3268226816,3268227327,EU
3268227328,3268227391,GB
@@ -77712,8 +81171,10 @@
3268238360,3268238367,DE
3268238368,3268238463,GB
3268238464,3268238471,DE
-3268238472,3268238623,GB
-3268238624,3268239103,EU
+3268238472,3268238759,GB
+3268238760,3268238767,EU
+3268238768,3268238847,GB
+3268238848,3268239103,EU
3268239104,3268239359,GB
3268239360,3268239583,EU
3268239584,3268240127,GB
@@ -77763,9 +81224,7 @@
3268248320,3268248447,GB
3268248448,3268248511,EU
3268248512,3268248543,GB
-3268248544,3268248831,EU
-3268248832,3268248959,GB
-3268248960,3268249599,EU
+3268248544,3268249599,EU
3268249600,3268251311,GB
3268251312,3268251327,IE
3268251328,3268251583,GB
@@ -78477,9 +81936,7 @@
3271280688,3271280703,SE
3271280704,3271280719,FI
3271280720,3271280735,SE
-3271280736,3271282687,FI
-3271282688,3271284735,AX
-3271284736,3271290623,FI
+3271280736,3271290623,FI
3271290624,3271290879,BE
3271290880,3271299071,FI
3271299072,3271299199,AX
@@ -79630,7 +83087,7 @@
3273015296,3273023487,SE
3273023488,3273024511,PL
3273024512,3273025535,NL
-3273025536,3273027583,RU
+3273025536,3273026559,RU
3273027584,3273028607,UA
3273028608,3273029631,PL
3273029632,3273030655,DK
@@ -79660,7 +83117,8 @@
3273050784,3273050879,GR
3273050880,3273051647,IT
3273051648,3273051903,US
-3273051904,3273052039,IT
+3273051904,3273051967,IE
+3273051968,3273052039,IT
3273052040,3273052047,NL
3273052048,3273052063,GR
3273052064,3273052087,IT
@@ -79753,8 +83211,8 @@
3273327280,3273327287,DE
3273327288,3273327359,EU
3273327360,3273327423,IE
-3273327424,3273327503,GB
-3273327504,3273327519,EU
+3273327424,3273327511,GB
+3273327512,3273327519,EU
3273327520,3273327551,IE
3273327552,3273328511,EU
3273328512,3273328639,DE
@@ -79870,8 +83328,8 @@
3273364992,3273365247,DE
3273365248,3273365503,EU
3273365504,3273365519,NL
-3273365520,3273365527,GB
-3273365528,3273365759,NL
+3273365520,3273365543,GB
+3273365544,3273365759,NL
3273365760,3273365767,GB
3273365768,3273365887,EU
3273365888,3273366015,FR
@@ -79957,12 +83415,12 @@
3273388928,3273389055,DE
3273389056,3273390079,EU
3273390080,3273390111,DE
-3273390112,3273390143,EU
+3273390112,3273390143,US
3273390144,3273390207,DE
3273390208,3273390335,EU
3273390336,3273390463,DE
-3273390464,3273391231,EU
-3273391232,3273391327,DE
+3273390464,3273391103,EU
+3273391104,3273391327,DE
3273391328,3273391343,EU
3273391344,3273391359,DE
3273391360,3273391871,EU
@@ -79997,7 +83455,6 @@
3273438208,3273438719,IL
3273438720,3273439231,PL
3273439232,3273439743,RO
-3273439744,3273440255,UA
3273440256,3273440767,RO
3273440768,3273441279,AT
3273441280,3273441463,FR
@@ -80061,7 +83518,7 @@
3273803776,3273804287,CH
3273804288,3273804799,UA
3273804800,3273805311,RO
-3273805312,3273805823,GB
+3273805312,3273805823,GI
3273805824,3273806335,PL
3273806336,3273806847,DE
3273806848,3273807359,SE
@@ -80521,6 +83978,7 @@
3274698752,3274699007,GB
3274699008,3274699263,FR
3274699264,3274699519,RO
+3274699520,3274699775,SI
3274699776,3274700031,GB
3274700032,3274700287,CH
3274700288,3274700543,PL
@@ -80553,6 +84011,7 @@
3274821632,3274823679,KZ
3274823680,3274825727,TR
3274825728,3274827775,DE
+3274827776,3274829823,RO
3274829824,3274831871,SE
3274831872,3274833919,RO
3274833920,3274842111,BY
@@ -80792,13 +84251,11 @@
3275423808,3275423871,EU
3275423872,3275424255,GB
3275424256,3275425791,EU
-3275425792,3275426599,GB
-3275426600,3275426607,EU
-3275426608,3275426671,GB
-3275426672,3275426815,EU
-3275426816,3275427199,GB
-3275427200,3275427327,EU
-3275427328,3275427583,GB
+3275425792,3275426687,GB
+3275426688,3275426815,EU
+3275426816,3275427271,GB
+3275427272,3275427279,EU
+3275427280,3275427583,GB
3275427584,3275427839,EU
3275427840,3275428375,GB
3275428376,3275428383,EU
@@ -80810,8 +84267,8 @@
3275430400,3275430591,EU
3275430592,3275430623,GB
3275430624,3275431935,EU
-3275431936,3275432447,GB
-3275432448,3275433983,EU
+3275431936,3275432703,GB
+3275432704,3275433983,EU
3275433984,3275437567,GB
3275437568,3275438079,EU
3275438080,3275438607,GB
@@ -80822,8 +84279,10 @@
3275442720,3275444223,EU
3275444224,3275444735,GB
3275444736,3275446271,EU
-3275446272,3275446943,GB
-3275446944,3275448319,EU
+3275446272,3275446991,GB
+3275446992,3275447007,EU
+3275447008,3275447039,GB
+3275447040,3275448319,EU
3275448320,3275449519,GB
3275449520,3275449527,FR
3275449528,3275450879,GB
@@ -80832,20 +84291,20 @@
3275451264,3275452415,EU
3275452416,3275454127,GB
3275454128,3275454143,EU
-3275454144,3275454159,GB
-3275454160,3275454463,EU
-3275454464,3275456383,GB
-3275456384,3275456511,EU
+3275454144,3275454263,GB
+3275454264,3275454271,EU
+3275454272,3275454367,GB
+3275454368,3275454463,EU
+3275454464,3275456415,GB
+3275456416,3275456511,EU
3275456512,3275457023,GB
3275457024,3275457791,FK
3275457792,3275458559,GB
3275458560,3275460095,IE
3275460096,3275460607,EU
3275460608,3275460863,HK
-3275460864,3275463471,GB
-3275463472,3275463487,EU
-3275463488,3275463519,GB
-3275463520,3275463679,EU
+3275460864,3275463523,GB
+3275463524,3275463679,EU
3275463680,3275464031,GB
3275464032,3275464047,IE
3275464048,3275468655,GB
@@ -80875,8 +84334,8 @@
3275509984,3275510015,PT
3275510016,3275510079,SE
3275510080,3275510143,ES
-3275510144,3275510207,IT
-3275510336,3275510399,IE
+3275510208,3275510271,SE
+3275510272,3275510399,IE
3275510400,3275510463,NL
3275510464,3275510527,GB
3275510528,3275510559,PL
@@ -81121,7 +84580,6 @@
3275628032,3275628543,IL
3275628544,3275629567,RU
3275629568,3275630079,UA
-3275630080,3275630591,EU
3275630592,3275631103,PL
3275631104,3275631615,FR
3275631616,3275632127,DE
@@ -81374,12 +84832,10 @@
3276018096,3276018127,GB
3276018128,3276018143,FR
3276018144,3276018159,GB
-3276018160,3276018183,FR
-3276018184,3276018207,GB
-3276018208,3276018375,FR
+3276018160,3276018375,FR
3276018376,3276018383,GB
-3276018384,3276018423,FR
-3276018424,3276018447,GB
+3276018384,3276018431,FR
+3276018432,3276018447,GB
3276018448,3276018495,FR
3276018496,3276018527,GB
3276018528,3276018543,FR
@@ -81414,15 +84870,15 @@
3276019864,3276019887,GB
3276019888,3276019919,FR
3276019920,3276019927,GB
-3276019928,3276020103,FR
-3276020104,3276020111,GB
-3276020112,3276020399,FR
+3276019928,3276020367,FR
+3276020368,3276020383,GB
+3276020384,3276020399,FR
3276020400,3276020423,GB
3276020424,3276020431,FR
3276020432,3276020439,GB
3276020440,3276020495,FR
-3276020496,3276020503,GB
-3276020504,3276020559,FR
+3276020496,3276020511,GB
+3276020512,3276020559,FR
3276020560,3276020567,GB
3276020568,3276020623,FR
3276020624,3276020631,GB
@@ -81434,14 +84890,10 @@
3276020880,3276020887,GB
3276020888,3276020943,FR
3276020944,3276020991,GB
-3276020992,3276021103,FR
-3276021104,3276021111,GB
-3276021112,3276021527,FR
-3276021528,3276021535,GB
-3276021536,3276021591,FR
+3276020992,3276021591,FR
3276021592,3276021599,GB
-3276021600,3276021855,FR
-3276021856,3276021871,GB
+3276021600,3276021863,FR
+3276021864,3276021871,GB
3276021872,3276022039,FR
3276022040,3276022047,GB
3276022048,3276022087,FR
@@ -81518,7 +84970,9 @@
3276026320,3276026351,GB
3276026352,3276026423,FR
3276026424,3276026431,GB
-3276026432,3276026527,FR
+3276026432,3276026439,FR
+3276026440,3276026447,GB
+3276026448,3276026527,FR
3276026528,3276026535,GB
3276026536,3276026543,FR
3276026544,3276026575,GB
@@ -81592,7 +85046,9 @@
3276029856,3276029887,GB
3276029888,3276029919,FR
3276029920,3276029967,GB
-3276029968,3276030079,FR
+3276029968,3276029983,FR
+3276029984,3276029999,GB
+3276030000,3276030079,FR
3276030080,3276030095,GB
3276030096,3276030191,FR
3276030192,3276030207,GB
@@ -81604,7 +85060,9 @@
3276030272,3276030303,GB
3276030304,3276030407,FR
3276030408,3276030415,GB
-3276030416,3276030543,FR
+3276030416,3276030463,FR
+3276030464,3276030495,GB
+3276030496,3276030543,FR
3276030544,3276030559,GB
3276030560,3276031255,FR
3276031256,3276031263,GB
@@ -81824,7 +85282,9 @@
3276045288,3276045311,GB
3276045312,3276045351,FR
3276045352,3276045359,GB
-3276045360,3276045455,FR
+3276045360,3276045391,FR
+3276045392,3276045407,GB
+3276045408,3276045455,FR
3276045456,3276045463,GB
3276045464,3276045479,FR
3276045480,3276045487,GB
@@ -81837,8 +85297,8 @@
3276045648,3276045767,FR
3276045768,3276045783,GB
3276045784,3276045815,FR
-3276045816,3276045823,GB
-3276045824,3276045919,FR
+3276045816,3276045855,GB
+3276045856,3276045919,FR
3276045920,3276045951,GB
3276045952,3276046335,FR
3276046336,3276062719,RU
@@ -81908,10 +85368,11 @@
3276128256,3276129279,AT
3276129280,3276131327,UA
3276131328,3276132351,DK
+3276132352,3276133375,PL
3276133376,3276134399,GB
3276134400,3276135423,RU
3276135424,3276136447,UA
-3276136448,3276138495,PL
+3276137472,3276138495,PL
3276138496,3276139519,NL
3276139520,3276140543,IL
3276140544,3276141567,DE
@@ -81925,11 +85386,7 @@
3276185600,3276193791,NO
3276193792,3276201983,RU
3276201984,3276210175,AT
-3276210176,3276227607,DE
-3276227608,3276227615,MT
-3276227616,3276227727,DE
-3276227728,3276227743,MT
-3276227744,3276233791,DE
+3276210176,3276233791,DE
3276233792,3276233799,RO
3276233800,3276233807,DE
3276233808,3276233823,RO
@@ -84051,7 +87508,9 @@
3276474272,3276474295,AT
3276474296,3276474319,EU
3276474320,3276474367,AT
-3276474368,3276475015,EU
+3276474368,3276474623,EU
+3276474624,3276474879,GB
+3276474880,3276475015,EU
3276475016,3276475063,IT
3276475064,3276475071,EU
3276475072,3276475135,IT
@@ -84435,8 +87894,8 @@
3276535552,3276535807,PK
3276535808,3276536063,FI
3276536064,3276536319,EU
-3276536320,3276536415,ES
-3276536416,3276536447,EU
+3276536320,3276536430,ES
+3276536431,3276536447,EU
3276536448,3276536511,ES
3276536512,3276536583,EU
3276536584,3276536591,HR
@@ -84446,8 +87905,8 @@
3276536688,3276536711,HU
3276536712,3276536735,EU
3276536736,3276536743,HU
-3276536744,3276536863,EU
-3276536864,3276536895,ES
+3276536744,3276536831,EU
+3276536832,3276536895,ES
3276536896,3276536967,EU
3276536968,3276536991,ES
3276536992,3276537151,EU
@@ -84497,13 +87956,13 @@
3276697088,3276697599,GB
3276697600,3276698111,UA
3276698112,3276699647,RU
-3276700160,3276700671,KZ
+3276700160,3276700671,UA
3276700672,3276701183,RO
3276701184,3276701695,RU
3276701696,3276709887,SE
3276709888,3276718079,DE
3276718080,3276726271,IT
-3276726272,3276727295,PK
+3276726272,3276727295,DE
3276727296,3276728319,ES
3276728320,3276729343,UA
3276729344,3276730367,PL
@@ -84907,7 +88366,9 @@
3276861440,3276865535,DK
3276865536,3276866559,NL
3276866560,3276866815,IT
-3276866816,3276866863,DE
+3276866816,3276866831,DE
+3276866832,3276866839,GB
+3276866840,3276866863,DE
3276866864,3276866879,GB
3276866880,3276866959,DE
3276866960,3276866967,GB
@@ -84927,12 +88388,10 @@
3276872480,3276872511,GB
3276872512,3276872703,DE
3276872704,3276873727,GB
-3276873728,3276874335,ES
-3276874336,3276874367,GB
+3276873728,3276874351,ES
+3276874352,3276874367,GB
3276874368,3276874751,ES
-3276874752,3276875007,NL
-3276875008,3276875263,GB
-3276875264,3276875775,NL
+3276874752,3276875775,NL
3276875776,3276876031,GB
3276876032,3276876287,DK
3276876288,3276876799,GB
@@ -84961,8 +88420,8 @@
3276883968,3276884487,PL
3276884488,3276886015,GB
3276886016,3276886271,RO
-3276886272,3276887551,GB
-3276887552,3276888063,DE
+3276886272,3276887167,GB
+3276887168,3276888063,DE
3276888064,3276888575,GB
3276888576,3276888831,AT
3276888832,3276889087,GB
@@ -84977,9 +88436,7 @@
3276891392,3276892159,US
3276892160,3276893695,IT
3276893696,3276894463,GB
-3276894464,3276894719,IT
-3276894720,3276894975,GB
-3276894976,3276895999,IT
+3276894464,3276895999,IT
3276896000,3276896255,CZ
3276896256,3276896831,BE
3276896832,3276896847,SE
@@ -84991,15 +88448,21 @@
3276898304,3276898775,CH
3276898776,3276898783,GB
3276898784,3276900039,CH
-3276900040,3276900095,GB
-3276900096,3276900351,CH
+3276900040,3276900047,GB
+3276900048,3276900351,CH
3276900352,3276900607,GB
-3276900608,3276900735,CH
-3276900736,3276902143,GB
+3276900608,3276900799,CH
+3276900800,3276900863,GB
+3276900864,3276901119,CH
+3276901120,3276901375,GB
+3276901376,3276901391,CH
+3276901392,3276902143,GB
3276902144,3276902151,CH
3276902152,3276902159,GB
3276902160,3276902175,CH
-3276902176,3276902399,GB
+3276902176,3276902207,GB
+3276902208,3276902271,CH
+3276902272,3276902399,GB
3276902400,3276902575,SE
3276902576,3276902655,GB
3276902656,3276903422,SE
@@ -85009,15 +88472,20 @@
3276905312,3276905319,ES
3276905320,3276905471,GB
3276905472,3276905727,SE
-3276905728,3276906239,BE
+3276905728,3276905983,BE
+3276905984,3276905999,GB
+3276906000,3276906003,BE
+3276906004,3276906239,GB
3276906240,3276906279,SE
3276906280,3276906495,GB
3276906496,3276906863,NL
3276906864,3276906879,GB
3276906880,3276907551,NL
3276907552,3276907775,GB
-3276907776,3276908031,NL
-3276908032,3276910079,GB
+3276907776,3276908159,NL
+3276908160,3276908287,GB
+3276908288,3276908543,NL
+3276908544,3276910079,GB
3276910080,3276910591,NL
3276910592,3276910967,IT
3276910968,3276910975,GB
@@ -85028,9 +88496,7 @@
3276913216,3276913919,IT
3276913920,3276913983,US
3276913984,3276914687,IT
-3276914688,3276915455,ES
-3276915456,3276915487,GB
-3276915488,3276916175,ES
+3276914688,3276916175,ES
3276916176,3276916183,GB
3276916184,3276917231,ES
3276917232,3276917247,GB
@@ -85038,28 +88504,28 @@
3276917280,3276917287,GB
3276917288,3276917311,ES
3276917312,3276917343,GB
-3276917344,3276917823,ES
-3276917824,3276918271,GB
-3276918272,3276918783,ES
+3276917344,3276917887,ES
+3276917888,3276918015,GB
+3276918016,3276918783,ES
3276918784,3276920551,DE
3276920552,3276920559,GB
3276920560,3276921183,DE
3276921184,3276921191,GB
3276921192,3276921239,DE
-3276921240,3276921343,GB
-3276921344,3276921399,DE
+3276921240,3276921247,GB
+3276921248,3276921279,DE
+3276921280,3276921295,GB
+3276921296,3276921303,DE
+3276921304,3276921399,GB
3276921400,3276921403,DK
-3276921404,3276921607,DE
-3276921608,3276921855,GB
-3276921856,3276922623,DE
+3276921404,3276921599,GB
+3276921600,3276921607,DE
+3276921608,3276921727,GB
+3276921728,3276922623,DE
3276922624,3276923431,FR
-3276923432,3276923455,GB
-3276923456,3276923615,FR
-3276923616,3276923647,GB
-3276923648,3276923743,FR
-3276923744,3276923751,GB
-3276923752,3276924039,FR
-3276924040,3276924095,GB
+3276923432,3276923439,GB
+3276923440,3276924071,FR
+3276924072,3276924095,GB
3276924096,3276924351,FR
3276924352,3276924415,GB
3276924416,3276925951,FR
@@ -85276,18 +88742,13 @@
3277464832,3277467471,US
3277467472,3277467551,CA
3277467552,3277471743,US
-3277471744,3277472511,NL
-3277472512,3277472607,EU
+3277471744,3277472607,NL
3277472608,3277472623,IL
-3277472624,3277474815,EU
+3277472624,3277474815,NL
3277474816,3277475711,BE
-3277475712,3277475839,EU
-3277475840,3277476095,NL
-3277476096,3277476607,EU
+3277475712,3277476607,NL
3277476608,3277477631,BE
-3277477632,3277478143,EU
-3277478144,3277478399,NL
-3277478400,3277479935,EU
+3277477632,3277479935,NL
3277479936,3277480959,GB
3277480960,3277481471,DK
3277481472,3277481983,PL
@@ -85319,6 +88780,7 @@
3277687296,3277687807,UA
3277687808,3277688319,RO
3277688320,3277688831,PL
+3277688832,3277689343,RU
3277689344,3277689855,AT
3277689856,3277690879,RU
3277690880,3277691391,KZ
@@ -85451,6 +88913,7 @@
3277840384,3277840895,FR
3277840896,3277841407,GR
3277841408,3277841919,RO
+3277841920,3277842431,IT
3277842432,3277842943,UA
3277842944,3277843455,PL
3277843456,3277843967,PT
@@ -85489,9 +88952,7 @@
3278054912,3278055423,NL
3278055424,3278061567,GB
3278061568,3278065663,NL
-3278065664,3278067967,GB
-3278067968,3278068223,BE
-3278068224,3278103039,GB
+3278065664,3278103039,GB
3278103040,3278103295,FR
3278103296,3278110719,GB
3278110720,3278110751,SE
@@ -85501,8 +88962,8 @@
3278111248,3278115327,SE
3278115328,3278116607,ES
3278116608,3278116863,SE
-3278116864,3278118303,ES
-3278118304,3278119935,SE
+3278116864,3278118399,ES
+3278118400,3278119935,SE
3278119936,3278119943,DE
3278119944,3278119967,SE
3278119968,3278119975,NO
@@ -85537,13 +88998,13 @@
3278769664,3278770175,DE
3278770176,3278770687,DK
3278770688,3278771199,DE
-3278771200,3278771711,GB
3278771712,3278772223,NL
3278772224,3278772735,BG
3278772736,3278773247,DE
3278773248,3278773759,NO
3278773760,3278774271,GB
3278774272,3278774783,RU
+3278774784,3278775295,FR
3278775296,3278775807,GB
3278775808,3278776319,IR
3278776320,3278776831,IL
@@ -85560,7 +89021,7 @@
3278782464,3278782975,GB
3278782976,3278783231,DE
3278783232,3278784703,GB
-3278784704,3278784735,US
+3278784704,3278784735,NL
3278784736,3278786911,GB
3278786912,3278786943,LU
3278786944,3278787567,GB
@@ -85637,8 +89098,7 @@
3278938368,3278938375,FR
3278938376,3278938379,DE
3278938380,3278938383,FR
-3278938384,3278938387,ZA
-3278938388,3278938399,DE
+3278938384,3278938399,DE
3278938400,3278938403,AT
3278938404,3278938407,GB
3278938408,3278938411,CH
@@ -85909,7 +89369,9 @@
3278939780,3278939783,FR
3278939784,3278939787,BE
3278939788,3278939791,DE
-3278939792,3278939803,ES
+3278939792,3278939795,ES
+3278939796,3278939799,DE
+3278939800,3278939803,ES
3278939804,3278939807,GB
3278939808,3278939815,DE
3278939816,3278939819,NL
@@ -86108,7 +89570,7 @@
3278940804,3278940807,DK
3278940808,3278940815,DE
3278940816,3278940819,IT
-3278940820,3278940823,GB
+3278940820,3278940823,DE
3278940824,3278940827,IT
3278940828,3278940831,DE
3278940832,3278940835,CH
@@ -86753,7 +90215,7 @@
3278943203,3278943203,SE
3278943204,3278943206,DE
3278943207,3278943207,IT
-3278943208,3278943208,GB
+3278943208,3278943208,DE
3278943209,3278943209,ES
3278943210,3278943212,IT
3278943213,3278943213,DE
@@ -87615,9 +91077,7 @@
3278944366,3278944366,MX
3278944367,3278944367,US
3278944368,3278944368,CA
-3278944369,3278944373,US
-3278944374,3278944374,PR
-3278944375,3278944379,US
+3278944369,3278944379,US
3278944380,3278944380,DE
3278944381,3278944385,US
3278944386,3278944386,DE
@@ -87684,9 +91144,7 @@
3278944580,3278944580,AR
3278944581,3278944581,US
3278944582,3278944583,DE
-3278944584,3278944586,US
-3278944587,3278944587,PR
-3278944588,3278944588,US
+3278944584,3278944588,US
3278944589,3278944589,DE
3278944590,3278944599,US
3278944600,3278944600,SA
@@ -87895,7 +91353,7 @@
3278945797,3278945797,BE
3278945798,3278945798,NL
3278945799,3278945799,LU
-3278945800,3278945800,SE
+3278945800,3278945800,DE
3278945801,3278945801,NL
3278945802,3278945802,PT
3278945803,3278945803,GB
@@ -87954,8 +91412,8 @@
3278945875,3278945875,ES
3278945876,3278945876,NL
3278945877,3278945877,SE
-3278945878,3278945879,FR
-3278945880,3278945880,DE
+3278945878,3278945878,FR
+3278945879,3278945880,DE
3278945881,3278945881,BE
3278945882,3278945886,DE
3278945887,3278945888,IT
@@ -88268,13 +91726,17 @@
3279593536,3279593567,DE
3279593568,3279593599,GB
3279593600,3279594495,DE
-3279594496,3279595903,GB
+3279594496,3279595775,GB
+3279595776,3279595839,DE
+3279595840,3279595903,GB
3279595904,3279595999,DE
3279596000,3279596023,GB
3279596024,3279596031,DE
3279596032,3279596543,GB
3279596544,3279597311,DE
-3279597312,3279600383,GB
+3279597312,3279598591,GB
+3279598592,3279599615,DE
+3279599616,3279600383,GB
3279600384,3279600479,DE
3279600480,3279600487,GB
3279600488,3279600639,DE
@@ -88343,8 +91805,7 @@
3280011784,3280011791,BE
3280011792,3280011903,EU
3280011904,3280011951,BE
-3280011952,3280014847,EU
-3280014848,3280015103,FR
+3280011952,3280015103,EU
3280015104,3280015359,GB
3280015360,3280015871,EU
3280015872,3280016383,GB
@@ -88922,8 +92383,14 @@
3280933617,3280933618,GB
3280933619,3280933620,DE
3280933621,3280933631,GB
-3280933632,3280934399,DE
-3280934400,3280934655,GB
+3280933632,3280933647,DE
+3280933648,3280933687,GB
+3280933688,3280933699,DE
+3280933700,3280933703,GB
+3280933704,3280933855,DE
+3280933856,3280934219,GB
+3280934220,3280934243,DE
+3280934244,3280934655,GB
3280934656,3280934863,DE
3280934864,3280934911,GB
3280934912,3280934943,DE
@@ -89202,8 +92669,10 @@
3280950016,3280950655,GB
3280950656,3280950687,DE
3280950688,3280951039,GB
-3280951040,3280952063,DE
-3280952064,3280952067,GB
+3280951040,3280951807,DE
+3280951808,3280951819,GB
+3280951820,3280951831,DE
+3280951832,3280952067,GB
3280952068,3280952079,DE
3280952080,3280952087,GB
3280952088,3280952095,DE
@@ -89270,7 +92739,13 @@
3280954128,3280954367,GB
3280954368,3280954495,DE
3280954496,3280955391,GB
-3280955392,3280956927,DE
+3280955392,3280955419,DE
+3280955420,3280955423,GB
+3280955424,3280955791,DE
+3280955792,3280955799,GB
+3280955800,3280956143,DE
+3280956144,3280956415,GB
+3280956416,3280956927,DE
3280956928,3280956991,GB
3280956992,3280957007,DE
3280957008,3280957015,GB
@@ -89286,8 +92761,8 @@
3280957250,3280957255,GB
3280957256,3280957263,DE
3280957264,3280957311,GB
-3280957312,3280957695,DE
-3280957696,3280957743,GB
+3280957312,3280957503,DE
+3280957504,3280957743,GB
3280957744,3280957791,DE
3280957792,3280957823,GB
3280957824,3280957839,DE
@@ -89310,13 +92785,15 @@
3280958916,3280958919,GB
3280958920,3280958927,DE
3280958928,3280958975,GB
-3280958976,3280959231,DE
-3280959232,3280959487,GB
+3280958976,3280959199,DE
+3280959200,3280959487,GB
3280959488,3280959711,DE
3280959712,3280959743,GB
3280959744,3280959935,DE
-3280959936,3280959999,GB
-3280960000,3280960039,DE
+3280959936,3280960015,GB
+3280960016,3280960023,DE
+3280960024,3280960031,GB
+3280960032,3280960039,DE
3280960040,3280960255,GB
3280960256,3280960287,DE
3280960288,3280960511,GB
@@ -89340,8 +92817,14 @@
3280963264,3280963303,GB
3280963304,3280963311,DE
3280963312,3280963327,GB
-3280963328,3280963583,DE
-3280963584,3280963590,GB
+3280963328,3280963343,DE
+3280963344,3280963359,GB
+3280963360,3280963495,DE
+3280963496,3280963511,GB
+3280963512,3280963515,DE
+3280963516,3280963519,GB
+3280963520,3280963527,DE
+3280963528,3280963590,GB
3280963591,3280963591,DE
3280963592,3280963593,GB
3280963594,3280963595,DE
@@ -89438,7 +92921,9 @@
3280976720,3280976831,GB
3280976832,3280976847,DE
3280976848,3280976895,GB
-3280976896,3280977407,DE
+3280976896,3280977119,DE
+3280977120,3280977135,GB
+3280977136,3280977407,DE
3280977408,3280977439,GB
3280977440,3280977479,DE
3280977480,3280977487,GB
@@ -90123,7 +93608,6 @@
3281343232,3281343487,FI
3281343488,3281343743,GB
3281343744,3281343999,TR
-3281344000,3281344255,PL
3281344256,3281344511,RU
3281344512,3281344767,UA
3281344768,3281345023,RU
@@ -90229,9 +93713,7 @@
3281975296,3281976319,RU
3281976320,3281976831,DE
3281976832,3281977343,RU
-3281977344,3281999095,NO
-3281999096,3281999103,US
-3281999104,3282042879,NO
+3281977344,3282042879,NO
3282042880,3282083839,CH
3282083840,3282084351,DE
3282084352,3282084863,RO
@@ -90284,6 +93766,14 @@
3282181120,3282181631,GB
3282181632,3282182143,DE
3282182144,3282190335,RU
+3282190336,3282190847,UA
+3282190848,3282191359,IL
+3282191360,3282191871,RU
+3282191872,3282192383,UA
+3282192384,3282192895,BG
+3282192896,3282193407,UA
+3282193408,3282193919,PL
+3282193920,3282194431,RU
3282194432,3282195455,UA
3282195456,3282196479,IE
3282196480,3282197503,UA
@@ -90407,9 +93897,7 @@
3283091456,3283156991,CH
3283156992,3283158215,DE
3283158216,3283158219,EE
-3283158220,3283160171,DE
-3283160172,3283160175,BE
-3283160176,3283173375,DE
+3283158220,3283173375,DE
3283173376,3283174399,PL
3283174400,3283176447,UA
3283176448,3283177471,GB
@@ -90497,7 +93985,9 @@
3283291488,3283291491,ES
3283291492,3283304919,DE
3283304920,3283304923,ES
-3283304924,3283305087,DE
+3283304924,3283304959,DE
+3283304960,3283305023,GB
+3283305024,3283305087,DE
3283305088,3283305127,FR
3283305128,3283305711,DE
3283305712,3283305715,ES
@@ -90997,26 +94487,25 @@
3283650960,3283650975,CH
3283650976,3283651071,GB
3283651072,3283651135,IT
-3283651136,3283651167,EU
+3283651136,3283651167,BE
3283651168,3283651183,ES
-3283651184,3283651199,EU
+3283651184,3283651199,BE
3283651200,3283651263,HU
3283651264,3283651327,ZA
-3283651328,3283651423,EU
+3283651328,3283651423,BE
3283651424,3283651439,DE
-3283651440,3283651463,EU
+3283651440,3283651463,BE
3283651464,3283651471,DE
-3283651472,3283651487,EU
+3283651472,3283651487,BE
3283651488,3283651519,FR
3283651520,3283651583,IL
3283651584,3283651591,GB
-3283651592,3283651599,EU
+3283651592,3283651599,BE
3283651600,3283651615,DE
-3283651616,3283651647,EU
+3283651616,3283651647,BE
3283651648,3283651663,SE
3283651664,3283651671,RO
-3283651672,3283651679,BE
-3283651680,3283651687,EU
+3283651672,3283651687,BE
3283651688,3283651695,IT
3283651696,3283651711,GB
3283651712,3283651727,CH
@@ -91027,21 +94516,20 @@
3283651840,3283651967,NL
3283651968,3283652031,DK
3283652032,3283652063,DE
-3283652064,3283652071,EU
+3283652064,3283652071,BE
3283652072,3283652079,GB
-3283652080,3283652095,EU
+3283652080,3283652095,BE
3283652096,3283652351,GB
3283652352,3283652479,IT
-3283652480,3283652519,EU
+3283652480,3283652519,BE
3283652520,3283652527,SE
-3283652528,3283652543,EU
+3283652528,3283652543,BE
3283652544,3283652575,FR
3283652576,3283652607,DE
3283652608,3283652863,NO
-3283652864,3283653055,BE
-3283653056,3283653247,EU
+3283652864,3283653247,BE
3283653248,3283653311,NO
-3283653312,3283653503,EU
+3283653312,3283653503,BE
3283653504,3283653631,GB
3283653632,3283653887,FR
3283653888,3283654015,SE
@@ -91049,7 +94537,7 @@
3283654144,3283654399,DE
3283654400,3283654655,CH
3283654656,3283654911,DK
-3283654912,3283655039,EU
+3283654912,3283655039,BE
3283655040,3283655167,DK
3283655168,3283655295,DE
3283655296,3283655423,BE
@@ -91057,16 +94545,16 @@
3283655680,3283655935,ES
3283655936,3283656191,ZA
3283656192,3283656223,GB
-3283656224,3283656255,EU
+3283656224,3283656255,BE
3283656256,3283656271,GB
-3283656272,3283656303,EU
+3283656272,3283656303,BE
3283656304,3283656311,GB
-3283656312,3283656447,EU
+3283656312,3283656447,BE
3283656448,3283656559,ES
3283656560,3283656575,FR
-3283656576,3283656591,EU
+3283656576,3283656591,BE
3283656592,3283656599,FR
-3283656600,3283656703,EU
+3283656600,3283656703,BE
3283656704,3283664895,HU
3283664896,3283673087,UA
3283673088,3283681279,GB
@@ -91240,7 +94728,6 @@
3284041984,3284042239,SI
3284042240,3284042495,GB
3284042496,3284042751,AT
-3284042752,3284043007,GB
3284043008,3284043263,DE
3284043264,3284043519,EE
3284043520,3284043775,DE
@@ -91366,7 +94853,6 @@
3284127232,3284127743,NL
3284127744,3284128255,RU
3284128256,3284128767,GB
-3284128768,3284129279,CZ
3284129280,3284129791,UA
3284129792,3284130303,DE
3284130304,3284130815,GB
@@ -91496,20 +94982,17 @@
3285057536,3285065727,IT
3285065728,3285073919,RU
3285073920,3285074687,GB
-3285074688,3285075199,NL
-3285075200,3285076607,EU
+3285074688,3285076607,NL
3285076608,3285076767,BE
-3285076768,3285078111,EU
+3285076768,3285078111,NL
3285078112,3285078143,GB
-3285078144,3285078175,EU
+3285078144,3285078175,NL
3285078176,3285078191,GB
-3285078192,3285079423,EU
+3285078192,3285079423,NL
3285079424,3285079551,DE
-3285079552,3285079807,EU
-3285079808,3285079935,NL
-3285079936,3285079967,EU
+3285079552,3285079967,NL
3285079968,3285079999,DE
-3285080000,3285082111,EU
+3285080000,3285082111,NL
3285082112,3285084159,AT
3285084160,3285085183,LU
3285085184,3285086207,GB
@@ -91568,6 +95051,7 @@
3285333504,3285334015,GB
3285334016,3285334527,NL
3285334528,3285335039,DE
+3285335040,3285335551,PL
3285335552,3285336063,SE
3285336064,3285352447,IT
3285352448,3285368831,RU
@@ -91625,11 +95109,7 @@
3285453056,3285453119,EU
3285453120,3285453415,GB
3285453416,3285453423,EU
-3285453424,3285453439,GB
-3285453440,3285453567,EU
-3285453568,3285453623,GB
-3285453624,3285453631,EU
-3285453632,3285454047,GB
+3285453424,3285454047,GB
3285454048,3285454079,EU
3285454080,3285454175,GB
3285454176,3285454207,EU
@@ -91827,8 +95307,8 @@
3285472000,3285472127,DE
3285472128,3285472159,EU
3285472160,3285472175,DE
-3285472176,3285472191,EU
-3285472192,3285472223,DE
+3285472176,3285472183,EU
+3285472184,3285472223,DE
3285472224,3285472255,EU
3285472256,3285472287,DE
3285472288,3285472367,EU
@@ -91906,8 +95386,8 @@
3285479424,3285479807,CH
3285479808,3285480447,EU
3285480448,3285480575,CH
-3285480576,3285480735,EU
-3285480736,3285480767,CH
+3285480576,3285480719,EU
+3285480720,3285480767,CH
3285480768,3285480775,EU
3285480776,3285480895,CH
3285480896,3285480959,EU
@@ -92110,7 +95590,7 @@
3285516224,3285516287,GR
3285516288,3285516543,DK
3285516544,3285516671,NO
-3285516672,3285516687,EU
+3285516672,3285516687,BE
3285516688,3285516691,NL
3285516692,3285516695,IT
3285516696,3285516703,NL
@@ -92119,17 +95599,17 @@
3285516736,3285516799,DE
3285516800,3285516927,GB
3285516928,3285516991,PL
-3285516992,3285517023,EU
+3285516992,3285517023,BE
3285517024,3285517055,SE
3285517056,3285517215,GB
3285517216,3285517247,AT
3285517248,3285518335,GB
3285518336,3285518351,NL
3285518352,3285518367,ES
-3285518368,3285518463,EU
+3285518368,3285518463,BE
3285518464,3285518591,ES
3285518592,3285518847,CH
-3285518848,3285519103,EU
+3285518848,3285519103,BE
3285519104,3285519359,FR
3285519360,3285519615,DE
3285519616,3285520127,GB
@@ -92140,20 +95620,19 @@
3285520576,3285520639,DE
3285520640,3285520767,NL
3285520768,3285520895,GB
-3285520896,3285521167,EU
+3285520896,3285521167,BE
3285521168,3285521407,GB
-3285521408,3285521535,BE
-3285521536,3285521695,EU
+3285521408,3285521695,BE
3285521696,3285521791,GB
-3285521792,3285522175,EU
+3285521792,3285522175,BE
3285522176,3285523071,GB
-3285523072,3285523079,EU
+3285523072,3285523079,BE
3285523080,3285523087,ES
3285523088,3285523199,CH
3285523200,3285523231,ZA
-3285523232,3285523327,EU
+3285523232,3285523327,BE
3285523328,3285523335,FI
-3285523336,3285523359,EU
+3285523336,3285523359,BE
3285523360,3285523391,GB
3285523392,3285523711,FR
3285523712,3285523967,CH
@@ -92164,106 +95643,89 @@
3285524176,3285524191,CH
3285524192,3285524223,BE
3285524224,3285524351,GB
-3285524352,3285524479,EU
+3285524352,3285524479,BE
3285524480,3285524735,DK
3285524736,3285524863,GB
-3285524864,3285524879,EU
-3285524880,3285524895,BE
+3285524864,3285524895,BE
3285524896,3285524927,ES
3285524928,3285524991,GB
-3285524992,3285525247,EU
+3285524992,3285525247,BE
3285525248,3285525503,CH
-3285525504,3285525759,EU
-3285525760,3285526015,BE
+3285525504,3285526015,BE
3285526016,3285526023,IL
-3285526024,3285526035,EU
+3285526024,3285526035,BE
3285526036,3285526039,FR
-3285526040,3285526047,EU
+3285526040,3285526047,BE
3285526048,3285526079,CZ
-3285526080,3285526143,EU
+3285526080,3285526143,BE
3285526144,3285526175,HU
-3285526176,3285526271,EU
-3285526272,3285526335,BE
-3285526336,3285526383,EU
+3285526176,3285526383,BE
3285526384,3285526399,PT
3285526400,3285526527,CH
3285526528,3285526783,ES
3285526784,3285526815,CH
-3285526816,3285526823,EU
-3285526824,3285526847,BE
+3285526816,3285526847,BE
3285526848,3285526911,CH
3285526912,3285527295,GB
-3285527296,3285527423,EU
+3285527296,3285527423,BE
3285527424,3285527427,GB
-3285527428,3285527431,EU
+3285527428,3285527431,BE
3285527432,3285527439,FR
3285527440,3285527455,LU
3285527456,3285527487,IL
-3285527488,3285527495,EU
+3285527488,3285527495,BE
3285527496,3285527503,DE
3285527504,3285527519,JP
-3285527520,3285527551,EU
+3285527520,3285527551,BE
3285527552,3285527615,IL
3285527616,3285527679,GB
-3285527680,3285527807,EU
+3285527680,3285527807,BE
3285527808,3285527811,GB
3285527812,3285527815,PL
-3285527816,3285527855,EU
+3285527816,3285527855,BE
3285527856,3285527871,FR
-3285527872,3285527967,EU
+3285527872,3285527967,BE
3285527968,3285527999,DE
-3285528000,3285528319,EU
+3285528000,3285528319,BE
3285528320,3285528447,DE
3285528448,3285528575,FR
-3285528576,3285528703,BE
-3285528704,3285528735,EU
-3285528736,3285528799,BE
+3285528576,3285528799,BE
3285528800,3285528831,GB
-3285528832,3285528839,BE
-3285528840,3285528847,EU
+3285528832,3285528847,BE
3285528848,3285528863,ZA
-3285528864,3285528883,EU
+3285528864,3285528883,BE
3285528884,3285528887,FR
-3285528888,3285528895,EU
+3285528888,3285528895,BE
3285528896,3285528911,GB
-3285528912,3285528927,BE
-3285528928,3285528931,EU
+3285528912,3285528931,BE
3285528932,3285528935,FR
-3285528936,3285528943,EU
+3285528936,3285528943,BE
3285528944,3285529071,GB
-3285529072,3285529087,EU
-3285529088,3285529151,BE
+3285529072,3285529151,BE
3285529152,3285529183,DE
3285529184,3285529199,NL
3285529200,3285529215,IL
3285529216,3285529247,CH
3285529248,3285529263,GB
-3285529264,3285529279,EU
-3285529280,3285529311,BE
-3285529312,3285529343,EU
+3285529264,3285529343,BE
3285529344,3285529599,IT
3285529600,3285529631,NO
3285529632,3285529663,IE
3285529664,3285529679,LI
3285529680,3285529687,FI
3285529688,3285529695,IT
-3285529696,3285529711,BE
-3285529712,3285529727,EU
+3285529696,3285529727,BE
3285529728,3285529855,GB
3285529856,3285529951,LU
3285529952,3285529983,GR
3285529984,3285529999,CZ
-3285530000,3285530143,EU
+3285530000,3285530143,BE
3285530144,3285530175,GB
3285530176,3285530183,NL
-3285530184,3285530211,EU
-3285530212,3285530215,BE
+3285530184,3285530215,BE
3285530216,3285530223,GB
3285530224,3285530271,FR
-3285530272,3285530303,EU
-3285530304,3285530335,BE
-3285530336,3285530367,EU
-3285530368,3285530399,BE
+3285530272,3285530399,BE
3285530400,3285530431,NL
3285530432,3285530463,IT
3285530464,3285530495,DE
@@ -92272,24 +95734,23 @@
3285530576,3285530583,GB
3285530584,3285530591,BE
3285530592,3285530607,GB
-3285530608,3285530623,BE
-3285530624,3285530655,EU
+3285530608,3285530655,BE
3285530656,3285530687,ZA
3285530688,3285530719,GB
-3285530720,3285530723,EU
+3285530720,3285530723,BE
3285530724,3285530727,GB
3285530728,3285530735,DE
3285530736,3285530739,GB
-3285530740,3285530743,EU
+3285530740,3285530743,BE
3285530744,3285530751,GB
3285530752,3285530767,IT
3285530768,3285530783,DE
-3285530784,3285530815,EU
+3285530784,3285530815,BE
3285530816,3285530831,GB
-3285530832,3285530879,EU
+3285530832,3285530879,BE
3285530880,3285530911,CH
3285530912,3285530975,GB
-3285530976,3285530983,EU
+3285530976,3285530983,BE
3285530984,3285530991,IE
3285530992,3285531007,GB
3285531008,3285531023,FR
@@ -92297,60 +95758,57 @@
3285531040,3285531071,ES
3285531072,3285531103,NL
3285531104,3285531119,FR
-3285531120,3285531127,BE
-3285531128,3285531263,EU
+3285531120,3285531263,BE
3285531264,3285531311,GB
3285531312,3285531327,DK
-3285531328,3285531343,EU
+3285531328,3285531343,BE
3285531344,3285531351,GB
3285531352,3285531355,FR
3285531356,3285531359,ES
-3285531360,3285531367,EU
+3285531360,3285531367,BE
3285531368,3285531375,DE
-3285531376,3285531379,EU
-3285531380,3285531383,BE
+3285531376,3285531383,BE
3285531384,3285531391,DE
3285531392,3285531423,BE
3285531424,3285531455,DE
-3285531456,3285531495,EU
+3285531456,3285531495,BE
3285531496,3285531503,NL
3285531504,3285531519,FR
-3285531520,3285531535,EU
+3285531520,3285531535,BE
3285531536,3285531551,DE
3285531552,3285531567,IL
-3285531568,3285531615,EU
+3285531568,3285531615,BE
3285531616,3285531647,NL
3285531648,3285531903,BE
3285531904,3285532159,GB
3285532160,3285532223,BE
3285532224,3285532231,ES
-3285532232,3285532287,EU
-3285532288,3285532415,BE
+3285532232,3285532415,BE
3285532416,3285532687,IT
3285532688,3285532703,DE
-3285532704,3285532711,EU
+3285532704,3285532711,BE
3285532712,3285532719,RU
3285532720,3285532735,IT
3285532736,3285532799,CH
3285532800,3285532831,DE
3285532832,3285532847,FI
3285532848,3285532863,IT
-3285532864,3285532895,EU
+3285532864,3285532895,BE
3285532896,3285532959,IT
-3285532960,3285532975,BE
-3285532976,3285533047,EU
+3285532960,3285533039,BE
+3285533040,3285533047,NL
3285533048,3285533055,BE
3285533056,3285533059,NL
-3285533060,3285533087,EU
+3285533060,3285533087,BE
3285533088,3285533103,IT
3285533104,3285533119,LU
-3285533120,3285533127,EU
+3285533120,3285533127,BE
3285533128,3285533135,SE
3285533136,3285533151,GB
3285533152,3285533183,FR
3285533184,3285533311,IT
3285533312,3285533343,SE
-3285533344,3285533367,EU
+3285533344,3285533367,BE
3285533368,3285533375,CH
3285533376,3285533471,GB
3285533472,3285533503,BE
@@ -92363,17 +95821,15 @@
3285533952,3285534079,IL
3285534080,3285534095,IT
3285534096,3285534111,TR
-3285534112,3285534143,EU
+3285534112,3285534143,BE
3285534144,3285534207,IT
3285534208,3285534463,PT
3285534464,3285534479,NL
-3285534480,3285534495,BE
-3285534496,3285534527,EU
+3285534480,3285534527,BE
3285534528,3285534559,FR
3285534560,3285534591,IT
3285534592,3285534627,GB
-3285534628,3285534631,EU
-3285534632,3285534639,BE
+3285534628,3285534639,BE
3285534640,3285534655,GB
3285534656,3285534719,IT
3285534720,3285534751,GB
@@ -92384,61 +95840,60 @@
3285534816,3285534831,HU
3285534832,3285534927,IE
3285534928,3285534943,GB
-3285534944,3285534975,EU
+3285534944,3285534975,BE
3285534976,3285535103,IT
-3285535104,3285535119,BE
-3285535120,3285535123,EU
+3285535104,3285535123,BE
3285535124,3285535127,ES
-3285535128,3285535131,EU
+3285535128,3285535131,BE
3285535132,3285535135,NL
3285535136,3285535139,FR
-3285535140,3285535143,EU
+3285535140,3285535143,BE
3285535144,3285535147,GR
3285535148,3285535151,CZ
3285535152,3285535155,SE
-3285535156,3285535231,EU
+3285535156,3285535231,BE
3285535232,3285535743,NO
3285535744,3285535871,IT
3285535872,3285535903,FR
3285535904,3285535907,DK
3285535908,3285535911,NO
-3285535912,3285535919,EU
+3285535912,3285535919,BE
3285535920,3285535927,NL
-3285535928,3285535951,EU
+3285535928,3285535951,BE
3285535952,3285535967,GB
-3285535968,3285535999,EU
+3285535968,3285535999,BE
3285536000,3285536063,GB
-3285536064,3285536079,EU
+3285536064,3285536079,BE
3285536080,3285536095,IT
3285536096,3285536111,GB
-3285536112,3285536255,EU
+3285536112,3285536255,BE
3285536256,3285536511,GB
3285536512,3285536543,LU
3285536544,3285536575,DE
3285536576,3285536607,IL
-3285536608,3285536703,EU
+3285536608,3285536703,BE
3285536704,3285536735,GB
3285536736,3285536739,IT
3285536740,3285536743,GB
3285536744,3285536747,DE
3285536748,3285536751,AT
-3285536752,3285536755,EU
+3285536752,3285536755,BE
3285536756,3285536759,IL
-3285536760,3285536767,EU
+3285536760,3285536767,BE
3285536768,3285536959,DK
3285536960,3285536991,ES
3285536992,3285537023,GB
3285537024,3285537087,IL
3285537088,3285537127,GB
-3285537128,3285537135,EU
+3285537128,3285537135,BE
3285537136,3285537143,DK
3285537144,3285537151,GB
3285537152,3285537167,DK
3285537168,3285537175,CH
-3285537176,3285537183,EU
+3285537176,3285537183,BE
3285537184,3285537215,DE
3285537216,3285537231,GB
-3285537232,3285537535,EU
+3285537232,3285537535,BE
3285537536,3285537599,RU
3285537600,3285537615,FR
3285537616,3285537631,BE
@@ -92451,7 +95906,7 @@
3285538048,3285538175,NL
3285538176,3285538183,DE
3285538184,3285538187,LU
-3285538188,3285538207,EU
+3285538188,3285538207,BE
3285538208,3285538239,LU
3285538240,3285538271,NO
3285538272,3285538287,FI
@@ -92462,14 +95917,13 @@
3285538328,3285538335,BE
3285538336,3285538351,GB
3285538352,3285538367,LU
-3285538368,3285538375,EU
+3285538368,3285538375,BE
3285538376,3285538383,AT
-3285538384,3285538399,EU
+3285538384,3285538399,BE
3285538400,3285538431,DK
-3285538432,3285538559,EU
-3285538560,3285538623,BE
+3285538432,3285538623,BE
3285538624,3285538687,LU
-3285538688,3285538719,EU
+3285538688,3285538719,BE
3285538720,3285538751,DE
3285538752,3285538755,IT
3285538756,3285538759,FR
@@ -92478,10 +95932,10 @@
3285538768,3285538783,CZ
3285538784,3285538815,BE
3285538816,3285538847,CH
-3285538848,3285538879,EU
+3285538848,3285538879,BE
3285538880,3285539071,ES
3285539072,3285539327,NL
-3285539328,3285539583,EU
+3285539328,3285539583,BE
3285539584,3285539711,IE
3285539712,3285539839,GB
3285539840,3285539967,IT
@@ -92489,38 +95943,38 @@
3285540032,3285540095,ZA
3285540096,3285540103,GB
3285540104,3285540107,IT
-3285540108,3285540111,EU
+3285540108,3285540111,BE
3285540112,3285540127,IL
3285540128,3285540159,ZA
3285540160,3285540191,FI
3285540192,3285540207,CH
3285540208,3285540215,IE
-3285540216,3285540219,EU
+3285540216,3285540219,BE
3285540220,3285540223,ZA
3285540224,3285540351,CZ
3285540352,3285540415,PT
3285540416,3285540423,ZA
-3285540424,3285540447,EU
+3285540424,3285540447,BE
3285540448,3285540479,DE
3285540480,3285540607,NL
-3285540608,3285540671,EU
+3285540608,3285540671,BE
3285540672,3285540735,DE
-3285540736,3285540863,EU
+3285540736,3285540863,BE
3285540864,3285540871,FR
-3285540872,3285540879,EU
+3285540872,3285540879,BE
3285540880,3285541375,FR
3285541376,3285541391,GB
3285541392,3285541439,FR
3285541440,3285541519,GB
3285541520,3285541527,BG
-3285541528,3285541535,EU
+3285541528,3285541535,BE
3285541536,3285541551,FR
-3285541552,3285541567,EU
+3285541552,3285541567,BE
3285541568,3285541599,GB
-3285541600,3285541631,EU
+3285541600,3285541631,BE
3285541632,3285541663,ES
3285541664,3285541695,FR
-3285541696,3285541759,EU
+3285541696,3285541759,BE
3285541760,3285541887,FR
3285541888,3285541919,GB
3285541920,3285541951,FR
@@ -92534,32 +95988,32 @@
3285543424,3285543679,SE
3285543680,3285543743,AT
3285543744,3285543759,FR
-3285543760,3285543775,EU
+3285543760,3285543775,BE
3285543776,3285543791,IT
3285543792,3285543795,ES
-3285543796,3285543799,EU
+3285543796,3285543799,BE
3285543800,3285543807,FR
3285543808,3285543871,NL
3285543872,3285543935,FR
-3285543936,3285544191,EU
+3285543936,3285544191,BE
3285544192,3285544255,IL
3285544256,3285544319,DE
3285544320,3285544335,ES
3285544336,3285544351,NL
-3285544352,3285544383,EU
+3285544352,3285544383,BE
3285544384,3285544479,FR
3285544480,3285544511,ES
3285544512,3285544639,FR
3285544640,3285544703,BE
3285544704,3285544959,FR
3285544960,3285545215,GB
-3285545216,3285545343,EU
+3285545216,3285545343,BE
3285545344,3285545379,GB
-3285545380,3285545471,EU
+3285545380,3285545471,BE
3285545472,3285545727,SE
3285545728,3285545983,FI
3285545984,3285545999,IT
-3285546000,3285546007,EU
+3285546000,3285546007,BE
3285546008,3285546015,IT
3285546016,3285546063,ES
3285546064,3285546071,IT
@@ -92568,7 +96022,7 @@
3285546240,3285546367,ZA
3285546368,3285546495,FR
3285546496,3285546559,NL
-3285546560,3285546623,EU
+3285546560,3285546623,BE
3285546624,3285546671,FR
3285546672,3285546687,SE
3285546688,3285546751,GB
@@ -92583,15 +96037,15 @@
3285547264,3285547519,LU
3285547520,3285547775,NL
3285547776,3285547903,ES
-3285547904,3285548031,EU
+3285547904,3285548031,BE
3285548032,3285548287,FR
3285548288,3285548543,DE
3285548544,3285548607,FR
3285548608,3285548639,LI
-3285548640,3285548647,EU
+3285548640,3285548647,BE
3285548648,3285548655,LI
3285548656,3285548735,GB
-3285548736,3285548767,EU
+3285548736,3285548767,BE
3285548768,3285548799,LU
3285548800,3285548831,IT
3285548832,3285548839,GB
@@ -92601,46 +96055,43 @@
3285549024,3285549039,PT
3285549040,3285549055,FR
3285549056,3285549183,DE
-3285549184,3285549215,EU
+3285549184,3285549215,BE
3285549216,3285549247,CH
3285549248,3285549279,DE
3285549280,3285549311,GB
3285549312,3285549695,DE
-3285549696,3285549719,EU
+3285549696,3285549719,BE
3285549720,3285549727,GB
3285549728,3285549735,SE
-3285549736,3285549767,EU
+3285549736,3285549767,BE
3285549768,3285549775,FI
3285549776,3285549791,DE
3285549792,3285549823,LU
3285549824,3285549871,DE
3285549872,3285549887,DK
3285549888,3285549951,DE
-3285549952,3285550335,EU
+3285549952,3285550335,BE
3285550336,3285550463,GB
3285550464,3285550527,DE
3285550528,3285550591,IT
3285550592,3285550847,FR
3285550848,3285550943,IT
3285550944,3285550975,NL
-3285550976,3285551007,EU
+3285550976,3285551007,BE
3285551008,3285551039,CH
3285551040,3285551071,DE
-3285551072,3285551103,EU
+3285551072,3285551103,BE
3285551104,3285551359,DE
-3285551360,3285551375,BE
-3285551376,3285551391,EU
+3285551360,3285551391,BE
3285551392,3285551423,DE
3285551424,3285551487,DK
-3285551488,3285551519,BE
-3285551520,3285551551,EU
+3285551488,3285551551,BE
3285551552,3285551615,DE
3285551616,3285551647,GB
3285551648,3285551679,FR
3285551680,3285551807,GB
3285551808,3285551839,RU
-3285551840,3285551871,EU
-3285551872,3285552127,BE
+3285551840,3285552127,BE
3285552128,3285552191,DE
3285552192,3285552255,ZA
3285552256,3285552287,CZ
@@ -92649,61 +96100,60 @@
3285552384,3285552511,DE
3285552512,3285552639,GB
3285552640,3285552927,DE
-3285552928,3285552959,EU
+3285552928,3285552959,BE
3285552960,3285553023,FR
-3285553024,3285553039,EU
+3285553024,3285553039,BE
3285553040,3285553055,EG
-3285553056,3285553087,EU
+3285553056,3285553087,BE
3285553088,3285553151,IT
3285553152,3285553215,DE
-3285553216,3285553247,EU
+3285553216,3285553247,BE
3285553248,3285553263,PL
3285553264,3285553727,DE
3285553728,3285553759,CH
3285553760,3285553767,GB
3285553768,3285553775,ZA
3285553776,3285553791,FR
-3285553792,3285553855,EU
+3285553792,3285553855,BE
3285553856,3285553887,ZA
3285553888,3285553919,DE
3285553920,3285554047,CH
3285554048,3285554127,DE
-3285554128,3285554143,EU
+3285554128,3285554143,BE
3285554144,3285554175,GB
3285554176,3285554431,AT
-3285554432,3285554687,EU
+3285554432,3285554687,BE
3285554688,3285554703,DE
-3285554704,3285554719,EU
+3285554704,3285554719,BE
3285554720,3285554751,FR
-3285554752,3285554815,EU
+3285554752,3285554815,BE
3285554816,3285554943,CH
3285554944,3285555199,LU
3285555200,3285555231,AT
3285555232,3285555263,NL
3285555264,3285555327,FR
3285555328,3285555455,IL
-3285555456,3285555711,EU
+3285555456,3285555711,BE
3285555712,3285555967,LU
3285555968,3285556223,IT
-3285556224,3285556479,EU
+3285556224,3285556479,BE
3285556480,3285556735,DE
3285556736,3285556767,CH
-3285556768,3285556771,EU
-3285556772,3285556775,BE
+3285556768,3285556775,BE
3285556776,3285556779,NL
-3285556780,3285556799,EU
+3285556780,3285556799,BE
3285556800,3285556863,DE
-3285556864,3285556991,EU
+3285556864,3285556991,BE
3285556992,3285557055,GB
3285557056,3285557119,NL
3285557120,3285557247,DE
3285557248,3285557363,NL
-3285557364,3285557375,EU
+3285557364,3285557375,BE
3285557376,3285557519,NL
3285557520,3285557535,FI
3285557536,3285557575,NL
3285557576,3285557579,SE
-3285557580,3285557583,EU
+3285557580,3285557583,BE
3285557584,3285557599,NL
3285557600,3285557631,BE
3285557632,3285557791,NL
@@ -92714,19 +96164,18 @@
3285557920,3285557951,FR
3285557952,3285558015,DE
3285558016,3285558271,NL
-3285558272,3285558399,BE
-3285558400,3285558463,EU
+3285558272,3285558463,BE
3285558464,3285558591,NL
-3285558592,3285558655,EU
+3285558592,3285558655,BE
3285558656,3285558783,IT
3285558784,3285559039,GB
-3285559040,3285559167,EU
+3285559040,3285559167,BE
3285559168,3285559231,NL
-3285559232,3285559295,EU
+3285559232,3285559295,BE
3285559296,3285559807,SE
3285559808,3285559839,IE
3285559840,3285559871,CH
-3285559872,3285559887,EU
+3285559872,3285559887,BE
3285559888,3285559903,SE
3285559904,3285559919,NL
3285559920,3285559935,SE
@@ -92736,7 +96185,7 @@
3285560384,3285560447,SE
3285560448,3285560479,LI
3285560480,3285560511,CH
-3285560512,3285560575,EU
+3285560512,3285560575,BE
3285560576,3285560831,DE
3285560832,3285561215,SE
3285561216,3285561343,NO
@@ -92745,31 +96194,31 @@
3285561472,3285561599,DK
3285561600,3285561619,NO
3285561620,3285561623,DE
-3285561624,3285561647,EU
+3285561624,3285561647,BE
3285561648,3285561663,NO
-3285561664,3285561727,EU
+3285561664,3285561727,BE
3285561728,3285561791,NO
-3285561792,3285561919,EU
+3285561792,3285561919,BE
3285561920,3285561951,CH
3285561952,3285561967,NO
-3285561968,3285561983,EU
+3285561968,3285561983,BE
3285561984,3285562111,FI
3285562112,3285562367,NO
3285562368,3285562751,FI
3285562752,3285562783,NL
-3285562784,3285562815,EU
+3285562784,3285562815,BE
3285562816,3285562879,IT
3285562880,3285562911,FI
-3285562912,3285562943,EU
+3285562912,3285562943,BE
3285562944,3285562975,DE
3285562976,3285562991,FI
-3285562992,3285562999,EU
+3285562992,3285562999,BE
3285563000,3285563007,GB
3285563008,3285563135,SE
3285563136,3285563391,FI
-3285563392,3285563455,EU
+3285563392,3285563455,BE
3285563456,3285563471,NL
-3285563472,3285563487,EU
+3285563472,3285563487,BE
3285563488,3285563519,SE
3285563520,3285563647,PL
3285563648,3285563903,CH
@@ -92778,118 +96227,114 @@
3285564160,3285564415,GB
3285564416,3285564511,CH
3285564512,3285564543,NO
-3285564544,3285564671,EU
+3285564544,3285564671,BE
3285564672,3285564735,CH
3285564736,3285564751,FR
-3285564752,3285564767,EU
+3285564752,3285564767,BE
3285564768,3285564799,SE
-3285564800,3285564927,EU
+3285564800,3285564927,BE
3285564928,3285565183,FR
3285565184,3285565439,NL
3285565440,3285565951,GB
3285565952,3285566015,FR
3285566016,3285566031,IT
-3285566032,3285566047,EU
+3285566032,3285566047,BE
3285566048,3285566079,CH
3285566080,3285566143,FR
-3285566144,3285566207,EU
+3285566144,3285566207,BE
3285566208,3285566495,RU
3285566496,3285566511,SE
3285566512,3285566527,FI
3285566528,3285566559,CH
-3285566560,3285566575,EU
+3285566560,3285566575,BE
3285566576,3285566591,CH
3285566592,3285566655,NL
-3285566656,3285566847,EU
+3285566656,3285566847,BE
3285566848,3285566975,FR
3285566976,3285567231,GB
3285567232,3285567487,PT
3285567488,3285568511,NL
3285568512,3285568671,DE
3285568672,3285568703,CH
-3285568704,3285568751,EU
+3285568704,3285568751,BE
3285568752,3285569023,DE
-3285569024,3285569407,EU
+3285569024,3285569407,BE
3285569408,3285569535,GB
3285569536,3285569791,DE
3285569792,3285570047,FI
3285570048,3285570175,FR
-3285570176,3285570207,EU
+3285570176,3285570207,BE
3285570208,3285570223,PL
3285570224,3285570239,NL
-3285570240,3285570303,EU
-3285570304,3285570559,BE
+3285570240,3285570559,BE
3285570560,3285570815,SE
3285570816,3285571071,IT
3285571072,3285571327,DE
3285571328,3285571583,FI
3285571584,3285571711,FR
3285571712,3285571775,SE
-3285571776,3285571791,BE
-3285571792,3285571807,EU
+3285571776,3285571807,BE
3285571808,3285571839,DE
-3285571840,3285571903,EU
+3285571840,3285571903,BE
3285571904,3285571967,SE
-3285571968,3285572095,EU
+3285571968,3285572095,BE
3285572096,3285572223,DE
3285572224,3285572351,FI
3285572352,3285572367,IR
3285572368,3285572383,ES
-3285572384,3285572447,EU
+3285572384,3285572447,BE
3285572448,3285572479,CH
3285572480,3285572607,FR
3285572608,3285572863,DK
3285572864,3285573119,IT
3285573120,3285573375,SE
-3285573376,3285573535,EU
+3285573376,3285573535,BE
3285573536,3285573567,CH
3285573568,3285573631,FR
3285573632,3285573887,NL
3285573888,3285573951,IL
-3285573952,3285574143,EU
+3285573952,3285574143,BE
3285574144,3285574399,RU
3285574400,3285574655,IL
3285574656,3285574911,GB
3285574912,3285575167,EU
3285575168,3285575423,ES
3285575424,3285575679,IL
-3285575680,3285575935,EU
+3285575680,3285575935,BE
3285575936,3285575999,DK
-3285576000,3285576063,EU
+3285576000,3285576063,BE
3285576064,3285576127,FR
-3285576128,3285576159,EU
+3285576128,3285576159,BE
3285576160,3285576191,DK
-3285576192,3285576447,EU
+3285576192,3285576447,BE
3285576448,3285576703,CZ
3285576704,3285576959,HU
-3285576960,3285577215,EU
+3285576960,3285577215,BE
3285577216,3285577471,ZA
3285577472,3285577599,IT
-3285577600,3285577983,EU
+3285577600,3285577983,BE
3285577984,3285578111,IT
3285578112,3285578239,DE
-3285578240,3285578367,EU
+3285578240,3285578367,BE
3285578368,3285578431,FR
-3285578432,3285578495,EU
+3285578432,3285578495,BE
3285578496,3285578751,DE
-3285578752,3285579007,EU
+3285578752,3285579007,BE
3285579008,3285579519,ES
3285579520,3285579775,FR
3285579776,3285580031,US
3285580032,3285580287,HU
3285580288,3285580415,DE
-3285580416,3285580543,EU
+3285580416,3285580543,BE
3285580544,3285580547,NL
-3285580548,3285580651,EU
+3285580548,3285580651,BE
3285580652,3285580655,SE
-3285580656,3285580799,EU
+3285580656,3285580799,BE
3285580800,3285580831,SE
3285580832,3285580847,PL
-3285580848,3285580927,EU
+3285580848,3285580927,BE
3285580928,3285581055,ZA
-3285581056,3285581183,EU
-3285581184,3285581311,BE
-3285581312,3285581503,EU
+3285581056,3285581503,BE
3285581504,3285581567,AT
3285581568,3285581599,FR
3285581600,3285581615,GB
@@ -93012,8 +96457,7 @@
3285916712,3285916719,CY
3285916720,3285916735,ES
3285916736,3285916799,GB
-3285916800,3285916927,EU
-3285916928,3285917183,YE
+3285916800,3285917183,EU
3285917184,3285917439,ES
3285917440,3285917695,YE
3285917696,3285918719,EU
@@ -93023,8 +96467,7 @@
3285919488,3285919743,UA
3285919744,3285921791,QA
3285921792,3285921823,CZ
-3285921824,3285921855,GB
-3285921856,3285921919,EU
+3285921824,3285921919,EU
3285921920,3285921983,GB
3285921984,3285922111,EU
3285922112,3285922175,FR
@@ -93089,14 +96532,14 @@
3285938432,3285938559,EU
3285938560,3285938607,GB
3285938608,3285938623,FR
-3285938624,3285938631,EU
+3285938624,3285938631,NG
3285938632,3285938639,ES
3285938640,3285938655,GB
-3285938656,3285938687,EU
+3285938656,3285938687,DE
3285938688,3285938943,ES
-3285938944,3285938951,EU
+3285938944,3285938951,NG
3285938952,3285938959,NL
-3285938960,3285938975,EU
+3285938960,3285938975,US
3285938976,3285939039,ES
3285939040,3285939199,EU
3285939200,3285939711,ES
@@ -93131,7 +96574,7 @@
3285947904,3285948159,NL
3285948160,3285948671,GB
3285948672,3285948927,SA
-3285948928,3285949183,GB
+3285948928,3285949183,NG
3285949184,3285949439,ES
3285949440,3285949695,DE
3285949696,3285949823,ES
@@ -93254,6 +96697,7 @@
3286334464,3286335487,BG
3286335488,3286336511,RU
3286336512,3286337535,DE
+3286337536,3286338559,PL
3286338560,3286339583,RO
3286339584,3286340607,UA
3286340608,3286342655,DE
@@ -93423,6 +96867,7 @@
3286892544,3286893055,LI
3286893056,3286893567,RU
3286893568,3286894591,UA
+3286894592,3286895103,PL
3286895104,3286895615,GB
3286895616,3286896127,DE
3286896128,3286896639,SE
@@ -93432,7 +96877,7 @@
3286898176,3286898687,HR
3286898688,3286899199,EU
3286899200,3286899711,IL
-3286899712,3286900223,HU
+3286899712,3286900223,DE
3286900224,3286900735,RO
3286900736,3286900991,BE
3286900992,3286901503,DE
@@ -93610,6 +97055,7 @@
3287218176,3287218431,DE
3287218432,3287218687,GB
3287218688,3287218943,RU
+3287218944,3287219199,FR
3287219200,3287219455,DE
3287219456,3287219711,CH
3287219712,3287220223,SE
@@ -93625,6 +97071,7 @@
3287425024,3287427759,SE
3287427760,3287427775,GB
3287427776,3287433215,SE
+3287433216,3287433727,PL
3287433728,3287434239,DE
3287434240,3287434751,PL
3287434752,3287435263,GB
@@ -93691,7 +97138,7 @@
3287464448,3287464703,PL
3287464704,3287464959,NL
3287464960,3287465215,SA
-3287465216,3287465471,NO
+3287465216,3287465471,SE
3287465472,3287465727,DE
3287465728,3287465983,FR
3287465984,3287467007,DK
@@ -93749,9 +97196,7 @@
3287555072,3287555583,GB
3287555584,3287556095,FR
3287556096,3287564287,TR
-3287564288,3287564623,FI
-3287564624,3287564655,AX
-3287564656,3287572479,FI
+3287564288,3287572479,FI
3287572480,3287578863,DE
3287578864,3287578879,LI
3287578880,3287580671,DE
@@ -93813,7 +97258,6 @@
3287668736,3287668991,SI
3287668992,3287669247,PL
3287669248,3287669503,LI
-3287669504,3287669759,IE
3287669760,3287670015,RO
3287670016,3287670271,UA
3287670272,3287670527,PL
@@ -94133,7 +97577,7 @@
3288444928,3288449023,NG
3288449024,3288465407,SD
3288465408,3288465919,JM
-3288465920,3288466175,ZA
+3288465920,3288466175,BW
3288466176,3288466431,MU
3288466432,3288467455,SY
3288467456,3288469503,BI
@@ -94295,9 +97739,7 @@
3290447872,3290456063,AR
3290456064,3290460159,MZ
3290460160,3290464255,ML
-3290464256,3290468351,PR
-3290468352,3290468607,DO
-3290468608,3290471487,PR
+3290464256,3290471487,PR
3290471488,3290471551,DO
3290471552,3290472447,PR
3290472448,3290480639,ZA
@@ -94308,9 +97750,11 @@
3290488832,3290489343,NG
3290489344,3290489855,KE
3290489856,3290490367,EG
+3290490880,3290492927,ZA
3290497024,3290955775,ZA
3290955776,3290980351,CR
3290980352,3290984447,ZA
+3291004928,3291021311,NG
3291021312,3291029503,ZA
3291029504,3291033343,TZ
3291033344,3291033599,KE
@@ -94325,6 +97769,13 @@
3291201536,3291201791,KE
3291201792,3291202047,ZM
3291202048,3291202303,GH
+3291202304,3291202559,ZA
+3291202560,3291202815,GH
+3291202816,3291203071,AO
+3291203072,3291203327,EG
+3291203328,3291203583,ZW
+3291203584,3291203839,ZA
+3291203840,3291204095,EG
3291217920,3291230207,ZA
3291230208,3291234303,GH
3291234304,3291242495,ZA
@@ -94398,6 +97849,7 @@
3291437568,3291437823,NA
3291437824,3291439103,ZA
3291447296,3291463679,CI
+3291742208,3292004351,ZA
3300917248,3300921343,MU
3300925440,3300929535,MG
3300933632,3300950015,MU
@@ -94520,12 +97972,15 @@
3302954240,3302954495,KE
3302987264,3302987775,MU
3305111552,3307208703,TN
+3313500160,3313762303,MA
3315597312,3316121599,EG
3316121600,3316645887,ZA
+3316645888,3317170175,KE
3317694464,3318218751,EG
3318218752,3318743039,DZ
3319791616,3320053759,MU
3320053760,3320315903,ZA
+3320578048,3320643583,ZA
3321886720,3321888767,MU
3321954304,3321970687,US
3322019840,3322023935,US
@@ -94947,32 +98402,7 @@
3330778880,3330779135,GB
3330779136,3330791423,US
3330791424,3330791679,CA
-3330791680,3330883583,US
-3330883584,3330884351,NL
-3330884352,3330884863,US
-3330884864,3330885119,GB
-3330885120,3330888063,US
-3330888064,3330888127,NL
-3330888128,3330888191,US
-3330888192,3330888703,AU
-3330888704,3330888959,US
-3330888960,3330889215,CH
-3330889216,3330889471,GB
-3330889472,3330890239,JP
-3330890240,3330890751,BE
-3330890752,3330891263,GB
-3330891264,3330892287,US
-3330892288,3330892543,FR
-3330892544,3330893567,US
-3330893568,3330893823,NL
-3330893824,3330894079,CA
-3330894080,3330894591,GB
-3330894592,3330894847,DE
-3330894848,3330897919,US
-3330897920,3330898175,CA
-3330898176,3330898431,DE
-3330898432,3330898943,FR
-3330898944,3331102463,US
+3330791680,3331102463,US
3331102464,3331102719,CA
3331102720,3331194879,US
3331194880,3331260415,AU
@@ -95309,10 +98739,7 @@
3340898048,3340898303,CA
3340898304,3340925071,US
3340925072,3340925079,CA
-3340925080,3340925199,US
-3340925200,3340925207,RU
-3340925208,3340925239,US
-3340925240,3340925247,MX
+3340925080,3340925247,US
3340925248,3340925255,AR
3340925256,3340925279,US
3340925280,3340925287,CA
@@ -95402,7 +98829,10 @@
3340926928,3340926935,ES
3340926936,3340926951,US
3340926952,3340926959,BR
-3340926960,3341444863,US
+3340926960,3341041663,US
+3341058048,3341082623,US
+3341082624,3341084671,CA
+3341084672,3341444863,US
3341444864,3341445631,DE
3341445632,3341479935,US
3341479936,3341480447,DE
@@ -95434,9 +98864,29 @@
3341645056,3341645567,CA
3341645568,3341646079,US
3341646080,3341646591,CA
-3341646592,3342139391,US
+3341646592,3341762559,US
+3341778944,3341807615,US
+3341807616,3341808639,CA
+3341808640,3341828095,US
+3341844480,3341863935,US
+3341863936,3341864959,AG
+3341864960,3341867007,US
+3341867008,3341869055,CA
+3341869056,3342139391,US
3342139392,3342204927,CH
-3342204928,3342598143,US
+3342204928,3342483455,US
+3342499840,3342505983,US
+3342505984,3342507007,BB
+3342507008,3342510079,US
+3342510080,3342512127,CA
+3342512128,3342516223,US
+3342516224,3342517247,CA
+3342517248,3342526463,US
+3342526464,3342528511,CA
+3342528512,3342548991,US
+3342565376,3342567423,CA
+3342567424,3342578687,US
+3342579712,3342581759,CA
3342598144,3342603263,CA
3342603264,3342604799,US
3342604800,3342605311,CA
@@ -95448,7 +98898,13 @@
3343365632,3343372543,CA
3343373312,3343376383,US
3343380480,3343384575,CA
-3343384576,3344171007,US
+3343384576,3343922175,US
+3343922176,3343922303,PA
+3343922304,3343922975,US
+3343922976,3343923007,PA
+3343923008,3343923135,US
+3343923136,3343923199,HK
+3343923200,3344171007,US
3344171008,3344255999,CA
3344256000,3344257023,US
3344261120,3344268543,CA
@@ -95745,8 +99201,8 @@
3355052288,3355053311,CA
3355053312,3355053567,US
3355054080,3355260927,US
-3355260928,3355262975,CA
-3355262976,3355310591,US
+3355260928,3355262719,CA
+3355262720,3355310591,US
3355310592,3355311103,CA
3355312128,3355319295,US
3355319296,3355320319,CA
@@ -95771,6 +99227,7 @@
3355447296,3355447551,CU
3355447552,3355447807,AR
3355447808,3355448063,HT
+3355448064,3355448319,AR
3355448320,3355449343,AN
3355449344,3355450367,CU
3355450368,3355451391,EC
@@ -96000,6 +99457,7 @@
3356070912,3356071423,BR
3356071424,3356072447,CL
3356072448,3356073215,CR
+3356073216,3356073471,AR
3356073472,3356075263,BR
3356075264,3356076287,BO
3356076288,3356078079,BR
@@ -96192,8 +99650,11 @@
3356295168,3356297215,CL
3356297216,3356299263,BR
3356299264,3356305663,MX
-3356305664,3356306431,AR
-3356307456,3356328959,MX
+3356305664,3356307455,AR
+3356307456,3356316415,MX
+3356316416,3356317695,AR
+3356317696,3356328959,MX
+3356328960,3356329983,HN
3356329984,3356332031,GF
3356332032,3356334079,CU
3356334080,3356336127,BO
@@ -96223,10 +99684,15 @@
3356368896,3356369407,BR
3356369408,3356369663,EC
3356369664,3356370175,BR
+3356370176,3356370943,AR
3356370944,3356372991,CO
3356372992,3356375039,CU
3356375040,3356377087,HN
-3356377088,3356389375,CL
+3356377088,3356379647,CL
+3356379648,3356380159,AR
+3356380160,3356380927,CL
+3356380928,3356381183,DO
+3356381184,3356389375,CL
3356389376,3356389887,CO
3356389888,3356391423,CL
3356391424,3356393471,CO
@@ -96540,7 +100006,8 @@
3359249760,3359249791,BR
3359249792,3359249887,AR
3359249888,3359250175,US
-3359250176,3359252039,AR
+3359250176,3359252031,AR
+3359252032,3359252039,US
3359252040,3359252047,IT
3359252048,3359252063,US
3359252064,3359252095,AR
@@ -96552,7 +100019,7 @@
3359257088,3359257103,BR
3359257104,3359257127,AR
3359257128,3359257135,BR
-3359257136,3359257151,AR
+3359257136,3359257151,US
3359257152,3359257183,BR
3359257184,3359257215,US
3359257216,3359257247,AR
@@ -96916,6 +100383,7 @@
3362476032,3362476287,HN
3362476288,3362476543,AR
3362476544,3362477055,CR
+3362477056,3362478079,AN
3362478080,3362480127,AR
3362480128,3362484223,PE
3362484224,3362484735,AR
@@ -96937,6 +100405,7 @@
3362529280,3362533375,PA
3362537472,3362545663,AR
3362545664,3362549759,PE
+3362549760,3362551807,AR
3362553856,3362557951,PY
3362562048,3362563071,BZ
3362563072,3362563199,PA
@@ -97798,7 +101267,6 @@
3392407552,3392409599,ID
3392409600,3392413695,JP
3392413696,3392413951,PK
-3392413952,3392414207,HK
3392414208,3392414463,PH
3392414464,3392414719,HK
3392414720,3392415231,AU
@@ -97976,6 +101444,7 @@
3392928256,3392928767,TW
3392928768,3392929279,VN
3392929280,3392929535,PK
+3392929536,3392929791,ID
3392929792,3392931839,MU
3392931840,3392933887,PH
3392933888,3392942079,JP
@@ -97999,6 +101468,28 @@
3392999424,3393003519,JP
3393003520,3393011711,PK
3393011712,3393019903,PH
+3393019904,3393020159,ID
+3393020160,3393020415,MN
+3393020416,3393021439,ID
+3393021440,3393021695,IN
+3393021696,3393021951,HK
+3393021952,3393022463,ID
+3393022464,3393022975,AP
+3393022976,3393023231,PH
+3393023232,3393023487,AU
+3393023488,3393023743,SG
+3393023744,3393023999,IN
+3393024000,3393024511,ID
+3393024512,3393025023,NZ
+3393025024,3393025279,AU
+3393025280,3393025535,IN
+3393025536,3393025791,PH
+3393025792,3393026047,AU
+3393026048,3393026559,HK
+3393026560,3393026815,AU
+3393026816,3393027071,PK
+3393027072,3393027839,ID
+3393027840,3393028095,PH
3393028096,3393060863,AU
3393060864,3393062911,FJ
3393062912,3393069055,ID
@@ -98156,6 +101647,28 @@
3393848320,3393849343,JP
3393849344,3393851391,CN
3393851392,3393855487,JP
+3393855488,3393855743,AU
+3393855744,3393855999,NZ
+3393856000,3393856255,AU
+3393856256,3393856511,HK
+3393856768,3393857023,SG
+3393857024,3393857535,NZ
+3393857536,3393858047,HK
+3393858048,3393858559,ID
+3393858560,3393858815,AU
+3393858816,3393859071,ID
+3393859072,3393859327,AU
+3393859328,3393859583,JP
+3393859584,3393860095,AU
+3393860096,3393860607,HK
+3393860608,3393860863,AU
+3393860864,3393861631,IN
+3393861632,3393861887,VN
+3393861888,3393862143,AU
+3393862144,3393862655,VN
+3393862656,3393862911,NZ
+3393862912,3393863167,AU
+3393863168,3393863679,HK
3393863680,3393865727,AU
3393865728,3393867775,ID
3393867776,3393880063,HK
@@ -98451,6 +101964,7 @@
3395156992,3395158015,CN
3395166208,3395170303,AU
3395170304,3395174399,JP
+3395174400,3395174911,AU
3395182592,3395190783,SG
3395190784,3395198975,JP
3395198976,3395203071,MY
@@ -99907,9 +103421,7 @@
3410780160,3410788351,BD
3410788352,3410792447,IN
3410792448,3410796543,BD
-3410796544,3410797567,KH
3410797568,3410798591,JP
-3410798592,3410799615,IN
3410799616,3410800639,SG
3410800640,3410804735,IN
3410804736,3410821119,PH
@@ -100461,7 +103973,6 @@
3413557248,3413565439,CN
3413565440,3413569535,TW
3413569536,3413569791,SG
-3413569792,3413570047,NZ
3413570048,3413570303,KH
3413570304,3413570559,AU
3413570560,3413571583,PH
@@ -100496,14 +104007,14 @@
3413593856,3413594111,KH
3413594112,3413595135,CN
3413595136,3413595391,NZ
-3413595392,3413595647,AP
+3413595392,3413595647,CN
3413595648,3413595903,AU
3413595904,3413596159,HK
3413596160,3413596671,AP
3413596672,3413597183,NP
3413597184,3413597695,AP
3413597696,3413597951,TW
-3413597952,3413598207,AU
+3413597952,3413602303,AU
3413639168,3413704703,SG
3413704704,3413737471,MY
3413737472,3413753855,TH
@@ -100652,7 +104163,6 @@
3415441408,3415474175,AU
3415474176,3415490559,CN
3415490560,3415491583,PK
-3415494656,3415495679,PH
3415495680,3415496191,ID
3415496704,3415497727,MY
3415497728,3415497983,TW
@@ -101824,9 +105334,7 @@
3423161480,3423161487,HK
3423161488,3423161613,US
3423161614,3423161621,CA
-3423161622,3423177471,US
-3423177472,3423177727,CA
-3423177728,3423182847,US
+3423161622,3423182847,US
3423182848,3423183199,CA
3423183200,3423183231,BM
3423183232,3423183263,CA
@@ -101848,9 +105356,7 @@
3423208194,3423208383,AN
3423208384,3423221759,US
3423221760,3423222783,CA
-3423222784,3423234751,US
-3423234752,3423234783,CA
-3423234784,3423235543,US
+3423222784,3423235543,US
3423235544,3423235551,TR
3423235552,3423235559,US
3423235560,3423235563,TR
@@ -101871,7 +105377,6 @@
3423264864,3423265247,US
3423265248,3423265263,EC
3423265264,3423266815,US
-3423266872,3423266879,US
3423268864,3423269135,CA
3423269136,3423269151,US
3423269152,3423269887,CA
@@ -102136,54 +105641,12 @@
3423401192,3423402943,US
3423402944,3423402951,RU
3423402952,3423412223,US
-3423412240,3423412255,GR
-3423412256,3423412287,TK
-3423412288,3423412319,RU
-3423412320,3423412335,CA
-3423412416,3423412479,SA
-3423412480,3423412495,CA
-3423412496,3423412511,US
-3423412544,3423412623,FR
-3423412624,3423412639,NO
-3423412656,3423412671,RU
-3423412688,3423412703,CA
-3423412704,3423412719,RU
-3423412720,3423412727,US
-3423412736,3423412751,CA
-3423412752,3423412767,US
-3423412768,3423412783,FI
-3423412800,3423412815,US
-3423412816,3423412831,GR
-3423412848,3423412863,US
-3423412928,3423412991,NL
-3423413056,3423413071,US
-3423413072,3423413135,CA
-3423413152,3423413167,US
-3423413184,3423413247,RS
-3423413248,3423413279,US
-3423413280,3423413295,SE
-3423413312,3423413327,PT
-3423413328,3423413343,US
-3423413376,3423413759,US
-3423414016,3423414143,CA
-3423414144,3423414159,FR
-3423414192,3423414207,US
3423414272,3423416319,US
3423417344,3423417470,US
3423417471,3423417480,AU
-3423417481,3423417636,US
-3423417637,3423417646,CA
-3423417647,3423417715,US
-3423417716,3423417725,BR
-3423417726,3423417769,US
-3423417770,3423417777,CA
-3423417778,3423417954,US
-3423417955,3423417964,GB
-3423417965,3423417975,US
+3423417481,3423417975,US
3423417976,3423417995,RO
-3423417996,3423418172,US
-3423418173,3423418180,JP
-3423418181,3423462655,US
+3423417996,3423462655,US
3423462656,3423462671,CA
3423462672,3423473663,US
3423473664,3423474655,CA
@@ -102194,9 +105657,7 @@
3423480320,3423480447,NG
3423480448,3423480527,A2
3423480528,3423480543,US
-3423480544,3423480575,A2
-3423480576,3423480831,DM
-3423480832,3423480927,A2
+3423480544,3423480927,A2
3423480928,3423480935,US
3423480936,3423480943,AO
3423480944,3423481007,A2
@@ -102209,9 +105670,9 @@
3423481856,3423493631,US
3423493632,3423493887,RU
3423493888,3423493903,ID
-3423493904,3423493911,ES
-3423493912,3423493927,TT
-3423493928,3423493967,US
+3423493904,3423493911,US
+3423493912,3423493919,TT
+3423493920,3423493967,US
3423493968,3423493975,AT
3423493976,3423498079,US
3423498080,3423498087,CA
@@ -102258,11 +105719,9 @@
3423585536,3423585551,IR
3423585552,3423585631,CA
3423585632,3423585647,US
-3423585648,3423585807,CA
-3423585808,3423585823,US
-3423585824,3423585839,CA
-3423585840,3423585847,US
-3423585848,3423585879,CA
+3423585648,3423585775,CA
+3423585776,3423585791,IR
+3423585792,3423585879,CA
3423585880,3423585887,US
3423585888,3423585895,CA
3423585896,3423585903,NL
@@ -102272,7 +105731,7 @@
3423585928,3423585935,NZ
3423585936,3423585999,CA
3423586000,3423586007,US
-3423586008,3423586015,PA
+3423586008,3423586015,NZ
3423586016,3423586031,US
3423586032,3423586039,NZ
3423586040,3423586159,CA
@@ -102320,42 +105779,7 @@
3423858688,3423862783,CA
3423862784,3424334847,US
3424334848,3424335871,CA
-3424335872,3424335903,US
-3424335904,3424335911,CN
-3424335912,3424335943,US
-3424335944,3424335951,BY
-3424335952,3424335983,US
-3424335984,3424335991,GB
-3424335992,3424336015,US
-3424336016,3424336023,BY
-3424336024,3424336087,US
-3424336088,3424336111,CA
-3424336112,3424336367,US
-3424336368,3424336375,SE
-3424336376,3424336495,US
-3424336496,3424336511,CN
-3424336512,3424336647,US
-3424336648,3424336655,BY
-3424336656,3424336703,US
-3424336704,3424336711,SG
-3424336712,3424336743,US
-3424336744,3424336751,GB
-3424336752,3424336775,US
-3424336776,3424336783,BE
-3424336784,3424336847,US
-3424336848,3424336855,BR
-3424336856,3424336871,US
-3424336872,3424336879,IN
-3424336880,3424337151,US
-3424337152,3424337159,BY
-3424337160,3424337175,US
-3424337176,3424337183,SG
-3424337184,3424337191,US
-3424337192,3424337199,BY
-3424337200,3424337255,US
-3424337256,3424337263,IL
-3424337264,3424337271,MX
-3424337272,3424378879,US
+3424335872,3424378879,US
3424378880,3424379135,PR
3424379136,3424493823,US
3424493824,3424494079,CA
@@ -102376,7 +105800,9 @@
3425875408,3425894399,CA
3425894400,3425912815,US
3425912816,3425912831,DO
-3425912832,3425914159,US
+3425912832,3425912847,US
+3425912848,3425912863,BB
+3425912864,3425914159,US
3425914160,3425914239,A2
3425914240,3425915807,US
3425915808,3425915823,NI
@@ -102388,7 +105814,15 @@
3426387968,3426388991,MX
3426388992,3426646015,US
3426646016,3426647039,CA
-3426647040,3426744319,US
+3426647040,3426680831,US
+3426680832,3426682111,KN
+3426682112,3426682367,US
+3426682368,3426682879,KN
+3426682880,3426683647,US
+3426683648,3426683903,KN
+3426683904,3426684159,US
+3426684160,3426684415,KN
+3426684416,3426744319,US
3426744320,3426746367,CA
3426746368,3427127295,US
3427127296,3427127551,CA
@@ -102986,11 +106420,13 @@
3434575360,3434575615,BR
3434575616,3434583039,US
3434583040,3434584063,NL
-3434584064,3434807295,US
-3434807296,3434831359,CA
+3434584064,3434807551,US
+3434807552,3434810111,CA
+3434810112,3434810367,US
+3434810368,3434831359,CA
3434831360,3434831615,US
-3434831616,3434872831,CA
-3434872832,3434907647,US
+3434831616,3434872575,CA
+3434872576,3434907647,US
3434907648,3434909695,PA
3434909696,3434913791,US
3434913792,3434914047,AG
@@ -103010,7 +106446,7 @@
3435069440,3435134975,CA
3435134976,3435507711,US
3435507712,3435511807,CA
-3435528192,3436249087,US
+3435511808,3436249087,US
3436249088,3436255743,CA
3436255744,3436256255,US
3436256256,3436282367,CA
@@ -103046,18 +106482,26 @@
3437292800,3437293055,CA
3437293056,3437296639,US
3437296640,3437296895,CA
-3437296896,3437297663,US
-3437297664,3437307391,CA
+3437296896,3437297919,US
+3437297920,3437307391,CA
3437307392,3437307903,US
3437307904,3437310975,CA
3437310976,3437311487,US
3437311488,3437331711,CA
3437331712,3437331967,US
-3437331968,3437334015,CA
+3437331968,3437332479,CA
+3437332480,3437332735,US
+3437332736,3437334015,CA
3437334016,3437334271,US
-3437334272,3437341695,CA
+3437334272,3437336063,CA
+3437336064,3437336319,US
+3437336320,3437341695,CA
3437341696,3437341951,US
-3437341952,3437358847,CA
+3437341952,3437343231,CA
+3437343232,3437343487,US
+3437343488,3437350911,CA
+3437350912,3437351423,US
+3437351424,3437358847,CA
3437358848,3437359103,US
3437359104,3437428735,CA
3437428736,3437691391,US
@@ -103127,7 +106571,7 @@
3437751808,3437752063,GB
3437752064,3437752319,ES
3437752320,3437752575,IE
-3437752832,3437755135,US
+3437752576,3437755135,US
3437755136,3437755647,JP
3437755648,3437755903,GB
3437755904,3437756159,US
@@ -103320,10 +106764,20 @@
3438084096,3438116863,CA
3438116864,3438215423,US
3438215424,3438215935,CA
+3438215936,3438216191,US
3438216192,3438217983,CA
3438217984,3438218239,US
3438218240,3438218751,CA
-3438219264,3438280703,CA
+3438218752,3438219263,US
+3438219264,3438219519,CA
+3438219520,3438219775,US
+3438219776,3438246911,CA
+3438246912,3438247167,US
+3438247168,3438252543,CA
+3438252544,3438252799,US
+3438252800,3438261759,CA
+3438261760,3438262015,US
+3438262016,3438280703,CA
3438280704,3438542847,US
3438542848,3438544943,CA
3438544944,3438544959,TC
@@ -103348,9 +106802,7 @@
3438592264,3438600319,CA
3438600320,3438600351,US
3438600352,3438608383,CA
-3438608384,3438689535,US
-3438689536,3438689791,CA
-3438689792,3438813183,US
+3438608384,3438813183,US
3438813184,3438814207,GH
3438814208,3438895103,US
3438895104,3438896895,HN
@@ -103449,7 +106901,11 @@
3448399360,3448399871,CA
3448399872,3448411391,US
3448411392,3448411455,CA
-3448411456,3448461311,US
+3448411456,3448414271,US
+3448414272,3448414295,JP
+3448414296,3448414303,US
+3448414304,3448414335,JP
+3448414336,3448461311,US
3448461312,3448461391,GB
3448461392,3448461415,US
3448461416,3448461423,SG
@@ -103488,8 +106944,12 @@
3448545976,3448546007,AU
3448546008,3448546047,US
3448546048,3448546079,MY
-3448546080,3448546111,SG
-3448546112,3448556671,US
+3448546080,3448546119,SG
+3448546120,3448546175,US
+3448546176,3448546207,SG
+3448546208,3448546431,US
+3448546432,3448546455,AU
+3448546456,3448556671,US
3448556672,3448556735,GB
3448556736,3448556799,US
3448556800,3448556815,GB
@@ -103499,7 +106959,9 @@
3448559104,3448559359,GB
3448559360,3448563015,US
3448563016,3448563031,GB
-3448563032,3449001245,US
+3448563032,3448569055,US
+3448569056,3448569087,MX
+3448569088,3449001245,US
3449001246,3449001246,MC
3449001247,3449159679,US
3449159680,3449160703,CA
@@ -103710,7 +107172,9 @@
3450936320,3450936351,HK
3450936352,3450974255,US
3450974256,3450974271,GB
-3450974272,3451170303,US
+3450974272,3450986495,US
+3450986496,3450986751,HK
+3450986752,3451170303,US
3451170304,3451170559,VE
3451170560,3451187967,US
3451187968,3451188223,AU
@@ -103784,7 +107248,7 @@
3452678144,3452682239,BE
3452682240,3452715007,US
3452715008,3452723199,CA
-3452731392,3452764159,US
+3452723200,3452764159,US
3452764160,3452764439,CA
3452764440,3452764447,US
3452764448,3452764487,CA
@@ -103836,9 +107300,7 @@
3452936192,3452960767,CA
3452960768,3453026303,US
3453026304,3453028607,CA
-3453029376,3453032447,US
-3453032448,3453032703,CA
-3453032704,3453039167,US
+3453029376,3453039167,US
3453039168,3453039183,AU
3453039184,3453039199,US
3453039200,3453039215,CA
@@ -104080,8 +107542,8 @@
3453554880,3453555711,US
3453555712,3453555767,GB
3453555768,3453599999,US
-3453600000,3453600511,GB
-3453600512,3453607935,US
+3453600000,3453600767,GB
+3453600768,3453607935,US
3453607936,3453608959,KN
3453608960,3453609983,LC
3453609984,3453610495,AG
@@ -104304,7 +107766,9 @@
3455647488,3455647743,IT
3455647744,3455713279,US
3455713280,3455778815,CA
-3455778816,3456303103,US
+3455778816,3455871999,US
+3455872000,3455872255,ZM
+3455872256,3456303103,US
3456303104,3456311295,JP
3456311296,3456892927,US
3456892928,3456958463,CA
@@ -104362,7 +107826,9 @@
3458144032,3458144047,DE
3458144048,3458144111,US
3458144112,3458144119,CA
-3458144120,3458195455,US
+3458144120,3458144415,US
+3458144416,3458144423,DE
+3458144424,3458195455,US
3458195456,3458196479,SG
3458196480,3458765631,US
3458765632,3458765695,CA
@@ -104563,30 +108029,29 @@
3460161536,3460163583,PR
3460163584,3460374527,US
3460374528,3460375551,MX
-3460375552,3460408359,US
-3460408360,3460408367,DE
-3460408368,3460409951,US
-3460409952,3460409967,DE
-3460409968,3460413535,US
-3460413536,3460413543,DE
-3460413544,3460453631,US
+3460375552,3460453631,US
3460453632,3460453887,BS
3460453888,3460507647,US
3460507648,3460507903,MX
-3460507904,3460854911,US
+3460507904,3460854439,US
+3460854440,3460854447,CA
+3460854448,3460854831,US
+3460854832,3460854847,VE
+3460854848,3460854911,US
3460854912,3460854943,GB
-3460854944,3460855023,US
-3460855024,3460855031,BR
-3460855032,3460855247,US
+3460854944,3460855247,US
3460855248,3460855255,AU
-3460855256,3460855271,US
+3460855256,3460855263,VE
+3460855264,3460855271,US
3460855272,3460855279,GB
3460855280,3460855287,CA
3460855288,3460855311,US
3460855312,3460855319,CA
3460855320,3460855463,US
3460855464,3460855471,SA
-3460855472,3460855535,US
+3460855472,3460855495,US
+3460855496,3460855503,CA
+3460855504,3460855535,US
3460855536,3460855543,MX
3460855544,3460855551,AU
3460855552,3460855631,US
@@ -104603,11 +108068,10 @@
3460855864,3460855871,US
3460855872,3460855879,GB
3460855880,3460855887,GU
-3460855888,3460855927,US
-3460855928,3460855935,GB
-3460855936,3460856007,US
+3460855888,3460856007,US
3460856008,3460856015,CA
-3460856016,3460856127,US
+3460856016,3460856119,US
+3460856120,3460856127,GB
3460856128,3460856135,JP
3460856136,3460856191,US
3460856192,3460856199,ZA
@@ -104629,7 +108093,11 @@
3460857056,3460857087,NZ
3460857088,3460857151,US
3460857152,3460857183,CA
-3460857184,3460857599,US
+3460857184,3460857431,US
+3460857432,3460857439,VE
+3460857440,3460857463,US
+3460857464,3460857471,GB
+3460857472,3460857599,US
3460857600,3460857855,AU
3460857856,3460891135,US
3460891136,3460891199,CL
@@ -105096,35 +108564,13 @@
3462340608,3462340863,CA
3462340864,3462350847,US
3462350848,3462351103,CA
-3462351104,3462478559,US
-3462478560,3462478591,IL
-3462478592,3462478623,US
-3462478624,3462478655,IL
-3462478656,3462478943,US
-3462478944,3462478975,IL
-3462478976,3462571095,US
+3462351104,3462571095,US
3462571096,3462571103,CA
3462571104,3462571663,US
3462571664,3462571671,CA
3462571672,3462593791,US
3462593792,3462594559,GN
-3462594560,3462605823,US
-3462605824,3462606847,UY
-3462606848,3462606863,US
-3462606864,3462606927,UY
-3462606928,3462606943,US
-3462606944,3462606991,UY
-3462606992,3462607007,US
-3462607008,3462607087,UY
-3462607088,3462607135,US
-3462607136,3462607167,UY
-3462607168,3462607199,US
-3462607200,3462607231,UY
-3462607232,3462607263,US
-3462607264,3462608799,UY
-3462608800,3462608815,US
-3462608816,3462608895,UY
-3462608896,3462633727,US
+3462594560,3462633727,US
3462633728,3462633799,BV
3462633800,3462633823,US
3462633824,3462633855,SG
@@ -105194,7 +108640,13 @@
3464185760,3464185791,PR
3464185792,3464190463,US
3464190464,3464190719,CA
-3464190720,3464195543,US
+3464190720,3464191799,US
+3464191800,3464191807,AF
+3464191808,3464191815,US
+3464191816,3464191823,CA
+3464191824,3464191831,US
+3464191832,3464191847,CA
+3464191848,3464195543,US
3464195544,3464195551,IT
3464195552,3464195887,US
3464195888,3464195895,PR
@@ -105206,9 +108658,7 @@
3464196160,3464196175,US
3464196176,3464196183,AU
3464196184,3464196191,IT
-3464196192,3464196287,US
-3464196288,3464196295,SG
-3464196296,3464208383,US
+3464196192,3464208383,US
3464208384,3464216575,CA
3464216576,3464309903,US
3464309904,3464309911,CA
@@ -105293,9 +108743,7 @@
3464768768,3464768895,CA
3464768896,3464769535,US
3464769536,3464773631,CA
-3464773632,3464799695,US
-3464799696,3464799703,JP
-3464799704,3464802303,US
+3464773632,3464802303,US
3464802304,3464806399,CA
3464806400,3465154559,US
3465154560,3465158655,BS
@@ -105309,7 +108757,9 @@
3465413120,3465413127,HK
3465413128,3465413375,US
3465413376,3465413383,HK
-3465413384,3465510911,US
+3465413384,3465462783,US
+3465462784,3465463039,GB
+3465463040,3465510911,US
3465510912,3465543679,JP
3465543680,3465982991,US
3465982992,3465983007,GB
@@ -105574,8 +109024,7 @@
3468082432,3468082687,NO
3468082688,3468083311,US
3468083312,3468083327,IN
-3468083328,3468083391,BR
-3468083392,3468083663,US
+3468083328,3468083663,US
3468083664,3468083679,ID
3468083680,3468083967,US
3468083968,3468084223,AU
@@ -105686,9 +109135,7 @@
3468128256,3468296191,US
3468296192,3468309503,CA
3468309504,3468309759,US
-3468309760,3468313471,CA
-3468313472,3468313599,US
-3468313600,3468319999,CA
+3468309760,3468319999,CA
3468320000,3468320255,US
3468320256,3468320351,CA
3468320352,3468320383,US
@@ -105730,7 +109177,9 @@
3468460032,3468468223,BM
3468468224,3468545791,US
3468545792,3468546047,SG
-3468546048,3468623871,US
+3468546048,3468619007,US
+3468619008,3468619263,CA
+3468619264,3468623871,US
3468623872,3468624527,CA
3468624528,3468624543,US
3468624544,3468624551,CA
@@ -105753,7 +109202,9 @@
3468628512,3468628607,US
3468628608,3468628927,CA
3468628928,3468628991,US
-3468628992,3468631583,CA
+3468628992,3468629311,CA
+3468629312,3468629319,US
+3468629320,3468631583,CA
3468631584,3468631615,US
3468631616,3468631679,CA
3468631680,3468631695,US
@@ -105794,20 +109245,15 @@
3470139392,3470143487,US
3470147584,3470148095,US
3470148096,3470148351,CA
-3470148352,3470148607,US
-3470148608,3470148863,CR
+3470148352,3470148863,US
3470148864,3470149119,CA
3470149120,3470150655,US
3470150656,3470150911,CA
3470150912,3470151935,US
3470151936,3470152703,CA
-3470152704,3470153215,US
-3470153216,3470153471,CA
-3470153472,3470154495,US
-3470154496,3470154751,CA
-3470154752,3470155007,US
-3470155008,3470155775,CA
-3470155776,3470184454,US
+3470152704,3470153983,US
+3470153984,3470154239,CA
+3470154240,3470184454,US
3470184455,3470184458,LK
3470184459,3470184460,RU
3470184461,3470184476,US
@@ -106289,30 +109735,27 @@
3470360800,3470360807,CA
3470360808,3470361039,US
3470361040,3470361055,CA
-3470361056,3470361615,US
-3470361616,3470361623,AF
-3470361624,3470361655,US
+3470361056,3470361655,US
3470361656,3470361671,CA
3470361672,3470361703,US
3470361704,3470361711,AF
3470361712,3470361935,US
3470361936,3470361951,CA
-3470361952,3470361959,CL
-3470361960,3470361983,US
+3470361952,3470361983,US
3470361984,3470361991,CA
3470361992,3470362111,US
3470362112,3470362119,CA
3470362120,3470362127,AU
-3470362128,3470362159,US
+3470362128,3470362135,US
+3470362136,3470362143,NL
+3470362144,3470362159,US
3470362160,3470362167,AF
-3470362168,3470362175,US
-3470362176,3470362191,CA
-3470362192,3470362263,US
+3470362168,3470362263,US
3470362264,3470362271,NZ
3470362272,3470362319,US
3470362320,3470362335,AF
-3470362336,3470362447,US
-3470362448,3470362479,CA
+3470362336,3470362455,US
+3470362456,3470362479,CA
3470362480,3470362495,US
3470362496,3470362503,CA
3470362504,3470362559,US
@@ -106341,9 +109784,7 @@
3470364416,3470364479,CA
3470364480,3470364495,HN
3470364496,3470364503,CA
-3470364504,3470364527,US
-3470364528,3470364535,CA
-3470364536,3470458879,US
+3470364504,3470458879,US
3470458880,3470475263,KR
3470475264,3470558207,US
3470558208,3470559231,HK
@@ -106448,7 +109889,8 @@
3470646920,3470646935,US
3470646936,3470646943,CA
3470646944,3470646959,BR
-3470646960,3470646991,US
+3470646960,3470646983,US
+3470646984,3470646991,AR
3470646992,3470646999,CN
3470647000,3470651391,US
3470651392,3470655487,CA
@@ -106587,7 +110029,11 @@
3470754304,3470754559,PE
3470754560,3470755839,US
3470755840,3470756095,ZA
-3470756096,3470761983,US
+3470756096,3470757887,US
+3470757888,3470760959,KN
+3470760960,3470761215,US
+3470761216,3470761727,KN
+3470761728,3470761983,US
3470761984,3470762751,CA
3470762752,3470762759,NL
3470762760,3470767871,CA
@@ -106599,9 +110045,7 @@
3470794752,3470802943,PA
3470802944,3470873288,US
3470873289,3470873296,MX
-3470873297,3470873584,US
-3470873585,3470873592,NA
-3470873593,3470875817,US
+3470873297,3470875817,US
3470875818,3470875827,JP
3470875828,3470876402,US
3470876403,3470876410,IN
@@ -106637,57 +110081,11 @@
3473040896,3473041407,BM
3473041408,3473096192,US
3473096193,3473096447,PH
-3473096448,3473109007,US
-3473109008,3473109023,UY
-3473109024,3473109039,US
-3473109040,3473109071,UY
-3473109072,3473109087,US
-3473109088,3473109151,UY
-3473109152,3473109167,US
-3473109168,3473109183,UY
-3473109184,3473109215,US
-3473109216,3473109247,UY
-3473109248,3473109279,US
-3473109280,3473109311,UY
-3473109312,3473109407,US
-3473109408,3473109471,UY
-3473109472,3473109487,US
-3473109488,3473109495,UY
-3473109496,3473109535,US
-3473109536,3473109543,UY
-3473109544,3473109567,US
-3473109568,3473109695,UY
-3473109696,3473109791,US
-3473109792,3473110271,UY
-3473110272,3473110303,US
-3473110304,3473110383,UY
-3473110384,3473110399,US
-3473110400,3473110431,UY
-3473110432,3473110495,US
-3473110496,3473110783,UY
-3473110784,3473110791,US
-3473110792,3473110815,UY
-3473110816,3473110831,US
-3473110832,3473111007,UY
-3473111008,3473111167,US
-3473111168,3473112575,UY
-3473112576,3473112639,US
-3473112640,3473112703,UY
-3473112704,3473112831,US
-3473112832,3473112863,UY
-3473112864,3473112895,US
-3473112896,3473112959,UY
-3473112960,3473276927,US
+3473096448,3473276927,US
3473276928,3473342463,CA
3473342464,3473375495,US
3473375496,3473375503,NZ
-3473375504,3473375671,US
-3473375672,3473375679,GB
-3473375680,3473377279,US
-3473377280,3473377535,GB
-3473377536,3473378559,US
-3473378560,3473378575,DE
-3473378576,3473381311,US
+3473375504,3473381311,US
3473381312,3473381343,DE
3473381344,3473703551,US
3473703552,3473703679,CA
@@ -106768,7 +110166,9 @@
3475745536,3475752703,US
3475752704,3475752959,AN
3475752960,3475881983,US
-3475881984,3475884031,CA
+3475881984,3475883487,CA
+3475883488,3475883519,US
+3475883520,3475884031,CA
3475884032,3475884287,US
3475884288,3475884319,CA
3475884320,3475884327,US
@@ -106783,9 +110183,7 @@
3476076320,3476076351,JO
3476076352,3476111359,US
3476111360,3476111871,CA
-3476111872,3476221951,US
-3476221952,3476223999,UY
-3476224000,3476265855,US
+3476111872,3476265855,US
3476265856,3476265919,EG
3476265920,3476348927,US
3476348928,3476349183,CA
@@ -106815,9 +110213,7 @@
3476721320,3476721327,GB
3476721328,3476721679,US
3476721680,3476721687,IT
-3476721688,3476721703,US
-3476721704,3476721711,SI
-3476721712,3476721743,US
+3476721688,3476721743,US
3476721744,3476721759,CA
3476721760,3476721799,US
3476721800,3476721807,GB
@@ -106836,11 +110232,7 @@
3476722528,3476722543,AU
3476722544,3476722591,US
3476722592,3476722607,GB
-3476722608,3476722695,US
-3476722696,3476722703,CA
-3476722704,3476722727,US
-3476722728,3476722735,BR
-3476722736,3476722759,US
+3476722608,3476722759,US
3476722760,3476722767,IN
3476722768,3476722775,US
3476722776,3476722783,GB
@@ -106850,22 +110242,17 @@
3476725184,3476725215,ZA
3476725216,3476725247,US
3476725248,3476725255,CA
-3476725256,3476725263,NL
-3476725264,3476725287,US
-3476725288,3476725295,NL
+3476725256,3476725295,US
3476725296,3476725303,CA
-3476725304,3476725359,NL
+3476725304,3476725351,US
+3476725352,3476725359,NL
3476725360,3476725367,US
3476725368,3476725375,CA
-3476725376,3476725383,VE
-3476725384,3476725399,US
+3476725376,3476725399,US
3476725400,3476725415,CA
3476725416,3476725423,US
3476725424,3476725431,GB
-3476725432,3476725439,NL
-3476725440,3476725455,US
-3476725456,3476725463,NL
-3476725464,3476732373,US
+3476725432,3476732373,US
3476732374,3476732377,MX
3476732378,3476881407,US
3476881408,3476946943,CA
@@ -106893,9 +110280,7 @@
3478323392,3478323399,CA
3478323400,3478331519,US
3478331520,3478331647,GB
-3478331648,3478331839,US
-3478331840,3478331847,DK
-3478331848,3478332991,US
+3478331648,3478332991,US
3478332992,3478332999,CA
3478333000,3478347903,US
3478347904,3478348031,MX
@@ -106912,9 +110297,7 @@
3478364272,3478372351,US
3478372352,3478380543,MX
3478380544,3479207935,US
-3479207936,3479214079,CA
-3479214080,3479214335,US
-3479214336,3479240703,CA
+3479207936,3479240703,CA
3479240704,3479289919,US
3479289920,3479289951,BD
3479289952,3479290063,US
@@ -106929,7 +110312,9 @@
3479290368,3479290431,BD
3479290432,3479290487,US
3479290488,3479290495,GB
-3479290496,3479290631,US
+3479290496,3479290583,US
+3479290584,3479290591,CA
+3479290592,3479290631,US
3479290632,3479290639,GB
3479290640,3479290743,US
3479290744,3479290751,EC
@@ -106974,7 +110359,9 @@
3479294032,3479294039,BD
3479294040,3479294223,US
3479294224,3479294231,TH
-3479294232,3479294487,US
+3479294232,3479294419,US
+3479294420,3479294423,CA
+3479294424,3479294487,US
3479294488,3479294495,MX
3479294496,3479294527,US
3479294528,3479294543,BD
@@ -107099,9 +110486,7 @@
3480251072,3480256511,CA
3480256512,3480284159,US
3480284160,3480284671,CA
-3480284672,3480416063,US
-3480416064,3480416095,PA
-3480416096,3480444927,US
+3480284672,3480444927,US
3480444928,3480446335,CA
3480446336,3480446463,US
3480446464,3480446575,CA
@@ -107255,8 +110640,8 @@
3480612096,3480612351,LU
3480612352,3480613631,DE
3480613632,3480839423,US
-3480839424,3480840191,GB
-3480840192,3480907263,US
+3480839424,3480839935,GB
+3480839936,3480907263,US
3480907264,3480907775,FR
3480907776,3480968191,US
3480968192,3480968447,AU
@@ -107310,7 +110695,9 @@
3483296005,3483296005,BE
3483296006,3483435007,US
3483435008,3483533311,CA
-3483533312,3483631615,US
+3483533312,3483552511,US
+3483552512,3483552607,GB
+3483552608,3483631615,US
3483631616,3483697151,CA
3483697152,3483791359,US
3483791360,3483791407,PR
@@ -107335,26 +110722,18 @@
3483877376,3483893759,CA
3483893760,3484013055,US
3484013056,3484013567,DE
-3484013568,3484319743,US
-3484320256,3484320815,US
-3484320816,3484320823,DE
-3484320832,3484321279,US
-3484321792,3484450815,US
+3484013568,3484450815,US
3484450816,3484451839,CA
3484451840,3484451871,US
3484451872,3484455263,CA
3484455264,3484455295,US
-3484455296,3484455359,CA
-3484455360,3484455391,US
-3484455392,3484455807,CA
+3484455296,3484455807,CA
3484455808,3484455871,US
3484455872,3484456191,CA
3484456192,3484456703,US
3484456704,3484457727,CA
3484457728,3484457983,US
-3484457984,3484458239,CA
-3484458240,3484458495,US
-3484458496,3484458783,CA
+3484457984,3484458783,CA
3484458784,3484458791,US
3484458792,3484458807,CA
3484458808,3484458815,US
@@ -107387,7 +110766,9 @@
3484460800,3484461079,CA
3484461080,3484461095,US
3484461096,3484461103,CA
-3484461104,3484461199,US
+3484461104,3484461135,US
+3484461136,3484461143,CA
+3484461144,3484461199,US
3484461200,3484461231,CA
3484461232,3484461263,US
3484461264,3484461271,CA
@@ -107400,13 +110781,11 @@
3484462104,3484462143,US
3484462144,3484462159,CA
3484462160,3484462175,US
-3484462176,3484462199,CA
-3484462200,3484462215,US
-3484462216,3484462263,CA
-3484462264,3484462271,US
-3484462272,3484462279,CA
-3484462280,3484462303,US
-3484462304,3484462975,CA
+3484462176,3484462207,CA
+3484462208,3484462215,US
+3484462216,3484462279,CA
+3484462280,3484462295,US
+3484462296,3484462975,CA
3484462976,3484463039,US
3484463040,3484463151,CA
3484463152,3484463183,US
@@ -107444,11 +110823,7 @@
3484472184,3484472199,US
3484472200,3484472223,CA
3484472224,3484472263,US
-3484472264,3484472271,CA
-3484472272,3484472279,US
-3484472280,3484472295,CA
-3484472296,3484472303,US
-3484472304,3484472311,CA
+3484472264,3484472311,CA
3484472312,3484472319,US
3484472320,3484472839,CA
3484472840,3484472855,US
@@ -107766,7 +111141,9 @@
3486646016,3486646143,JP
3486646144,3486646271,US
3486646272,3486662655,CA
-3486662656,3486699519,US
+3486662656,3486677055,US
+3486677056,3486677071,CA
+3486677072,3486699519,US
3486699520,3486699775,CA
3486699776,3486700399,US
3486700400,3486700407,CA
@@ -107797,11 +111174,7 @@
3487858688,3487859199,KY
3487859200,3487861759,BM
3487861760,3487862015,KY
-3487862016,3487862271,BM
-3487862272,3487862783,KY
-3487862784,3487863039,BM
-3487863040,3487863807,KY
-3487863808,3487875071,BM
+3487862016,3487875071,BM
3487875072,3487891455,US
3487891456,3487907839,CA
3487907840,3487969791,US
@@ -107893,13 +111266,7 @@
3489969152,3489969663,PR
3489969664,3490041503,US
3490041504,3490041535,CA
-3490041536,3490072831,US
-3490072832,3490073279,CA
-3490073280,3490073311,US
-3490073312,3490073375,CA
-3490073376,3490073599,US
-3490073600,3490074622,CA
-3490074623,3490228735,US
+3490041536,3490228735,US
3490228736,3490229247,CO
3490229248,3490263039,US
3490263040,3490267135,CO
@@ -107915,7 +111282,9 @@
3490732432,3490732447,CA
3490732448,3490786047,US
3490786048,3490786303,PR
-3490786304,3490879231,US
+3490786304,3490796799,US
+3490796800,3490797055,CA
+3490797056,3490879231,US
3490879232,3490879487,PR
3490879488,3490922495,US
3490922496,3490924543,CO
@@ -107988,8 +111357,7 @@
3492151296,3492167679,CA
3492167680,3492188799,US
3492188800,3492188831,CH
-3492188832,3492208639,US
-3492216832,3492472039,US
+3492188832,3492472039,US
3492472040,3492472047,GB
3492472048,3492646623,US
3492646624,3492646639,IL
@@ -108025,25 +111393,12 @@
3493081600,3493082623,PY
3493082624,3493089023,US
3493089024,3493089279,A2
-3493089280,3493089311,BO
-3493089312,3493089343,US
-3493089344,3493090815,BO
-3493090816,3493091327,US
+3493089280,3493091327,US
3493091328,3493092351,BO
3493092352,3493092607,NA
-3493092608,3493135167,US
-3493135168,3493135199,CY
-3493135200,3493135871,US
-3493135872,3493136127,CA
-3493136128,3493138207,US
+3493092608,3493138207,US
3493138208,3493138239,DE
-3493138240,3493139711,US
-3493139712,3493139775,CA
-3493139776,3493139839,US
-3493139840,3493139935,CA
-3493139936,3493140127,US
-3493140128,3493140159,CA
-3493140160,3493141279,US
+3493138240,3493141279,US
3493141280,3493141311,CY
3493141312,3493244927,US
3493244928,3493249023,PR
@@ -108055,7 +111410,11 @@
3493874688,3493875711,BM
3493875712,3493881855,US
3493881856,3493882879,CA
-3493882880,3493901311,US
+3493882880,3493886715,US
+3493886716,3493886719,BZ
+3493886720,3493901023,US
+3493901024,3493901031,HK
+3493901032,3493901311,US
3493901312,3493901567,AE
3493901568,3493901599,IL
3493901600,3493901759,US
@@ -108068,9 +111427,11 @@
3493902216,3493902223,CA
3493902224,3493903551,US
3493903552,3493903567,KW
-3493903568,3493907199,US
+3493903568,3493906431,US
+3493906944,3493907199,US
3493907200,3493907231,GB
-3493907232,3493914111,US
+3493907232,3493907263,US
+3493907328,3493914111,US
3493914112,3493914367,CA
3493914368,3493936127,US
3493936128,3493937151,CA
@@ -108085,47 +111446,14 @@
3493991424,3493998591,US
3493998592,3494000639,AI
3494000640,3494003711,US
-3494003712,3494003967,CA
-3494003968,3494003983,US
-3494003984,3494003991,SA
-3494003992,3494003999,US
-3494004000,3494004047,CA
-3494004048,3494004055,US
-3494004056,3494004095,CA
-3494004096,3494004111,US
-3494004112,3494004127,CA
-3494004128,3494004159,BR
-3494004160,3494004183,US
-3494004184,3494004290,CA
-3494004291,3494004312,US
-3494004313,3494004319,CA
-3494004320,3494004351,FR
-3494004352,3494004383,US
-3494004384,3494004735,CA
+3494003712,3494004735,CA
3494004736,3494009855,US
3494009856,3494010879,CA
3494010880,3494011231,US
3494011232,3494011247,HK
3494011248,3494014975,US
3494014976,3494017023,CA
-3494017024,3494035455,US
-3494035712,3494035791,US
-3494035792,3494035807,BY
-3494035808,3494035823,CY
-3494035824,3494035887,US
-3494035888,3494035904,RU
-3494035905,3494035967,ES
-3494035968,3494036031,US
-3494036032,3494036047,CA
-3494036048,3494036063,RU
-3494036064,3494036255,US
-3494036256,3494036287,CA
-3494036288,3494036319,US
-3494036320,3494036351,RU
-3494036352,3494036417,EE
-3494036418,3494036431,US
-3494036432,3494036439,RU
-3494036480,3494044671,US
+3494017024,3494044671,US
3494044672,3494045695,CA
3494045696,3494049791,US
3494049792,3494051839,CA
@@ -108136,7 +111464,15 @@
3494088704,3494090751,CA
3494090752,3494094847,US
3494094848,3494095871,CA
-3494095872,3494102623,US
+3494095872,3494101319,US
+3494101320,3494101327,GB
+3494101328,3494101377,US
+3494101378,3494101385,JM
+3494101386,3494101407,US
+3494101408,3494101415,CO
+3494101416,3494101429,US
+3494101430,3494101437,GB
+3494101438,3494102623,US
3494102624,3494102639,SB
3494102640,3494102735,US
3494102736,3494102751,VI
@@ -108157,7 +111493,15 @@
3494110162,3494114303,US
3494115328,3494115471,US
3494115472,3494115487,AU
-3494115488,3494116407,US
+3494115488,3494115495,US
+3494115496,3494115503,CA
+3494115504,3494115983,US
+3494115984,3494115991,AU
+3494115992,3494116007,US
+3494116008,3494116015,GB
+3494116016,3494116375,US
+3494116376,3494116383,GB
+3494116384,3494116407,US
3494116408,3494116415,CA
3494116416,3494116431,US
3494116432,3494116439,GB
@@ -108208,7 +111552,9 @@
3494206848,3494206887,CA
3494206888,3494206911,US
3494206912,3494206943,CA
-3494206944,3494228319,US
+3494206944,3494228031,US
+3494228032,3494228095,AU
+3494228096,3494228319,US
3494228320,3494228335,RU
3494228336,3494228495,US
3494228496,3494228511,CA
@@ -108261,8 +111607,8 @@
3494299688,3494299695,SC
3494299696,3494299727,US
3494299728,3494299735,SC
-3494299736,3494300359,US
-3494300360,3494300383,TW
+3494299736,3494300367,US
+3494300368,3494300383,TW
3494300384,3494300927,US
3494300928,3494301055,TW
3494301056,3494301247,US
@@ -108286,10 +111632,16 @@
3494313552,3494316031,US
3494316032,3494317055,CA
3494317056,3494336511,US
-3494336512,3494337535,CA
+3494336512,3494337023,CA
+3494337024,3494337087,US
+3494337088,3494337135,CA
+3494337136,3494337151,US
+3494337152,3494337535,CA
3494337536,3494342655,US
3494342656,3494344703,CA
-3494344704,3494350079,US
+3494344704,3494349223,US
+3494349224,3494349231,GB
+3494349232,3494350079,US
3494350080,3494350087,AU
3494350088,3494350095,US
3494350096,3494350103,CA
@@ -108407,96 +111759,8 @@
3494605824,3494606847,CA
3494606848,3494610943,US
3494610944,3494611967,CA
-3494611968,3494624263,US
-3494624264,3494624271,DE
-3494624272,3494624279,US
-3494624280,3494624287,GB
-3494624288,3494624295,ES
-3494624296,3494624319,US
-3494624320,3494624327,CR
-3494624328,3494624335,SA
-3494624336,3494624343,MY
-3494624344,3494624351,CA
-3494624352,3494624367,US
-3494624368,3494624375,CA
-3494624376,3494624383,LT
-3494624384,3494624391,UA
-3494624392,3494624399,GB
-3494624400,3494624407,US
-3494624408,3494624415,CA
-3494624416,3494624423,RU
-3494624424,3494624439,US
-3494624440,3494624447,NL
-3494624448,3494624455,CA
-3494624456,3494624463,ES
-3494624464,3494624471,US
-3494624472,3494624479,ZA
-3494624480,3494624527,US
-3494624528,3494624535,CA
-3494624536,3494624543,US
-3494624544,3494624551,CA
-3494624552,3494624591,US
-3494624592,3494624599,RU
-3494624600,3494624607,IL
-3494624608,3494624631,US
-3494624632,3494624639,ZA
-3494624640,3494624647,GB
-3494624648,3494624655,MK
-3494624656,3494624671,US
-3494624672,3494624679,BY
-3494624680,3494624687,US
-3494624688,3494624695,JP
-3494624696,3494624703,NL
-3494624704,3494624711,DE
-3494624712,3494624719,US
-3494624720,3494624727,ZA
-3494624728,3494624735,SG
-3494624736,3494624751,US
-3494624752,3494624759,DE
-3494624760,3494624767,RU
-3494624768,3494624775,US
-3494624776,3494624791,CA
-3494624792,3494624799,US
-3494624800,3494624807,RU
-3494624808,3494624815,CA
-3494624816,3494624823,US
-3494624824,3494624831,CA
-3494624832,3494624855,US
-3494624856,3494624863,CA
-3494624864,3494624871,US
-3494624872,3494624879,CA
-3494624880,3494624887,US
-3494624888,3494624903,CA
-3494624904,3494624911,JP
-3494624912,3494624919,DE
-3494624920,3494624935,US
-3494624936,3494624943,CA
-3494624944,3494624951,US
-3494624952,3494624959,CA
-3494624960,3494624975,AU
-3494624976,3494624983,RU
-3494624984,3494624991,CA
-3494624992,3494625047,US
-3494625048,3494625055,CA
-3494625056,3494625063,UA
-3494625064,3494625071,NL
-3494625072,3494625111,US
-3494625112,3494625119,VG
-3494625120,3494625127,IT
-3494625128,3494625143,US
-3494625144,3494625151,AU
-3494625152,3494625159,US
-3494625160,3494625167,UA
-3494625168,3494625183,US
-3494625184,3494625199,CA
-3494625200,3494625207,UA
-3494625208,3494625223,US
-3494625224,3494625231,CA
-3494625232,3494625247,US
-3494625248,3494625255,RO
-3494625256,3494625263,US
-3494625264,3494625271,AE
-3494625272,3494625279,AU
+3494611968,3494624255,US
+3494624256,3494625279,CA
3494625280,3494627327,US
3494627328,3494628351,BM
3494628352,3494651903,US
@@ -108534,11 +111798,14 @@
3494698792,3494698799,CA
3494698800,3494698843,US
3494698844,3494698847,EG
-3494698848,3494698887,US
+3494698848,3494698879,US
+3494698880,3494698887,IN
3494698888,3494698895,EG
3494698896,3494700031,US
3494700032,3494701055,CA
-3494701056,3494712319,US
+3494701056,3494705319,US
+3494705320,3494705327,MX
+3494705328,3494712319,US
3494712320,3494713343,CA
3494713344,3494727679,US
3494727680,3494729727,CA
@@ -108546,33 +111813,46 @@
3494730752,3494731775,CA
3494731776,3494743039,US
3494743040,3494744063,CA
-3494744064,3494744703,US
+3494744064,3494744399,US
+3494744400,3494744407,AU
+3494744408,3494744703,US
3494744704,3494744711,DK
3494744712,3494745151,US
3494745152,3494745159,AU
3494745160,3494745303,US
3494745304,3494745311,AU
-3494745312,3494745919,US
+3494745312,3494745879,US
+3494745880,3494745887,GB
+3494745888,3494745919,US
3494745920,3494745927,CN
-3494745928,3494757375,US
+3494745928,3494745951,US
+3494745952,3494745959,GB
+3494745960,3494746019,US
+3494746020,3494746023,AU
+3494746024,3494757375,US
3494757376,3494758399,CA
3494758400,3494763007,US
3494763008,3494763015,ES
3494763016,3494763047,US
3494763048,3494763055,JP
-3494763056,3494763063,US
+3494763056,3494763063,AU
3494763064,3494763071,MX
3494763072,3494763119,US
3494763120,3494763127,DE
3494763128,3494763143,US
3494763144,3494763151,ES
-3494763152,3494763903,US
+3494763152,3494763199,US
+3494763200,3494763207,KY
+3494763208,3494763903,US
3494763904,3494763919,AU
-3494763920,3494764295,US
+3494763920,3494763983,US
+3494763984,3494763999,AU
+3494764000,3494764295,US
3494764296,3494764303,CA
3494764304,3494764343,US
3494764344,3494764351,GB
-3494764352,3494764383,US
+3494764352,3494764375,US
+3494764376,3494764383,AU
3494764384,3494764391,GB
3494764392,3494764447,US
3494764448,3494764463,GB
@@ -108602,13 +111882,25 @@
3494866944,3494867967,CA
3494867968,3494893567,US
3494893568,3494894591,CA
-3494894592,3494917119,US
-3494917120,3494917631,CA
-3494917632,3494928383,US
+3494894592,3494906367,US
+3494906368,3494906431,IL
+3494906432,3494917119,US
+3494917120,3494918143,CA
+3494918144,3494928383,US
3494928384,3494930431,CA
-3494930432,3494938623,US
+3494930432,3494935746,US
+3494935747,3494935747,GB
+3494935748,3494936002,US
+3494936003,3494936003,GB
+3494936004,3494936258,US
+3494936259,3494936259,GB
+3494936260,3494936514,US
+3494936515,3494936515,GB
+3494936516,3494938623,US
3494938624,3494939647,CA
-3494939648,3494964223,US
+3494939648,3494950655,US
+3494950656,3494950911,PH
+3494950912,3494964223,US
3494964224,3494965247,PR
3494965248,3494968319,US
3494968320,3494972415,CA
@@ -108651,40 +111943,69 @@
3495136504,3495136847,US
3495136848,3495136855,PR
3495136856,3495153663,US
-3495153664,3495154303,CA
-3495154304,3495154431,US
-3495154432,3495154751,CA
-3495154752,3495154759,US
-3495154760,3495154823,CA
-3495154824,3495154831,US
-3495154832,3495154839,CA
-3495154840,3495154847,US
-3495154848,3495155711,CA
+3495153664,3495155711,CA
3495155712,3495157039,US
3495157040,3495157047,SE
3495157048,3495164239,US
3495164240,3495164247,CA
-3495164248,3495192575,US
+3495164248,3495190527,US
3495192576,3495193599,CA
3495193600,3495215103,US
3495215104,3495217151,VI
3495217152,3495219199,VC
-3495219200,3495251967,US
+3495219200,3495235663,US
+3495235664,3495235671,BR
+3495235672,3495235679,AU
+3495235680,3495235687,BR
+3495235688,3495235695,IN
+3495235696,3495235703,FR
+3495235704,3495235775,US
+3495235776,3495235783,MY
+3495235784,3495235791,HR
+3495235792,3495235799,US
+3495235800,3495235807,ES
+3495235808,3495235823,US
+3495235824,3495235831,GB
+3495235832,3495235903,US
+3495235904,3495235911,CA
+3495235912,3495235991,US
+3495235992,3495235999,CA
+3495236000,3495236015,US
+3495236016,3495236023,GB
+3495236024,3495236111,US
+3495236112,3495236119,CZ
+3495236120,3495236135,US
+3495236136,3495236143,CR
+3495236144,3495236367,US
+3495236368,3495236375,CA
+3495236376,3495251967,US
3495251968,3495254015,CA
3495254016,3495260159,US
3495260160,3495261183,CA
-3495261184,3495286783,US
+3495261184,3495276287,US
+3495276288,3495276351,IN
+3495276352,3495286783,US
3495286784,3495288831,CA
-3495288832,3495292927,US
-3495292928,3495292943,GB
-3495292944,3495331839,US
+3495288832,3495331839,US
3495331840,3495332863,A2
3495332864,3495333887,CA
3495333888,3495349247,US
3495349248,3495350271,CA
3495350272,3495358463,US
3495358464,3495359487,CA
-3495359488,3495367679,US
+3495359488,3495362623,US
+3495362624,3495362631,BD
+3495362632,3495362639,AR
+3495362640,3495362711,US
+3495362712,3495362719,AR
+3495362720,3495362727,US
+3495362728,3495362735,A2
+3495362736,3495362751,SG
+3495362752,3495363019,US
+3495363020,3495363023,AR
+3495363024,3495363399,US
+3495363400,3495363407,BD
+3495363408,3495367679,US
3495367680,3495368703,CA
3495368704,3495370239,US
3495370240,3495370495,CA
@@ -108692,12 +112013,30 @@
3495370752,3495372799,BS
3495372800,3495375871,US
3495375872,3495376895,CA
-3495376896,3495399423,US
+3495376896,3495393429,US
+3495393430,3495393445,AU
+3495393446,3495399423,US
3495399424,3495400447,KN
3495400448,3495401471,US
3495403520,3495412735,US
3495412736,3495413759,CA
-3495413760,3495429119,US
+3495413760,3495424033,US
+3495424034,3495424042,IN
+3495424043,3495424286,US
+3495424287,3495424308,IN
+3495424309,3495424321,US
+3495424322,3495424346,IN
+3495424347,3495424355,US
+3495424356,3495424381,IN
+3495424382,3495424629,US
+3495424630,3495424637,IN
+3495424638,3495424789,US
+3495424790,3495424797,IN
+3495424798,3495424865,US
+3495424866,3495424878,IN
+3495424879,3495424913,US
+3495424914,3495424919,IN
+3495424920,3495429119,US
3495429120,3495430143,CA
3495430144,3495440799,US
3495440800,3495440815,PL
@@ -108733,13 +112072,35 @@
3495526400,3495527423,CA
3495527424,3495542783,US
3495542784,3495544831,A2
-3495544832,3495549183,US
-3495549184,3495549302,CA
-3495549303,3495549334,US
-3495549335,3495549439,CA
-3495549440,3495549727,US
-3495549728,3495549760,CA
-3495549761,3495549809,US
+3495544832,3495547092,US
+3495547093,3495547093,BD
+3495547094,3495547102,US
+3495547103,3495547103,BD
+3495547104,3495547426,US
+3495547427,3495547427,BD
+3495547428,3495547445,US
+3495547446,3495547447,BD
+3495547448,3495547471,US
+3495547472,3495547479,GB
+3495547480,3495547605,US
+3495547606,3495547606,BD
+3495547607,3495548205,US
+3495548206,3495548207,ID
+3495548208,3495548544,US
+3495548545,3495548545,BD
+3495548546,3495548549,US
+3495548550,3495548550,BD
+3495548551,3495548586,US
+3495548587,3495548588,LK
+3495548589,3495548635,US
+3495548636,3495548637,BD
+3495548638,3495548640,US
+3495548641,3495548648,BD
+3495548649,3495549238,US
+3495549239,3495549302,CA
+3495549303,3495549366,US
+3495549367,3495549430,CA
+3495549431,3495549809,US
3495549810,3495549813,IN
3495549814,3495549917,US
3495549918,3495549923,CA
@@ -108765,9 +112126,7 @@
3495657552,3495657567,GB
3495657568,3495658015,US
3495658016,3495658023,IN
-3495658024,3495658039,US
-3495658040,3495658047,CO
-3495658048,3495658319,US
+3495658024,3495658319,US
3495658320,3495658327,IN
3495658328,3495673855,US
3495673856,3495674623,GP
@@ -108783,82 +112142,76 @@
3495718912,3495719151,A2
3495719152,3495720959,CA
3495720960,3495724031,US
-3495724032,3495727103,CA
+3495724032,3495724735,CA
+3495724736,3495724799,US
+3495724800,3495727103,CA
3495727104,3495740415,US
3495740416,3495741439,CA
3495741440,3495749631,US
-3495749632,3495750655,CA
+3495749632,3495749735,CA
+3495749736,3495749745,US
+3495749746,3495749767,CA
+3495749768,3495749777,US
+3495749778,3495749785,CA
+3495749786,3495749829,GB
+3495749830,3495749908,CA
+3495749909,3495749933,GB
+3495749934,3495749941,CA
+3495749942,3495749951,US
+3495749952,3495749959,CA
+3495749960,3495749990,GB
+3495749991,3495749991,CA
+3495749992,3495750021,GB
+3495750022,3495750026,CA
+3495750027,3495750051,US
+3495750052,3495750074,CA
+3495750075,3495750109,GB
+3495750110,3495750189,CA
+3495750190,3495750204,PA
+3495750205,3495750267,CA
+3495750268,3495750277,US
+3495750278,3495750302,CA
+3495750303,3495750327,US
+3495750328,3495750343,CA
+3495750344,3495750378,AU
+3495750379,3495750434,CA
+3495750435,3495750444,AU
+3495750445,3495750655,CA
3495750656,3495781311,US
3495781312,3495781375,CA
-3495781376,3495815167,US
-3495815168,3495817215,CA
+3495781376,3495812879,US
+3495812880,3495812895,GB
+3495812896,3495815167,US
+3495815168,3495815615,CA
+3495815616,3495815619,US
+3495815620,3495817215,CA
3495817216,3495828479,US
3495828480,3495829503,CA
3495829504,3495847935,US
3495847936,3495849983,CA
-3495849984,3495862271,US
+3495849984,3495859394,US
+3495859395,3495859395,GB
+3495859396,3495859650,US
+3495859651,3495859651,GB
+3495859652,3495862271,US
3495862272,3495864319,CA
-3495864320,3495865343,GP
-3495865344,3495866367,CA
+3495864320,3495864831,DM
+3495864832,3495865343,GP
+3495865344,3495865599,CA
+3495865600,3495865631,BD
+3495865632,3495866207,CA
+3495866208,3495866239,BD
+3495866240,3495866359,CA
+3495866360,3495866363,US
+3495866364,3495866367,CA
3495866368,3495868415,VC
3495868416,3495871487,US
3495871488,3495872511,CA
-3495872512,3495882799,US
-3495882800,3495882807,AM
-3495882808,3495882815,US
-3495882816,3495882823,RU
-3495882824,3495882863,US
-3495882864,3495882871,AU
-3495882872,3495882895,US
-3495882896,3495882911,CN
-3495882912,3495882927,JP
-3495882928,3495882983,US
-3495882984,3495882991,AU
-3495882992,3495882999,CA
-3495883000,3495883215,US
-3495883216,3495883223,AU
-3495883224,3495883287,US
-3495883288,3495883295,GB
-3495883296,3495883311,US
-3495883312,3495883319,TR
-3495883320,3495883327,SA
-3495883328,3495883367,US
-3495883368,3495883375,AU
-3495883376,3495883391,US
-3495883392,3495883399,IN
-3495883400,3495883407,US
-3495883408,3495883415,EG
-3495883416,3495883439,US
-3495883440,3495883447,GB
-3495883448,3495883479,US
-3495883480,3495883487,BR
-3495883488,3495883503,CN
-3495883504,3495883615,US
-3495883616,3495883623,AU
-3495883624,3495883631,US
-3495883632,3495883647,GM
-3495883648,3495883759,US
-3495883760,3495883775,CN
-3495883776,3495884119,US
-3495884120,3495884127,CA
-3495884128,3495884239,US
-3495884240,3495884247,AU
-3495884248,3495884263,US
-3495884264,3495884271,IN
-3495884272,3495884287,CN
-3495884288,3495884447,US
-3495884448,3495884463,AU
-3495884464,3495884479,US
-3495884480,3495884487,BY
-3495884488,3495884519,US
-3495884520,3495884527,IN
-3495884528,3495884543,US
-3495884544,3495884551,RO
-3495884552,3495884679,US
-3495884680,3495884687,AU
-3495884688,3495884719,US
-3495884720,3495884735,CA
-3495884736,3495896063,US
+3495872512,3495881119,US
+3495881120,3495881151,PA
+3495881152,3495881471,US
+3495881472,3495881727,PA
+3495881728,3495896063,US
3495896064,3495897087,PR
3495897088,3495930879,US
3495930880,3495931903,CA
@@ -108881,7 +112234,11 @@
3496202304,3496205839,US
3496205840,3496205855,ID
3496205856,3496205871,CA
-3496205872,3496296447,US
+3496205872,3496220995,US
+3496220996,3496220997,GB
+3496220998,3496221014,US
+3496221015,3496221016,GB
+3496221017,3496296447,US
3496296448,3496312831,CA
3496312832,3496468479,US
3496468480,3496476671,CA
@@ -109101,49 +112458,13 @@
3497164288,3497164295,GB
3497164296,3497164799,US
3497164800,3497181183,CA
-3497181184,3497222407,US
-3497222408,3497222415,IN
-3497222416,3497222463,US
-3497222464,3497222479,IN
-3497222480,3497223791,US
-3497223792,3497223807,CH
-3497223808,3497223839,US
-3497223840,3497223871,CH
-3497223872,3497223879,US
-3497223880,3497223887,ID
-3497223888,3497224255,US
-3497224256,3497224319,IN
-3497224320,3497224831,US
-3497224832,3497224863,CH
-3497224864,3497225375,US
-3497225376,3497225383,CN
-3497225384,3497225471,US
-3497225472,3497225535,IN
-3497225536,3497226295,US
+3497181184,3497226295,US
3497226296,3497226303,SG
3497226304,3497226391,US
3497226392,3497226399,IR
3497226400,3497226687,US
3497226688,3497226719,GB
-3497226720,3497226783,US
-3497226784,3497226815,CH
-3497226816,3497226831,US
-3497226832,3497226847,CH
-3497226848,3497226943,US
-3497226944,3497226959,CH
-3497226960,3497227023,US
-3497227024,3497227039,GB
-3497227040,3497227231,US
-3497227232,3497227247,CH
-3497227248,3497227255,CN
-3497227256,3497227263,CH
-3497227264,3497227391,US
-3497227392,3497227407,CN
-3497227408,3497227527,US
-3497227528,3497227535,CN
-3497227536,3497228079,US
-3497228080,3497228087,CN
-3497228088,3497233407,US
+3497226720,3497233407,US
3497233408,3497233663,CN
3497233664,3497263815,US
3497263816,3497263823,GB
@@ -109338,9 +112659,7 @@
3502202648,3502202655,PR
3502202656,3502207535,US
3502207536,3502207543,PR
-3502207544,3502418175,US
-3502418176,3502418431,GU
-3502418432,3502439167,US
+3502207544,3502439167,US
3502439168,3502439423,PK
3502439424,3502470143,US
3502470144,3502471167,MX
@@ -109352,9 +112671,7 @@
3502545664,3502545919,BS
3502545920,3502683135,US
3502683136,3502683391,MC
-3502683392,3502929663,US
-3502929664,3502929919,GU
-3502929920,3502993407,US
+3502683392,3502993407,US
3502993408,3502993919,NL
3502993920,3503027327,US
3503027328,3503027359,GB
@@ -109385,9 +112702,7 @@
3503478784,3503479039,DE
3503479040,3503738879,US
3503738880,3503740927,CO
-3503740928,3503757823,US
-3503757824,3503758335,GU
-3503758336,3503826087,US
+3503740928,3503826087,US
3503826088,3503826095,PR
3503826096,3503890431,US
3503890432,3503894527,CO
@@ -109403,9 +112718,7 @@
3504207872,3504208127,CA
3504208128,3504223743,US
3504223744,3504223999,RO
-3504224000,3504521215,US
-3504521216,3504521727,GU
-3504521728,3504889343,US
+3504224000,3504889343,US
3504889344,3504889855,PK
3504889856,3504922623,US
3504922624,3504923391,PH
@@ -109454,7 +112767,9 @@
3506043136,3506044927,PA
3506044928,3506052543,US
3506052544,3506052559,DE
-3506052560,3506135263,US
+3506052560,3506058815,US
+3506058816,3506058823,AF
+3506058824,3506135263,US
3506135264,3506135295,GB
3506135296,3506177967,US
3506177968,3506177983,DE
@@ -109478,9 +112793,7 @@
3507025408,3507025663,IQ
3507025664,3507101919,US
3507101920,3507101935,IL
-3507101936,3507134591,US
-3507134592,3507134607,GB
-3507134608,3507290111,US
+3507101936,3507290111,US
3507290112,3507355647,AR
3507355648,3507479079,US
3507479080,3507479080,CA
@@ -109488,12 +112801,12 @@
3507479109,3507479109,CA
3507479110,3507482153,US
3507482154,3507482155,CA
-3507482156,3507540015,US
+3507482156,3507485103,US
+3507485104,3507485119,CA
+3507485120,3507540015,US
3507540016,3507540031,IN
3507540032,3507585023,US
-3507585024,3507586623,CA
-3507586624,3507586655,US
-3507586656,3507598911,CA
+3507585024,3507598911,CA
3507598912,3507598943,US
3507598944,3507601407,CA
3507601408,3507634335,US
@@ -110249,27 +113562,19 @@
3509775904,3509775919,AU
3509775920,3509775943,US
3509775944,3509775951,IT
-3509775952,3509775975,US
-3509775976,3509775983,GB
-3509775984,3509776023,US
+3509775952,3509776023,US
3509776024,3509776031,CA
3509776032,3509776047,US
3509776048,3509776055,SA
3509776056,3509776095,US
3509776096,3509776103,AU
3509776104,3509776111,US
-3509776112,3509776127,IT
-3509776128,3509776224,US
-3509776225,3509776256,CA
-3509776257,3509776288,TC
-3509776289,3509776352,US
-3509776353,3509776382,GB
-3509776383,3509777159,US
+3509776112,3509776119,IT
+3509776120,3509777159,US
3509777160,3509777167,CN
3509777168,3509777175,RU
-3509777176,3509777199,US
-3509777200,3509777207,GB
-3509777208,3509777215,CA
+3509777176,3509777207,US
+3509777208,3509777215,IN
3509777216,3509777223,TH
3509777224,3509777271,US
3509777272,3509777279,IT
@@ -110283,9 +113588,7 @@
3509778400,3509778431,NL
3509778432,3509778703,US
3509778704,3509778711,CA
-3509778712,3509778847,US
-3509778848,3509778855,CA
-3509778856,3509778903,US
+3509778712,3509778903,US
3509778904,3509778911,RU
3509778912,3509778919,US
3509778920,3509778927,GB
@@ -110303,55 +113606,31 @@
3509830408,3509830415,GB
3509830416,3509830943,US
3509830944,3509830951,BE
-3509830952,3509831039,US
-3509831040,3509831047,DE
-3509831048,3509831135,US
+3509830952,3509831135,US
3509831136,3509831143,IN
-3509831144,3509831287,US
-3509831288,3509831295,GB
-3509831296,3509831303,US
-3509831304,3509831311,CO
-3509831312,3509831319,CN
-3509831320,3509831535,US
+3509831144,3509831535,US
3509831536,3509831551,LB
3509831552,3509831615,US
3509831616,3509831647,IL
3509831648,3509831735,US
3509831736,3509831743,AT
-3509831744,3509831799,US
-3509831800,3509831807,DO
+3509831744,3509831807,US
3509831808,3509831815,IN
3509831816,3509831823,CA
3509831824,3509831831,US
3509831832,3509831839,GB
-3509831840,3509831959,US
-3509831960,3509831967,CA
-3509831968,3509832079,US
-3509832080,3509832087,CN
-3509832088,3509833103,US
+3509831840,3509833103,US
3509833104,3509833111,IN
3509833112,3509833535,US
3509833536,3509833543,CA
3509833544,3509833551,IN
3509833552,3509833567,US
3509833568,3509833599,PH
-3509833600,3509833623,US
-3509833624,3509833631,GR
-3509833632,3509833703,US
+3509833600,3509833703,US
3509833704,3509833711,ZA
-3509833712,3509834095,US
-3509834096,3509834103,IL
-3509834104,3509834111,US
+3509833712,3509834111,US
3509834112,3509834143,IL
-3509834144,3509834167,US
-3509834168,3509834175,BR
-3509834176,3509834287,US
-3509834288,3509834303,IN
-3509834304,3509834399,US
-3509834400,3509834407,BD
-3509834408,3509834431,US
-3509834432,3509834463,JP
-3509834464,3509834495,US
+3509834144,3509834495,US
3509834496,3509834503,NO
3509834504,3509834519,US
3509834520,3509834527,BD
@@ -110361,9 +113640,7 @@
3509834832,3509834847,CO
3509834848,3509835103,US
3509835104,3509835111,GB
-3509835112,3509836375,US
-3509836376,3509836383,GR
-3509836384,3509837167,US
+3509835112,3509837167,US
3509837168,3509837175,GB
3509837176,3509837623,US
3509837624,3509837639,GB
@@ -110826,7 +114103,11 @@
3510897443,3510897443,IE
3510897444,3510935551,US
3510935552,3510943743,CA
-3510943744,3511140351,US
+3510943744,3511129087,US
+3511129088,3511129183,CA
+3511129184,3511129199,US
+3511129200,3511131135,CA
+3511131136,3511132159,US
3511140352,3511156735,CA
3511156736,3511331199,US
3511331200,3511331231,CA
@@ -110852,9 +114133,7 @@
3512011904,3512012095,US
3512012096,3512012159,GB
3512012160,3512012175,MX
-3512012176,3512012191,US
-3512012192,3512012223,BR
-3512012224,3512012255,US
+3512012176,3512012255,US
3512012256,3512012287,GB
3512012288,3512013583,US
3512013584,3512013599,CA
@@ -111459,8 +114738,8 @@
3512695840,3512695871,GB
3512695872,3512696831,US
3512696832,3512699647,SE
-3512699648,3512701951,US
-3512701952,3512705023,SE
+3512699648,3512699903,US
+3512699904,3512705023,SE
3512705024,3512844287,US
3512844288,3512844543,CA
3512844544,3512844607,A1
@@ -111535,66 +114814,16 @@
3514590720,3514591103,SV
3514591104,3514591487,US
3514591488,3514592255,NI
-3514592256,3514597375,SV
-3514597376,3514763423,US
-3514763424,3514763439,PA
-3514763440,3514763711,US
-3514763712,3514763727,VE
-3514763728,3514763775,US
-3514763776,3514763791,PA
-3514763792,3514764047,US
-3514764048,3514764063,PA
-3514764064,3514765823,US
-3514765824,3514765855,PA
-3514765856,3514765919,US
-3514765920,3514765951,VE
-3514765952,3514766111,US
-3514766112,3514766143,VE
-3514766144,3514766207,US
-3514766208,3514766271,PA
-3514766272,3514766303,US
-3514766304,3514766335,PA
-3514766336,3514766463,US
-3514766464,3514766495,PA
-3514766496,3514766879,US
-3514766880,3514766911,PA
-3514766912,3514767199,US
-3514767200,3514767231,VE
-3514767232,3514767455,US
-3514767456,3514767487,VE
-3514767488,3514768127,US
-3514768128,3514768191,VE
-3514768192,3514769023,US
-3514769024,3514769151,PA
-3514769152,3514769215,US
-3514769216,3514769279,PA
-3514769280,3514775295,US
-3514775296,3514775551,PA
-3514775552,3514776063,US
-3514776064,3514776319,VE
-3514776320,3514776343,US
-3514776344,3514776351,VE
-3514776352,3514776407,US
-3514776408,3514776415,VE
-3514776416,3514781695,US
-3514781696,3514782719,VE
-3514782720,3514787583,US
-3514787584,3514787839,PA
-3514787840,3514791679,US
-3514791680,3514793983,PA
-3514793984,3514826751,US
+3514592256,3514593279,SV
+3514593280,3514596863,US
+3514596864,3514597375,SV
+3514597376,3514826751,US
3514826752,3514843135,CA
3514843136,3515114247,US
3515114248,3515114255,AU
3515114256,3515149567,US
3515149568,3515149583,AU
-3515149584,3515154943,US
-3515154944,3515155199,CA
-3515155200,3515155455,US
-3515155456,3515155711,CA
-3515155712,3515166719,US
-3515166720,3515166975,CA
-3515166976,3515170991,US
+3515149584,3515170991,US
3515170992,3515170999,KR
3515171000,3515185151,US
3515185152,3515185407,CA
@@ -111604,9 +114833,7 @@
3515358976,3515359231,MX
3515359232,3515452639,US
3515452640,3515452655,KR
-3515452656,3515452775,US
-3515452776,3515452783,JP
-3515452784,3515453055,US
+3515452656,3515453055,US
3515453056,3515453071,JP
3515453072,3515453679,US
3515453680,3515453687,JP
@@ -111615,9 +114842,7 @@
3515454080,3515454095,US
3515454096,3515454111,JP
3515454112,3515454143,US
-3515454144,3515454159,JP
-3515454160,3515454167,US
-3515454168,3515454207,JP
+3515454144,3515454207,JP
3515454208,3515454399,US
3515454400,3515454463,JP
3515454464,3515455311,US
@@ -111725,9 +114950,7 @@
3517116416,3517120511,CA
3517120512,3517233151,US
3517233152,3517235199,GU
-3517235200,3517308927,US
-3517308928,3517313023,CA
-3517313024,3517382655,US
+3517235200,3517382655,US
3517382656,3517383679,CA
3517383680,3517383935,US
3517383936,3517384447,CA
@@ -112022,25 +115245,27 @@
3517546496,3517562879,CA
3517562880,3517596671,US
3517596672,3517596927,NO
-3517596928,3517597183,SE
+3517596928,3517597183,IE
3517597184,3517597695,US
3517597696,3517598207,SE
3517598208,3517598463,IE
3517598464,3517598591,SE
3517598592,3517599231,US
-3517599232,3517600767,SE
+3517599232,3517599263,BG
+3517599264,3517600767,SE
3517600768,3517601279,US
3517601280,3517602047,SE
3517602048,3517602303,DE
3517602304,3517602559,US
3517602560,3517602623,SE
3517602624,3517602815,US
-3517602816,3517603071,SE
-3517603072,3517603615,US
+3517602816,3517603327,SE
+3517603328,3517603615,US
3517603616,3517603647,DE
-3517603648,3517603839,US
-3517603840,3517603903,SE
-3517603904,3517603967,MA
+3517603648,3517603711,US
+3517603712,3517603775,SE
+3517603776,3517603839,US
+3517603840,3517603967,SE
3517603968,3517604031,DE
3517604032,3517604095,SE
3517604096,3517604351,US
@@ -112062,8 +115287,8 @@
3517609856,3517610047,US
3517610048,3517610191,SE
3517610192,3517610199,US
-3517610200,3517610207,SE
-3517610208,3517610495,US
+3517610200,3517610239,SE
+3517610240,3517610495,US
3517610496,3517611263,IE
3517611264,3517611295,SE
3517611296,3517611303,US
@@ -112102,7 +115327,8 @@
3518076672,3518076927,PA
3518076928,3518077103,US
3518077104,3518077111,GB
-3518077112,3518374719,US
+3518077112,3518078975,US
+3518083072,3518374719,US
3518374720,3518374783,IN
3518374784,3518380223,US
3518380224,3518380287,DE
@@ -112123,95 +115349,51 @@
3518759408,3518759423,CY
3518759424,3518760511,US
3518760512,3518760575,AU
-3518760576,3518760703,HU
+3518760576,3518760647,HU
+3518760648,3518760655,US
+3518760656,3518760703,HU
3518760704,3518762495,US
3518762496,3518762751,GB
-3518762752,3518764047,US
-3518764048,3518764223,GB
-3518764224,3518764671,US
+3518762752,3518764671,US
3518764672,3518764703,NL
3518764704,3518765311,US
3518765312,3518765567,CA
3518765568,3518766879,US
3518766880,3518766911,TH
-3518766912,3518890831,US
-3518890832,3518890839,IT
-3518890840,3518891175,US
-3518891176,3518891183,GB
-3518891184,3518891767,US
-3518891768,3518891775,BG
-3518891776,3518892039,US
-3518892040,3518892047,GT
-3518892048,3518892223,US
+3518766912,3518892223,US
3518892224,3518892231,CL
3518892232,3518892415,US
3518892416,3518892423,GB
-3518892424,3518894095,US
-3518894096,3518894103,KW
-3518894104,3518894343,US
-3518894344,3518894351,MY
-3518894352,3518894439,US
+3518892424,3518894439,US
3518894440,3518894447,TR
-3518894448,3518895719,US
-3518895720,3518895727,PH
-3518895728,3518895775,US
+3518894448,3518895775,US
3518895776,3518895783,CA
3518895784,3518895791,TH
-3518895792,3518895799,US
-3518895800,3518895807,AR
-3518895808,3518896215,US
+3518895792,3518896215,US
3518896216,3518896223,CA
3518896224,3518896231,US
3518896232,3518896239,CN
-3518896240,3518896519,US
-3518896520,3518896527,AE
-3518896528,3518896543,US
-3518896544,3518896551,BD
-3518896552,3518896895,US
+3518896240,3518896895,US
3518896896,3518896903,GB
-3518896904,3518897071,US
-3518897072,3518897079,IT
-3518897080,3518897119,US
+3518896904,3518897119,US
3518897120,3518897127,IT
-3518897128,3518897423,US
-3518897424,3518897431,IN
-3518897432,3518897879,US
-3518897880,3518897887,AM
-3518897888,3518898015,US
-3518898016,3518898023,IN
-3518898024,3518898143,US
+3518897128,3518898143,US
3518898144,3518898151,BR
-3518898152,3518898167,US
-3518898168,3518898175,RO
-3518898176,3518903175,US
-3518903176,3518903183,BR
-3518903184,3518903191,US
+3518898152,3518903191,US
3518903192,3518903199,JP
-3518903200,3518903399,US
-3518903400,3518903407,PK
-3518903408,3518903871,US
+3518903200,3518903871,US
3518903872,3518903879,PK
3518903880,3518903927,US
3518903928,3518903935,RU
-3518903936,3518903959,US
-3518903960,3518903967,GB
-3518903968,3518903999,US
-3518904000,3518904007,ES
-3518904008,3518904015,US
+3518903936,3518904015,US
3518904016,3518904031,EG
3518904032,3518911743,US
3518911744,3518911999,GB
3518912000,3518912511,US
3518912512,3518912767,IN
-3518912768,3518919031,US
-3518919032,3518919039,GT
-3518919040,3518919095,US
-3518919096,3518919103,BD
-3518919104,3518921447,US
+3518912768,3518921447,US
3518921448,3518921455,CN
-3518921456,3518921479,US
-3518921480,3518921487,BD
-3518921488,3518929535,US
+3518921456,3518929535,US
3518929536,3518929599,CA
3518929600,3518995695,US
3518995696,3518995703,GB
@@ -112230,9 +115412,7 @@
3519352904,3519381503,US
3519381504,3519397887,CA
3519397888,3519406079,US
-3519406080,3519406111,IT
-3519406112,3519406127,US
-3519406128,3519406143,DE
+3519406080,3519406143,IT
3519406144,3519406207,US
3519406208,3519406215,SA
3519406216,3519406255,US
@@ -112295,9 +115475,7 @@
3519411392,3519411711,US
3519411712,3519411967,AR
3519411968,3519412223,DE
-3519412224,3519412463,US
-3519412464,3519412479,GB
-3519412480,3519412519,US
+3519412224,3519412519,US
3519412520,3519412527,RU
3519412528,3519412735,US
3519412736,3519412751,RU
@@ -112307,42 +115485,15 @@
3519413760,3519414271,CA
3519414272,3519417087,US
3519417088,3519417151,IT
-3519417152,3519417215,DE
-3519417216,3519420767,US
+3519417152,3519417183,DE
+3519417184,3519420767,US
3519420768,3519420775,HK
3519420776,3519422495,US
3519422496,3519422527,CA
3519422528,3519475711,US
3519475712,3519476223,BH
3519476224,3519477759,A2
-3519477760,3519566871,US
-3519566872,3519566879,IE
-3519566880,3519566943,US
-3519566944,3519566951,GB
-3519566952,3519567087,US
-3519567088,3519567096,IE
-3519567097,3519567679,US
-3519567680,3519567687,GB
-3519567688,3519567727,US
-3519567728,3519567735,LB
-3519567736,3519567759,US
-3519567760,3519567767,JP
-3519567768,3519567831,US
-3519567832,3519567863,LB
-3519567864,3519568911,US
-3519568912,3519568919,FR
-3519568920,3519568927,LB
-3519568928,3519568991,US
-3519568992,3519568999,GB
-3519569000,3519569071,US
-3519569072,3519569079,LB
-3519569080,3519569103,US
-3519569104,3519569111,GB
-3519569112,3519569127,US
-3519569128,3519569135,GB
-3519569136,3519569727,US
-3519569728,3519569735,JP
-3519569736,3519578367,US
+3519477760,3519578367,US
3519578368,3519578623,NA
3519578624,3519578879,US
3519578880,3519579135,CA
@@ -112376,8 +115527,7 @@
3519590912,3519590927,GB
3519590928,3519590943,EE
3519590944,3519590959,AG
-3519590960,3519591055,US
-3519591056,3519591071,MT
+3519590960,3519591071,US
3519591072,3519591087,IM
3519591088,3519591167,US
3519591168,3519591423,GB
@@ -112766,15 +115916,13 @@
3520937984,3520954367,CA
3520954368,3520956155,US
3520956156,3520956159,CH
-3520956160,3520958783,US
-3520958784,3520958847,CA
-3520958848,3520966111,US
-3520966112,3520966119,CA
-3520966120,3520978943,US
+3520956160,3520978943,US
3520978944,3520979711,BZ
3520979712,3520999423,US
3520999424,3521003519,CA
-3521003520,3521007103,US
+3521003520,3521003583,US
+3521003584,3521003647,IL
+3521003648,3521007103,US
3521007104,3521007111,IN
3521007112,3521011743,US
3521011744,3521011751,PK
@@ -112787,9 +115935,7 @@
3521013560,3521013567,GB
3521013568,3521013951,US
3521013952,3521013959,AU
-3521013960,3521014103,US
-3521014104,3521014111,NL
-3521014112,3521014127,US
+3521013960,3521014127,US
3521014128,3521014135,GR
3521014136,3521014143,CA
3521014144,3521028095,US
@@ -112851,10 +115997,8 @@
3521835904,3521835967,CA
3521835968,3521836351,US
3521836352,3521836415,IL
-3521836416,3521836503,US
-3521836504,3521836511,IL
-3521836512,3521836687,US
-3521836688,3521836703,CA
+3521836416,3521836687,US
+3521836688,3521836703,GB
3521836704,3521904639,US
3521904640,3521921023,JM
3521921024,3521933321,US
@@ -112923,26 +116067,19 @@
3522121216,3522121471,US
3522121472,3522121983,LY
3522121984,3522122239,AW
-3522122240,3522131455,US
-3522131456,3522131487,PE
-3522131488,3522131519,RS
-3522131520,3522131711,US
+3522122240,3522131711,US
3522131712,3522131743,GB
3522131744,3522131775,DE
3522131776,3522131807,BR
3522131808,3522132479,US
3522132480,3522132543,CO
-3522132544,3522132575,TR
+3522132544,3522132575,US
3522132576,3522132607,UA
3522132608,3522132639,CA
-3522132640,3522132671,PE
+3522132640,3522132671,BO
3522132672,3522132703,BR
3522132704,3522132735,LK
-3522132736,3522132767,US
-3522132768,3522132799,RO
-3522132800,3522133567,US
-3522133568,3522133568,PT
-3522133569,3522133599,US
+3522132736,3522133599,US
3522133600,3522133631,JP
3522133632,3522133639,US
3522133640,3522133647,DE
@@ -112959,15 +116096,7 @@
3522759592,3522759599,CA
3522759600,3522763263,US
3522763264,3522763519,CA
-3522763520,3522768895,US
-3522768896,3522769151,CA
-3522769152,3522769919,US
-3522769920,3522770175,CA
-3522770176,3522807807,US
-3522807808,3522807815,JP
-3522807816,3522820863,US
-3522820864,3522821119,CA
-3522821120,3522854911,US
+3522763520,3522854911,US
3522854912,3522859999,CA
3522860000,3522860031,IN
3522860032,3522871295,CA
@@ -113384,9 +116513,7 @@
3556769792,3556774399,DE
3556774400,3556786175,EU
3556786176,3556794367,RU
-3556794368,3556795647,ES
-3556795648,3556795679,IT
-3556795680,3556797767,ES
+3556794368,3556797767,ES
3556797768,3556797775,GB
3556797776,3556797839,ES
3556797840,3556797847,PT
@@ -113513,7 +116640,9 @@
3557244928,3557253119,IT
3557253120,3557261311,RU
3557261312,3557277695,DE
-3557277696,3557285887,NL
+3557277696,3557280334,NL
+3557280335,3557280336,IN
+3557280337,3557285887,NL
3557285888,3557294079,RU
3557294080,3557302271,DE
3557302272,3557310463,UA
@@ -113553,8 +116682,8 @@
3557341552,3557341559,EU
3557341560,3557341567,BE
3557341568,3557341663,EU
-3557341664,3557341679,BE
-3557341680,3557341951,EU
+3557341664,3557341695,BE
+3557341696,3557341951,EU
3557341952,3557342479,BE
3557342480,3557342495,EU
3557342496,3557342511,BE
@@ -113586,8 +116715,8 @@
3557360624,3557360639,JE
3557360640,3557360680,GB
3557360681,3557360687,JE
-3557360688,3557360807,GB
-3557360808,3557360895,JE
+3557360688,3557360815,GB
+3557360816,3557360895,JE
3557360896,3557360927,GB
3557360928,3557360943,JE
3557360944,3557360959,GB
@@ -113615,7 +116744,11 @@
3557363456,3557363471,GB
3557363472,3557363479,JE
3557363480,3557363655,GB
-3557363656,3557363783,JE
+3557363656,3557363663,JE
+3557363664,3557363671,GB
+3557363672,3557363679,JE
+3557363680,3557363687,GB
+3557363688,3557363783,JE
3557363784,3557363791,GB
3557363792,3557364223,JE
3557364224,3557364479,GB
@@ -113638,14 +116771,14 @@
3557364896,3557364927,JE
3557364928,3557364959,GB
3557364960,3557364991,JE
-3557364992,3557365055,GB
-3557365056,3557365103,JE
+3557364992,3557365087,GB
+3557365088,3557365103,JE
3557365104,3557365111,GB
3557365112,3557365119,JE
3557365120,3557365183,GB
3557365184,3557365247,JE
-3557365248,3557365407,GB
-3557365408,3557365503,JE
+3557365248,3557365423,GB
+3557365424,3557365503,JE
3557365504,3557365511,GB
3557365512,3557365519,JE
3557365520,3557365551,GB
@@ -113736,23 +116869,21 @@
3557834752,3557842943,IR
3557842944,3557851135,FI
3557851136,3557859327,HU
-3557859328,3557867519,SE
+3557859328,3557860831,SE
+3557860832,3557860847,FI
+3557860848,3557867519,SE
3557867520,3557875711,RU
3557875712,3557883903,DE
3557883904,3557892095,RU
3557892096,3557900287,IE
3557900288,3557916671,AT
3557916672,3557924863,NO
-3557924864,3557933055,AX
+3557924864,3557933055,FI
3557933056,3557941247,IT
3557941248,3557945183,DE
3557945184,3557945199,GB
3557945200,3557957631,DE
-3557957632,3557960975,SI
-3557960976,3557960983,AE
-3557960984,3557961375,SI
-3557961376,3557961407,AE
-3557961408,3557965823,SI
+3557957632,3557965823,SI
3557965824,3557974015,DE
3557974016,3557982207,CH
3557982208,3557990399,NO
@@ -113761,7 +116892,13 @@
3558006784,3558014975,GB
3558014976,3558023167,RU
3558023168,3558023199,GB
-3558023200,3558030655,DE
+3558023200,3558023343,DE
+3558023344,3558023359,GB
+3558023360,3558024383,DE
+3558024384,3558024415,GB
+3558024416,3558028063,DE
+3558028064,3558028071,CH
+3558028072,3558030655,DE
3558030656,3558030659,CH
3558030660,3558031359,DE
3558031360,3558039551,GB
@@ -113859,15 +116996,14 @@
3558288424,3558288447,GB
3558288448,3558288483,US
3558288484,3558288487,GB
-3558288488,3558288495,GU
-3558288496,3558288639,US
+3558288488,3558288639,US
3558288640,3558288671,BE
3558288672,3558288687,DE
3558288688,3558288703,BE
3558288704,3558288719,GB
3558288720,3558288895,BE
-3558288896,3558289103,FR
-3558289104,3558289119,GB
+3558288896,3558289111,FR
+3558289112,3558289119,GB
3558289120,3558289151,FR
3558289152,3558289407,GB
3558289408,3558289663,NL
@@ -113909,11 +117045,11 @@
3558292288,3558292543,NL
3558292544,3558292607,GB
3558292608,3558292735,NL
-3558292736,3558292871,GB
-3558292872,3558292879,NL
-3558292880,3558292895,GB
-3558292896,3558293087,NL
-3558293088,3558293247,GB
+3558292736,3558292863,GB
+3558292864,3558293143,NL
+3558293144,3558293151,GB
+3558293152,3558293199,NL
+3558293200,3558293247,GB
3558293248,3558293503,NL
3558293504,3558301695,RU
3558301696,3558310319,DE
@@ -114031,13 +117167,11 @@
3558719488,3558735871,IL
3558735872,3558736127,GB
3558736128,3558736639,GG
-3558736640,3558737023,GB
-3558737024,3558737151,GG
+3558736640,3558737055,GB
+3558737056,3558737151,GG
3558737152,3558737279,GB
3558737280,3558737919,GG
-3558737920,3558738431,GB
-3558738432,3558738687,GG
-3558738688,3558738751,GB
+3558737920,3558738751,GB
3558738752,3558738943,GG
3558738944,3558738991,GB
3558738992,3558739007,GG
@@ -114247,7 +117381,8 @@
3559006208,3559014399,RU
3559014400,3559016191,DE
3559016192,3559016207,GB
-3559016208,3559022591,DE
+3559016208,3559016215,JP
+3559016216,3559022591,DE
3559022592,3559030783,RU
3559030784,3559038720,ES
3559038721,3559038975,US
@@ -114268,13 +117403,11 @@
3559088376,3559088379,GB
3559088380,3559089023,BE
3559089024,3559089027,GB
-3559089028,3559089055,BE
-3559089056,3559089063,DE
-3559089064,3559089407,BE
+3559089028,3559089351,BE
+3559089352,3559089359,GB
+3559089360,3559089407,BE
3559089408,3559089411,GB
-3559089412,3559089423,BE
-3559089424,3559089427,GB
-3559089428,3559089439,BE
+3559089412,3559089439,BE
3559089440,3559089443,GB
3559089444,3559089447,BE
3559089448,3559089451,GB
@@ -114293,11 +117426,15 @@
3559089656,3559089659,GB
3559089660,3559090071,BE
3559090072,3559090079,NL
-3559090080,3559090439,BE
+3559090080,3559090127,BE
+3559090128,3559090135,GB
+3559090136,3559090439,BE
3559090440,3559090443,GB
3559090444,3559090463,BE
3559090464,3559090467,GB
-3559090468,3559090483,BE
+3559090468,3559090471,BE
+3559090472,3559090479,GB
+3559090480,3559090483,BE
3559090484,3559090487,GB
3559090488,3559090587,BE
3559090588,3559090591,GB
@@ -114307,7 +117444,9 @@
3559090776,3559090779,GB
3559090780,3559090803,BE
3559090804,3559090807,GB
-3559090808,3559090863,BE
+3559090808,3559090831,BE
+3559090832,3559090839,GB
+3559090840,3559090863,BE
3559090864,3559090871,GB
3559090872,3559090895,BE
3559090896,3559090899,GB
@@ -114325,9 +117464,13 @@
3559091204,3559091207,GB
3559091208,3559091211,BE
3559091212,3559091215,GB
-3559091216,3559091423,BE
+3559091216,3559091223,BE
+3559091224,3559091231,GB
+3559091232,3559091423,BE
3559091424,3559091427,GB
-3559091428,3559091507,BE
+3559091428,3559091439,BE
+3559091440,3559091447,ES
+3559091448,3559091507,BE
3559091508,3559091511,GB
3559091512,3559091535,BE
3559091536,3559091543,GB
@@ -114337,16 +117480,22 @@
3559091592,3559091615,GB
3559091616,3559091631,BE
3559091632,3559091639,LU
-3559091640,3559092159,BE
+3559091640,3559091855,BE
+3559091856,3559091863,GB
+3559091864,3559092159,BE
3559092160,3559092160,GB
3559092161,3559092222,BE
3559092223,3559092223,GB
-3559092224,3559092735,BE
+3559092224,3559092295,BE
+3559092296,3559092303,GB
+3559092304,3559092399,BE
+3559092400,3559092407,GB
+3559092408,3559092735,BE
3559092736,3559092739,GB
3559092740,3559092799,BE
3559092800,3559092803,GB
-3559092804,3559092855,BE
-3559092856,3559092863,GB
+3559092804,3559092847,BE
+3559092848,3559092863,GB
3559092864,3559092871,BE
3559092872,3559092895,GB
3559092896,3559092939,BE
@@ -114358,7 +117507,9 @@
3559093000,3559093007,BE
3559093008,3559093015,GB
3559093016,3559093023,FR
-3559093024,3559093063,BE
+3559093024,3559093047,BE
+3559093048,3559093055,GB
+3559093056,3559093063,BE
3559093064,3559093071,FR
3559093072,3559093075,BE
3559093076,3559093079,GB
@@ -114415,7 +117566,8 @@
3559094320,3559094335,GB
3559094336,3559094423,BE
3559094424,3559094447,GB
-3559094448,3559094527,BE
+3559094448,3559094455,ES
+3559094456,3559094527,BE
3559094528,3559095039,GB
3559095040,3559095055,BE
3559095056,3559095063,GB
@@ -114449,7 +117601,6 @@
3559096320,3559103231,RO
3559103232,3559103487,GB
3559103488,3559104511,RO
-3559104512,3559112703,UA
3559112704,3559120895,IT
3559120896,3559129087,GB
3559129088,3559137279,BG
@@ -114502,7 +117653,6 @@
3559186432,3559194623,RU
3559194624,3559202815,SE
3559202816,3559211007,DE
-3559211008,3559219199,GR
3559219200,3559227391,SE
3559227392,3559235583,DK
3559235584,3559243775,DE
@@ -114558,14 +117708,18 @@
3559491440,3559491455,ES
3559491456,3559491647,NL
3559491648,3559491711,ES
-3559491712,3559491839,NL
+3559491712,3559491727,NL
+3559491728,3559491735,ES
+3559491736,3559491839,NL
3559491840,3559491871,ES
3559491872,3559491903,GB
3559491904,3559491967,ES
3559491968,3559492003,NL
3559492004,3559492007,ES
3559492008,3559492013,NL
-3559492014,3559492031,ES
+3559492014,3559492015,ES
+3559492016,3559492023,NL
+3559492024,3559492031,ES
3559492032,3559493151,NL
3559493152,3559493167,ES
3559493168,3559493247,NL
@@ -114589,7 +117743,19 @@
3559586304,3559587839,DE
3559587840,3559596031,KW
3559596032,3559604223,BG
-3559604224,3559612415,DE
+3559604224,3559607983,DE
+3559607984,3559607999,LU
+3559608000,3559608079,DE
+3559608080,3559608095,LU
+3559608096,3559608135,DE
+3559608136,3559608143,LU
+3559608144,3559611135,DE
+3559611136,3559611391,GB
+3559611392,3559611583,DE
+3559611584,3559611647,LU
+3559611648,3559611731,DE
+3559611732,3559611735,NL
+3559611736,3559612415,DE
3559612416,3559620607,IT
3559620608,3559628799,CH
3559628800,3559636991,GB
@@ -114682,15 +117848,15 @@
3559902176,3559902187,EE
3559902188,3559902191,UA
3559902192,3559902207,EE
-3559902208,3559902623,UA
-3559902624,3559902631,EE
-3559902632,3559902975,UA
+3559902208,3559902975,UA
3559902976,3559903231,EE
-3559903232,3559903743,UA
+3559903232,3559903487,UA
+3559903488,3559903551,EE
+3559903552,3559903743,UA
3559903744,3559904023,EE
3559904024,3559904255,UA
-3559904256,3559904383,EE
-3559904384,3559904607,UA
+3559904256,3559904511,EE
+3559904512,3559904607,UA
3559904608,3559904639,EE
3559904640,3559905019,UA
3559905020,3559905031,EE
@@ -114700,20 +117866,24 @@
3559905144,3559905151,UA
3559905152,3559905155,EE
3559905156,3559905159,UA
-3559905160,3559905247,EE
+3559905160,3559905225,EE
+3559905226,3559905231,UA
+3559905232,3559905247,EE
3559905248,3559905255,UA
3559905256,3559905297,EE
3559905298,3559905299,UA
-3559905300,3559905307,EE
-3559905308,3559905535,UA
+3559905300,3559905317,EE
+3559905318,3559905319,LT
+3559905320,3559905323,EE
+3559905324,3559905535,UA
3559905536,3559905623,EE
3559905624,3559905631,UA
-3559905632,3559905951,EE
-3559905952,3559905983,UA
+3559905632,3559905975,EE
+3559905976,3559905983,UA
3559905984,3559906257,EE
-3559906258,3559906263,UA
-3559906264,3559906783,EE
-3559906784,3559906815,UA
+3559906258,3559906259,UA
+3559906260,3559906799,EE
+3559906800,3559906815,UA
3559906816,3559906975,EE
3559906976,3559907071,UA
3559907072,3559907327,EE
@@ -114773,7 +117943,7 @@
3560316928,3560325119,NL
3560325120,3560333311,DK
3560333312,3560341503,RO
-3560349696,3560357887,GB
+3560341504,3560357887,GB
3560357888,3560366079,GR
3560366080,3560366687,CH
3560366688,3560366695,IT
@@ -114832,9 +118002,7 @@
3560742632,3560742911,DE
3560742912,3560751103,AT
3560751104,3560767487,DE
-3560767488,3560832255,NL
-3560832256,3560832511,GB
-3560832512,3560832791,NL
+3560767488,3560832791,NL
3560832792,3560832799,BE
3560832800,3560833023,NL
3560833024,3560841215,GB
@@ -115606,7 +118774,7 @@
3560943160,3560943160,NO
3560943161,3560943161,BE
3560943162,3560943162,GR
-3560943163,3560943163,CH
+3560943163,3560943163,DE
3560943164,3560943164,PL
3560943165,3560943165,FR
3560943166,3560943166,GB
@@ -116091,7 +119259,7 @@
3560943761,3560943761,GB
3560943762,3560943762,IT
3560943763,3560943763,FR
-3560943764,3560943764,PL
+3560943764,3560943764,DE
3560943765,3560943765,SE
3560943766,3560943766,CY
3560943767,3560943768,DE
@@ -116762,9 +119930,7 @@
3560947044,3560947067,US
3560947068,3560947071,AR
3560947072,3560947075,BR
-3560947076,3560947087,US
-3560947088,3560947091,PR
-3560947092,3560947095,US
+3560947076,3560947095,US
3560947096,3560947099,MX
3560947100,3560947107,US
3560947108,3560947111,DE
@@ -116772,8 +119938,7 @@
3560947124,3560947127,CO
3560947128,3560947143,US
3560947144,3560947147,DE
-3560947148,3560947151,PR
-3560947152,3560947159,US
+3560947148,3560947159,US
3560947160,3560947163,PR
3560947164,3560947191,US
3560947192,3560947195,VE
@@ -116823,7 +119988,8 @@
3560947688,3560947711,JP
3560947712,3560950839,SE
3560950840,3560950843,CZ
-3560950844,3560950863,SE
+3560950844,3560950847,FI
+3560950848,3560950863,SE
3560950864,3560950867,DK
3560950868,3560950871,ES
3560950872,3560950956,SE
@@ -116832,7 +119998,9 @@
3560951028,3560951031,DK
3560951032,3560951039,SE
3560951040,3560951043,NO
-3560951044,3560951088,SE
+3560951044,3560951083,SE
+3560951084,3560951087,DK
+3560951088,3560951088,SE
3560951089,3560951090,PL
3560951091,3560951091,SE
3560951092,3560951095,IT
@@ -116840,9 +120008,12 @@
3560951104,3560951107,DE
3560951108,3560951111,DK
3560951112,3560951115,FR
-3560951116,3560951195,SE
+3560951116,3560951119,SE
+3560951120,3560951123,CZ
+3560951124,3560951195,SE
3560951196,3560951199,DK
-3560951200,3560951207,SE
+3560951200,3560951203,SE
+3560951204,3560951207,AE
3560951208,3560951211,DK
3560951212,3560951215,IT
3560951216,3560951307,SE
@@ -116879,7 +120050,10 @@
3560951596,3560951599,CZ
3560951600,3560951679,SE
3560951680,3560951683,DE
-3560951684,3560951807,SE
+3560951684,3560951759,SE
+3560951760,3560951763,DK
+3560951764,3560951767,HU
+3560951768,3560951807,SE
3560951808,3560951811,US
3560951812,3560951816,SE
3560951817,3560951818,ES
@@ -117072,10 +120246,12 @@
3561610240,3561610495,US
3561610496,3561610527,FR
3561610528,3561610719,GB
-3561610720,3561611295,FR
-3561611296,3561611559,GB
+3561610720,3561611311,FR
+3561611312,3561611559,GB
3561611560,3561611567,FR
-3561611568,3561614175,GB
+3561611568,3561612287,GB
+3561612288,3561612415,FR
+3561612416,3561614175,GB
3561614176,3561614199,FR
3561614200,3561614335,GB
3561614336,3561614591,FR
@@ -117196,8 +120372,8 @@
3561929856,3561929879,GB
3561929880,3561929919,NL
3561929920,3561929967,GB
-3561929968,3561930335,NL
-3561930336,3561930495,GB
+3561929968,3561930239,NL
+3561930240,3561930495,GB
3561930496,3561930511,NL
3561930512,3561930519,BE
3561930520,3561930527,FR
@@ -117220,6 +120396,7 @@
3561963144,3561963151,AU
3561963152,3561963519,DE
3561963520,3561971711,BE
+3561971712,3561975807,CZ
3561975808,3561979903,UA
3561979904,3561988095,ES
3561988096,3562004479,DE
@@ -117494,6 +120671,7 @@
3562651648,3562659839,DE
3562659840,3562668031,SK
3562668032,3562676223,IT
+3562676224,3562684415,UA
3562684416,3562692607,FI
3562692608,3562695375,UA
3562695376,3562695379,CZ
@@ -117566,9 +120744,7 @@
3563028480,3563036671,IR
3563036672,3563044863,BG
3563044864,3563053055,ES
-3563053056,3563053503,GB
-3563053504,3563053527,US
-3563053528,3563061247,GB
+3563053056,3563061247,GB
3563061248,3563061759,GH
3563061760,3563062527,NG
3563062528,3563067391,GH
@@ -117579,7 +120755,7 @@
3563068416,3563069183,NG
3563069184,3563069439,GH
3563069440,3563077631,HU
-3563077632,3563085823,FR
+3563077632,3563085823,SE
3563085824,3563094015,RU
3563094016,3563096255,DE
3563096256,3563096287,GB
@@ -117802,8 +120978,8 @@
3563851024,3563851135,ES
3563851136,3563851839,NL
3563851840,3563851903,ES
-3563851904,3563851967,NL
-3563851968,3563852095,ES
+3563851904,3563852031,NL
+3563852032,3563852095,ES
3563852096,3563852191,NL
3563852192,3563852207,GB
3563852208,3563852216,NL
@@ -117859,9 +121035,7 @@
3564024136,3564024143,IT
3564024144,3564024447,GB
3564024448,3564024463,IT
-3564024464,3564024671,GB
-3564024672,3564024783,IT
-3564024784,3564027903,GB
+3564024464,3564027903,GB
3564027904,3564041215,DE
3564041216,3564041727,RU
3564041728,3564044287,DE
@@ -117903,7 +121077,9 @@
3564185344,3564191743,UA
3564191744,3564199935,BE
3564199936,3564208127,RU
-3564208128,3564216319,GB
+3564208128,3564212735,GB
+3564212736,3564213007,IE
+3564213008,3564216319,GB
3564216320,3564224511,PT
3564224512,3564232703,GB
3564232704,3564240895,RU
@@ -118059,9 +121235,7 @@
3564363776,3564371967,UA
3564371968,3564380159,DE
3564380160,3564388351,FI
-3564388352,3564392959,SE
-3564392960,3564393087,NO
-3564393088,3564396543,SE
+3564388352,3564396543,SE
3564396544,3564404735,RU
3564404736,3564412927,BG
3564412928,3564421119,IL
@@ -118144,7 +121318,9 @@
3564560392,3564560399,CA
3564560400,3564560415,US
3564560416,3564560511,GB
-3564560512,3564560607,US
+3564560512,3564560527,US
+3564560528,3564560543,GB
+3564560544,3564560607,US
3564560608,3564560927,GB
3564560928,3564560959,US
3564560960,3564561039,GB
@@ -118251,13 +121427,15 @@
3564699648,3564716031,GB
3564716032,3564724223,IT
3564724224,3564732415,NL
-3564732416,3564734287,DE
+3564732416,3564733183,DE
+3564733184,3564733439,GB
+3564733440,3564734287,DE
3564734288,3564734303,GB
3564734304,3564734399,DE
3564734400,3564734431,GB
3564734432,3564734815,DE
-3564734816,3564734819,GB
-3564734820,3564734847,DE
+3564734816,3564734823,GB
+3564734824,3564734847,DE
3564734848,3564734975,GB
3564734976,3564736511,DE
3564736512,3564736527,GB
@@ -118327,8 +121505,8 @@
3564881160,3564881199,GB
3564881200,3564881203,FR
3564881204,3564881231,GB
-3564881232,3564881263,NL
-3564881264,3564881343,GB
+3564881232,3564881247,NL
+3564881248,3564881343,GB
3564881344,3564881359,NL
3564881360,3564881375,GB
3564881376,3564881439,NL
@@ -118354,8 +121532,8 @@
3564882144,3564882239,NL
3564882240,3564882255,GB
3564882256,3564882271,NL
-3564882272,3564882399,GB
-3564882400,3564882943,NL
+3564882272,3564882431,GB
+3564882432,3564882943,NL
3564882944,3564883007,GB
3564883008,3564883039,NL
3564883040,3564883071,GB
@@ -118384,9 +121562,7 @@
3564884560,3564884567,NL
3564884568,3564884735,GB
3564884736,3564885039,NL
-3564885040,3564885087,GB
-3564885088,3564885119,NL
-3564885120,3564885215,GB
+3564885040,3564885215,GB
3564885216,3564885343,NL
3564885344,3564885359,GB
3564885360,3564885367,NL
@@ -118409,7 +121585,9 @@
3564885776,3564885791,GB
3564885792,3564885799,NL
3564885800,3564885839,GB
-3564885840,3564885887,NL
+3564885840,3564885855,NL
+3564885856,3564885871,GB
+3564885872,3564885887,NL
3564885888,3564885919,GB
3564885920,3564885935,NL
3564885936,3564885951,GB
@@ -118533,8 +121711,7 @@
3564904448,3564912639,DE
3564912640,3564920831,BG
3564920832,3564922879,ES
-3564922880,3564928511,US
-3564928512,3564929023,RU
+3564922880,3564929023,US
3564929024,3564937215,AT
3564937216,3564945407,RS
3564945408,3564947175,GB
@@ -118746,14 +121923,14 @@
3565036288,3565036543,GB
3565036544,3565037119,IE
3565037120,3565037135,GB
-3565037136,3565037279,IE
-3565037280,3565037567,GB
+3565037136,3565037311,IE
+3565037312,3565037567,GB
3565037568,3565037823,IE
3565037824,3565038591,GB
3565038592,3565038663,IE
3565038664,3565039615,GB
-3565039616,3565041663,IE
-3565041664,3565043711,GB
+3565039616,3565042175,IE
+3565042176,3565043711,GB
3565043712,3565047807,AT
3565047808,3565048063,LI
3565048064,3565051903,AT
@@ -119253,10 +122430,7 @@
3567165440,3567169535,RU
3567169536,3567173631,MK
3567173632,3567239167,GB
-3567239168,3567250143,NL
-3567250144,3567250175,EU
-3567250176,3567250943,NL
-3567250944,3567255551,EU
+3567239168,3567255551,NL
3567255552,3567321087,PL
3567321088,3567323007,GB
3567323008,3567323023,CH
@@ -119311,17 +122485,17 @@
3567388608,3567388671,GB
3567388672,3567388927,CZ
3567388928,3567389183,DE
-3567389184,3567389695,GB
+3567389184,3567389311,GB
+3567389312,3567389375,DE
+3567389376,3567389695,GB
3567389696,3567390975,DE
3567390976,3567391107,GB
3567391108,3567391111,DE
3567391112,3567391147,GB
3567391148,3567391151,DE
3567391152,3567391231,GB
-3567391232,3567391615,DE
-3567391616,3567391759,GB
-3567391760,3567391791,DE
-3567391792,3567391807,GB
+3567391232,3567391743,DE
+3567391744,3567391807,GB
3567391808,3567391839,DE
3567391840,3567392767,GB
3567392768,3567393023,DE
@@ -119353,8 +122527,10 @@
3567399392,3567399423,GB
3567399424,3567399439,DE
3567399440,3567399487,GB
-3567399488,3567399871,DE
-3567399872,3567399935,GB
+3567399488,3567399647,DE
+3567399648,3567399679,GB
+3567399680,3567399807,DE
+3567399808,3567399935,GB
3567399936,3567400703,DE
3567400704,3567400735,GB
3567400736,3567400751,DE
@@ -119573,7 +122749,9 @@
3568848872,3568848879,GB
3568848880,3568876159,DE
3568876160,3568876287,ES
-3568876288,3568916399,DE
+3568876288,3568915791,DE
+3568915792,3568915807,LU
+3568915808,3568916399,DE
3568916400,3568916407,IT
3568916408,3568938311,DE
3568938312,3568938319,FI
@@ -119599,9 +122777,7 @@
3569238400,3569238527,AT
3569238528,3569239071,BE
3569239072,3569239103,LU
-3569239104,3569239231,BE
-3569239232,3569239263,LU
-3569239264,3569239519,BE
+3569239104,3569239519,BE
3569239520,3569239551,LU
3569239552,3569239983,BE
3569239984,3569239999,BN
@@ -120620,9 +123796,7 @@
3574153360,3574153367,AT
3574153368,3574153615,DE
3574153616,3574153623,AT
-3574153624,3574153731,DE
-3574153732,3574153735,HU
-3574153736,3574155627,DE
+3574153624,3574155627,DE
3574155628,3574155631,NL
3574155632,3574155727,DE
3574155728,3574155731,AT
@@ -120723,9 +123897,9 @@
3574917632,3574919359,DE
3574919360,3574919391,FR
3574919392,3574920223,DE
-3574920224,3574920239,RO
+3574920224,3574920239,LU
3574920240,3574920503,DE
-3574920504,3574920511,RO
+3574920504,3574920511,LU
3574920512,3574923263,DE
3574923264,3574939647,RU
3574939648,3574956031,SE
@@ -120739,7 +123913,9 @@
3575185408,3575250943,PL
3575250944,3575316479,IT
3575316480,3575349247,RU
-3575349248,3575355231,ES
+3575349248,3575351679,ES
+3575351680,3575351687,NL
+3575351688,3575355231,ES
3575355232,3575355247,GB
3575355248,3575360199,ES
3575360200,3575360207,FR
@@ -120763,161 +123939,156 @@
3575513088,3575545855,PT
3575545856,3575562239,FR
3575562240,3575578623,DE
-3575578624,3575578879,EU
+3575578624,3575578879,BE
3575578880,3575579135,AU
-3575579136,3575579647,EU
+3575579136,3575579647,BE
3575579648,3575579903,AU
-3575579904,3575581439,EU
+3575579904,3575581439,BE
3575581440,3575581567,GB
3575581568,3575581695,IT
-3575581696,3575582207,EU
+3575581696,3575582207,BE
3575582208,3575582463,CH
3575582464,3575582719,FR
-3575582720,3575583103,EU
+3575582720,3575583103,BE
3575583104,3575583111,HU
3575583112,3575583115,GB
3575583116,3575583119,FR
-3575583120,3575583231,EU
+3575583120,3575583231,BE
3575583232,3575583487,IT
-3575583488,3575585791,EU
+3575583488,3575585791,BE
3575585792,3575586047,EG
3575586048,3575586303,IT
3575586304,3575586815,BE
3575586816,3575587071,GB
-3575587072,3575587199,EU
-3575587200,3575587215,BE
-3575587216,3575587231,EU
+3575587072,3575587231,BE
3575587232,3575587247,NL
3575587248,3575587255,FR
-3575587256,3575587263,EU
+3575587256,3575587263,BE
3575587264,3575587271,CH
-3575587272,3575587287,EU
+3575587272,3575587287,BE
3575587288,3575587295,PL
-3575587296,3575587319,EU
+3575587296,3575587319,BE
3575587320,3575587323,PL
-3575587324,3575587839,EU
+3575587324,3575587839,BE
3575587840,3575588351,GB
-3575588352,3575588863,EU
+3575588352,3575588863,BE
3575588864,3575589887,A2
-3575589888,3575590399,EU
+3575589888,3575590399,BE
3575590400,3575590911,A2
-3575590912,3575592447,EU
-3575592448,3575592959,BE
-3575592960,3575595007,EU
+3575590912,3575595007,BE
3575595008,3575595519,GB
-3575595520,3575596287,EU
+3575595520,3575596287,BE
3575596288,3575596415,GB
-3575596416,3575596543,EU
+3575596416,3575596543,BE
3575596544,3575596799,FR
-3575596800,3575622607,EU
+3575596800,3575622607,BE
3575622608,3575622611,GB
-3575622612,3575622655,EU
+3575622612,3575622655,BE
3575622656,3575622815,GB
-3575622816,3575622847,EU
+3575622816,3575622847,BE
3575622848,3575622879,IT
3575622880,3575622911,FI
3575622912,3575623167,GB
-3575623168,3575624703,EU
+3575623168,3575624703,BE
3575624704,3575624831,FR
3575624832,3575624839,PT
3575624840,3575624863,GB
3575624864,3575624895,IL
3575624896,3575624911,GB
-3575624912,3575624959,EU
+3575624912,3575624959,BE
3575624960,3575624991,GB
3575624992,3575624999,IT
3575625000,3575625007,GB
3575625008,3575625023,NL
3575625024,3575625027,EG
-3575625028,3575625035,EU
+3575625028,3575625035,BE
3575625036,3575625039,GB
-3575625040,3575625047,EU
+3575625040,3575625047,BE
3575625048,3575625055,FI
-3575625056,3575625071,EU
+3575625056,3575625071,BE
3575625072,3575625087,PL
-3575625088,3575625095,BE
-3575625096,3575625103,EU
+3575625088,3575625103,BE
3575625104,3575625151,GB
-3575625152,3575625351,EU
+3575625152,3575625351,BE
3575625352,3575625359,GB
-3575625360,3575625375,EU
+3575625360,3575625375,BE
3575625376,3575625407,IT
-3575625408,3575625439,EU
+3575625408,3575625439,BE
3575625440,3575625455,ES
-3575625456,3575625471,EU
+3575625456,3575625471,BE
3575625472,3575625503,NO
-3575625504,3575625983,EU
+3575625504,3575625983,BE
3575625984,3575625991,SE
-3575625992,3575626047,EU
+3575625992,3575626047,BE
3575626048,3575626111,FR
-3575626112,3575626319,EU
+3575626112,3575626319,BE
3575626320,3575626335,GB
3575626336,3575626351,ES
3575626352,3575626367,DE
-3575626368,3575626503,EU
+3575626368,3575626503,BE
3575626504,3575626511,CH
-3575626512,3575626519,EU
+3575626512,3575626519,BE
3575626520,3575626527,FR
-3575626528,3575626567,EU
+3575626528,3575626567,BE
3575626568,3575626575,RO
-3575626576,3575626599,EU
+3575626576,3575626599,BE
3575626600,3575626607,IE
-3575626608,3575626631,EU
+3575626608,3575626631,BE
3575626632,3575626639,GB
3575626640,3575626647,DE
3575626648,3575626655,IT
-3575626656,3575627311,EU
+3575626656,3575627311,BE
3575627312,3575627327,ES
3575627328,3575627335,SE
-3575627336,3575627359,EU
+3575627336,3575627359,BE
3575627360,3575627367,ES
-3575627368,3575627423,EU
+3575627368,3575627423,BE
3575627424,3575627431,DE
-3575627432,3575627487,EU
+3575627432,3575627487,BE
3575627488,3575627503,GB
-3575627504,3575627711,EU
+3575627504,3575627711,BE
3575627712,3575627775,GB
3575627776,3575628543,NL
-3575628544,3575628631,EU
+3575628544,3575628631,BE
3575628632,3575628639,GB
-3575628640,3575628815,EU
+3575628640,3575628815,BE
3575628816,3575628823,ES
3575628824,3575628831,FR
-3575628832,3575629183,EU
+3575628832,3575629183,BE
3575629184,3575629247,NL
-3575629248,3575629279,EU
+3575629248,3575629279,BE
3575629280,3575629287,GB
-3575629288,3575629295,EU
+3575629288,3575629295,BE
3575629296,3575629303,NL
-3575629304,3575629823,EU
+3575629304,3575629823,BE
3575629824,3575629855,GR
3575629856,3575629871,DE
-3575629872,3575629935,EU
+3575629872,3575629935,BE
3575629936,3575629951,FR
-3575629952,3575630015,EU
+3575629952,3575630015,BE
3575630016,3575630023,GR
-3575630024,3575630063,EU
+3575630024,3575630063,BE
3575630064,3575630079,ZA
3575630080,3575630335,BE
3575630336,3575630463,IT
3575630464,3575630591,CH
3575630592,3575630847,IL
-3575630848,3575630975,EU
+3575630848,3575630975,BE
3575630976,3575630991,FR
-3575630992,3575631103,EU
+3575630992,3575631103,BE
3575631104,3575631111,AT
3575631112,3575631119,CH
3575631120,3575631127,DE
-3575631128,3575631135,EU
+3575631128,3575631135,BE
3575631136,3575631143,HU
-3575631144,3575631159,EU
+3575631144,3575631159,BE
3575631160,3575631167,GB
3575631168,3575631199,NL
3575631200,3575631207,IE
-3575631208,3575631223,EU
+3575631208,3575631223,BE
3575631224,3575631231,IL
3575631232,3575631295,CH
-3575631296,3575631615,EU
+3575631296,3575631615,BE
3575631616,3575631631,SE
3575631632,3575631639,BE
3575631640,3575631647,CH
@@ -120925,177 +124096,173 @@
3575631664,3575631679,DE
3575631680,3575631695,SE
3575631696,3575631711,IT
-3575631712,3575631759,EU
+3575631712,3575631759,BE
3575631760,3575631775,ZA
-3575631776,3575631791,EU
+3575631776,3575631791,BE
3575631792,3575631799,ES
3575631800,3575631807,CZ
-3575631808,3575631855,EU
+3575631808,3575631855,BE
3575631856,3575631863,ZA
-3575631864,3575631871,EU
-3575631872,3575632639,IL
+3575631864,3575631871,BE
+3575631872,3575632127,IL
+3575632128,3575632639,BE
3575632640,3575632655,NO
-3575632656,3575632703,EU
+3575632656,3575632703,BE
3575632704,3575632711,GB
-3575632712,3575632783,EU
+3575632712,3575632783,BE
3575632784,3575632791,GB
-3575632792,3575632831,EU
-3575632832,3575632847,BE
+3575632792,3575632847,BE
3575632848,3575632863,CH
-3575632864,3575632871,BE
-3575632872,3575632879,EU
+3575632864,3575632879,BE
3575632880,3575632895,DE
-3575632896,3575632967,EU
+3575632896,3575632967,BE
3575632968,3575632975,GB
-3575632976,3575632991,EU
+3575632976,3575632991,BE
3575632992,3575632999,IT
-3575633000,3575633039,EU
+3575633000,3575633039,BE
3575633040,3575633055,DE
3575633056,3575633063,SE
3575633064,3575633071,NL
-3575633072,3575633087,EU
+3575633072,3575633087,BE
3575633088,3575633119,GB
-3575633120,3575633135,EU
+3575633120,3575633135,BE
3575633136,3575633143,GB
-3575633144,3575633599,EU
+3575633144,3575633599,BE
3575633600,3575633663,NL
-3575633664,3575633727,EU
+3575633664,3575633727,BE
3575633728,3575633735,AT
3575633736,3575633743,IT
-3575633744,3575633783,EU
+3575633744,3575633783,BE
3575633784,3575633791,DE
-3575633792,3575633887,EU
+3575633792,3575633887,BE
3575633888,3575633895,SE
-3575633896,3575633919,EU
+3575633896,3575633919,BE
3575633920,3575633983,CH
3575633984,3575633991,DE
-3575633992,3575633999,EU
+3575633992,3575633999,BE
3575634000,3575634007,PT
3575634008,3575634015,DK
3575634016,3575634047,GB
-3575634048,3575634175,BE
-3575634176,3575634183,EU
+3575634048,3575634183,BE
3575634184,3575634191,AT
-3575634192,3575634255,EU
+3575634192,3575634255,BE
3575634256,3575634271,IT
-3575634272,3575634367,EU
+3575634272,3575634367,BE
3575634368,3575634399,NO
3575634400,3575634431,GB
-3575634432,3575634455,EU
+3575634432,3575634455,BE
3575634456,3575634463,DE
-3575634464,3575634495,EU
+3575634464,3575634495,BE
3575634496,3575634511,FI
3575634512,3575634519,CH
-3575634520,3575634591,EU
+3575634520,3575634591,BE
3575634592,3575634599,ES
-3575634600,3575634607,EU
+3575634600,3575634607,BE
3575634608,3575634615,GB
3575634616,3575634623,DE
-3575634624,3575634695,EU
+3575634624,3575634695,BE
3575634696,3575634703,FI
-3575634704,3575634711,EU
+3575634704,3575634711,BE
3575634712,3575634719,DE
-3575634720,3575634767,EU
+3575634720,3575634767,BE
3575634768,3575634775,NO
-3575634776,3575634783,EU
+3575634776,3575634783,BE
3575634784,3575634791,FR
3575634792,3575634799,ES
3575634800,3575634807,BE
3575634808,3575634815,SE
-3575634816,3575634879,EU
+3575634816,3575634879,BE
3575634880,3575634911,GB
3575634912,3575634919,SE
3575634920,3575634927,GB
3575634928,3575634935,IT
-3575634936,3575635015,EU
+3575634936,3575635015,BE
3575635016,3575635023,CH
3575635024,3575635039,ES
-3575635040,3575635055,EU
+3575635040,3575635055,BE
3575635056,3575635063,CH
-3575635064,3575635071,EU
+3575635064,3575635071,BE
3575635072,3575635087,SE
-3575635088,3575635103,EU
+3575635088,3575635103,BE
3575635104,3575635119,PT
3575635120,3575635135,PL
3575635136,3575635151,DE
3575635152,3575635159,PT
3575635160,3575635167,DE
3575635168,3575635175,GB
-3575635176,3575635199,EU
+3575635176,3575635199,BE
3575635200,3575635455,NO
3575635456,3575635463,RU
3575635464,3575635471,GB
-3575635472,3575635583,EU
+3575635472,3575635583,BE
3575635584,3575635615,EG
3575635616,3575635631,FI
-3575635632,3575635647,EU
+3575635632,3575635647,BE
3575635648,3575635679,GB
-3575635680,3575635695,EU
+3575635680,3575635695,BE
3575635696,3575635703,GB
-3575635704,3575635775,EU
+3575635704,3575635775,BE
3575635776,3575635839,CH
3575635840,3575635847,GB
3575635848,3575635855,FR
3575635856,3575635871,TR
-3575635872,3575635983,EU
+3575635872,3575635983,BE
3575635984,3575635999,DE
-3575636000,3575636143,EU
+3575636000,3575636143,BE
3575636144,3575636151,HU
-3575636152,3575636607,EU
+3575636152,3575636607,BE
3575636608,3575636735,FR
-3575636736,3575636807,EU
+3575636736,3575636807,BE
3575636808,3575636815,GB
-3575636816,3575636823,EU
+3575636816,3575636823,BE
3575636824,3575636831,RU
-3575636832,3575636855,EU
+3575636832,3575636855,BE
3575636856,3575636863,DE
-3575636864,3575636871,EU
+3575636864,3575636871,BE
3575636872,3575636879,CZ
-3575636880,3575636895,EU
+3575636880,3575636895,BE
3575636896,3575636903,PL
3575636904,3575636911,CZ
-3575636912,3575636927,EU
+3575636912,3575636927,BE
3575636928,3575636959,DE
-3575636960,3575636983,EU
+3575636960,3575636983,BE
3575636984,3575636991,FR
-3575636992,3575637039,EU
+3575636992,3575637039,BE
3575637040,3575637055,DE
-3575637056,3575637151,EU
+3575637056,3575637151,BE
3575637152,3575637183,GB
-3575637184,3575637367,EU
-3575637368,3575637375,BE
-3575637376,3575637407,EU
+3575637184,3575637407,BE
3575637408,3575637439,LU
3575637440,3575637471,GB
-3575637472,3575638103,EU
+3575637472,3575638103,BE
3575638104,3575638111,GB
-3575638112,3575638175,EU
+3575638112,3575638175,BE
3575638176,3575638239,GB
-3575638240,3575638263,EU
+3575638240,3575638263,BE
3575638264,3575638271,PL
-3575638272,3575638279,EU
+3575638272,3575638279,BE
3575638280,3575638287,RU
-3575638288,3575638303,EU
+3575638288,3575638303,BE
3575638304,3575638335,NO
-3575638336,3575638527,EU
+3575638336,3575638527,BE
3575638528,3575638543,DE
-3575638544,3575638559,EU
+3575638544,3575638559,BE
3575638560,3575638591,GB
-3575638592,3575638623,EU
+3575638592,3575638623,BE
3575638624,3575638639,PL
-3575638640,3575638719,EU
+3575638640,3575638719,BE
3575638720,3575638735,NL
3575638736,3575638751,GR
-3575638752,3575638767,EU
+3575638752,3575638767,BE
3575638768,3575638783,SE
-3575638784,3575638911,EU
+3575638784,3575638911,BE
3575638912,3575638943,FR
3575638944,3575638975,GB
-3575638976,3575639007,EU
+3575638976,3575639007,BE
3575639008,3575639011,GB
3575639012,3575639023,IE
3575639024,3575639039,PL
-3575639040,3575640063,EU
+3575639040,3575640063,BE
3575640064,3575644159,TR
3575644160,3575709695,DK
3575709696,3575730175,AT
@@ -121689,7 +124856,10 @@
3576239040,3576239071,GB
3576239072,3576239087,FR
3576239088,3576239103,GB
-3576239104,3576239663,FR
+3576239104,3576239615,FR
+3576239616,3576239623,GB
+3576239624,3576239631,IT
+3576239632,3576239663,FR
3576239664,3576239671,GB
3576239672,3576240039,FR
3576240040,3576240047,GB
@@ -121707,7 +124877,9 @@
3576241344,3576241351,GB
3576241352,3576241383,FR
3576241384,3576241399,GB
-3576241400,3576241935,FR
+3576241400,3576241855,FR
+3576241856,3576241887,GB
+3576241888,3576241935,FR
3576241936,3576241943,GB
3576241944,3576241951,FR
3576241952,3576241991,GB
@@ -121748,8 +124920,10 @@
3576249824,3576249831,FR
3576249832,3576249839,GB
3576249840,3576250623,FR
-3576250624,3576250879,GB
-3576250880,3576251407,FR
+3576250624,3576251007,GB
+3576251008,3576251039,FR
+3576251040,3576251135,GB
+3576251136,3576251407,FR
3576251408,3576251519,GB
3576251520,3576251583,FR
3576251584,3576251599,GB
@@ -121757,9 +124931,7 @@
3576251616,3576251647,GB
3576251648,3576252415,FR
3576252416,3576252671,GB
-3576252672,3576254487,FR
-3576254488,3576254495,GB
-3576254496,3576254551,FR
+3576252672,3576254551,FR
3576254552,3576254559,GB
3576254560,3576254607,FR
3576254608,3576254615,GB
@@ -121947,9 +125119,7 @@
3576261104,3576261111,GB
3576261112,3576261375,FR
3576261376,3576261631,GB
-3576261632,3576261823,FR
-3576261824,3576261887,GB
-3576261888,3576261927,FR
+3576261632,3576261927,FR
3576261928,3576261935,GB
3576261936,3576263439,FR
3576263440,3576263487,GB
@@ -121963,7 +125133,9 @@
3576263584,3576263599,GB
3576263600,3576263615,FR
3576263616,3576263623,GB
-3576263624,3576263751,FR
+3576263624,3576263679,FR
+3576263680,3576263743,GB
+3576263744,3576263751,FR
3576263752,3576263759,GB
3576263760,3576263791,FR
3576263792,3576263887,GB
@@ -121981,12 +125153,14 @@
3576264576,3576264623,GB
3576264624,3576264639,FR
3576264640,3576264687,GB
-3576264688,3576265303,FR
+3576264688,3576265287,FR
+3576265288,3576265295,GB
+3576265296,3576265303,FR
3576265304,3576265311,GB
3576265312,3576265327,FR
3576265328,3576265335,GB
-3576265336,3576265359,FR
-3576265360,3576265367,GB
+3576265336,3576265343,FR
+3576265344,3576265367,GB
3576265368,3576265375,FR
3576265376,3576265383,GB
3576265384,3576265399,FR
@@ -122044,13 +125218,16 @@
3576954880,3576987647,NO
3576987648,3577001983,GB
3577001984,3577003583,NL
-3577003584,3577003743,GB
-3577003744,3577003767,NL
+3577003584,3577003711,GB
+3577003712,3577003727,NL
+3577003728,3577003735,GB
+3577003736,3577003767,NL
3577003768,3577003771,GB
3577003772,3577003775,NL
3577003776,3577020415,GB
3577020416,3577085951,NL
3577085952,3577151487,DE
+3577151488,3577167871,FR
3577167872,3577184255,ET
3577184256,3577217023,CH
3577217024,3577282559,FR
@@ -122078,13 +125255,19 @@
3577559776,3577559783,FR
3577559784,3577562391,DE
3577562392,3577562399,GB
-3577562400,3577577231,DE
+3577562400,3577567711,DE
+3577567712,3577567719,IT
+3577567720,3577577231,DE
3577577232,3577577247,US
-3577577248,3577592431,DE
+3577577248,3577580887,DE
+3577580888,3577580895,DK
+3577580896,3577592431,DE
3577592432,3577592447,FR
3577592448,3577592743,DE
3577592744,3577592751,IE
-3577592752,3577608743,DE
+3577592752,3577606599,DE
+3577606600,3577606607,GB
+3577606608,3577608743,DE
3577608744,3577608751,ES
3577608752,3577610367,DE
3577610368,3577610495,GB
@@ -122145,9 +125328,7 @@
3577625600,3577625823,EU
3577625824,3577625839,GB
3577625840,3577625855,DE
-3577625856,3577626175,GB
-3577626176,3577626239,EU
-3577626240,3577626367,GB
+3577625856,3577626367,GB
3577626368,3577626623,EU
3577626624,3577627135,FR
3577627136,3577627391,EU
@@ -122332,7 +125513,9 @@
3578920960,3578986495,IT
3578986496,3578988095,DE
3578988096,3578988099,CH
-3578988100,3578996999,DE
+3578988100,3578992959,DE
+3578992960,3578992975,GB
+3578992976,3578996999,DE
3578997000,3578997007,CH
3578997008,3578997935,DE
3578997936,3578997943,FR
@@ -122362,7 +125545,9 @@
3579193728,3579193815,NL
3579193816,3579193823,ES
3579193824,3579193855,NL
-3579193856,3579194103,GB
+3579193856,3579194039,GB
+3579194040,3579194047,SE
+3579194048,3579194103,GB
3579194104,3579194111,US
3579194112,3579197055,GB
3579197056,3579197183,US
@@ -122374,7 +125559,11 @@
3579205632,3579205887,IE
3579205888,3579210079,GB
3579210080,3579210087,BE
-3579210088,3579221071,GB
+3579210088,3579213247,GB
+3579213248,3579213311,IT
+3579213312,3579221023,GB
+3579221024,3579221039,FR
+3579221040,3579221071,GB
3579221072,3579221087,DE
3579221088,3579221103,GB
3579221104,3579221119,IT
@@ -122628,9 +125817,7 @@
3580254208,3580260351,DE
3580260352,3580265727,AT
3580265728,3580338175,SE
-3580338176,3580338432,HR
-3580338433,3580338687,SE
-3580338688,3580339199,HR
+3580338176,3580339199,HR
3580339200,3580362751,SE
3580362752,3580473375,GB
3580473376,3580473391,IE
@@ -122780,9 +125967,12 @@
3582091264,3582099455,QA
3582099456,3582107647,GB
3582107648,3582115839,NL
-3582115840,3582120959,SE
+3582115840,3582116863,SE
+3582116864,3582117887,EE
+3582117888,3582119423,LT
+3582119424,3582120959,SE
3582120960,3582121983,EE
-3582121984,3582124031,SE
+3582121984,3582124031,LT
3582124032,3582125383,FI
3582125384,3582125391,AX
3582125392,3582132223,FI
@@ -122820,7 +126010,9 @@
3582222512,3582222527,DK
3582222528,3582222863,SE
3582222864,3582222879,NO
-3582222880,3582223967,SE
+3582222880,3582223087,SE
+3582223088,3582223095,NL
+3582223096,3582223967,SE
3582223968,3582223975,NO
3582223976,3582226599,SE
3582226600,3582226607,FI
@@ -122834,7 +126026,20 @@
3582287872,3582296063,DE
3582296064,3582304255,GB
3582304256,3582312447,UA
-3582312448,3582320639,GB
+3582312448,3582312703,GB
+3582312704,3582312959,JE
+3582312960,3582314495,GB
+3582314496,3582314751,JE
+3582314752,3582315775,GB
+3582315776,3582316543,JE
+3582316544,3582317055,GB
+3582317056,3582317311,JE
+3582317312,3582317567,GB
+3582317568,3582318079,JE
+3582318080,3582318591,GB
+3582318592,3582318847,JE
+3582318848,3582320383,GB
+3582320384,3582320639,JE
3582320640,3582328831,CH
3582328832,3582337023,HU
3582337024,3582341119,ES
@@ -123015,8 +126220,7 @@
3582571136,3582571199,FR
3582571200,3582571303,EU
3582571304,3582571307,CH
-3582571308,3582571311,FR
-3582571312,3582571375,EU
+3582571308,3582571375,EU
3582571376,3582571391,FR
3582571392,3582571407,EU
3582571408,3582571423,FR
@@ -123025,16 +126229,14 @@
3582571488,3582571647,EU
3582571648,3582571687,IE
3582571688,3582571691,EU
-3582571692,3582571707,IE
-3582571708,3582571727,EU
-3582571728,3582571743,IE
+3582571692,3582571719,IE
+3582571720,3582571735,EU
+3582571736,3582571743,IE
3582571744,3582571751,EU
3582571752,3582571839,IE
3582571840,3582571999,EU
3582572000,3582572015,IE
-3582572016,3582572023,EU
-3582572024,3582572031,IE
-3582572032,3582572415,EU
+3582572016,3582572415,EU
3582572416,3582572431,CH
3582572432,3582572447,EU
3582572448,3582572451,CH
@@ -123072,9 +126274,7 @@
3582573600,3582573615,CH
3582573616,3582573631,EU
3582573632,3582573695,CH
-3582573696,3582573727,EU
-3582573728,3582573759,CH
-3582573760,3582573823,EU
+3582573696,3582573823,EU
3582573824,3582573887,CH
3582573888,3582573895,EU
3582573896,3582573903,CH
@@ -123090,15 +126290,7 @@
3582590976,3582599167,FR
3582599168,3582607359,DE
3582607360,3582615551,RU
-3582615552,3582618111,A2
-3582618112,3582618367,CY
-3582618368,3582619647,A2
-3582619648,3582619903,CY
-3582619904,3582620671,A2
-3582620672,3582622207,CY
-3582622208,3582622591,A2
-3582622592,3582622719,LB
-3582622720,3582623743,A2
+3582615552,3582623743,CY
3582623744,3582631935,FI
3582631936,3582640127,NO
3582640128,3582648319,RU
@@ -123121,7 +126313,9 @@
3582746624,3582754815,RU
3582754816,3582763007,GR
3582763008,3582771199,FI
-3582771200,3582779391,CY
+3582771200,3582772479,CY
+3582772480,3582772735,GB
+3582772736,3582779391,CY
3582779392,3582787583,RU
3582787584,3582795775,PT
3582795776,3582803967,ES
@@ -123131,6 +126325,7 @@
3582828544,3582836735,KZ
3582836736,3582853119,RU
3582853120,3582861311,SE
+3582861312,3582869503,RU
3582869504,3582877695,NO
3582877696,3582885887,AT
3582885888,3582894079,TR
@@ -123177,7 +126372,9 @@
3583032160,3583032191,FR
3583032192,3583032319,IT
3583032320,3583032575,FR
-3583032576,3583033343,IT
+3583032576,3583032831,IT
+3583032832,3583033087,SG
+3583033088,3583033343,IT
3583033344,3583041535,FR
3583041536,3583049727,NL
3583049728,3583066111,RU
@@ -123240,9 +126437,7 @@
3583338032,3583338047,RS
3583338048,3583338143,ME
3583338144,3583338175,RS
-3583338176,3583339519,ME
-3583339520,3583339775,AL
-3583339776,3583341039,ME
+3583338176,3583341039,ME
3583341040,3583341055,AL
3583341056,3583342335,ME
3583342336,3583342591,RS
@@ -123340,9 +126535,7 @@
3583706224,3583706231,NA
3583706232,3583706295,UA
3583706296,3583706319,NA
-3583706320,3583706375,UA
-3583706376,3583706383,NA
-3583706384,3583706463,UA
+3583706320,3583706463,UA
3583706464,3583706471,NA
3583706472,3583706495,UA
3583706496,3583706511,NA
@@ -123356,9 +126549,7 @@
3583706592,3583706607,NA
3583706608,3583706615,UA
3583706616,3583706623,NA
-3583706624,3583706647,UA
-3583706648,3583706655,NA
-3583706656,3583706679,UA
+3583706624,3583706679,UA
3583706680,3583706687,NA
3583706688,3583706695,UA
3583706696,3583706711,NA
@@ -123408,15 +126599,11 @@
3583708041,3583708095,NA
3583708096,3583708167,UA
3583708168,3583708175,NA
-3583708176,3583708183,UA
-3583708184,3583708191,RU
-3583708192,3583708223,UA
-3583708224,3583708239,NA
+3583708176,3583708231,UA
+3583708232,3583708239,NA
3583708240,3583708423,UA
3583708424,3583708431,NA
-3583708432,3583708455,UA
-3583708456,3583708463,NA
-3583708464,3583708479,UA
+3583708432,3583708479,UA
3583708480,3583708543,NA
3583708544,3583708575,UA
3583708576,3583708583,NA
@@ -123424,13 +126611,10 @@
3583708608,3583708623,NA
3583708624,3583709447,UA
3583709448,3583709455,NA
-3583709456,3583709463,DE
-3583709464,3583709479,UA
-3583709480,3583709487,US
-3583709488,3583709503,UA
-3583709504,3583709519,RU
-3583709520,3583709527,UA
-3583709528,3583709543,NA
+3583709456,3583709503,UA
+3583709504,3583709511,RU
+3583709512,3583709535,UA
+3583709536,3583709543,NA
3583709544,3583709551,UA
3583709552,3583709559,NA
3583709560,3583709575,UA
@@ -123438,8 +126622,8 @@
3583709584,3583709599,UA
3583709600,3583709607,NA
3583709608,3583709615,RU
-3583709616,3583709623,UA
-3583709624,3583709639,NA
+3583709616,3583709631,UA
+3583709632,3583709639,NA
3583709640,3583709663,UA
3583709664,3583709671,NA
3583709672,3583709699,UA
@@ -123462,9 +126646,9 @@
3583709912,3583709927,UA
3583709928,3583709943,NA
3583709944,3583710055,UA
-3583710056,3583710063,NA
-3583710064,3583710072,DE
-3583710073,3583710087,NA
+3583710056,3583710072,NA
+3583710073,3583710079,UA
+3583710080,3583710087,NA
3583710088,3583710103,UA
3583710104,3583710111,NA
3583710112,3583710119,UA
@@ -123475,7 +126659,8 @@
3583710240,3583710247,NA
3583710248,3583710319,UA
3583710320,3583710335,NA
-3583710336,3583710375,UA
+3583710336,3583710367,UA
+3583710368,3583710375,AQ
3583710376,3583710383,NA
3583710384,3583710407,UA
3583710408,3583710415,NA
@@ -123483,9 +126668,7 @@
3583710456,3583710459,NA
3583710460,3583710519,UA
3583710520,3583710527,NA
-3583710528,3583710535,UA
-3583710536,3583710543,RU
-3583710544,3583710631,UA
+3583710528,3583710631,UA
3583710632,3583710639,NA
3583710640,3583710671,UA
3583710672,3583710679,NA
@@ -123493,21 +126676,17 @@
3583710704,3583710711,NA
3583710712,3583710743,UA
3583710744,3583710751,BE
-3583710752,3583710759,US
-3583710760,3583710823,UA
+3583710752,3583710823,UA
3583710824,3583710831,NA
-3583710832,3583710847,UA
-3583710848,3583710855,IL
+3583710832,3583710855,UA
3583710856,3583710863,NA
3583710864,3583710871,UA
3583710872,3583710879,NA
3583710880,3583710887,UA
-3583710888,3583710911,NA
-3583710912,3583710935,UA
+3583710888,3583710903,NA
+3583710904,3583710935,UA
3583710936,3583710943,NA
-3583710944,3583710959,UA
-3583710960,3583710967,NA
-3583710968,3583710991,UA
+3583710944,3583710991,UA
3583710992,3583710999,NA
3583711000,3583711007,UA
3583711008,3583711015,RU
@@ -123538,22 +126717,16 @@
3583711640,3583711695,UA
3583711696,3583711703,NA
3583711704,3583711711,UA
-3583711712,3583711727,NA
-3583711728,3583711759,UA
-3583711760,3583711767,NA
-3583711768,3583711783,UA
+3583711712,3583711719,NA
+3583711720,3583711783,UA
3583711784,3583711799,NA
-3583711800,3583711807,UA
-3583711808,3583711823,NA
-3583711824,3583711831,UA
-3583711832,3583711839,NA
-3583711840,3583711871,UA
+3583711800,3583711815,UA
+3583711816,3583711823,NA
+3583711824,3583711871,UA
3583711872,3583711879,NA
3583711880,3583712015,UA
3583712016,3583712031,NA
-3583712032,3583712095,UA
-3583712096,3583712111,NA
-3583712112,3583712119,UA
+3583712032,3583712119,UA
3583712120,3583712127,NA
3583712128,3583712159,UA
3583712160,3583712199,NA
@@ -123561,21 +126734,14 @@
3583712288,3583712295,NA
3583712296,3583712311,UA
3583712312,3583712319,NA
-3583712320,3583712415,UA
-3583712416,3583712423,NA
-3583712424,3583712431,SG
-3583712432,3583712439,UA
-3583712440,3583712479,NA
-3583712480,3583712591,UA
-3583712592,3583712599,NA
-3583712600,3583712623,UA
+3583712320,3583712447,UA
+3583712448,3583712479,NA
+3583712480,3583712623,UA
3583712624,3583712631,NA
-3583712632,3583712639,UA
-3583712640,3583712647,NA
-3583712648,3583712655,UA
+3583712632,3583712655,UA
3583712656,3583712663,NA
-3583712664,3583712703,UA
-3583712704,3583712719,NA
+3583712664,3583712711,UA
+3583712712,3583712719,NA
3583712720,3583712727,UA
3583712728,3583712735,RU
3583712736,3583712743,NA
@@ -123583,32 +126749,27 @@
3583712760,3583712763,NA
3583712764,3583712775,UA
3583712776,3583712783,NA
-3583712784,3583712839,UA
-3583712840,3583712847,NA
-3583712848,3583712911,UA
-3583712912,3583712943,NA
-3583712944,3583712959,UA
-3583712960,3583712983,NA
-3583712984,3583713007,UA
+3583712784,3583712831,UA
+3583712832,3583712847,AQ
+3583712848,3583712927,UA
+3583712928,3583712943,NA
+3583712944,3583713007,UA
3583713008,3583713015,RU
3583713016,3583713031,UA
3583713032,3583713039,NA
-3583713040,3583713063,UA
-3583713064,3583713071,KP
+3583713040,3583713071,UA
3583713072,3583713079,NA
3583713080,3583713103,UA
3583713104,3583713111,AZ
-3583713112,3583713127,UA
-3583713128,3583713135,IT
-3583713136,3583713143,UA
+3583713112,3583713143,UA
3583713144,3583713151,NA
3583713152,3583713167,UA
3583713168,3583713175,EG
3583713176,3583713183,UA
3583713184,3583713191,NA
-3583713192,3583713223,UA
-3583713224,3583713231,NA
-3583713232,3583713279,UA
+3583713192,3583713271,UA
+3583713272,3583713275,RU
+3583713276,3583713279,UA
3583713280,3583721471,CZ
3583721472,3583729663,DE
3583729664,3583737855,TR
@@ -123621,9 +126782,9 @@
3583742720,3583743487,DE
3583743488,3583743519,EU
3583743520,3583743551,FR
-3583743552,3583743679,EU
-3583743680,3583743711,GB
-3583743712,3583743975,EU
+3583743552,3583743615,EU
+3583743616,3583743743,GB
+3583743744,3583743975,EU
3583743976,3583743983,GB
3583743984,3583744067,EU
3583744068,3583744071,GB
@@ -123769,9 +126930,7 @@
3584295760,3584295767,PT
3584295768,3584295807,AT
3584295808,3584295815,PT
-3584295816,3584295935,AT
-3584295936,3584295943,AS
-3584295944,3584303103,AT
+3584295816,3584303103,AT
3584303104,3584311295,ES
3584311296,3584319487,DE
3584319488,3584327679,LT
@@ -123895,7 +127054,37 @@
3584929728,3584931375,CH
3584931376,3584931391,ES
3584931392,3584933887,CH
-3584933888,3584942079,PL
+3584933888,3584933919,SE
+3584933920,3584933927,PL
+3584933928,3584934079,SE
+3584934080,3584934087,PL
+3584934088,3584934167,SE
+3584934168,3584934171,PL
+3584934172,3584934219,SE
+3584934220,3584934223,PL
+3584934224,3584934431,SE
+3584934432,3584934439,PL
+3584934440,3584935487,SE
+3584935488,3584935491,PL
+3584935492,3584935735,SE
+3584935736,3584935739,PL
+3584935740,3584935775,SE
+3584935776,3584935779,PL
+3584935780,3584936227,SE
+3584936228,3584936231,PL
+3584936232,3584936327,SE
+3584936328,3584936331,PL
+3584936332,3584938607,SE
+3584938608,3584938611,PL
+3584938612,3584938711,SE
+3584938712,3584938715,PL
+3584938716,3584938719,SE
+3584938720,3584938723,PL
+3584938724,3584941111,SE
+3584941112,3584941115,PL
+3584941116,3584941131,SE
+3584941132,3584941135,PL
+3584941136,3584942079,SE
3584942080,3584950271,DK
3584950272,3584958463,UA
3584958464,3584966655,DE
@@ -123986,7 +127175,9 @@
3585531904,3585540095,AT
3585540096,3585542335,DE
3585542336,3585542351,TR
-3585542352,3585548287,DE
+3585542352,3585544903,DE
+3585544904,3585544911,CH
+3585544912,3585548287,DE
3585548288,3585556479,RU
3585556480,3585564671,DE
3585564672,3585572863,RU
@@ -124076,6 +127267,7 @@
3585716424,3585720319,AT
3585720320,3585728511,GB
3585728512,3585736703,SE
+3585736704,3585744895,HR
3585744896,3585750335,FR
3585750336,3585750351,GB
3585750352,3585750367,DE
@@ -124111,9 +127303,7 @@
3585835952,3585835959,SO
3585835960,3585835967,TD
3585835968,3585835983,ER
-3585835984,3585836007,NL
-3585836008,3585836023,IQ
-3585836024,3585836287,NL
+3585835984,3585836287,NL
3585836288,3585836543,CH
3585836544,3585837055,DZ
3585837056,3585837567,IQ
@@ -124174,7 +127364,9 @@
3585937408,3585940479,NL
3585940480,3585940735,BE
3585940736,3585941503,NL
-3585941504,3585949695,PL
+3585941504,3585943135,PL
+3585943136,3585943167,US
+3585943168,3585949695,PL
3585949696,3585957887,KW
3585957888,3585966079,SE
3585966080,3585974271,CH
@@ -124323,21 +127515,21 @@
3586677488,3586677759,DE
3586677760,3586678015,GR
3586678016,3586678271,DE
-3586678272,3586678335,FR
-3586678336,3586678399,US
+3586678272,3586678399,FR
3586678400,3586678415,GB
-3586678416,3586678439,IE
+3586678416,3586678431,FR
+3586678432,3586678439,IE
3586678440,3586678447,FR
3586678448,3586678527,IE
-3586678528,3586678671,FR
+3586678528,3586678655,FR
+3586678656,3586678671,CY
3586678672,3586678679,GB
3586678680,3586678687,MU
3586678688,3586678783,GB
3586678784,3586679039,IT
3586679040,3586679103,FR
3586679104,3586679167,DE
-3586679168,3586679231,US
-3586679232,3586679327,FR
+3586679168,3586679327,FR
3586679328,3586679343,DK
3586679344,3586679359,FR
3586679360,3586679423,DE
@@ -124443,23 +127635,57 @@
3586916352,3586924031,IT
3586924032,3586924047,US
3586924048,3586924543,IT
-3586924544,3586924831,AX
-3586924832,3586924839,FI
-3586924840,3586924879,AX
-3586924880,3586924887,FI
-3586924888,3586924967,AX
-3586924968,3586924983,FI
-3586924984,3586925439,AX
-3586925440,3586925471,FI
-3586925472,3586925567,AX
+3586924544,3586924743,FI
+3586924744,3586924751,AX
+3586924752,3586924767,FI
+3586924768,3586924799,AX
+3586924800,3586924871,FI
+3586924872,3586924879,AX
+3586924880,3586924919,FI
+3586924920,3586924927,AX
+3586924928,3586924943,FI
+3586924944,3586924959,AX
+3586924960,3586924983,FI
+3586924984,3586925055,AX
+3586925056,3586925103,FI
+3586925104,3586925135,AX
+3586925136,3586925247,FI
+3586925248,3586925263,AX
+3586925264,3586925311,FI
+3586925312,3586925375,AX
+3586925376,3586925439,FI
+3586925440,3586925503,AX
+3586925504,3586925535,FI
+3586925536,3586925567,AX
3586925568,3586925695,FI
-3586925696,3586926591,AX
+3586925696,3586925759,AX
+3586925760,3586925791,FI
+3586925792,3586925823,AX
+3586925824,3586925831,FI
+3586925832,3586925855,AX
+3586925856,3586925887,FI
+3586925888,3586925919,AX
+3586925920,3586925983,FI
+3586925984,3586926003,AX
+3586926004,3586926015,FI
+3586926016,3586926047,AX
+3586926048,3586926079,FI
+3586926080,3586926591,AX
3586926592,3586926847,SE
-3586926848,3586928255,AX
-3586928256,3586928287,FI
-3586928288,3586928335,AX
-3586928336,3586928351,FI
-3586928352,3586932735,AX
+3586926848,3586927103,FI
+3586927104,3586927999,AX
+3586928000,3586928127,FI
+3586928128,3586928143,AX
+3586928144,3586928159,FI
+3586928160,3586928175,AX
+3586928176,3586928223,FI
+3586928224,3586928239,AX
+3586928240,3586928287,FI
+3586928288,3586928319,AX
+3586928320,3586928335,FI
+3586928336,3586928351,AX
+3586928352,3586928639,FI
+3586928640,3586932735,AX
3586932736,3586949119,LB
3586949120,3586965503,SE
3586965504,3586981887,NL
@@ -124516,9 +127742,7 @@
3587227648,3587227759,NL
3587227760,3587227775,GB
3587227776,3587227903,NL
-3587227904,3587227919,GB
-3587227920,3587227935,NL
-3587227936,3587227967,GB
+3587227904,3587227967,GB
3587227968,3587227983,DE
3587227984,3587228047,GB
3587228048,3587228087,NL
@@ -124535,7 +127759,8 @@
3587228928,3587229455,GB
3587229456,3587229823,NL
3587229824,3587229839,GB
-3587229840,3587229871,NL
+3587229840,3587229855,ES
+3587229856,3587229871,NL
3587229872,3587229887,GB
3587229888,3587229920,NL
3587229921,3587229935,GB
@@ -124617,23 +127842,25 @@
3587237568,3587237887,GB
3587237888,3587238471,NL
3587238472,3587238479,GB
-3587238480,3587238535,NL
-3587238536,3587238543,GB
-3587238544,3587238607,NL
+3587238480,3587238527,NL
+3587238528,3587238543,GB
+3587238544,3587238575,NL
+3587238576,3587238583,GB
+3587238584,3587238607,NL
3587238608,3587238911,GB
3587238912,3587239303,NL
3587239304,3587239311,GB
-3587239312,3587239791,NL
-3587239792,3587239807,GB
-3587239808,3587239871,NL
-3587239872,3587239935,GB
-3587239936,3587240015,NL
-3587240016,3587240023,GB
-3587240024,3587240087,NL
+3587239312,3587239903,NL
+3587239904,3587239935,GB
+3587239936,3587240087,NL
3587240088,3587240095,GB
3587240096,3587240103,NL
3587240104,3587240107,GB
-3587240108,3587240439,NL
+3587240108,3587240271,NL
+3587240272,3587240287,GB
+3587240288,3587240359,NL
+3587240360,3587240367,GB
+3587240368,3587240439,NL
3587240440,3587240447,GB
3587240448,3587240511,NL
3587240512,3587240575,GB
@@ -124783,10 +128010,9 @@
3587375104,3587383295,TR
3587383296,3587391487,CZ
3587391488,3587407871,KZ
-3587407872,3587408127,NL
-3587408128,3587415039,BE
-3587415040,3587422719,NL
-3587422720,3587424255,BE
+3587407872,3587408383,NL
+3587408384,3587408895,BE
+3587408896,3587424255,NL
3587424256,3587440639,DE
3587440640,3587457023,SE
3587457024,3587459263,GB
@@ -124806,19 +128032,11 @@
3587620864,3587637247,SE
3587637248,3587653631,FR
3587653632,3587670015,SK
-3587670016,3587673763,IT
-3587673764,3587673767,GB
-3587673768,3587673787,IT
-3587673788,3587673792,GB
-3587673793,3587679135,IT
+3587670016,3587679135,IT
3587679136,3587679143,ES
3587679144,3587683327,IT
3587683328,3587683359,FR
-3587683360,3587683415,IT
-3587683416,3587683416,GB
-3587683417,3587685831,IT
-3587685832,3587685839,GB
-3587685840,3587686031,IT
+3587683360,3587686031,IT
3587686032,3587686039,FR
3587686040,3587687591,IT
3587687592,3587687599,NL
@@ -124846,9 +128064,7 @@
3587850240,3587854335,NL
3587854336,3587866623,PL
3587866624,3587874815,FR
-3587874816,3587877383,DE
-3587877384,3587877391,US
-3587877392,3587877407,DE
+3587874816,3587877407,DE
3587877408,3587877439,NL
3587877440,3587878527,DE
3587878528,3587878559,AT
@@ -124877,6 +128093,7 @@
3588112384,3588128767,FR
3588128768,3588145151,HU
3588145152,3588153343,PL
+3588153344,3588161535,RU
3588161536,3588227071,FR
3588227072,3588292607,BE
3588292608,3588308991,AT
@@ -124900,9 +128117,7 @@
3588521984,3588538367,PT
3588538368,3588544383,GB
3588544384,3588544391,IE
-3588544392,3588547327,GB
-3588547328,3588547583,IE
-3588547584,3588550447,GB
+3588544392,3588550447,GB
3588550448,3588550463,IE
3588550464,3588553983,GB
3588553984,3588554239,IE
@@ -124972,11 +128187,13 @@
3589034368,3589034431,NL
3589034432,3589034495,FR
3589034496,3589037055,ES
-3589037056,3589037343,NL
+3589037056,3589037183,BE
+3589037184,3589037343,NL
3589037344,3589037375,SE
3589037376,3589037423,NL
3589037424,3589037439,ES
-3589037440,3589037495,NL
+3589037440,3589037487,NL
+3589037488,3589037495,IT
3589037496,3589037503,CH
3589037504,3589037551,NL
3589037552,3589037559,BE
@@ -125039,7 +128256,8 @@
3589429248,3589429503,FR
3589429504,3589430271,GB
3589430272,3589430543,FR
-3589430544,3589431295,GB
+3589430544,3589430559,ES
+3589430560,3589431295,GB
3589431296,3589431343,FR
3589431344,3589432319,GB
3589432320,3589432575,CH
@@ -125065,7 +128283,9 @@
3589436160,3589436415,GB
3589436416,3589436671,FR
3589436672,3589436799,PL
-3589436800,3589439487,GB
+3589436800,3589436927,GB
+3589436928,3589437183,PL
+3589437184,3589439487,GB
3589439488,3589444631,SE
3589444632,3589444639,NO
3589444640,3589455871,SE
@@ -125081,8 +128301,8 @@
3589554176,3589570559,PS
3589570560,3589570655,NL
3589570656,3589578751,GB
-3589578752,3589579263,NL
-3589579264,3589579775,GB
+3589578752,3589579391,NL
+3589579392,3589579775,GB
3589579776,3589580799,NL
3589580800,3589580895,GB
3589580896,3589581055,NL
@@ -125119,7 +128339,7 @@
3589680768,3589685247,FR
3589685248,3589718015,GB
3589718016,3589719343,BE
-3589719344,3589719347,GB
+3589719344,3589719347,LU
3589719348,3589719847,BE
3589719848,3589719855,AT
3589719856,3589719967,BE
@@ -125136,16 +128356,14 @@
3589720312,3589720575,BE
3589720576,3589720583,ES
3589720584,3589720599,FR
-3589720600,3589720603,BE
-3589720604,3589720607,GB
-3589720608,3589720623,BE
+3589720600,3589720623,BE
3589720624,3589720631,GB
3589720632,3589720639,FR
3589720640,3589720655,BE
3589720656,3589720663,ES
3589720664,3589720687,BE
3589720688,3589720695,GB
-3589720696,3589720703,FR
+3589720696,3589720703,ES
3589720704,3589720727,BE
3589720728,3589720735,GB
3589720736,3589720743,BE
@@ -125173,9 +128391,7 @@
3589721048,3589721055,ES
3589721056,3589721063,BE
3589721064,3589721071,GB
-3589721072,3589721147,BE
-3589721148,3589721151,GB
-3589721152,3589721159,BE
+3589721072,3589721159,BE
3589721160,3589721167,GB
3589721168,3589721231,BE
3589721232,3589721247,GB
@@ -125195,9 +128411,7 @@
3589721952,3589721967,GB
3589721968,3589722023,BE
3589722024,3589722031,FR
-3589722032,3589722059,BE
-3589722060,3589722063,GB
-3589722064,3589722111,BE
+3589722032,3589722111,BE
3589722112,3589722143,GB
3589722144,3589722159,BE
3589722160,3589722167,FR
@@ -125209,19 +128423,16 @@
3589722264,3589722271,GB
3589722272,3589722279,BE
3589722280,3589722287,FR
-3589722288,3589722295,BE
-3589722296,3589722299,GB
-3589722300,3589722303,BE
+3589722288,3589722303,BE
3589722304,3589722311,FR
3589722312,3589722319,GB
3589722320,3589722335,FR
3589722336,3589722343,BE
3589722344,3589722359,FR
3589722360,3589722383,BE
-3589722384,3589722391,FR
-3589722392,3589722395,BE
-3589722396,3589722399,GB
-3589722400,3589722439,BE
+3589722384,3589722391,DE
+3589722392,3589722431,BE
+3589722432,3589722439,ES
3589722440,3589722447,GB
3589722448,3589722623,BE
3589722624,3589722631,GB
@@ -125233,16 +128444,12 @@
3589722792,3589722799,GB
3589722800,3589722835,BE
3589722836,3589722843,GB
-3589722844,3589722859,BE
-3589722860,3589722863,GB
-3589722864,3589722943,BE
+3589722844,3589722943,BE
3589722944,3589722951,GB
3589722952,3589722959,FR
-3589722960,3589722979,BE
-3589722980,3589722991,GB
-3589722992,3589722995,BE
-3589722996,3589722999,GB
-3589723000,3589723023,BE
+3589722960,3589722983,BE
+3589722984,3589722991,GB
+3589722992,3589723023,BE
3589723024,3589723031,FR
3589723032,3589723975,BE
3589723976,3589723983,FR
@@ -125292,27 +128499,16 @@
3589726488,3589726495,GB
3589726496,3589726535,BE
3589726536,3589726543,GB
-3589726544,3589729743,BE
+3589726544,3589727007,BE
+3589727008,3589727015,FR
+3589727016,3589729735,BE
+3589729736,3589729743,ES
3589729744,3589729751,GB
-3589729752,3589730071,BE
-3589730072,3589730075,GB
-3589730076,3589730087,BE
+3589729752,3589730087,BE
3589730088,3589730095,GB
3589730096,3589730111,BE
3589730112,3589730119,GB
-3589730120,3589730139,BE
-3589730140,3589730143,GB
-3589730144,3589731603,BE
-3589731604,3589731607,GB
-3589731608,3589731635,BE
-3589731636,3589731639,GB
-3589731640,3589731719,BE
-3589731720,3589731723,GB
-3589731724,3589731731,BE
-3589731732,3589731735,GB
-3589731736,3589731819,BE
-3589731820,3589731823,GB
-3589731824,3589733375,BE
+3589730120,3589733375,BE
3589733376,3589733439,LU
3589733440,3589734399,BE
3589734400,3589742591,EG
@@ -125410,22 +128606,18 @@
3590151144,3590151151,HR
3590151152,3590154047,SI
3590154048,3590154063,HR
-3590154064,3590155799,SI
-3590155800,3590155807,HR
+3590154064,3590155775,SI
+3590155776,3590155807,HR
3590155808,3590155815,SI
3590155816,3590155823,HR
-3590155824,3590156031,SI
-3590156032,3590156287,RS
-3590156288,3590156415,HR
-3590156416,3590156423,SI
-3590156424,3590156431,HR
+3590155824,3590155871,SI
+3590155872,3590156431,HR
3590156432,3590156447,SI
-3590156448,3590156679,HR
-3590156680,3590156687,SI
+3590156448,3590156671,HR
+3590156672,3590156687,SI
3590156688,3590156719,HR
3590156720,3590156727,SI
-3590156728,3590156959,HR
-3590156960,3590156991,AE
+3590156728,3590156991,HR
3590156992,3590157039,SI
3590157040,3590157311,HR
3590157312,3590157343,RS
@@ -125573,22 +128765,29 @@
3590308048,3590308055,NG
3590308056,3590308063,A2
3590308064,3590308071,ZW
-3590308072,3590308087,A2
+3590308072,3590308079,RW
+3590308080,3590308087,TZ
3590308088,3590308095,AO
-3590308096,3590308183,A2
-3590308184,3590308191,IQ
+3590308096,3590308119,A2
+3590308120,3590308127,IQ
+3590308128,3590308175,A2
+3590308176,3590308191,IQ
3590308192,3590308199,A2
-3590308200,3590308223,IQ
-3590308224,3590308247,A2
-3590308248,3590308263,IQ
-3590308264,3590308271,A2
-3590308272,3590308287,IQ
+3590308200,3590308215,IQ
+3590308216,3590308247,A2
+3590308248,3590308287,IQ
3590308288,3590308303,A2
3590308304,3590308311,SO
3590308312,3590308319,IQ
-3590308320,3590308335,A2
-3590308336,3590308343,IQ
-3590308344,3590308607,A2
+3590308320,3590308327,A2
+3590308328,3590308343,IQ
+3590308344,3590308351,A2
+3590308352,3590308367,IQ
+3590308368,3590308383,A2
+3590308384,3590308391,IQ
+3590308392,3590308447,A2
+3590308448,3590308455,IQ
+3590308456,3590308607,A2
3590308608,3590308735,NG
3590308736,3590308767,A2
3590308768,3590308775,RW
@@ -125597,10 +128796,7 @@
3590308800,3590308807,A2
3590308808,3590308815,ZM
3590308816,3590308823,KE
-3590308824,3590308831,A2
-3590308832,3590308839,ZW
-3590308840,3590308847,ET
-3590308848,3590308855,A2
+3590308824,3590308855,A2
3590308856,3590308863,NG
3590308864,3590308951,A2
3590308952,3590308959,GH
@@ -125623,49 +128819,107 @@
3590309536,3590309543,SO
3590309544,3590309551,AM
3590309552,3590309575,A2
-3590309576,3590309583,NG
+3590309576,3590309583,US
3590309584,3590309615,A2
3590309616,3590309623,UG
-3590309624,3590309631,ZW
-3590309632,3590309639,A2
-3590309640,3590309647,IQ
-3590309648,3590309687,A2
-3590309688,3590309695,IQ
-3590309696,3590309727,A2
-3590309728,3590309743,IQ
-3590309744,3590309751,A2
-3590309752,3590309759,IQ
-3590309760,3590309799,A2
+3590309624,3590309631,A2
+3590309632,3590309647,IQ
+3590309648,3590309671,A2
+3590309672,3590309687,IQ
+3590309688,3590309711,A2
+3590309712,3590309719,IQ
+3590309720,3590309727,A2
+3590309728,3590309759,IQ
+3590309760,3590309767,A2
+3590309768,3590309775,IQ
+3590309776,3590309783,A2
+3590309784,3590309791,IQ
+3590309792,3590309799,A2
3590309800,3590309807,IQ
-3590309808,3590309831,A2
+3590309808,3590309815,A2
+3590309816,3590309823,IQ
+3590309824,3590309831,A2
3590309832,3590309839,IQ
-3590309840,3590309879,A2
+3590309840,3590309863,A2
+3590309864,3590309871,IQ
+3590309872,3590309879,A2
3590309880,3590309887,IQ
-3590309888,3590310159,A2
-3590310160,3590310167,IQ
+3590309888,3590310143,A2
+3590310144,3590310167,IQ
3590310168,3590310175,A2
3590310176,3590310183,LR
-3590310184,3590310191,IQ
-3590310192,3590310279,A2
-3590310280,3590310287,IQ
-3590310288,3590310288,A2
-3590310289,3590310303,IQ
-3590310304,3590310327,A2
+3590310184,3590310207,IQ
+3590310208,3590310215,SD
+3590310216,3590310223,A2
+3590310224,3590310255,IQ
+3590310256,3590310263,A2
+3590310264,3590310271,SD
+3590310272,3590310279,A2
+3590310280,3590310303,IQ
+3590310304,3590310311,A2
+3590310312,3590310319,IQ
+3590310320,3590310327,A2
3590310328,3590310335,NG
3590310336,3590310343,IQ
-3590310344,3590310391,A2
-3590310392,3590310399,IQ
-3590310400,3590310655,A2
+3590310344,3590310351,A2
+3590310352,3590310367,IQ
+3590310368,3590310383,A2
+3590310384,3590310391,IQ
+3590310392,3590310655,A2
3590310656,3590310911,GB
-3590310912,3590311247,A2
-3590311248,3590311255,NG
-3590311256,3590311423,A2
+3590310912,3590310919,IQ
+3590310920,3590310951,A2
+3590310952,3590310959,IQ
+3590310960,3590310967,A2
+3590310968,3590311007,IQ
+3590311008,3590311015,A2
+3590311016,3590311023,IQ
+3590311024,3590311031,A2
+3590311032,3590311039,IQ
+3590311040,3590311055,A2
+3590311056,3590311063,IQ
+3590311064,3590311079,A2
+3590311080,3590311087,IQ
+3590311088,3590311119,A2
+3590311120,3590311135,IQ
+3590311136,3590311143,A2
+3590311144,3590311151,IQ
+3590311152,3590311159,A2
+3590311160,3590311167,IQ
+3590311168,3590311175,A2
+3590311176,3590311183,CD
+3590311184,3590311199,A2
+3590311200,3590311207,SD
+3590311208,3590311215,CD
+3590311216,3590311223,AO
+3590311224,3590311231,CD
+3590311232,3590311239,AO
+3590311240,3590311255,A2
+3590311256,3590311263,ZW
+3590311264,3590311271,A2
+3590311272,3590311279,SD
+3590311280,3590311287,NG
+3590311288,3590311295,A2
+3590311296,3590311303,LR
+3590311304,3590311311,NG
+3590311312,3590311319,CD
+3590311320,3590311327,CI
+3590311328,3590311335,CD
+3590311336,3590311343,SD
+3590311344,3590311351,A2
+3590311352,3590311359,CD
+3590311360,3590311367,CI
+3590311368,3590311383,CD
+3590311384,3590311391,NG
+3590311392,3590311423,A2
3590311424,3590311679,GB
3590311680,3590311935,YT
3590311936,3590312703,MW
3590312704,3590312799,A2
3590312800,3590312807,KE
-3590312808,3590312895,A2
+3590312808,3590312815,A2
+3590312816,3590312823,US
+3590312824,3590312895,A2
3590312896,3590312903,ZA
3590312904,3590312911,AO
3590312912,3590312919,NG
@@ -125684,13 +128938,15 @@
3590314720,3590314727,TG
3590314728,3590314735,UG
3590314736,3590314743,NG
-3590314744,3590314823,A2
+3590314744,3590314767,A2
+3590314768,3590314775,US
+3590314776,3590314823,A2
3590314824,3590314831,ZW
3590314832,3590314887,A2
3590314888,3590314895,NG
3590314896,3590314903,A2
3590314904,3590314911,KE
-3590314912,3590314927,GH
+3590314912,3590314927,A2
3590314928,3590314943,NG
3590314944,3590314967,A2
3590314968,3590314973,YT
@@ -125705,7 +128961,9 @@
3590316080,3590316087,LB
3590316088,3590316127,A2
3590316128,3590316151,NG
-3590316152,3590316231,A2
+3590316152,3590316191,A2
+3590316192,3590316199,IQ
+3590316200,3590316231,A2
3590316232,3590316239,LB
3590316240,3590316271,A2
3590316272,3590316279,IQ
@@ -125717,9 +128975,7 @@
3590316664,3590316671,LY
3590316672,3590316727,A2
3590316728,3590316735,LB
-3590316736,3590316815,A2
-3590316816,3590316831,IQ
-3590316832,3590317055,A2
+3590316736,3590317055,A2
3590317056,3590317311,NG
3590317312,3590317343,AO
3590317344,3590317439,A2
@@ -125733,8 +128989,8 @@
3590317504,3590317527,A2
3590317528,3590317543,IQ
3590317544,3590317567,A2
-3590317568,3590317823,IQ
-3590317824,3590317951,A2
+3590317568,3590317695,IQ
+3590317696,3590317951,A2
3590317952,3590318047,UA
3590318048,3590319167,A2
3590319168,3590319231,AE
@@ -125783,7 +129039,8 @@
3590322352,3590322391,A2
3590322392,3590322399,IQ
3590322400,3590322415,AO
-3590322416,3590322431,A2
+3590322416,3590322423,A2
+3590322424,3590322431,NG
3590322432,3590322559,LB
3590322560,3590322607,A2
3590322608,3590322687,LB
@@ -125794,13 +129051,23 @@
3590323912,3590323967,A2
3590323968,3590323975,SD
3590323976,3590323983,A2
-3590323984,3590323991,NG
-3590323992,3590324023,A2
+3590323984,3590323999,NG
+3590324000,3590324007,LR
+3590324008,3590324015,A2
+3590324016,3590324023,NG
3590324024,3590324031,ZW
-3590324032,3590324095,NG
-3590324096,3590324103,A2
-3590324104,3590324111,ZW
-3590324112,3590324215,A2
+3590324032,3590324103,A2
+3590324104,3590324111,KE
+3590324112,3590324119,A2
+3590324120,3590324127,NG
+3590324128,3590324159,A2
+3590324160,3590324167,NG
+3590324168,3590324175,BW
+3590324176,3590324183,LR
+3590324184,3590324191,SD
+3590324192,3590324199,VG
+3590324200,3590324207,UG
+3590324208,3590324215,CD
3590324216,3590324223,NG
3590324224,3623890943,US
3623890944,3623891199,ZA
@@ -125821,8 +129088,8 @@
3624272384,3624272415,US
3624272416,3624272639,CA
3624272640,3624272895,DZ
-3624272896,3624279039,CA
-3624279040,3624279087,BD
+3624272896,3624279071,CA
+3624279072,3624279087,BD
3624279088,3624281087,CA
3624281088,3624281343,HT
3624281344,3624283135,CA
@@ -125847,11 +129114,7 @@
3624303760,3624304639,CA
3624304640,3624321023,US
3624321024,3624325119,CA
-3624325120,3624330511,US
-3624330512,3624330519,IN
-3624330520,3624333183,US
-3624333184,3624333215,IN
-3624333216,3624357887,US
+3624325120,3624357887,US
3624357888,3624358143,KN
3624358144,3624359679,US
3624359680,3624360703,AN
@@ -125920,15 +129183,11 @@
3624380968,3624380983,TW
3624380984,3624381471,US
3624381472,3624381487,AU
-3624381488,3624381535,US
-3624381536,3624381551,CA
-3624381552,3624381567,US
+3624381488,3624381567,US
3624381568,3624381583,MY
3624381584,3624381631,US
3624381632,3624381647,GB
-3624381648,3624381711,US
-3624381712,3624381727,OM
-3624381728,3624381807,US
+3624381648,3624381807,US
3624381808,3624381823,IN
3624381824,3624381855,US
3624381856,3624381887,AU
@@ -125939,9 +129198,7 @@
3624382048,3624383071,US
3624383072,3624383087,GB
3624383088,3624383103,PT
-3624383104,3624383183,US
-3624383184,3624383199,DE
-3624383200,3624384767,US
+3624383104,3624384767,US
3624384768,3624385023,CA
3624385024,3624386559,US
3624386560,3624394751,CA
@@ -125952,14 +129209,14 @@
3624443872,3624443879,US
3624443880,3624443903,CA
3624443904,3624443919,US
-3624443920,3624444343,CA
+3624443920,3624444303,CA
+3624444304,3624444319,US
+3624444320,3624444343,CA
3624444344,3624444351,US
3624444352,3624444359,CA
3624444360,3624444367,US
3624444368,3624452095,CA
-3624452096,3624474879,US
-3624474880,3624475391,CA
-3624475392,3624480767,US
+3624452096,3624480767,US
3624480768,3624484863,CA
3624484864,3624534015,US
3624534016,3624534271,PA
@@ -125983,7 +129240,9 @@
3624547216,3624547239,US
3624547240,3624547255,A2
3624547256,3624547263,AS
-3624547264,3624547591,US
+3624547264,3624547327,US
+3624547328,3624547583,A2
+3624547584,3624547591,US
3624547592,3624547647,A2
3624547648,3624547711,US
3624547712,3624547743,A2
@@ -125999,15 +129258,13 @@
3624548032,3624548039,A2
3624548040,3624548063,US
3624548064,3624548087,A2
-3624548088,3624548607,US
-3624548608,3624548671,A2
-3624548672,3624548687,US
+3624548088,3624548095,US
+3624548096,3624548679,A2
+3624548680,3624548687,US
3624548688,3624548703,A2
3624548704,3624548711,US
3624548712,3624548735,A2
-3624548736,3624548815,US
-3624548816,3624548823,A2
-3624548824,3624548935,US
+3624548736,3624548935,US
3624548936,3624548959,A2
3624548960,3624548975,US
3624548976,3624549023,A2
@@ -126018,27 +129275,12 @@
3624549088,3624549095,US
3624549096,3624549111,A2
3624549112,3624549375,US
-3624549376,3624549887,AS
-3624549888,3624550143,A2
+3624549376,3624550143,A2
3624550144,3624587263,US
3624587264,3624591359,JM
3624595456,3624730623,US
3624730624,3624796159,CA
-3624796160,3624798207,US
-3624798208,3624799231,CA
-3624799232,3624799743,US
-3624799744,3624799999,CA
-3624800000,3624800255,US
-3624800768,3624801023,CA
-3624801024,3624803071,US
-3624803072,3624803583,CA
-3624803840,3624804351,US
-3624804608,3624804863,CA
-3624804864,3624807679,US
-3624807936,3624808447,CA
-3624808448,3624811519,US
-3624811520,3624812287,CA
-3624812288,3624817679,US
+3624812544,3624817679,US
3624817680,3624817687,CA
3624817688,3624820735,US
3624820736,3624820799,CY
@@ -126077,8 +129319,8 @@
3624900608,3624900639,AU
3624900640,3624900671,BE
3624900672,3624900735,US
-3624900736,3624900799,CA
-3624900800,3624900831,US
+3624900736,3624900767,CA
+3624900768,3624900831,US
3624900832,3624900863,DE
3624900864,3624900951,US
3624900952,3624900959,FR
@@ -126114,7 +129356,9 @@
3624905088,3624905151,CA
3624905152,3624905471,US
3624905472,3624905727,CA
-3624905728,3624906879,US
+3624905728,3624906465,US
+3624906466,3624906495,CA
+3624906496,3624906879,US
3624906880,3624907007,TW
3624907008,3624907039,FR
3624907040,3624907071,US
@@ -126131,7 +129375,7 @@
3624907746,3624907775,IN
3624907776,3624907903,US
3624907904,3624908031,SG
-3624908032,3624908159,TW
+3624908032,3624908159,CA
3624908160,3624908287,US
3624908288,3624908319,CA
3624908320,3624908351,US
@@ -126155,7 +129399,8 @@
3624909824,3624909951,CA
3624909952,3624910079,US
3624910080,3624910111,CA
-3624910112,3624910175,US
+3624910112,3624910143,US
+3624910144,3624910175,CA
3624910176,3624910207,BE
3624910208,3624910271,US
3624910272,3624910303,FR
@@ -126172,9 +129417,11 @@
3624911008,3624911039,GB
3624911040,3624911103,US
3624911104,3624911135,CA
-3624911136,3624911199,US
+3624911136,3624911167,US
+3624911168,3624911199,MY
3624911200,3624911231,BE
-3624911232,3624911359,US
+3624911232,3624911263,CA
+3624911264,3624911359,US
3624911360,3624911615,CA
3624911616,3624911647,US
3624911648,3624911651,RU
@@ -126182,10 +129429,13 @@
3624912000,3624912127,CA
3624912128,3624913023,US
3624913024,3624913087,IN
-3624913088,3624913311,US
+3624913088,3624913247,US
+3624913248,3624913279,CA
+3624913280,3624913311,US
3624913312,3624913343,CA
3624913344,3624913375,PK
-3624913376,3624913535,US
+3624913376,3624913407,US
+3624913408,3624913535,CA
3624913536,3624913663,IN
3624913664,3624914047,US
3624914048,3624914079,IN
@@ -126202,9 +129452,9 @@
3624915456,3624915903,US
3624915904,3624915935,HK
3624915936,3624916159,US
-3624916160,3624916223,MY
-3624916224,3624916479,US
-3624916480,3624916735,CA
+3624916160,3624916191,MY
+3624916192,3624916223,US
+3624916224,3624916735,CA
3624916736,3624917247,US
3624917248,3624917503,AU
3624917504,3624917919,US
@@ -126212,22 +129462,22 @@
3624917952,3624917983,US
3624917984,3624918015,CA
3624918016,3624918527,US
-3624918528,3624918783,CA
-3624918784,3624918815,HK
+3624918528,3624918815,CA
3624918816,3624918847,US
3624918848,3624918875,IN
-3624918876,3624919007,US
+3624918876,3624918943,US
+3624918944,3624918975,CA
+3624918976,3624919007,US
3624919008,3624919039,MY
3624919040,3624919071,US
3624919072,3624919103,BE
3624919104,3624919295,US
3624919296,3624919423,CA
3624919424,3624919551,IN
-3624919552,3624919679,CA
-3624919680,3624919967,US
+3624919552,3624919967,US
3624919968,3624919999,BE
3624920000,3624920031,CA
-3624920032,3624920063,US
+3624920032,3624920063,TZ
3624920064,3624920191,CA
3624920192,3624920319,IN
3624920320,3624920703,CA
@@ -126239,15 +129489,17 @@
3624921344,3624921855,US
3624921856,3624922111,CA
3624922112,3624922143,US
-3624922144,3624922207,MY
+3624922144,3624922175,FR
+3624922176,3624922207,MY
3624922208,3624922239,FR
-3624922240,3624922271,US
-3624922272,3624922287,CR
-3624922288,3624922335,US
+3624922240,3624922335,US
3624922336,3624922367,FR
3624922368,3624922495,IN
3624922496,3624922623,BE
-3624922624,3624922815,US
+3624922624,3624922655,US
+3624922656,3624922687,CA
+3624922688,3624922783,US
+3624922784,3624922815,CN
3624922816,3624922847,FR
3624922848,3624922879,US
3624922880,3624923135,IN
@@ -126278,18 +129530,13 @@
3624990464,3624991223,CA
3624991224,3624991231,US
3624991232,3624992767,CA
-3624992768,3625002351,US
-3625002352,3625002367,CA
-3625002368,3625019135,US
-3625019136,3625019391,ES
-3625019392,3625042327,US
+3624992768,3625042327,US
3625042328,3625042335,IT
3625042336,3625058303,US
3625058304,3625091071,CA
3625091072,3625116671,US
3625116672,3625116767,CA
-3625116768,3625116775,US
-3625116776,3625116927,CA
+3625116768,3625116927,US
3625116928,3625117183,SE
3625117184,3625117775,US
3625117776,3625117783,CA
@@ -126341,9 +129588,7 @@
3625293616,3625295871,CA
3625295872,3625320447,US
3625320448,3625320467,CA
-3625320468,3625321727,US
-3625321728,3625321983,PA
-3625321984,3625325055,US
+3625320468,3625325055,US
3625325056,3625325087,RU
3625325088,3625326632,US
3625326633,3625326642,GB
@@ -126353,8 +129598,7 @@
3625327815,3625327824,GB
3625327825,3625327907,US
3625327908,3625327917,ID
-3625327918,3625333375,US
-3625333376,3625333383,PA
+3625327918,3625333383,US
3625333384,3625333391,GB
3625333392,3625333455,US
3625333456,3625333463,GB
@@ -126400,9 +129644,7 @@
3625375136,3625375167,RU
3625375168,3625375247,US
3625375248,3625375255,CA
-3625375256,3625375271,US
-3625375272,3625375279,GB
-3625375280,3625375359,US
+3625375256,3625375359,US
3625375360,3625375367,SE
3625375368,3625375399,US
3625375400,3625375407,MT
@@ -126484,7 +129726,7 @@
3626228464,3626228479,AE
3626228480,3626270719,US
3626270720,3626287103,CA
-3626287104,3626332159,US
+3626287104,3626328063,US
3626332160,3626336255,CA
3626336256,3626381317,US
3626381318,3626381321,AU
@@ -127080,15 +130322,9 @@
3627507712,3627511807,CA
3627511808,3627519616,US
3627519617,3627519626,CA
-3627519627,3627522690,US
-3627522691,3627522700,GB
-3627522701,3627524751,US
-3627524752,3627524759,AE
-3627524760,3627524979,US
+3627519627,3627524979,US
3627524980,3627524987,IR
-3627524988,3627525200,US
-3627525201,3627525208,AU
-3627525209,3627532287,US
+3627524988,3627532287,US
3627532288,3627544575,CA
3627544576,3627659263,US
3627659264,3627663359,CA
@@ -127102,9 +130338,7 @@
3627667520,3627667583,CA
3627667584,3627669831,US
3627669832,3627669839,CA
-3627669840,3627670799,US
-3627670800,3627670811,CA
-3627670812,3627679743,US
+3627669840,3627679743,US
3627679744,3627712511,CA
3627712512,3627745343,US
3627745344,3627745375,BE
@@ -127117,10 +130351,15 @@
3627746400,3627746431,CA
3627746432,3627746559,US
3627746560,3627746815,IN
-3627746816,3627753471,US
+3627746816,3627747159,US
+3627747160,3627747167,IN
+3627747168,3627753471,US
3627753472,3627753727,AR
-3627753728,3627769855,US
-3627778048,3627802623,US
+3627753728,3627755007,US
+3627755008,3627755135,IE
+3627755136,3627755263,US
+3627755264,3627755391,IE
+3627755392,3627802623,US
3627802624,3627810815,CA
3627810816,3627842047,US
3627842048,3627842303,IS
@@ -127192,9 +130431,7 @@
3628155104,3628155119,NZ
3628155120,3628155647,US
3628155648,3628155903,CA
-3628155904,3628156159,US
-3628156160,3628156415,GB
-3628156416,3628161023,US
+3628155904,3628161023,US
3628161024,3628161279,CA
3628161280,3628164927,US
3628164928,3628164943,IE
@@ -127348,8 +130585,8 @@
3629202012,3629202015,US
3629202016,3629202047,CA
3629202048,3629202175,US
-3629202176,3629202207,CA
-3629202208,3629202219,US
+3629202176,3629202203,CA
+3629202204,3629202219,US
3629202220,3629202239,CA
3629202240,3629202263,US
3629202264,3629202271,CA
@@ -127363,9 +130600,7 @@
3629202428,3629203199,CA
3629203200,3629318143,US
3629318144,3629326335,CA
-3629326336,3629331967,US
-3629331968,3629332479,CA
-3629332480,3629539327,US
+3629326336,3629539327,US
3629539328,3629547519,CA
3629547520,3629662207,US
3629662208,3629662463,GB
@@ -127873,9 +131108,7 @@
3630746880,3630747391,TZ
3630747392,3630780415,US
3630780416,3630784511,CA
-3630784512,3630784895,US
-3630784896,3630784911,IL
-3630784912,3630787568,US
+3630784512,3630787568,US
3630787569,3630787576,IE
3630787577,3630850047,US
3630850048,3630854143,CA
@@ -127899,9 +131132,7 @@
3631015296,3631015311,CN
3631015312,3631015887,US
3631015888,3631015903,CN
-3631015904,3631016243,US
-3631016244,3631016257,BD
-3631016258,3631016555,US
+3631015904,3631016555,US
3631016556,3631016571,CN
3631016572,3631016581,US
3631016582,3631016613,BD
@@ -127926,17 +131157,7 @@
3631045632,3631045759,CA
3631045760,3631045983,US
3631045984,3631045991,CA
-3631045992,3631057577,US
-3631057578,3631057597,GB
-3631057598,3631058405,US
-3631058406,3631058415,CA
-3631058416,3631058511,US
-3631058512,3631058521,CA
-3631058522,3631058581,US
-3631058582,3631058591,CA
-3631058592,3631059229,US
-3631059230,3631059239,NO
-3631059240,3631112191,US
+3631045992,3631112191,US
3631112192,3631116543,BB
3631116544,3631117567,GD
3631117568,3631117823,BB
@@ -128006,7 +131227,6 @@
3631881792,3631939583,US
3631939584,3632005119,CA
3632005120,3632136191,US
-3632136192,3632144383,CA
3632144384,3632152575,US
3632152576,3632168959,CA
3632168960,3632197631,US
@@ -128021,21 +131241,15 @@
3632284880,3632284895,CA
3632284896,3632286479,US
3632286480,3632286495,CA
-3632286496,3632287239,US
-3632287240,3632287263,CA
-3632287264,3632289583,US
+3632286496,3632289583,US
3632289584,3632289599,PH
3632289600,3632291775,US
3632291776,3632291839,GB
3632291840,3632332799,US
3632332800,3632357375,CA
-3632357376,3632370559,US
-3632370560,3632370575,NG
-3632370576,3632373503,US
-3632373504,3632373759,NG
-3632373760,3632381951,US
+3632357376,3632381951,US
3632381952,3632390143,CA
-3632390144,3632414719,US
+3632390144,3632406527,US
3632414720,3632422911,CA
3632422912,3632451583,US
3632451584,3632455679,CA
@@ -128494,9 +131708,7 @@
3632902144,3632971775,US
3632971776,3632972031,CA
3632972032,3632972063,US
-3632972064,3632976287,CA
-3632976288,3632976303,US
-3632976304,3632988159,CA
+3632972064,3632988159,CA
3632988160,3633029119,US
3633029120,3633029631,PY
3633029632,3633030143,NI
@@ -128566,8 +131778,8 @@
3633034048,3633034079,A2
3633034080,3633034519,US
3633034520,3633034527,NG
-3633034528,3633034559,US
-3633034560,3633034751,NG
+3633034528,3633034623,US
+3633034624,3633034751,NG
3633034752,3633035015,US
3633035016,3633035023,NL
3633035024,3633035071,US
@@ -128605,16 +131817,7 @@
3633336480,3633340415,KY
3633340416,3633344511,US
3633344512,3633348607,CA
-3633348608,3633373535,US
-3633373536,3633373567,BA
-3633373568,3633374799,US
-3633374800,3633374815,CA
-3633374816,3633376959,US
-3633376960,3633376991,CA
-3633376992,3633377087,US
-3633377088,3633377119,IN
-3633377120,3633379327,US
-3633381376,3633405951,US
+3633348608,3633405951,US
3633405952,3633410047,CA
3633410048,3633479679,US
3633479680,3633483775,CA
@@ -128622,44 +131825,38 @@
3633513985,3633514238,ES
3633514239,3633545215,US
3633545216,3633545727,GA
-3633545728,3633546239,A2
+3633545728,3633545983,A2
+3633545984,3633546239,US
3633546240,3633546751,GA
-3633546752,3633547263,A2
+3633546752,3633547007,A2
+3633547008,3633547263,US
3633547264,3633548287,GA
3633548288,3633548543,A2
3633548544,3633548799,GA
-3633548800,3633548927,A2
+3633548800,3633548863,A2
+3633548864,3633548927,US
3633548928,3633549055,GA
3633549056,3633549375,A2
3633549376,3633549391,US
3633549392,3633549567,A2
3633549568,3633549823,GA
-3633549824,3633550079,A2
-3633550080,3633550335,US
-3633550336,3633550463,A2
-3633550464,3633550527,US
-3633550528,3633550847,A2
+3633549824,3633550335,US
+3633550336,3633550431,A2
+3633550432,3633550591,US
+3633550592,3633550695,A2
+3633550696,3633550847,US
3633550848,3633551359,GA
-3633551360,3633552383,A2
-3633552384,3633552639,US
+3633551360,3633552639,US
3633552640,3633552911,A2
3633552912,3633552927,GA
-3633552928,3633552951,US
-3633552952,3633552959,A2
-3633552960,3633552967,US
-3633552968,3633553031,A2
-3633553032,3633553039,US
-3633553040,3633553127,A2
-3633553128,3633553135,US
-3633553136,3633553151,A2
+3633552928,3633553119,US
+3633553120,3633553127,A2
+3633553128,3633553143,US
+3633553144,3633553151,A2
3633553152,3633553279,GW
-3633553280,3633553295,US
-3633553296,3633553351,A2
-3633553352,3633553367,US
-3633553368,3633553399,A2
-3633553400,3633812775,US
-3633812776,3633812783,CA
-3633812784,3633815551,US
+3633553280,3633553311,US
+3633553312,3633553343,A2
+3633553344,3633815551,US
3633815552,3633816079,CA
3633816080,3633816095,US
3633816096,3633816119,CA
@@ -128676,8 +131873,8 @@
3633816248,3633816255,IN
3633816256,3633816263,NG
3633816264,3633816279,CA
-3633816280,3633816303,US
-3633816304,3633816351,CA
+3633816280,3633816311,US
+3633816312,3633816351,CA
3633816352,3633816383,IN
3633816384,3633816391,NG
3633816392,3633816399,US
@@ -128690,16 +131887,18 @@
3633816504,3633816511,IN
3633816512,3633816519,US
3633816520,3633816527,ZA
-3633816528,3633819135,CA
+3633816528,3633816535,CA
+3633816536,3633816543,US
+3633816544,3633819135,CA
3633819136,3633819199,IN
3633819200,3633819391,CA
3633819392,3633819423,IN
3633819424,3633819647,CA
3633819648,3633821279,US
3633821280,3633821311,BB
-3633821312,3633822207,US
-3633822208,3633822335,CY
-3633822336,3633881087,US
+3633821312,3633822303,US
+3633822304,3633822327,CA
+3633822328,3633881087,US
3633881088,3633885183,AN
3633885184,3633889279,US
3633889280,3633893375,CA
@@ -128718,15 +131917,11 @@
3634098176,3634125831,US
3634125832,3634125839,CA
3634125840,3634125855,JP
-3634125856,3634125887,US
-3634125888,3634125903,GB
-3634125904,3634125951,US
+3634125856,3634125951,US
3634125952,3634125967,CA
3634125968,3634135423,US
3634135424,3634135487,CA
-3634135488,3634135935,US
-3634135936,3634136062,CA
-3634136063,3634136103,US
+3634135488,3634136103,US
3634136104,3634136111,CA
3634136112,3634138127,US
3634138128,3634138143,CA
@@ -128772,15 +131967,7 @@
3635314688,3635322879,CA
3635322880,3635425279,US
3635425280,3635429375,CA
-3635429376,3635458527,US
-3635458528,3635458543,CH
-3635458544,3635460031,US
-3635460032,3635460095,CH
-3635460096,3635460543,US
-3635460544,3635460575,CH
-3635460576,3635460799,US
-3635460800,3635460831,CH
-3635460832,3635464031,US
+3635429376,3635464031,US
3635464032,3635464063,GB
3635464064,3635464127,US
3635464128,3635464135,GB
@@ -128869,7 +132056,9 @@
3636151489,3636151535,US
3636151536,3636151759,CA
3636151760,3636151775,US
-3636151776,3636152575,CA
+3636151776,3636152303,CA
+3636152304,3636152319,US
+3636152320,3636152575,CA
3636152576,3636152591,US
3636152592,3636152639,CA
3636152640,3636152647,US
@@ -128895,9 +132084,7 @@
3636154912,3636154975,CA
3636154976,3636154979,US
3636154980,3636154990,CA
-3636154991,3636154991,US
-3636154992,3636155007,CA
-3636155008,3636155071,US
+3636154991,3636155071,US
3636155072,3636155391,CA
3636155392,3636155407,US
3636155408,3636155455,CA
@@ -128939,7 +132126,9 @@
3636159840,3636159871,CA
3636159872,3636159999,IN
3636160000,3636160255,US
-3636160256,3636160415,CA
+3636160256,3636160335,CA
+3636160336,3636160343,US
+3636160344,3636160415,CA
3636160416,3636160431,US
3636160432,3636160831,CA
3636160832,3636160895,US
@@ -128952,8 +132141,8 @@
3636161792,3636161871,CA
3636161872,3636161885,US
3636161886,3636161943,CA
-3636161944,3636161951,US
-3636161952,3636162559,CA
+3636161944,3636162015,US
+3636162016,3636162559,CA
3636162560,3636163583,US
3636163584,3636164095,CA
3636164096,3636164111,BV
@@ -129009,41 +132198,26 @@
3636635392,3636635775,CR
3636635776,3636636415,US
3636636416,3636636543,CR
-3636636544,3636667647,US
-3636667904,3636668159,SC
-3636668416,3636668671,GI
-3636668672,3636668927,US
-3636668928,3636669183,BZ
-3636669184,3636669439,CY
-3636669696,3636669951,SC
-3636669952,3636670207,DE
-3636670304,3636670335,RU
-3636670464,3636670527,US
-3636670656,3636670719,RU
-3636670784,3636670799,RU
-3636670976,3636671007,VG
-3636671200,3636671231,IT
-3636671232,3636671487,SC
-3636671488,3636671743,GB
-3636674560,3636822015,US
+3636636544,3636822015,US
3636822016,3636854783,CA
3636854784,3636887551,US
3636887552,3636895743,CA
-3636895744,3636904351,US
-3636904352,3636904383,MY
-3636904384,3636904511,US
+3636895744,3636904063,US
+3636904064,3636904095,GB
+3636904096,3636904159,US
+3636904160,3636904191,CA
+3636904192,3636904447,US
+3636904448,3636904479,CA
+3636904480,3636904511,HK
3636904512,3636904543,CA
3636904544,3636904575,IN
3636904576,3636904607,US
-3636904608,3636904639,IN
-3636904640,3636904703,US
+3636904608,3636904671,IN
+3636904672,3636904703,US
3636904704,3636904959,MY
-3636904960,3636905087,US
-3636905088,3636905215,MY
-3636905216,3636905471,US
+3636904960,3636905471,US
3636905472,3636905727,CA
-3636905728,3636905759,HK
-3636905760,3636905791,US
+3636905728,3636905791,US
3636905792,3636905823,IN
3636905824,3636905887,US
3636905888,3636905951,CA
@@ -129056,30 +132230,40 @@
3636906176,3636906207,IN
3636906208,3636906367,US
3636906368,3636906465,IN
-3636906466,3636906623,US
+3636906466,3636906495,US
+3636906496,3636906623,CA
3636906624,3636906751,IN
3636906752,3636906879,US
3636906880,3636907007,IN
-3636907008,3636907103,US
+3636907008,3636907039,CA
+3636907040,3636907103,US
3636907104,3636907135,IN
-3636907136,3636907199,CA
-3636907200,3636907231,HK
+3636907136,3636907167,CA
+3636907168,3636907199,US
+3636907200,3636907231,CA
3636907232,3636907775,US
3636907776,3636908031,CA
3636908032,3636908543,US
3636908544,3636908799,IN
-3636908800,3636909055,US
-3636909056,3636909567,CA
-3636909568,3636909663,US
+3636908800,3636908863,US
+3636908864,3636908991,CA
+3636908992,3636909055,US
+3636909056,3636909311,CA
+3636909312,3636909663,US
3636909664,3636909695,IT
-3636909696,3636909791,CA
+3636909696,3636909727,CA
+3636909728,3636909759,US
+3636909760,3636909791,CA
3636909792,3636909855,US
3636909856,3636909887,CN
3636909888,3636909951,IT
-3636909952,3636910079,US
-3636910080,3636910335,CA
-3636910336,3636910399,IN
-3636910400,3636910495,US
+3636909952,3636909983,US
+3636909984,3636910015,TZ
+3636910016,3636910335,US
+3636910336,3636910367,IN
+3636910368,3636910399,US
+3636910400,3636910431,IN
+3636910432,3636910495,US
3636910496,3636910527,BE
3636910528,3636910591,US
3636910592,3636910719,CA
@@ -129090,40 +132274,52 @@
3636911360,3636911423,US
3636911424,3636911455,BE
3636911456,3636911615,US
-3636911616,3636911743,TW
+3636911616,3636911743,CA
3636911744,3636911871,IN
-3636911872,3636912383,US
+3636911872,3636911903,US
+3636911904,3636911935,CA
+3636911936,3636912383,US
3636912384,3636912447,JP
3636912448,3636912959,US
3636912960,3636912991,BE
-3636912992,3636913919,US
-3636913920,3636914175,CA
-3636914176,3636914431,US
-3636914432,3636914687,CA
+3636912992,3636913279,US
+3636913280,3636913407,CA
+3636913408,3636913535,US
+3636913536,3636913663,CA
+3636913664,3636913919,US
+3636913920,3636914687,CA
3636914688,3636914815,US
3636914816,3636914943,CA
3636914944,3636915103,US
3636915104,3636915135,IN
3636915136,3636915199,US
3636915200,3636915327,IN
-3636915328,3636915455,US
+3636915328,3636915455,CA
3636915456,3636915583,IN
-3636915584,3636916223,US
+3636915584,3636915711,CA
+3636915712,3636915839,US
+3636915840,3636915967,CA
+3636915968,3636916031,US
+3636916032,3636916063,CA
+3636916064,3636916223,US
3636916224,3636916351,CA
3636916352,3636916479,US
3636916480,3636916607,CA
3636916608,3636916735,IN
-3636916736,3636916991,US
-3636916992,3636917120,CA
-3636917121,3636917255,US
+3636916736,3636916927,US
+3636916928,3636916959,CA
+3636916960,3636916991,US
+3636916992,3636917119,CA
+3636917120,3636917255,US
3636917256,3636917263,IN
-3636917264,3636917271,CA
-3636917272,3636917295,US
+3636917264,3636917295,US
3636917296,3636917303,IN
-3636917304,3636917447,US
+3636917304,3636917359,US
+3636917360,3636917367,AU
+3636917368,3636917447,US
3636917448,3636917455,HK
-3636917456,3636917631,US
-3636917632,3636919039,CA
+3636917456,3636917503,US
+3636917504,3636919039,CA
3636919040,3636919071,IN
3636919072,3636919103,US
3636919104,3636919135,CA
@@ -129134,14 +132330,15 @@
3636919712,3636919743,BE
3636919744,3636919807,US
3636919808,3636919871,GB
-3636919872,3637071887,US
+3636919872,3636920127,US
+3636920128,3636920191,CA
+3636920192,3637071887,US
3637071888,3637071903,AD
3637071904,3637071935,US
3637071936,3637071943,SK
3637071944,3637071951,IL
3637071952,3637071967,CY
-3637071968,3637071999,US
-3637072000,3637072015,CA
+3637071968,3637072015,US
3637072016,3637072031,CY
3637072032,3637072071,US
3637072072,3637072079,FI
@@ -129308,9 +132505,7 @@
3638370304,3638374751,CA
3638374752,3638374767,US
3638374768,3638386687,CA
-3638386688,3638494175,US
-3638494176,3638494183,CA
-3638494184,3638509295,US
+3638386688,3638509295,US
3638509296,3638509311,GB
3638509312,3638509567,US
3638509568,3638526911,CA
@@ -129345,11 +132540,7 @@
3639258679,3639263231,CA
3639263232,3639279615,US
3639279616,3639283711,CA
-3639283712,3639322511,US
-3639322512,3639322519,JP
-3639322520,3639322535,US
-3639322536,3639322543,JP
-3639322544,3639342703,US
+3639283712,3639342703,US
3639342704,3639342711,GB
3639342712,3639343135,US
3639343136,3639343167,GB
@@ -129441,7 +132632,6 @@
3639439640,3639440767,US
3639440768,3639440895,IN
3639440896,3639476223,US
-3639507456,3639507967,US
3639541760,3639558143,US
3639558144,3639566335,CA
3639566336,3639607295,US
@@ -129537,19 +132727,23 @@
3639680992,3639681023,CL
3639681024,3639730175,US
3639730176,3639734271,CA
-3639734272,3639886095,US
-3639886096,3639886103,CN
-3639886104,3639886591,US
+3639734272,3639886591,US
3639886592,3639886599,SG
-3639886600,3639888927,US
-3639888928,3639888959,NO
-3639888960,3639892359,US
+3639886600,3639892359,US
3639892360,3639892367,ID
3639892368,3639892375,US
3639892376,3639892383,ID
3639892384,3639892415,US
3639892416,3639892431,MX
-3639892432,3639902207,US
+3639892432,3639892815,US
+3639892816,3639892831,MX
+3639892832,3639893119,US
+3639893120,3639893151,DE
+3639893152,3639893167,US
+3639893168,3639893199,DE
+3639893200,3639893207,US
+3639893208,3639893215,DE
+3639893216,3639902207,US
3639902208,3639918591,PE
3639918592,3639934975,AR
3639934976,3640001751,US
@@ -129862,7 +133056,11 @@
3641559136,3641560959,DE
3641560960,3641561087,NL
3641561088,3641565183,RU
-3641565184,3641573375,SE
+3641565184,3641567343,SE
+3641567344,3641567351,FI
+3641567352,3641568967,SE
+3641568968,3641568975,NO
+3641568976,3641573375,SE
3641573376,3641577471,NO
3641577472,3641581567,RU
3641581568,3641585663,ES
@@ -129935,9 +133133,7 @@
3641762012,3641762047,GR
3641762048,3641762571,CY
3641762572,3641762575,GR
-3641762576,3641762591,CY
-3641762592,3641762595,GR
-3641762596,3641762607,CY
+3641762576,3641762607,CY
3641762608,3641762611,GR
3641762612,3641762647,CY
3641762648,3641762655,GR
@@ -130146,6 +133342,7 @@
3642056704,3642060799,RU
3642060800,3642064895,KE
3642064896,3642068991,SE
+3642068992,3642073087,AL
3642073088,3642077183,LV
3642077184,3642081271,BE
3642081272,3642081278,US
@@ -130250,7 +133447,6 @@
3642249216,3642253311,FR
3642253312,3642257407,FI
3642257408,3642261503,RU
-3642261504,3642265599,GB
3642265600,3642266111,AE
3642266112,3642266367,IR
3642266368,3642266623,AE
@@ -130328,6 +133524,7 @@
3642503168,3642507263,LV
3642507264,3642509311,FR
3642509312,3642511359,RU
+3642511360,3642515455,CZ
3642515456,3642519551,DE
3642519552,3642523647,IT
3642523648,3642527743,GB
@@ -130352,14 +133549,11 @@
3642552688,3642552831,UA
3642552832,3642552847,EE
3642552848,3642553095,UA
-3642553096,3642553097,LV
-3642553098,3642553099,UA
-3642553100,3642553139,LV
+3642553096,3642553139,LV
3642553140,3642553143,UA
3642553144,3642553175,LV
3642553176,3642553183,UA
-3642553184,3642553335,LV
-3642553336,3642553343,UA
+3642553184,3642553343,LV
3642553344,3642553371,RU
3642553372,3642553375,UA
3642553376,3642553377,RU
@@ -130390,9 +133584,9 @@
3642554120,3642554123,UA
3642554124,3642554151,RU
3642554152,3642554177,UA
-3642554178,3642554203,RU
-3642554204,3642554205,UA
-3642554206,3642554223,RU
+3642554178,3642554207,RU
+3642554208,3642554211,UA
+3642554212,3642554223,RU
3642554224,3642554239,UA
3642554240,3642554271,RU
3642554272,3642554367,UA
@@ -130441,17 +133635,21 @@
3642555184,3642555199,UA
3642555200,3642555223,LT
3642555224,3642555227,LV
-3642555228,3642555391,LT
-3642555392,3642555499,PL
-3642555500,3642555647,UA
+3642555228,3642555289,LT
+3642555290,3642555295,UA
+3642555296,3642555391,LT
+3642555392,3642555493,PL
+3642555494,3642555495,UA
+3642555496,3642555503,PL
+3642555504,3642555647,UA
3642555648,3642555683,SE
3642555684,3642555687,UA
3642555688,3642555695,SE
-3642555696,3642555703,LV
+3642555696,3642555703,UA
3642555704,3642555707,FI
3642555708,3642555711,SE
3642555712,3642555727,RU
-3642555728,3642555735,SE
+3642555728,3642555735,UA
3642555736,3642555743,GB
3642555744,3642555759,SE
3642555760,3642555771,GB
@@ -130460,9 +133658,7 @@
3642555784,3642555787,GB
3642555788,3642555789,UA
3642555790,3642555791,SE
-3642555792,3642555839,UA
-3642555840,3642555903,SE
-3642555904,3642556159,UA
+3642555792,3642556159,UA
3642556160,3642556415,LV
3642556416,3642560511,CZ
3642560512,3642564607,KG
@@ -130478,18 +133674,9 @@
3642601472,3642605567,RU
3642605568,3642609663,GB
3642609664,3642613759,DZ
-3642613760,3642614527,AX
-3642614528,3642614783,FI
-3642614784,3642615103,AX
-3642615104,3642615167,FI
-3642615168,3642615295,AX
-3642615296,3642615551,FI
-3642615552,3642615567,AX
-3642615568,3642615583,FI
+3642613760,3642615583,FI
3642615584,3642615615,AX
-3642615616,3642615679,FI
-3642615680,3642616383,AX
-3642616384,3642617855,FI
+3642615616,3642617855,FI
3642617856,3642621951,JO
3642621952,3642626047,IT
3642626048,3642630143,BE
@@ -130737,8 +133924,8 @@
3645149952,3645150559,DE
3645150560,3645150591,HK
3645150592,3645150615,DE
-3645150616,3645150623,US
-3645150624,3645150975,DE
+3645150616,3645150639,US
+3645150640,3645150975,DE
3645150976,3645151231,US
3645151232,3645151487,DE
3645151488,3645151615,MT
@@ -130859,9 +134046,9 @@
3645460480,3645464575,UA
3645464576,3645468671,SE
3645468672,3645472767,RU
-3645472768,3645476863,UA
3645476864,3645480959,DE
3645480960,3645485055,RO
+3645485056,3645489151,PL
3645489152,3645493247,RU
3645493248,3645501439,IT
3645501440,3645505535,PL
@@ -131056,8 +134243,7 @@
3645763715,3645763715,NL
3645763716,3645763716,DE
3645763717,3645763717,NL
-3645763718,3645763718,DE
-3645763719,3645763719,NL
+3645763718,3645763719,DE
3645763720,3645763720,IT
3645763721,3645763721,DE
3645763722,3645763722,GR
@@ -131349,7 +134535,8 @@
3645764110,3645764110,DK
3645764111,3645764111,DE
3645764112,3645764112,IT
-3645764113,3645764114,ES
+3645764113,3645764113,ES
+3645764114,3645764114,DE
3645764115,3645764115,GB
3645764116,3645764116,GR
3645764117,3645764117,DE
@@ -131841,12 +135028,14 @@
3645779968,3645784063,PS
3645784064,3645788159,NG
3645788160,3645792255,GB
+3645792256,3645796351,TR
3645796352,3645800447,CH
3645800448,3645804543,DE
3645804544,3645808639,GB
3645808640,3645812735,DE
3645812736,3645816831,RU
3645816832,3645825023,FI
+3645825024,3645829119,RU
3645829120,3645833215,NL
3645833216,3645841407,RU
3645841408,3645845503,BG
@@ -131899,7 +135088,9 @@
3647886188,3647886207,GB
3647886208,3647886271,DE
3647886272,3647886303,GB
-3647886304,3647890463,DE
+3647886304,3647889663,DE
+3647889664,3647889671,BE
+3647889672,3647890463,DE
3647890464,3647890471,FR
3647890472,3647912447,DE
3647912448,3647912511,BE
@@ -131907,9 +135098,7 @@
3647916800,3647917055,SE
3647917056,3647917599,DE
3647917600,3647917615,US
-3647917616,3647936823,DE
-3647936824,3647936827,GB
-3647936828,3647936871,DE
+3647917616,3647936871,DE
3647936872,3647936879,FR
3647936880,3647954231,DE
3647954232,3647954239,GB
@@ -131919,7 +135108,9 @@
3647957512,3647957519,GB
3647957520,3647959567,DE
3647959568,3647959575,ES
-3647959576,3647961215,DE
+3647959576,3647959599,DE
+3647959600,3647959607,AT
+3647959608,3647961215,DE
3647961216,3647961247,IT
3647961248,3647963167,DE
3647963168,3647963183,BE
@@ -131960,9 +135151,7 @@
3647966576,3647966583,DE
3647966584,3647967231,GB
3647967232,3647968255,BE
-3647968256,3647968703,FR
-3647968704,3647968767,GB
-3647968768,3647969279,FR
+3647968256,3647969279,FR
3647969280,3647969791,IT
3647969792,3647970303,BE
3647970304,3647971327,FR
@@ -131970,12 +135159,9 @@
3647971672,3647971679,DE
3647971680,3647972191,GB
3647972192,3647972199,DE
-3647972200,3647972215,GB
-3647972216,3647972223,DE
-3647972224,3647972259,GB
+3647972200,3647972259,GB
3647972260,3647972263,DE
-3647972264,3647972343,GB
-3647972344,3647972351,DE
+3647972264,3647972351,GB
3647972352,3647973679,IT
3647973680,3647973695,DE
3647973696,3647973783,IT
@@ -131986,13 +135172,9 @@
3647974048,3647974055,DE
3647974056,3647974399,IT
3647974400,3647976447,ES
-3647976448,3647976503,BE
-3647976504,3647976511,DE
-3647976512,3647976559,BE
+3647976448,3647976559,BE
3647976560,3647976575,FR
-3647976576,3647976607,BE
-3647976608,3647976639,BR
-3647976640,3647976647,BE
+3647976576,3647976647,BE
3647976648,3647976663,DE
3647976664,3647976719,BE
3647976720,3647976727,DE
@@ -132004,10 +135186,10 @@
3647976792,3647976799,DE
3647976800,3647976927,BE
3647976928,3647976935,DE
-3647976936,3647977071,BE
-3647977072,3647977087,DE
-3647977088,3647977119,BE
-3647977120,3647977215,DE
+3647976936,3647977079,BE
+3647977080,3647977087,DE
+3647977088,3647977151,BE
+3647977152,3647977215,DE
3647977216,3647977471,BE
3647977472,3647977791,GB
3647977792,3647977855,IE
@@ -132016,14 +135198,20 @@
3647978776,3647978783,DE
3647978784,3647978871,NL
3647978872,3647978879,DE
-3647978880,3647978887,NL
-3647978888,3647979519,DE
+3647978880,3647978895,NL
+3647978896,3647978911,DE
+3647978912,3647978927,NL
+3647978928,3647979007,DE
+3647979008,3647979136,IT
+3647979137,3647979519,DE
3647979520,3647980543,FR
3647980544,3647981055,GB
3647981056,3647981567,IE
3647981568,3647982591,BE
3647982592,3647983615,IT
-3647983616,3647995903,DE
+3647983616,3647984639,NL
+3647984640,3647985151,DK
+3647985152,3647995903,DE
3647995904,3648004095,RU
3648004096,3648004607,GB
3648004608,3648006271,RU
@@ -132135,7 +135323,9 @@
3648181024,3648181055,AT
3648181056,3648181215,DE
3648181216,3648181231,RU
-3648181232,3648181311,DE
+3648181232,3648181247,DE
+3648181248,3648181279,IT
+3648181280,3648181311,DE
3648181312,3648181343,AT
3648181344,3648181375,DE
3648181376,3648181407,RU
@@ -132145,9 +135335,7 @@
3648181552,3648181567,RU
3648181568,3648181631,DE
3648181632,3648181647,AT
-3648181648,3648181655,DE
-3648181656,3648181663,IT
-3648181664,3648181887,DE
+3648181648,3648181887,DE
3648181888,3648181903,AT
3648181904,3648182143,DE
3648182144,3648182159,NL
@@ -132165,8 +135353,10 @@
3648182816,3648182823,US
3648182824,3648182831,RU
3648182832,3648182847,DE
-3648182848,3648182911,IT
-3648182912,3648183871,DE
+3648182848,3648182879,AT
+3648182880,3648183551,DE
+3648183552,3648183679,BR
+3648183680,3648183871,DE
3648183872,3648183935,GB
3648183936,3648184319,DE
3648184320,3648192511,RU
@@ -132240,11 +135430,7 @@
3648417880,3648417919,GB
3648417920,3648418047,AT
3648418048,3648418079,GB
-3648418080,3648418095,ES
-3648418096,3648418111,GB
-3648418112,3648418135,ES
-3648418136,3648418143,GB
-3648418144,3648418247,ES
+3648418080,3648418247,ES
3648418248,3648418255,CH
3648418256,3648418263,ES
3648418264,3648418271,GB
@@ -132382,24 +135568,17 @@
3650244608,3650256895,GB
3650256896,3650265087,DE
3650265088,3650269183,CH
-3650269184,3650273279,GB
+3650269184,3650273071,GB
+3650273072,3650273279,IR
3650273280,3650277375,IT
3650277376,3650281471,IR
3650281472,3650285567,FR
3650285568,3650289663,UA
3650289664,3650297855,RU
3650297856,3650301951,LT
-3650301952,3650306623,DE
-3650306624,3650306639,GE
-3650306640,3650306775,DE
+3650301952,3650306775,DE
3650306776,3650306779,GE
-3650306780,3650306783,DE
-3650306784,3650306791,AT
-3650306792,3650306799,DE
-3650306800,3650306807,AT
-3650306808,3650306943,DE
-3650306944,3650306959,GB
-3650306960,3650307007,DE
+3650306780,3650307007,DE
3650307008,3650307010,GB
3650307011,3650310143,DE
3650310144,3650314239,GB
@@ -132416,7 +135595,9 @@
3650338816,3650342911,FR
3650342912,3650344463,CH
3650344464,3650344479,AT
-3650344480,3650344879,CH
+3650344480,3650344559,CH
+3650344560,3650344575,AT
+3650344576,3650344879,CH
3650344880,3650344911,PT
3650344912,3650345879,CH
3650345880,3650345887,IM
@@ -132548,7 +135729,9 @@
3650912640,3650912671,FR
3650912672,3650923103,GB
3650923104,3650923135,FR
-3650923136,3650945023,GB
+3650923136,3650926591,GB
+3650926592,3650929663,ES
+3650929664,3650945023,GB
3650945024,3651010559,DK
3651010560,3651076095,GB
3651076096,3651077375,DE
@@ -132587,8 +135770,9 @@
3651087872,3651088127,DE
3651088128,3651088383,IE
3651088384,3651088639,GR
-3651088640,3651088895,SG
-3651088896,3651098111,DE
+3651088640,3651090919,DE
+3651090920,3651090959,IE
+3651090960,3651098111,DE
3651098112,3651098367,IE
3651098368,3651098623,FR
3651098624,3651101439,DE
@@ -132619,7 +135803,8 @@
3651108864,3651141631,EE
3651141632,3651173375,DE
3651173376,3651173631,ES
-3651173632,3651199231,DE
+3651173632,3651198975,DE
+3651198976,3651199231,GB
3651199232,3651199487,ES
3651199488,3651199743,GB
3651199744,3651200255,ES
@@ -132632,8 +135817,13 @@
3651202048,3651202175,FR
3651202176,3651202303,GB
3651202304,3651202815,ES
-3651202816,3651203071,GB
-3651203072,3651207167,US
+3651202816,3651203583,GB
+3651203584,3651203839,FR
+3651203840,3651204095,DE
+3651204096,3651204223,ES
+3651204224,3651204351,DE
+3651204352,3651204607,PL
+3651204608,3651207167,DE
3651207168,3651207199,GB
3651207200,3651207223,EU
3651207224,3651207295,GB
@@ -132766,7 +135956,11 @@
3651886380,3651886383,CD
3651886384,3651886391,BE
3651886392,3651886395,CD
-3651886396,3651886435,BE
+3651886396,3651886407,BE
+3651886408,3651886415,CD
+3651886416,3651886423,BE
+3651886424,3651886427,CD
+3651886428,3651886435,BE
3651886436,3651886451,CD
3651886452,3651886455,BE
3651886456,3651886459,CD
@@ -132776,7 +135970,9 @@
3651886480,3651886495,CD
3651886496,3651886511,BE
3651886512,3651886527,CD
-3651886528,3651887103,BE
+3651886528,3651886591,BE
+3651886592,3651886847,CD
+3651886848,3651887103,BE
3651887104,3651891199,GB
3651891200,3651895295,DE
3651895296,3651899391,GB
@@ -132879,56 +136075,29 @@
3652011520,3652011775,IT
3652011776,3652014079,RU
3652014080,3652018175,SA
-3652018176,3652018239,IE
-3652018240,3652018303,GB
-3652018304,3652018687,IE
-3652018688,3652018943,GB
-3652018944,3652019169,IE
-3652019170,3652019199,GB
+3652018176,3652019183,IE
+3652019184,3652019199,GB
3652019200,3652019327,IE
3652019328,3652019335,GB
-3652019336,3652019351,IE
-3652019352,3652019359,GB
-3652019360,3652019407,IE
-3652019408,3652019423,GB
-3652019424,3652019455,IE
+3652019336,3652019455,IE
3652019456,3652019471,GB
3652019472,3652019479,IE
3652019480,3652019487,GB
-3652019488,3652019527,IE
-3652019528,3652019551,GB
-3652019552,3652019615,IE
-3652019616,3652019631,GB
-3652019632,3652019663,IE
-3652019664,3652019679,GB
-3652019680,3652019687,IE
-3652019688,3652019695,GB
-3652019696,3652019735,IE
-3652019736,3652019751,GB
-3652019752,3652019791,IE
-3652019792,3652019807,GB
-3652019808,3652019815,IE
-3652019816,3652019887,GB
-3652019888,3652019935,IE
-3652019936,3652019951,GB
-3652019952,3652020255,IE
-3652020256,3652020279,GB
-3652020280,3652020351,IE
-3652020352,3652020479,GB
-3652020480,3652020767,IE
-3652020768,3652020799,GB
+3652019488,3652019567,IE
+3652019568,3652019583,GB
+3652019584,3652019599,IE
+3652019600,3652019615,GB
+3652019616,3652019679,IE
+3652019680,3652019687,GB
+3652019688,3652019735,IE
+3652019736,3652019739,GB
+3652019740,3652019751,IE
+3652019752,3652019759,GB
+3652019760,3652020799,IE
3652020800,3652020863,DE
-3652020864,3652020991,GB
-3652020992,3652021063,IE
-3652021064,3652021087,GB
-3652021088,3652021151,IE
-3652021152,3652021247,GB
-3652021248,3652021423,IE
-3652021424,3652021759,GB
-3652021760,3652021775,IE
-3652021776,3652021791,GB
-3652021792,3652021887,IE
-3652021888,3652022271,GB
+3652020864,3652021415,IE
+3652021416,3652021423,BE
+3652021424,3652022271,IE
3652022272,3652026367,ES
3652026368,3652028031,DE
3652028032,3652028063,US
@@ -133017,10 +136186,12 @@
3652714496,3652985039,DE
3652985040,3652985047,FR
3652985048,3653029775,DE
-3653029776,3653029791,RO
+3653029776,3653029791,LU
3653029792,3653039103,DE
3653039104,3653039359,IT
-3653039360,3653238783,DE
+3653039360,3653039999,DE
+3653040000,3653040015,LU
+3653040016,3653238783,DE
3653238784,3653334141,CH
3653334142,3653334142,AT
3653334143,3653341871,CH
@@ -133048,7 +136219,8 @@
3653403976,3653403983,A2
3653403984,3653403999,UA
3653404000,3653404008,LB
-3653404009,3653404039,A2
+3653404009,3653404015,ZM
+3653404016,3653404039,A2
3653404040,3653404047,IQ
3653404048,3653404063,A2
3653404064,3653404071,LB
@@ -133085,7 +136257,9 @@
3653405064,3653405071,IQ
3653405072,3653405095,A2
3653405096,3653405103,NG
-3653405104,3653405167,A2
+3653405104,3653405135,A2
+3653405136,3653405143,CD
+3653405144,3653405167,A2
3653405168,3653405183,UA
3653405184,3653405439,AT
3653405440,3653407015,A2
@@ -133099,9 +136273,7 @@
3653407120,3653407127,ZW
3653407128,3653407167,A2
3653407168,3653407231,NG
-3653407232,3653407367,A2
-3653407368,3653407375,NG
-3653407376,3653407391,A2
+3653407232,3653407391,A2
3653407392,3653407399,NG
3653407400,3653407423,A2
3653407424,3653407487,ZW
@@ -133121,23 +136293,35 @@
3653408048,3653408063,A2
3653408064,3653408071,ZM
3653408072,3653408079,NG
-3653408080,3653408143,A2
+3653408080,3653408119,A2
+3653408120,3653408127,NG
+3653408128,3653408143,A2
3653408144,3653408151,NG
3653408152,3653408167,A2
3653408168,3653408175,ZW
-3653408176,3653408183,A2
+3653408176,3653408183,US
3653408184,3653408191,MW
-3653408192,3653408231,A2
+3653408192,3653408199,A2
+3653408200,3653408207,NG
+3653408208,3653408231,A2
3653408232,3653408239,KE
-3653408240,3653408247,ZM
-3653408248,3653408767,A2
+3653408240,3653408247,BF
+3653408248,3653408271,A2
+3653408272,3653408287,IQ
+3653408288,3653408319,A2
+3653408320,3653408327,IQ
+3653408328,3653408767,A2
3653408768,3653409023,CD
3653409024,3653409039,A2
3653409040,3653409047,NG
-3653409048,3653409087,A2
+3653409048,3653409063,A2
+3653409064,3653409071,CD
+3653409072,3653409087,A2
3653409088,3653409095,CD
-3653409096,3653409111,A2
-3653409112,3653409127,NG
+3653409096,3653409103,A2
+3653409104,3653409111,MW
+3653409112,3653409119,NG
+3653409120,3653409127,A2
3653409128,3653409143,CD
3653409144,3653409151,NG
3653409152,3653409191,A2
@@ -133145,7 +136329,9 @@
3653409200,3653409223,A2
3653409224,3653409231,NG
3653409232,3653409279,A2
-3653409280,3653409535,TZ
+3653409280,3653409311,TZ
+3653409312,3653409319,IQ
+3653409320,3653409535,TZ
3653409536,3653409559,UA
3653409560,3653409567,CM
3653409568,3653409575,UA
@@ -133164,11 +136350,10 @@
3653410096,3653410111,ZW
3653410112,3653410119,A2
3653410120,3653410127,NG
-3653410128,3653410143,A2
-3653410144,3653410151,ET
+3653410128,3653410151,A2
3653410152,3653410159,KE
3653410160,3653410175,NG
-3653410176,3653410183,KE
+3653410176,3653410183,US
3653410184,3653410191,MZ
3653410192,3653410199,ZW
3653410200,3653410215,A2
@@ -133289,7 +136474,6 @@
3653652480,3653656575,RU
3653656576,3653660671,GB
3653660672,3653664767,CZ
-3653664768,3653668863,UA
3653668864,3653672959,SE
3653672960,3653681151,RU
3653681152,3653685247,ES
@@ -133440,7 +136624,9 @@
3664004352,3664004607,MY
3664004608,3664004863,SG
3664004864,3664005119,KH
-3664005120,3664006143,ID
+3664005120,3664005887,ID
+3664005888,3664006143,MY
+3664006144,3664006399,AU
3664052224,3664084991,NZ
3664084992,3664117759,KR
3664117760,3664248831,HK
diff --git a/src/config/torrc.bridge.in b/src/config/torrc.bridge.in
new file mode 100644
index 0000000000..557b7adf46
--- /dev/null
+++ b/src/config/torrc.bridge.in
@@ -0,0 +1,171 @@
+## Configuration file for a typical Tor user
+## Last updated 16 July 2009 for Tor 0.2.2.1-alpha.
+## (May or may not work for much older or much newer versions of Tor.)
+##
+## Lines that begin with "## " try to explain what's going on. Lines
+## that begin with just "#" are disabled commands: you can enable them
+## by removing the "#" symbol.
+##
+## See 'man tor', or https://www.torproject.org/tor-manual.html,
+## for more options you can use in this file.
+##
+## Tor will look for this file in various places based on your platform:
+## https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ#torrc
+
+
+## Replace this with "SocksPort 0" if you plan to run Tor only as a
+## relay, and not make any local application connections yourself.
+SocksPort 9050 # what port to open for local application connections
+SocksListenAddress 127.0.0.1 # accept connections only from localhost
+#SocksListenAddress 192.168.0.1:9100 # listen on this IP:port also
+
+## Entry policies to allow/deny SOCKS requests based on IP address.
+## First entry that matches wins. If no SocksPolicy is set, we accept
+## all (and only) requests from SocksListenAddress.
+#SocksPolicy accept 192.168.0.0/16
+#SocksPolicy reject *
+
+## Logs go to stdout at level "notice" unless redirected by something
+## else, like one of the below lines. You can have as many Log lines as
+## you want.
+##
+## We advise using "notice" in most cases, since anything more verbose
+## may provide sensitive information to an attacker who obtains the logs.
+##
+## Send all messages of level 'notice' or higher to @LOCALSTATEDIR@/log/tor/notices.log
+#Log notice file @LOCALSTATEDIR@/log/tor/notices.log
+## Send every possible message to @LOCALSTATEDIR@/log/tor/debug.log
+#Log debug file @LOCALSTATEDIR@/log/tor/debug.log
+## Use the system log instead of Tor's logfiles
+#Log notice syslog
+## To send all messages to stderr:
+#Log debug stderr
+
+## Uncomment this to start the process in the background... or use
+## --runasdaemon 1 on the command line. This is ignored on Windows;
+## see the FAQ entry if you want Tor to run as an NT service.
+#RunAsDaemon 1
+
+## The directory for keeping all the keys/etc. By default, we store
+## things in $HOME/.tor on Unix, and in Application Data\tor on Windows.
+#DataDirectory @LOCALSTATEDIR@/lib/tor
+
+## The port on which Tor will listen for local connections from Tor
+## controller applications, as documented in control-spec.txt.
+#ControlPort 9051
+## If you enable the controlport, be sure to enable one of these
+## authentication methods, to prevent attackers from accessing it.
+#HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C
+#CookieAuthentication 1
+
+############### This section is just for location-hidden services ###
+
+## Once you have configured a hidden service, you can look at the
+## contents of the file ".../hidden_service/hostname" for the address
+## to tell people.
+##
+## HiddenServicePort x y:z says to redirect requests on port x to the
+## address y:z.
+
+#HiddenServiceDir @LOCALSTATEDIR@/lib/tor/hidden_service/
+#HiddenServicePort 80 127.0.0.1:80
+
+#HiddenServiceDir @LOCALSTATEDIR@/lib/tor/other_hidden_service/
+#HiddenServicePort 80 127.0.0.1:80
+#HiddenServicePort 22 127.0.0.1:22
+
+################ This section is just for relays #####################
+#
+## See https://www.torproject.org/docs/tor-doc-relay for details.
+
+## Required: what port to advertise for incoming Tor connections.
+ORPort 9001
+## If you want to listen on a port other than the one advertised
+## in ORPort (e.g. to advertise 443 but bind to 9090), uncomment the
+## line below too. You'll need to do ipchains or other port forwarding
+## yourself to make this work.
+#ORListenAddress 0.0.0.0:9090
+
+## A handle for your relay, so people don't have to refer to it by key.
+Nickname Unnamed
+
+## The IP address or full DNS name for your relay. Leave commented out
+## and Tor will guess.
+#Address noname.example.com
+
+## Define these to limit how much relayed traffic you will allow. Your
+## own traffic is still unthrottled. Note that RelayBandwidthRate must
+## be at least 20 KB.
+#RelayBandwidthRate 100 KB # Throttle traffic to 100KB/s (800Kbps)
+#RelayBandwidthBurst 200 KB # But allow bursts up to 200KB/s (1600Kbps)
+RelayBandwidthBurst 10485760
+RelayBandwidthRate 5242880
+
+## Use these to restrict the maximum traffic per day, week, or month.
+## Note that this threshold applies to sent _and_ to received bytes,
+## not to their sum: Setting "4 GB" may allow up to 8 GB
+## total before hibernating.
+##
+## Set a maximum of 4 gigabytes each way per period.
+#AccountingMax 4 GB
+## Each period starts daily at midnight (AccountingMax is per day)
+#AccountingStart day 00:00
+## Each period starts on the 3rd of the month at 15:00 (AccountingMax
+## is per month)
+#AccountingStart month 3 15:00
+
+## Contact info to be published in the directory, so we can contact you
+## if your relay is misconfigured or something else goes wrong. Google
+## indexes this, so spammers might also collect it.
+#ContactInfo Random Person <nobody AT example dot com>
+## You might also include your PGP or GPG fingerprint if you have one:
+#ContactInfo 1234D/FFFFFFFF Random Person <nobody AT example dot com>
+
+## Uncomment this to mirror directory information for others. Please do
+## if you have enough bandwidth.
+DirPort 9030 # what port to advertise for directory connections
+## If you want to listen on a port other than the one advertised
+## in DirPort (e.g. to advertise 80 but bind to 9091), uncomment the line
+## below too. You'll need to do ipchains or other port forwarding yourself
+## to make this work.
+#DirListenAddress 0.0.0.0:9091
+## Uncomment to return an arbitrary blob of html on your DirPort. Now you
+## can explain what Tor is if anybody wonders why your IP address is
+## contacting them. See contrib/tor-exit-notice.html in Tor's source
+## distribution for a sample.
+#DirPortFrontPage @CONFDIR@/tor-exit-notice.html
+
+## Uncomment this if you run more than one Tor relay, and add the identity
+## key fingerprint of each Tor relay you control, even if they're on
+## different networks. You declare it here so Tor clients can avoid
+## using more than one of your relays in a single circuit. See
+## https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ#MultipleServers
+#MyFamily $keyid,$keyid,...
+
+## A comma-separated list of exit policies. They're considered first
+## to last, and the first match wins. If you want to _replace_
+## the default exit policy, end this with either a reject *:* or an
+## accept *:*. Otherwise, you're _augmenting_ (prepending to) the
+## default exit policy. Leave commented to just use the default, which is
+## described in the man page or at
+## https://www.torproject.org/documentation.html
+##
+## Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses
+## for issues you might encounter if you use the default exit policy.
+##
+## If certain IPs and ports are blocked externally, e.g. by your firewall,
+## you should update your exit policy to reflect this -- otherwise Tor
+## users will be told that those destinations are down.
+##
+#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports but no more
+#ExitPolicy accept *:119 # accept nntp as well as default exit policy
+#ExitPolicy reject *:* # no exits allowed
+#
+## Bridge relays (or "bridges") are Tor relays that aren't listed in the
+## main directory. Since there is no complete public list of them, even if an
+## ISP is filtering connections to all the known Tor relays, they probably
+## won't be able to block all the bridges. Also, websites won't treat you
+## differently because they won't know you're running Tor. If you can
+## be a real relay, please do; but if not, be a bridge!
+BridgeRelay 1
+ExitPolicy reject *:*
diff --git a/src/config/torrc.complete.in b/src/config/torrc.complete.in
deleted file mode 100644
index 310458a5c0..0000000000
--- a/src/config/torrc.complete.in
+++ /dev/null
@@ -1,533 +0,0 @@
-# $Id$
-# Last updated on $Date$
-####################################################################
-## This config file is divided into four sections. They are:
-## 1. Global Options (clients and servers)
-## 2. Client Options Only
-## 3. Server Options Only
-## 4. Directory Server Options (for running your own Tor network)
-## 5. Hidden Service Options (clients and servers)
-##
-## The conventions used are:
-## double hash (##) is for summary text about the config option;
-## single hash (#) is for the config option; and,
-## the config option is always after the text.
-####################################################################
-
-
-## Section 1: Global Options (clients and servers)
-
-## A token bucket limits the average incoming bandwidth on this node
-## to the specified number of bytes per second. (Default: 2MB)
-#BandwidthRate N bytes|KB|MB|GB|TB
-
-## Limit the maximum token bucket size (also known as the burst) to
-## the given number of bytes. (Default: 5 MB)
-#BandwidthBurst N bytes|KB|MB|GB|TB
-
-## If set, we will not advertise more than this amount of bandwidth
-## for our BandwidthRate. Server operators who want to reduce the
-## number of clients who ask to build circuits through them (since
-## this is proportional to advertised bandwidth rate) can thus
-## reduce the CPU demands on their server without impacting
-## network performance.
-#MaxAdvertisedBandwidth N bytes|KB|MB|GB|TB
-
-## If set, Tor will accept connections from the same machine
-## (localhost only) on this port, and allow those connections to
-## control the Tor process using the Tor Control Protocol
-## (described in control-spec.txt). Note: unless you also specify
-## one of HashedControlPassword or CookieAuthentication, setting
-## this option will cause Tor to allow any process on the local
-## host to control it.
-#ControlPort Port
-
-## Don’t allow any connections on the control port except when the
-## other process knows the password whose one-way hash is
-## hashed_password. You can compute the hash of a password by
-## running "tor --hash-password password".
-#HashedControlPassword hashed_password
-
-## If this option is set to 1, don’t allow any connections on the
-## control port except when the connecting process knows the
-## contents of a file named "control_auth_cookie", which Tor will
-## create in its data directory. This authentication method
-## should only be used on systems with good filesystem security.
-## (Default: 0)
-#CookieAuthentication 0|1
-
-## Store working data in DIR (Default: /usr/local/var/lib/tor)
-#DataDirectory DIR
-
-## Every time the specified period elapses, Tor downloads a direc-
-## tory. A directory contains a signed list of all known servers
-## as well as their current liveness status. A value of "0 sec-
-## onds" tells Tor to choose an appropriate default.
-## (Default: 1 hour for clients, 20 minutes for servers)
-#DirFetchPeriod N seconds|minutes|hours|days|weeks
-
-## Tor only trusts directories signed with one of these keys, and
-## uses the given addresses to connect to the trusted directory
-## servers. If no DirServer lines are specified, Tor uses the built-in
-## defaults (moria1, moria2, tor26), so you can leave this alone unless
-## you need to change it.
-##
-## WARNING! Changing these options will make your Tor behave
-## differently from everyone else's, and hurt your anonymity. Even
-## uncommenting these lines is a bad idea. They are the defaults now,
-## but the defaults may change in the future, leaving you behind.
-##
-#DirServer moria1 v1 18.244.0.188:9031 FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441
-#DirServer moria2 v1 18.244.0.114:80 719B E45D E224 B607 C537 07D0 E214 3E2D 423E 74CF
-#DirServer tor26 v1 86.59.21.38:80 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D
-
-## On startup, setgid to this user.
-#Group GID
-
-## Tor will make all its directory requests through this host:port
-## (or host:80 if port is not specified), rather than connecting
-## directly to any directory servers.
-#HttpProxy host[:port]
-
-## If defined, Tor will use this username:password for Basic Http
-## proxy authentication, as in RFC 2617. This is currently the
-## only form of Http proxy authentication that Tor supports; feel
-## free to submit a patch if you want it to support others.
-#HttpProxyAuthenticator username:password
-
-## Tor will make all its OR (SSL) connections through this
-## host:port (or host:443 if port is not specified), via HTTP CON-
-## NECT rather than connecting directly to servers. You may want
-## to set FascistFirewall to restrict the set of ports you might
-## try to connect to, if your Https proxy only allows connecting
-## to certain ports.
-#HttpsProxy host[:port]
-
-## If defined, Tor will use this username:password for Basic Https
-## proxy authentication, as in RFC 2617. This is currently the
-## only form of Https proxy authentication that Tor supports; feel
-## free to submit a patch if you want it to support others.
-#HttpsProxyAuthenticator username:password
-
-## To keep firewalls from expiring connections, send a padding
-## keepalive cell every NUM seconds on open connections that are
-## in use. If the connection has no open circuits, it will instead
-## be closed after NUM seconds of idleness. (Default: 5 minutes)
-#KeepalivePeriod NUM
-
-## Send all messages between minSeverity and maxSeverity to the
-## standard output stream, the standard error stream, or to the
-## system log. (The "syslog" value is only supported on Unix.)
-## Recognized severity levels are debug, info, notice, warn, and
-## err. If only one severity level is given, all messages of that
-## level or higher will be sent to the listed destination.
-#Log minSeverity[-maxSeverity] stderr|stdout|syslog
-
-## As above, but send log messages to the listed filename. The
-## "Log" option may appear more than once in a configuration file.
-## Messages are sent to all the logs that match their severity
-## level.
-#Log minSeverity[-maxSeverity] file FILENAME
-
-## Maximum number of simultaneous sockets allowed. You probably
-## don’t need to adjust this. (Default: 1024)
-#MaxConn NUM
-
-## Make all outbound connections originate from the IP address
-## specified. This is only useful when you have multiple network
-## interfaces, and you want all of Tor’s outgoing connections to
-## use a single one.
-#OutboundBindAddress IP
-
-## On startup, write our PID to FILE. On clean shutdown, remove
-## FILE.
-#PIDFile FILE
-
-## If 1, Tor forks and daemonizes to the background. (Default: 0)
-#RunAsDaemon 0|1
-
-## If 1, Tor replaces potentially sensitive strings in the logs
-## (e.g. addresses) with the string [scrubbed]. This way logs can
-## still be useful, but they don’t leave behind personally identi-
-## fying information about what sites a user might have visited.
-## (Default: 1)
-#SafeLogging 0|1
-
-## Every time the specified period elapses, Tor downloads signed
-## status information about the current state of known servers. A
-## value of "0 seconds" tells Tor to choose an appropriate
-## default. (Default: 30 minutes for clients, 15 minutes for
-## servers)
-#StatusFetchPeriod N seconds|minutes|hours|days|weeks
-
-## On startup, setuid to this user.
-#User UID
-
-## If non-zero, try to use crypto hardware acceleration when
-## available. (Default: 1)
-#HardwareAccel 0|1
-
-
-## Section 2: Client Options Only
-
-## Where on our circuits should we allow Tor servers that the
-## directory servers haven’t authenticated as "verified"?
-## (Default: middle,rendezvous)
-#AllowUnverifiedNodes entry|exit|middle|introduction|rendezvous|...
-
-## If set to 1, Tor will under no circumstances run as a server.
-## The default is to run as a client unless ORPort is configured.
-## (Usually, you don’t need to set this; Tor is pretty smart at
-## figuring out whether you are reliable and high-bandwidth enough
-## to be a useful server.)
-## This option will likely be deprecated in the future; see the
-## NoPublish option below. (Default: 0)
-#ClientOnly 0|1
-
-## A list of preferred nodes to use for the first hop in the
-## circuit, if possible.
-#EntryNodes nickname,nickname,...
-
-## A list of preferred nodes to use for the last hop in the
-## circuit, if possible.
-#ExitNodes nickname,nickname,...
-
-## A list of nodes to never use when building a circuit.
-#ExcludeNodes nickname,nickname,...
-
-## If 1, Tor will never use any nodes besides those listed in
-## "exitnodes" for the last hop of a circuit.
-#StrictExitNodes 0|1
-
-## If 1, Tor will never use any nodes besides those listed in
-## "entrynodes" for the first hop of a circuit.
-#StrictEntryNodes 0|1
-
-## If 1, Tor will only create outgoing connections to ORs running
-## on ports that your firewall allows (defaults to 80 and 443; see
-## FirewallPorts). This will allow you to run Tor as a client
-## behind a firewall with restrictive policies, but will not allow
-## you to run as a server behind such a firewall.
-#FascistFirewall 0|1
-
-## A list of ports that your firewall allows you to connect to.
-## Only used when FascistFirewall is set. (Default: 80, 443)
-#FirewallPorts PORTS
-
-## A comma-separated list of IPs that your firewall allows you to
-## connect to. Only used when FascistFirewall is set. The format
-## is as for the addresses in ExitPolicy.
-## For example, ’FirewallIPs 99.0.0.0/8, *:80’ means that your
-## firewall allows connections to everything inside net 99, and
-## to port 80 outside.
-#FirewallIPs ADDR[/MASK][:PORT]...
-
-## A list of ports for services that tend to have long-running
-## connections (e.g. chat and interactive shells). Circuits for
-## streams that use these ports will contain only high-uptime
-## nodes, to reduce the chance that a node will go down before the
-## stream is finished. (Default: 21, 22, 706, 1863, 5050, 5190,
-## 5222, 5223, 6667, 8300, 8888)
-#LongLivedPorts PORTS
-
-## When a request for address arrives to Tor, it will rewrite it
-## to newaddress before processing it. For example, if you always
-## want connections to www.indymedia.org to exit via torserver
-## (where torserver is the nickname of the server),
-## use "MapAddress www.indymedia.org www.indymedia.org.torserver.exit".
-#MapAddress address newaddress
-
-## Every NUM seconds consider whether to build a new circuit.
-## (Default: 30 seconds)
-#NewCircuitPeriod NUM
-
-## Feel free to reuse a circuit that was first used at most NUM
-## seconds ago, but never attach a new stream to a circuit that is
-## too old. (Default: 10 minutes)
-#MaxCircuitDirtiness NUM
-
-## The named Tor servers constitute a "family" of similar or co-
-## administered servers, so never use any two of them in the same
-## circuit. Defining a NodeFamily is only needed when a server
-## doesn’t list the family itself (with MyFamily). This option can
-## be used multiple times.
-#NodeFamily nickname,nickname,...
-
-## A list of preferred nodes to use for the rendezvous point, if
-## possible.
-#RendNodes nickname,nickname,...
-
-## A list of nodes to never use when choosing a rendezvous point.
-#RendExcludeNodes nickname,nickname,...
-
-## Advertise this port to listen for connections from SOCKS-speak-
-## ing applications. Set this to 0 if you don’t want to allow
-## application connections. (Default: 9050)
-#SOCKSPort PORT
-
-## Bind to this address to listen for connections from SOCKS-
-## speaking applications. (Default: 127.0.0.1) You can also spec-
-## ify a port (e.g. 192.168.0.1:9100). This directive can be spec-
-## ified multiple times to bind to multiple addresses/ports.
-#SOCKSBindAddress IP[:PORT]
-
-## Set an entrance policy for this server, to limit who can con-
-## nect to the SOCKS ports. The policies have the same form as
-## exit policies below.
-#SOCKSPolicy policy,policy,...
-
-## For each value in the comma separated list, Tor will track
-## recent connections to hosts that match this value and attempt
-## to reuse the same exit node for each. If the value is prepended
-## with a ’.’, it is treated as matching an entire domain. If one
-## of the values is just a ’.’, it means match everything. This
-## option is useful if you frequently connect to sites that will
-## expire all your authentication cookies (ie log you out) if your
-## IP address changes. Note that this option does have the disad-
-## vantage of making it more clear that a given history is associ-
-## ated with a single user. However, most people who would wish to
-## observe this will observe it through cookies or other protocol-
-## specific means anyhow.
-#TrackHostExits host,.domain,...
-
-## Since exit servers go up and down, it is desirable to expire
-## the association between host and exit server after NUM seconds.
-## The default is 1800 seconds (30 minutes).
-#TrackHostExitsExpire NUM
-
-## If this option is set to 1, we pick a few entry servers as our
-## "helpers", and try to use only those fixed entry servers. This
-## is desirable, because constantly changing servers increases the
-## odds that an adversary who owns some servers will observe a
-## fraction of your paths. (Defaults to 0; will eventually
-## default to 1.)
-#UseHelperNodes 0|1
-
-## If UseHelperNodes is set to 1, we will try to pick a total of
-## NUM helper nodes as entries for our circuits. (Defaults to 3.)
-#NumHelperNodes NUM
-
-
-## Section 3: Server Options Only
-
-## The IP or fqdn of this server (e.g. moria.mit.edu). You can
-## leave this unset, and Tor will guess your IP.
-#Address address
-
-## Administrative contact information for server.
-#ContactInfo email_address
-
-## Set an exit policy for this server. Each policy is of the form
-## "accept|reject ADDR[/MASK][:PORT]". If /MASK is omitted then
-## this policy just applies to the host given. Instead of giving
-## a host or network you can also use "*" to denote the universe
-## (0.0.0.0/0). PORT can be a single port number, an interval of
-## ports "FROM_PORT-TO_PORT", or "*". If PORT is omitted, that
-## means "*".
-##
-## For example, "reject 127.0.0.1:*,reject 192.168.1.0/24:*,accept
-## *:*" would reject any traffic destined for localhost and any
-## 192.168.1.* address, but accept anything else.
-##
-## This directive can be specified multiple times so you don’t
-## have to put it all on one line.
-##
-## See RFC 3330 for more details about internal and reserved IP
-## address space. Policies are considered first to last, and the
-## first match wins. If you want to _replace_ the default exit
-## policy, end your exit policy with either a reject *:* or an
-## accept *:*. Otherwise, you’re _augmenting_ (prepending to) the
-## default exit policy. The default exit policy is:
-## reject 0.0.0.0/8
-## reject 169.254.0.0/16
-## reject 127.0.0.0/8
-## reject 192.168.0.0/16
-## reject 10.0.0.0/8
-## reject 172.16.0.0/12
-## reject *:25
-## reject *:119
-## reject *:135-139
-## reject *:445
-## reject *:1214
-## reject *:4661-4666
-## reject *:6346-6429
-## reject *:6699
-## reject *:6881-6999
-## accept *:*
-#ExitPolicy policy,policy,...
-
-## If you have more than this number of onionskins queued for
-## decrypt, reject new ones. (Default: 100)
-#MaxOnionsPending NUM
-
-## Declare that this Tor server is controlled or administered by a
-## group or organization identical or similar to that of the other
-## named servers. When two servers both declare that they are in
-## the same ’family’, Tor clients will not use them in the same
-## circuit. (Each server only needs to list the other servers in
-## its family; it doesn’t need to list itself, but it won’t hurt.)
-#MyFamily nickname,nickname,...
-
-## Set the server’s nickname to ’name’.
-#Nickname name
-
-## If you set NoPublish 1, Tor will act as a server if you have an
-## ORPort defined, but it will not publish its descriptor to the
-## dirservers. This option is useful if you're testing out your
-## server, or if you're using alternate dirservers (e.g. for other
-## Tor networks such as Blossom). (Default: 0)
-#NoPublish 0|1
-
-## How many processes to use at once for decrypting onionskins.
-## (Default: 1)
-#NumCPUs num
-
-## Advertise this port to listen for connections from Tor clients
-## and servers.
-#ORPort PORT
-
-## Bind to this IP address to listen for connections from Tor
-## clients and servers. If you specify a port, bind to this port
-## rather than the one specified in ORPort. (Default: 0.0.0.0)
-#ORBindAddress IP[:PORT]
-
-## Whenever an outgoing connection tries to connect to one of a
-## given set of addresses, connect to target (an address:port
-## pair) instead. The address pattern is given in the same format
-## as for an exit policy. The address translation applies after
-## exit policies are applied. Multiple RedirectExit options can
-## be used: once any one has matched successfully, no subsequent
-## rules are considered. You can specify that no redirection is
-## to be performed on a given set of addresses by using the spe-
-## cial target string "pass", which prevents subsequent rules from
-## being considered.
-#RedirectExit pattern target
-
-## When we get a SIGINT and we're a server, we begin shutting
-## down: we close listeners and start refusing new circuits. After
-## NUM seconds, we exit. If we get a second SIGINT, we exit imme-
-## diately. (Default: 30 seconds)
-#ShutdownWaitLengthNUM
-
-## Every time the specified period elapses, Tor uploads its server
-## descriptors to the directory servers. This information is also
-## uploaded whenever it changes. (Default: 20 minutes)
-#DirPostPeriod N seconds|minutes|hours|days|weeks
-
-## A token bucket limits the average relayed bandwidth (server
-## traffic only, not client traffic) on this node to the specified
-## number of bytes per second.
-#RelayBandwidthRate N bytes|KB|MB|GB|TB
-
-## Limit the maximum token bucket size (also known as the burst) for
-## relayed traffic (server traffic only, not client traffic) to the
-## given number of bytes.
-#RelayBandwidthBurst N bytes|KB|MB|GB|TB
-
-## Never send more than the specified number of bytes in a given
-## accounting period, or receive more than that number in the
-## period. For example, with AccountingMax set to 1 GB, a server
-## could send 900 MB and receive 800 MB and continue running. It
-## will only hibernate once one of the two reaches 1 GB. When the
-## number of bytes is exhausted, Tor will hibernate until some
-## time in the next accounting period. To prevent all servers
-## from waking at the same time, Tor will also wait until a random
-## point in each period before waking up. If you have bandwidth
-## cost issues, enabling hibernation is preferable to setting a
-## low bandwidth, since it provides users with a collection of
-## fast servers that are up some of the time, which is more useful
-## than a set of slow servers that are always "available".
-#AccountingMax N bytes|KB|MB|GB|TB
-
-## Specify how long accounting periods last. If month is given,
-## each accounting period runs from the time HH:MM on the dayth
-## day of one month to the same day and time of the next. (The
-## day must be between 1 and 28.) If week is given, each account-
-## ing period runs from the time HH:MM of the dayth day of one
-## week to the same day and time of the next week, with Monday as
-## day 1 and Sunday as day 7. If day is given, each accounting
-## period runs from the time HH:MM each day to the same time on
-## the next day. All times are local, and given in 24-hour time.
-## (Defaults to "month 1 0:00".)
-#AccountingStart day|week|month [day] HH:MM
-
-
-## Section 4: Directory Server Options (for running your own Tor
-## network)
-
-## When this option is set to 1, Tor operates as an authoritative
-## directory server. Instead of caching the directory, it gener-
-## ates its own list of good servers, signs it, and sends that to
-## the clients. Unless the clients already have you listed as a
-## trusted directory, you probably do not want to set this option.
-## Please coordinate with the other admins at
-## tor-ops@freehaven.net if you think you should be a directory.
-#AuthoritativeDirectory 0|1
-
-## Advertise the directory service on this port.
-#DirPort PORT
-
-## Bind the directory service to this address. If you specify a
-## port, bind to this port rather than the one specified in DirPort.
-## (Default: 0.0.0.0)
-#DirBindAddress IP[:PORT]
-
-## Set an entrance policy for this server, to limit who can con-
-## nect to the directory ports. The policies have the same form
-## as exit policies above.
-#DirPolicy policy,policy,...
-
-## STRING is a command-separated list of Tor versions currently
-## believed to be safe. The list is included in each directory,
-## and nodes which pull down the directory learn whether they need
-## to upgrade. This option can appear multiple times: the values
-## from multiple lines are spliced together.
-#RecommendedVersions STRING
-
-
-## If set to 1, Tor will accept router descriptors with arbitrary
-## "Address" elements. Otherwise, if the address is not an IP or
-## is a private IP, it will reject the router descriptor. Defaults
-## to 0.
-#DirAllowPrivateAddresses 0|1
-
-## If set to 1, Tor tries to build circuits through all of the
-## servers it knows about, so it can tell which are up and which
-## are down. This option is only useful for authoritative direc-
-## tories, so you probably don't want to use it.
-#RunTesting 0|1
-
-## Section 5: Hidden Service Options (clients and servers)
-
-## Store data files for a hidden service in DIRECTORY. Every hid-
-## den service must have a separate directory. You may use this
-## option multiple times to specify multiple services.
-#HiddenServiceDir DIRECTORY
-
-## Configure a virtual port VIRTPORT for a hidden service. You
-## may use this option multiple times; each time applies to the
-## service using the most recent hiddenservicedir. By default,
-## this option maps the virtual port to the same port on
-## 127.0.0.1. You may override the target port, address, or both
-## by specifying a target of addr, port, or addr:port.
-#HiddenServicePort VIRTPORT [TARGET]
-
-## If possible, use the specified nodes as introduction points for
-## the hidden service. If this is left unset, Tor will be smart
-## and pick some reasonable ones; most people can leave this unset.
-#HiddenServiceNodes nickname,nickname,...
-
-## Do not use the specified nodes as introduction points for the
-## hidden service. In normal use there is no reason to set this.
-#HiddenServiceExcludeNodes nickname,nickname,...
-
-## Publish the given rendezvous service descriptor versions for the
-## hidden service.
-#HiddenServiceVersion 0,2
-
-## Every time the specified period elapses, Tor uploads any ren-
-## dezvous service descriptors to the directory servers. This
-## information is also uploaded whenever it changes.
-## (Default: 20 minutes)
-#RendPostPeriod N seconds|minutes|hours|days|weeks
-#
diff --git a/src/config/torrc.sample.in b/src/config/torrc.sample.in
index d0b1ee1591..f0c78ce5a9 100644
--- a/src/config/torrc.sample.in
+++ b/src/config/torrc.sample.in
@@ -1,5 +1,5 @@
## Configuration file for a typical Tor user
-## Last updated 12 April 2009 for Tor 0.2.1.14-rc.
+## Last updated 16 July 2009 for Tor 0.2.2.1-alpha.
## (May or may not work for much older or much newer versions of Tor.)
##
## Lines that begin with "## " try to explain what's going on. Lines
@@ -95,9 +95,22 @@ SocksListenAddress 127.0.0.1 # accept connections only from localhost
## Define these to limit how much relayed traffic you will allow. Your
## own traffic is still unthrottled. Note that RelayBandwidthRate must
-## be at least 20 KBytes.
-#RelayBandwidthRate 100 KBytes # Throttle traffic to 100KB/s (800Kbps)
-#RelayBandwidthBurst 200 KBytes # But allow bursts up to 200KB/s (1600Kbps)
+## be at least 20 KB.
+#RelayBandwidthRate 100 KB # Throttle traffic to 100KB/s (800Kbps)
+#RelayBandwidthBurst 200 KB # But allow bursts up to 200KB/s (1600Kbps)
+
+## Use these to restrict the maximum traffic per day, week, or month.
+## Note that this threshold applies to sent _and_ to received bytes,
+## not to their sum: Setting "4 GB" may allow up to 8 GB
+## total before hibernating.
+##
+## Set a maximum of 4 gigabytes each way per period.
+#AccountingMax 4 GB
+## Each period starts daily at midnight (AccountingMax is per day)
+#AccountingStart day 00:00
+## Each period starts on the 3rd of the month at 15:00 (AccountingMax
+## is per month)
+#AccountingStart month 3 15:00
## Contact info to be published in the directory, so we can contact you
## if your relay is misconfigured or something else goes wrong. Google
@@ -116,8 +129,9 @@ SocksListenAddress 127.0.0.1 # accept connections only from localhost
#DirListenAddress 0.0.0.0:9091
## Uncomment to return an arbitrary blob of html on your DirPort. Now you
## can explain what Tor is if anybody wonders why your IP address is
-## contacting them. See contrib/tor-exit-notice.html for a sample.
-#DirPortFrontPage /etc/tor/exit-notice.html
+## contacting them. See contrib/tor-exit-notice.html in Tor's source
+## distribution for a sample.
+#DirPortFrontPage @CONFDIR@/tor-exit-notice.html
## Uncomment this if you run more than one Tor relay, and add the identity
## key fingerprint of each Tor relay you control, even if they're on
diff --git a/src/or/Makefile.am b/src/or/Makefile.am
index ad2476ff15..a9ac3cdee1 100644
--- a/src/or/Makefile.am
+++ b/src/or/Makefile.am
@@ -1,8 +1,5 @@
-TESTS = test
-
-noinst_PROGRAMS = test
-
bin_PROGRAMS = tor
+noinst_LIBRARIES = libtor.a
if BUILD_NT_SERVICES
tor_platform_source=ntmain.c
@@ -10,18 +7,30 @@ else
tor_platform_source=
endif
-EXTRA_DIST=ntmain.c
+EXTRA_DIST=ntmain.c or_sha1.i
+
+if USE_EXTERNAL_EVDNS
+evdns_source=
+else
+evdns_source=eventdns.c
+endif
-tor_SOURCES = buffers.c circuitbuild.c circuitlist.c \
+libtor_a_SOURCES = buffers.c circuitbuild.c circuitlist.c \
circuituse.c command.c config.c \
connection.c connection_edge.c connection_or.c control.c \
cpuworker.c directory.c dirserv.c dirvote.c \
dns.c dnsserv.c geoip.c hibernate.c main.c $(tor_platform_source) \
+ microdesc.c \
networkstatus.c onion.c policies.c \
reasons.c relay.c rendcommon.c rendclient.c rendmid.c \
rendservice.c rephist.c router.c routerlist.c routerparse.c \
- eventdns.c \
- tor_main.c
+ $(evdns_source) config_codedigest.c
+
+#libtor_a_LIBADD = ../common/libor.a ../common/libor-crypto.a \
+# ../common/libor-event.a
+
+
+tor_SOURCES = tor_main.c
AM_CPPFLAGS = -DSHARE_DATADIR="\"$(datadir)\"" \
-DLOCALSTATEDIR="\"$(localstatedir)\"" \
@@ -32,76 +41,48 @@ AM_CPPFLAGS = -DSHARE_DATADIR="\"$(datadir)\"" \
# matters a lot there, and is quite hard to debug if you forget to do it.
tor_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ @TOR_LDFLAGS_libevent@
-tor_LDADD = ../common/libor.a ../common/libor-crypto.a \
- -lz @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@
-test_SOURCES = buffers.c circuitbuild.c circuitlist.c \
- circuituse.c command.c config.c \
- connection.c connection_edge.c connection_or.c control.c \
- cpuworker.c directory.c dirserv.c dirvote.c \
- dns.c dnsserv.c geoip.c hibernate.c main.c $(tor_platform_source) \
- networkstatus.c onion.c policies.c \
- reasons.c relay.c rendcommon.c rendclient.c rendmid.c \
- rendservice.c rephist.c router.c routerlist.c routerparse.c \
- eventdns.c \
- test_data.c test.c
+tor_LDADD = ./libtor.a ../common/libor.a ../common/libor-crypto.a \
+ ../common/libor-event.a \
+ @TOR_ZLIB_LIBS@ -lm @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@
-test_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
- @TOR_LDFLAGS_libevent@
-test_LDADD = ../common/libor.a ../common/libor-crypto.a \
- -lz @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@
+noinst_HEADERS = buffers.h circuitbuild.h circuitlist.h circuituse.h \
+ command.h config.h connection_edge.h connection.h connection_or.h \
+ control.h cpuworker.h directory.h dirserv.h dirvote.h dns.h \
+ dnsserv.h geoip.h hibernate.h main.h microdesc.h networkstatus.h \
+ ntmain.h onion.h policies.h reasons.h relay.h rendclient.h \
+ rendcommon.h rendmid.h rendservice.h rephist.h router.h routerlist.h \
+ routerparse.h or.h eventdns.h eventdns_tor.h micro-revision.i
-noinst_HEADERS = or.h eventdns.h eventdns_tor.h micro-revision.i
+config_codedigest.o: or_sha1.i
tor_main.o: micro-revision.i
micro-revision.i: FORCE
- @svkdir=$$SVKROOT; \
- if test "x$$svkdir" = x ; then \
- svkdir=$$HOME/.svk; \
- fi; \
- if test -d ../../.git && test -x "`which git 2>&1;true`" ; then \
- if test -d ../../.git/svn && test -x "`which git-svn 2>&1;true`" ; then \
- git-svn info ../../README | \
- sed -n 's/^Revision: \([0-9][0-9]*\).*/"\1"/p' \
- > micro-revision.tmp \
- || true; \
- fi; \
- elif test -d ../../.svn && test -x "`which svn 2>&1;true`" ; then \
- svn info ../.. | \
- sed -n 's/^Revision: \([0-9][0-9]*\).*/"\1"/p' > micro-revision.tmp \
- || true; \
- elif test -x "`which svk 2>&1;true`" && test -d $$svkdir/local; then \
- location=../..; \
- rev=x; \
- while test x$$rev = xx; do \
- x=`svk info $$location | \
- sed -n 's/^Mirrored From:.*, Rev\. \([0-9][0-9]*\)/\1/p'`; \
- if test x$$x != x; then \
- rev=$$x; \
- break; \
- else \
- loc=`svk info $$location | \
- sed -n 's/^Copied From: \(.*\), Rev\. [0-9][0-9]*/\1/p' | \
- head -1`; \
- if test x$$loc = x; then \
- break; \
- else \
- location=/$$loc; \
- fi; \
- fi; \
- done; \
- if test x$$rev != xx; then \
- echo \"$$rev\" > micro-revision.tmp; \
- fi; \
- fi; \
- if test ! -f micro-revision.tmp ; then \
- if test ! -f micro-revision.i ; then \
- echo '""' > micro-revision.i; \
- fi; \
- elif test ! -f micro-revision.i || \
+ @rm -f micro-revision.tmp; \
+ if test -d ../../.git && test -x "`which git 2>&1;true`"; then \
+ HASH="`git rev-parse --short=16 HEAD`"; \
+ echo \"$$HASH\" > micro-revision.tmp; \
+ fi; \
+ if test ! -f micro-revision.tmp ; then \
+ if test ! -f micro-revision.i ; then \
+ echo '""' > micro-revision.i; \
+ fi; \
+ elif test ! -f micro-revision.i || \
test x"`cat micro-revision.tmp`" != x"`cat micro-revision.i`"; then \
- mv micro-revision.tmp micro-revision.i; \
+ mv micro-revision.tmp micro-revision.i; \
fi; true
+or_sha1.i: $(tor_SOURCES)
+ if test "@SHA1SUM@" != none; then \
+ @SHA1SUM@ $(tor_SOURCES) | @SED@ -n 's/^\(.*\)$$/"\1\\n"/p' > or_sha1.i; \
+ elif test "@OPENSSL@" != none; then \
+ @OPENSSL@ sha1 $(tor_SOURCES) | @SED@ -n 's/SHA1(\(.*\))= \(.*\)/"\2 \1\\n"/p' > or_sha1.i; \
+ else \
+ rm or_sha1.i; \
+ touch or_sha1.i; \
+ fi
+
+CLEANFILES = micro-revision.i
+
#Dummy target to ensure that micro-revision.i _always_ gets built.
FORCE:
diff --git a/src/or/buffers.c b/src/or/buffers.c
index f26c202198..f84fb45c64 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -12,6 +12,14 @@
**/
#define BUFFERS_PRIVATE
#include "or.h"
+#include "buffers.h"
+#include "config.h"
+#include "connection_edge.h"
+#include "connection_or.h"
+#include "control.h"
+#include "reasons.h"
+#include "../common/util.h"
+#include "../common/torlog.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -145,10 +153,13 @@ get_freelist(size_t alloc)
/** Deallocate a chunk or put it on a freelist */
static void
-chunk_free(chunk_t *chunk)
+chunk_free_unchecked(chunk_t *chunk)
{
- size_t alloc = CHUNK_ALLOC_SIZE(chunk->memlen);
- chunk_freelist_t *freelist = get_freelist(alloc);
+ size_t alloc;
+ chunk_freelist_t *freelist;
+
+ alloc = CHUNK_ALLOC_SIZE(chunk->memlen);
+ freelist = get_freelist(alloc);
if (freelist && freelist->cur_length < freelist->max_length) {
chunk->next = freelist->head;
freelist->head = chunk;
@@ -193,7 +204,7 @@ chunk_new_with_alloc_size(size_t alloc)
}
#else
static void
-chunk_free(chunk_t *chunk)
+chunk_free_unchecked(chunk_t *chunk)
{
tor_free(chunk);
}
@@ -259,13 +270,22 @@ buf_shrink_freelists(int free_all)
int n_to_free = free_all ? freelists[i].cur_length :
(freelists[i].lowest_length - slack);
int n_to_skip = freelists[i].cur_length - n_to_free;
+ int orig_length = freelists[i].cur_length;
int orig_n_to_free = n_to_free, n_freed=0;
int orig_n_to_skip = n_to_skip;
int new_length = n_to_skip;
chunk_t **chp = &freelists[i].head;
chunk_t *chunk;
while (n_to_skip) {
- tor_assert((*chp)->next);
+ if (! (*chp)->next) {
+ log_warn(LD_BUG, "I wanted to skip %d chunks in the freelist for "
+ "%d-byte chunks, but only found %d. (Length %d)",
+ orig_n_to_skip, (int)freelists[i].alloc_size,
+ orig_n_to_skip-n_to_skip, freelists[i].cur_length);
+ assert_freelist_ok(&freelists[i]);
+ goto done;
+ }
+ // tor_assert((*chp)->next);
chp = &(*chp)->next;
--n_to_skip;
}
@@ -290,13 +310,15 @@ buf_shrink_freelists(int free_all)
}
// tor_assert(!n_to_free);
freelists[i].cur_length = new_length;
- log_info(LD_MM, "Cleaned freelist for %d-byte chunks: kept %d, "
- "dropped %d.",
- (int)freelists[i].alloc_size, orig_n_to_skip, orig_n_to_free);
+ log_info(LD_MM, "Cleaned freelist for %d-byte chunks: original "
+ "length %d, kept %d, dropped %d.",
+ (int)freelists[i].alloc_size, orig_length,
+ orig_n_to_skip, orig_n_to_free);
}
freelists[i].lowest_length = freelists[i].cur_length;
assert_freelist_ok(&freelists[i]);
}
+ done:
enable_control_logging();
#else
(void) free_all;
@@ -404,7 +426,7 @@ buf_pullup(buf_t *buf, size_t bytes, int nulterminate)
dest->next = src->next;
if (buf->tail == src)
buf->tail = dest;
- chunk_free(src);
+ chunk_free_unchecked(src);
} else {
memcpy(CHUNK_WRITE_PTR(dest), src->data, n);
dest->datalen += n;
@@ -450,7 +472,7 @@ buf_remove_from_front(buf_t *buf, size_t n)
buf->head = victim->next;
if (buf->tail == victim)
buf->tail = NULL;
- chunk_free(victim);
+ chunk_free_unchecked(victim);
}
}
check();
@@ -484,7 +506,7 @@ buf_clear(buf_t *buf)
buf->datalen = 0;
for (chunk = buf->head; chunk; chunk = next) {
next = chunk->next;
- chunk_free(chunk);
+ chunk_free_unchecked(chunk);
}
buf->head = buf->tail = NULL;
}
@@ -523,6 +545,8 @@ buf_slack(const buf_t *buf)
void
buf_free(buf_t *buf)
{
+ if (!buf)
+ return;
buf_clear(buf);
buf->magic = 0xdeadbeef;
tor_free(buf);
@@ -1275,6 +1299,43 @@ fetch_from_buf_http(buf_t *buf,
return 1;
}
+/**
+ * Wait this many seconds before warning the user about using SOCKS unsafely
+ * again (requires that WarnUnsafeSocks is turned on). */
+#define SOCKS_WARN_INTERVAL 5
+
+/** Warn that the user application has made an unsafe socks request using
+ * protocol <b>socks_protocol</b> on port <b>port</b>. Don't warn more than
+ * once per SOCKS_WARN_INTERVAL, unless <b>safe_socks</b> is set. */
+static void
+log_unsafe_socks_warning(int socks_protocol, const char *address,
+ uint16_t port, int safe_socks)
+{
+ static ratelim_t socks_ratelim = RATELIM_INIT(SOCKS_WARN_INTERVAL);
+
+ or_options_t *options = get_options();
+ char *m = NULL;
+ if (! options->WarnUnsafeSocks)
+ return;
+ if (safe_socks || (m = rate_limit_log(&socks_ratelim, approx_time()))) {
+ log_warn(LD_APP,
+ "Your application (using socks%d to port %d) is giving "
+ "Tor only an IP address. Applications that do DNS resolves "
+ "themselves may leak information. Consider using Socks4A "
+ "(e.g. via privoxy or socat) instead. For more information, "
+ "please see https://wiki.torproject.org/TheOnionRouter/"
+ "TorFAQ#SOCKSAndDNS.%s%s",
+ socks_protocol,
+ (int)port,
+ safe_socks ? " Rejecting." : "",
+ m ? m : "");
+ tor_free(m);
+ }
+ control_event_client_status(LOG_WARN,
+ "DANGEROUS_SOCKS PROTOCOL=SOCKS%d ADDRESS=%s:%d",
+ socks_protocol, address, (int)port);
+}
+
/** There is a (possibly incomplete) socks handshake on <b>buf</b>, of one
* of the forms
* - socks4: "socksheader username\\0"
@@ -1313,10 +1374,6 @@ fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
char *next, *startaddr;
struct in_addr in;
- /* If the user connects with socks4 or the wrong variant of socks5,
- * then log a warning to let him know that it might be unwise. */
- static int have_warned_about_unsafe_socks = 0;
-
if (buf->datalen < 2) /* version and another byte */
return 0;
@@ -1396,21 +1453,8 @@ fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
req->port = ntohs(get_uint16(buf->head->data+4+addrlen));
buf_remove_from_front(buf, 6+addrlen);
if (req->command != SOCKS_COMMAND_RESOLVE_PTR &&
- !addressmap_have_mapping(req->address,0) &&
- !have_warned_about_unsafe_socks) {
- log_warn(LD_APP,
- "Your application (using socks5 to port %d) is giving "
- "Tor only an IP address. Applications that do DNS resolves "
- "themselves may leak information. Consider using Socks4A "
- "(e.g. via privoxy or socat) instead. For more information, "
- "please see http://wiki.noreply.org/noreply/TheOnionRouter/"
- "TorFAQ#SOCKSAndDNS.%s", req->port,
- safe_socks ? " Rejecting." : "");
- /*have_warned_about_unsafe_socks = 1;*/
- /*(for now, warn every time)*/
- control_event_client_status(LOG_WARN,
- "DANGEROUS_SOCKS PROTOCOL=SOCKS5 ADDRESS=%s:%d",
- req->address, req->port);
+ !addressmap_have_mapping(req->address,0)) {
+ log_unsafe_socks_warning(5, req->address, req->port, safe_socks);
if (safe_socks)
return -1;
}
@@ -1475,8 +1519,8 @@ fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
return -1;
}
- req->port = ntohs(*(uint16_t*)(buf->head->data+2));
- destip = ntohl(*(uint32_t*)(buf->head->data+4));
+ req->port = ntohs(get_uint16(buf->head->data+2));
+ destip = ntohl(get_uint32(buf->head->data+4));
if ((!req->port && req->command!=SOCKS_COMMAND_RESOLVE) || !destip) {
log_warn(LD_APP,"socks4: Port or DestIP is zero. Rejecting.");
return -1;
@@ -1491,7 +1535,8 @@ fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
return -1;
}
log_debug(LD_APP,
- "socks4: successfully read destip (%s)", safe_str(tmpbuf));
+ "socks4: successfully read destip (%s)",
+ safe_str_client(tmpbuf));
socks4_prot = socks4;
}
@@ -1509,20 +1554,9 @@ fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
startaddr = NULL;
if (socks4_prot != socks4a &&
- !addressmap_have_mapping(tmpbuf,0) &&
- !have_warned_about_unsafe_socks) {
- log_warn(LD_APP,
- "Your application (using socks4 to port %d) is giving Tor "
- "only an IP address. Applications that do DNS resolves "
- "themselves may leak information. Consider using Socks4A "
- "(e.g. via privoxy or socat) instead. For more information, "
- "please see http://wiki.noreply.org/noreply/TheOnionRouter/"
- "TorFAQ#SOCKSAndDNS.%s", req->port,
- safe_socks ? " Rejecting." : "");
- /*have_warned_about_unsafe_socks = 1;*/ /*(for now, warn every time)*/
- control_event_client_status(LOG_WARN,
- "DANGEROUS_SOCKS PROTOCOL=SOCKS4 ADDRESS=%s:%d",
- tmpbuf, req->port);
+ !addressmap_have_mapping(tmpbuf,0)) {
+ log_unsafe_socks_warning(4, tmpbuf, req->port, safe_socks);
+
if (safe_socks)
return -1;
}
@@ -1614,6 +1648,132 @@ fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
}
}
+/** Inspect a reply from SOCKS server stored in <b>buf</b> according
+ * to <b>state</b>, removing the protocol data upon success. Return 0 on
+ * incomplete response, 1 on success and -1 on error, in which case
+ * <b>reason</b> is set to a descriptive message (free() when finished
+ * with it).
+ *
+ * As a special case, 2 is returned when user/pass is required
+ * during SOCKS5 handshake and user/pass is configured.
+ */
+int
+fetch_from_buf_socks_client(buf_t *buf, int state, char **reason)
+{
+ unsigned char *data;
+ size_t addrlen;
+
+ if (buf->datalen < 2)
+ return 0;
+
+ buf_pullup(buf, 128, 0);
+ tor_assert(buf->head && buf->head->datalen >= 2);
+
+ data = (unsigned char *) buf->head->data;
+
+ switch (state) {
+ case PROXY_SOCKS4_WANT_CONNECT_OK:
+ /* Wait for the complete response */
+ if (buf->head->datalen < 8)
+ return 0;
+
+ if (data[1] != 0x5a) {
+ *reason = tor_strdup(socks4_response_code_to_string(data[1]));
+ return -1;
+ }
+
+ /* Success */
+ buf_remove_from_front(buf, 8);
+ return 1;
+
+ case PROXY_SOCKS5_WANT_AUTH_METHOD_NONE:
+ /* we don't have any credentials */
+ if (data[1] != 0x00) {
+ *reason = tor_strdup("server doesn't support any of our "
+ "available authentication methods");
+ return -1;
+ }
+
+ log_info(LD_NET, "SOCKS 5 client: continuing without authentication");
+ buf_clear(buf);
+ return 1;
+
+ case PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929:
+ /* we have a username and password. return 1 if we can proceed without
+ * providing authentication, or 2 otherwise. */
+ switch (data[1]) {
+ case 0x00:
+ log_info(LD_NET, "SOCKS 5 client: we have auth details but server "
+ "doesn't require authentication.");
+ buf_clear(buf);
+ return 1;
+ case 0x02:
+ log_info(LD_NET, "SOCKS 5 client: need authentication.");
+ buf_clear(buf);
+ return 2;
+ /* fall through */
+ }
+
+ *reason = tor_strdup("server doesn't support any of our available "
+ "authentication methods");
+ return -1;
+
+ case PROXY_SOCKS5_WANT_AUTH_RFC1929_OK:
+ /* handle server reply to rfc1929 authentication */
+ if (data[1] != 0x00) {
+ *reason = tor_strdup("authentication failed");
+ return -1;
+ }
+
+ log_info(LD_NET, "SOCKS 5 client: authentication successful.");
+ buf_clear(buf);
+ return 1;
+
+ case PROXY_SOCKS5_WANT_CONNECT_OK:
+ /* response is variable length. BND.ADDR, etc, isn't needed
+ * (don't bother with buf_pullup()), but make sure to eat all
+ * the data used */
+
+ /* wait for address type field to arrive */
+ if (buf->datalen < 4)
+ return 0;
+
+ switch (data[3]) {
+ case 0x01: /* ip4 */
+ addrlen = 4;
+ break;
+ case 0x04: /* ip6 */
+ addrlen = 16;
+ break;
+ case 0x03: /* fqdn (can this happen here?) */
+ if (buf->datalen < 5)
+ return 0;
+ addrlen = 1 + data[4];
+ break;
+ default:
+ *reason = tor_strdup("invalid response to connect request");
+ return -1;
+ }
+
+ /* wait for address and port */
+ if (buf->datalen < 6 + addrlen)
+ return 0;
+
+ if (data[1] != 0x00) {
+ *reason = tor_strdup(socks5_response_code_to_string(data[1]));
+ return -1;
+ }
+
+ buf_remove_from_front(buf, 6 + addrlen);
+ return 1;
+ }
+
+ /* shouldn't get here... */
+ tor_assert(0);
+
+ return -1;
+}
+
/** Return 1 iff buf looks more like it has an (obsolete) v0 controller
* command on it than any valid v1 controller command. */
int
diff --git a/src/or/buffers.h b/src/or/buffers.h
new file mode 100644
index 0000000000..8fd403d954
--- /dev/null
+++ b/src/or/buffers.h
@@ -0,0 +1,58 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file buffers.h
+ * \brief Header file for buffers.c.
+ **/
+
+#ifndef _TOR_BUFFERS_H
+#define _TOR_BUFFERS_H
+
+buf_t *buf_new(void);
+buf_t *buf_new_with_capacity(size_t size);
+void buf_free(buf_t *buf);
+void buf_clear(buf_t *buf);
+void buf_shrink(buf_t *buf);
+void buf_shrink_freelists(int free_all);
+void buf_dump_freelist_sizes(int severity);
+
+size_t buf_datalen(const buf_t *buf);
+size_t buf_allocation(const buf_t *buf);
+size_t buf_slack(const buf_t *buf);
+
+int read_to_buf(int s, size_t at_most, buf_t *buf, int *reached_eof,
+ int *socket_error);
+int read_to_buf_tls(tor_tls_t *tls, size_t at_most, buf_t *buf);
+
+int flush_buf(int s, buf_t *buf, size_t sz, size_t *buf_flushlen);
+int flush_buf_tls(tor_tls_t *tls, buf_t *buf, size_t sz, size_t *buf_flushlen);
+
+int write_to_buf(const char *string, size_t string_len, buf_t *buf);
+int write_to_buf_zlib(buf_t *buf, tor_zlib_state_t *state,
+ const char *data, size_t data_len, int done);
+int move_buf_to_buf(buf_t *buf_out, buf_t *buf_in, size_t *buf_flushlen);
+int fetch_from_buf(char *string, size_t string_len, buf_t *buf);
+int fetch_var_cell_from_buf(buf_t *buf, var_cell_t **out, int linkproto);
+int fetch_from_buf_http(buf_t *buf,
+ char **headers_out, size_t max_headerlen,
+ char **body_out, size_t *body_used, size_t max_bodylen,
+ int force_complete);
+int fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
+ int log_sockstype, int safe_socks);
+int fetch_from_buf_socks_client(buf_t *buf, int state, char **reason);
+int fetch_from_buf_line(buf_t *buf, char *data_out, size_t *data_len);
+
+int peek_buf_has_control0_command(buf_t *buf);
+
+void assert_buf_ok(buf_t *buf);
+
+#ifdef BUFFERS_PRIVATE
+int buf_find_string_offset(const buf_t *buf, const char *s, size_t n);
+#endif
+
+#endif
+
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 0ec5aaef58..2fe750ea5b 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -9,9 +9,45 @@
* \brief The actual details of building circuits.
**/
+#define CIRCUIT_PRIVATE
+
#include "or.h"
+#include "circuitbuild.h"
+#include "circuitlist.h"
+#include "circuituse.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_edge.h"
+#include "connection_or.h"
+#include "control.h"
+#include "directory.h"
+#include "main.h"
+#include "networkstatus.h"
+#include "onion.h"
+#include "policies.h"
+#include "relay.h"
+#include "rephist.h"
+#include "router.h"
+#include "routerlist.h"
+#include "routerparse.h"
+#include "crypto.h"
+#undef log
+#include <math.h>
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+#define CBT_BIN_TO_MS(bin) ((bin)*CBT_BIN_WIDTH + (CBT_BIN_WIDTH/2))
/********* START VARIABLES **********/
+/** Global list of circuit build times */
+// FIXME: Add this as a member for entry_guard_t instead of global?
+// Then we could do per-guard statistics, as guards are likely to
+// vary in their own latency. The downside of this is that guards
+// can change frequently, so we'd be building a lot more circuits
+// most likely.
+circuit_build_times_t circ_times;
/** A global list of all circuits at this hop. */
extern circuit_t *global_circuitlist;
@@ -47,6 +83,10 @@ static smartlist_t *entry_guards = NULL;
* and those changes need to be flushed to disk. */
static int entry_guards_dirty = 0;
+/** If set, we're running the unit tests: we should avoid clobbering
+ * our state file or accessing get_options() or get_or_state() */
+static int unit_tests = 0;
+
/********* END VARIABLES ************/
static int circuit_deliver_create_cell(circuit_t *circ,
@@ -59,6 +99,1236 @@ static int onion_append_hop(crypt_path_t **head_ptr, extend_info_t *choice);
static void entry_guards_changed(void);
+static int
+circuit_build_times_disabled(void)
+{
+ if (unit_tests) {
+ return 0;
+ } else {
+ int consensus_disabled = networkstatus_get_param(NULL, "cbtdisabled",
+ 0);
+ int config_disabled = !get_options()->LearnCircuitBuildTimeout;
+ int dirauth_disabled = get_options()->AuthoritativeDir;
+ int state_disabled = (get_or_state()->LastWritten == -1);
+
+ if (consensus_disabled || config_disabled || dirauth_disabled ||
+ state_disabled) {
+ log_info(LD_CIRC,
+ "CircuitBuildTime learning is disabled. "
+ "Consensus=%d, Config=%d, AuthDir=%d, StateFile=%d",
+ consensus_disabled, config_disabled, dirauth_disabled,
+ state_disabled);
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+}
+
+static int32_t
+circuit_build_times_max_timeouts(void)
+{
+ int32_t num = networkstatus_get_param(NULL, "cbtmaxtimeouts",
+ CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT);
+ return num;
+}
+
+static int32_t
+circuit_build_times_default_num_xm_modes(void)
+{
+ int32_t num = networkstatus_get_param(NULL, "cbtnummodes",
+ CBT_DEFAULT_NUM_XM_MODES);
+ return num;
+}
+
+static int32_t
+circuit_build_times_min_circs_to_observe(void)
+{
+ int32_t num = networkstatus_get_param(NULL, "cbtmincircs",
+ CBT_DEFAULT_MIN_CIRCUITS_TO_OBSERVE);
+ return num;
+}
+
+/** Return true iff <b>cbt</b> has recorded enough build times that we
+ * want to start acting on the timeout it implies. */
+int
+circuit_build_times_enough_to_compute(circuit_build_times_t *cbt)
+{
+ return cbt->total_build_times >= circuit_build_times_min_circs_to_observe();
+}
+
+double
+circuit_build_times_quantile_cutoff(void)
+{
+ int32_t num = networkstatus_get_param(NULL, "cbtquantile",
+ CBT_DEFAULT_QUANTILE_CUTOFF);
+ return num/100.0;
+}
+
+static double
+circuit_build_times_close_quantile(void)
+{
+ int32_t num = networkstatus_get_param(NULL, "cbtclosequantile",
+ CBT_DEFAULT_CLOSE_QUANTILE);
+
+ return num/100.0;
+}
+
+static int32_t
+circuit_build_times_test_frequency(void)
+{
+ int32_t num = networkstatus_get_param(NULL, "cbttestfreq",
+ CBT_DEFAULT_TEST_FREQUENCY);
+ return num;
+}
+
+static int32_t
+circuit_build_times_min_timeout(void)
+{
+ int32_t num = networkstatus_get_param(NULL, "cbtmintimeout",
+ CBT_DEFAULT_TIMEOUT_MIN_VALUE);
+ return num;
+}
+
+int32_t
+circuit_build_times_initial_timeout(void)
+{
+ int32_t num = networkstatus_get_param(NULL, "cbtinitialtimeout",
+ CBT_DEFAULT_TIMEOUT_INITIAL_VALUE);
+ return num;
+}
+
+static int32_t
+circuit_build_times_recent_circuit_count(void)
+{
+ int32_t num = networkstatus_get_param(NULL, "cbtrecentcount",
+ CBT_DEFAULT_RECENT_CIRCUITS);
+ return num;
+}
+
+/**
+ * This function is called when we get a consensus update.
+ *
+ * It checks to see if we have changed any consensus parameters
+ * that require reallocation or discard of previous stats.
+ */
+void
+circuit_build_times_new_consensus_params(circuit_build_times_t *cbt,
+ networkstatus_t *ns)
+{
+ int32_t num = networkstatus_get_param(ns, "cbtrecentcount",
+ CBT_DEFAULT_RECENT_CIRCUITS);
+
+ if (num > 0 && num != cbt->liveness.num_recent_circs) {
+ int8_t *recent_circs;
+ log_notice(LD_CIRC, "Changing recent timeout size from %d to %d",
+ cbt->liveness.num_recent_circs, num);
+
+ tor_assert(cbt->liveness.timeouts_after_firsthop);
+
+ /*
+ * Technically this is a circular array that we are reallocating
+ * and memcopying. However, since it only consists of either 1s
+ * or 0s, and is only used in a statistical test to determine when
+ * we should discard our history after a sufficient number of 1's
+ * have been reached, it is fine if order is not preserved or
+ * elements are lost.
+ *
+ * cbtrecentcount should only be changing in cases of severe network
+ * distress anyway, so memory correctness here is paramount over
+ * doing acrobatics to preserve the array.
+ */
+ recent_circs = tor_malloc_zero(sizeof(int8_t)*num);
+ memcpy(recent_circs, cbt->liveness.timeouts_after_firsthop,
+ sizeof(int8_t)*MIN(num, cbt->liveness.num_recent_circs));
+
+ // Adjust the index if it needs it.
+ if (num < cbt->liveness.num_recent_circs) {
+ cbt->liveness.after_firsthop_idx = MIN(num-1,
+ cbt->liveness.after_firsthop_idx);
+ }
+
+ tor_free(cbt->liveness.timeouts_after_firsthop);
+ cbt->liveness.timeouts_after_firsthop = recent_circs;
+ cbt->liveness.num_recent_circs = num;
+ }
+}
+
+/** Make a note that we're running unit tests (rather than running Tor
+ * itself), so we avoid clobbering our state file. */
+void
+circuitbuild_running_unit_tests(void)
+{
+ unit_tests = 1;
+}
+
+/**
+ * Return the initial default or configured timeout in milliseconds
+ */
+static double
+circuit_build_times_get_initial_timeout(void)
+{
+ double timeout;
+ if (!unit_tests && get_options()->CircuitBuildTimeout) {
+ timeout = get_options()->CircuitBuildTimeout*1000;
+ if (timeout < circuit_build_times_min_timeout()) {
+ log_warn(LD_CIRC, "Config CircuitBuildTimeout too low. Setting to %ds",
+ circuit_build_times_min_timeout()/1000);
+ timeout = circuit_build_times_min_timeout();
+ }
+ } else {
+ timeout = circuit_build_times_initial_timeout();
+ }
+ return timeout;
+}
+
+/**
+ * Reset the build time state.
+ *
+ * Leave estimated parameters, timeout and network liveness intact
+ * for future use.
+ */
+void
+circuit_build_times_reset(circuit_build_times_t *cbt)
+{
+ memset(cbt->circuit_build_times, 0, sizeof(cbt->circuit_build_times));
+ cbt->total_build_times = 0;
+ cbt->build_times_idx = 0;
+ cbt->have_computed_timeout = 0;
+}
+
+/**
+ * Initialize the buildtimes structure for first use.
+ *
+ * Sets the initial timeout values based on either the config setting,
+ * the consensus param, or the default (CBT_DEFAULT_TIMEOUT_INITIAL_VALUE).
+ */
+void
+circuit_build_times_init(circuit_build_times_t *cbt)
+{
+ memset(cbt, 0, sizeof(*cbt));
+ cbt->liveness.num_recent_circs = circuit_build_times_recent_circuit_count();
+ cbt->liveness.timeouts_after_firsthop = tor_malloc_zero(sizeof(int8_t)*
+ cbt->liveness.num_recent_circs);
+ cbt->close_ms = cbt->timeout_ms = circuit_build_times_get_initial_timeout();
+ control_event_buildtimeout_set(cbt, BUILDTIMEOUT_SET_EVENT_RESET);
+}
+
+#if 0
+/**
+ * Rewind our build time history by n positions.
+ */
+static void
+circuit_build_times_rewind_history(circuit_build_times_t *cbt, int n)
+{
+ int i = 0;
+
+ cbt->build_times_idx -= n;
+ cbt->build_times_idx %= CBT_NCIRCUITS_TO_OBSERVE;
+
+ for (i = 0; i < n; i++) {
+ cbt->circuit_build_times[(i+cbt->build_times_idx)
+ %CBT_NCIRCUITS_TO_OBSERVE]=0;
+ }
+
+ if (cbt->total_build_times > n) {
+ cbt->total_build_times -= n;
+ } else {
+ cbt->total_build_times = 0;
+ }
+
+ log_info(LD_CIRC,
+ "Rewound history by %d places. Current index: %d. "
+ "Total: %d", n, cbt->build_times_idx, cbt->total_build_times);
+}
+#endif
+
+/**
+ * Add a new build time value <b>time</b> to the set of build times. Time
+ * units are milliseconds.
+ *
+ * circuit_build_times <b>cbt</a> is a circular array, so loop around when
+ * array is full.
+ */
+int
+circuit_build_times_add_time(circuit_build_times_t *cbt, build_time_t time)
+{
+ if (time <= 0 || time > CBT_BUILD_TIME_MAX) {
+ log_warn(LD_BUG, "Circuit build time is too large (%u)."
+ "This is probably a bug.", time);
+ tor_fragile_assert();
+ return -1;
+ }
+
+ log_debug(LD_CIRC, "Adding circuit build time %u", time);
+
+ cbt->circuit_build_times[cbt->build_times_idx] = time;
+ cbt->build_times_idx = (cbt->build_times_idx + 1) % CBT_NCIRCUITS_TO_OBSERVE;
+ if (cbt->total_build_times < CBT_NCIRCUITS_TO_OBSERVE)
+ cbt->total_build_times++;
+
+ if ((cbt->total_build_times % CBT_SAVE_STATE_EVERY) == 0) {
+ /* Save state every n circuit builds */
+ if (!unit_tests && !get_options()->AvoidDiskWrites)
+ or_state_mark_dirty(get_or_state(), 0);
+ }
+
+ return 0;
+}
+
+/**
+ * Return maximum circuit build time
+ */
+static build_time_t
+circuit_build_times_max(circuit_build_times_t *cbt)
+{
+ int i = 0;
+ build_time_t max_build_time = 0;
+ for (i = 0; i < CBT_NCIRCUITS_TO_OBSERVE; i++) {
+ if (cbt->circuit_build_times[i] > max_build_time
+ && cbt->circuit_build_times[i] != CBT_BUILD_ABANDONED)
+ max_build_time = cbt->circuit_build_times[i];
+ }
+ return max_build_time;
+}
+
+#if 0
+/** Return minimum circuit build time */
+build_time_t
+circuit_build_times_min(circuit_build_times_t *cbt)
+{
+ int i = 0;
+ build_time_t min_build_time = CBT_BUILD_TIME_MAX;
+ for (i = 0; i < CBT_NCIRCUITS_TO_OBSERVE; i++) {
+ if (cbt->circuit_build_times[i] && /* 0 <-> uninitialized */
+ cbt->circuit_build_times[i] < min_build_time)
+ min_build_time = cbt->circuit_build_times[i];
+ }
+ if (min_build_time == CBT_BUILD_TIME_MAX) {
+ log_warn(LD_CIRC, "No build times less than CBT_BUILD_TIME_MAX!");
+ }
+ return min_build_time;
+}
+#endif
+
+/**
+ * Calculate and return a histogram for the set of build times.
+ *
+ * Returns an allocated array of histrogram bins representing
+ * the frequency of index*CBT_BIN_WIDTH millisecond
+ * build times. Also outputs the number of bins in nbins.
+ *
+ * The return value must be freed by the caller.
+ */
+static uint32_t *
+circuit_build_times_create_histogram(circuit_build_times_t *cbt,
+ build_time_t *nbins)
+{
+ uint32_t *histogram;
+ build_time_t max_build_time = circuit_build_times_max(cbt);
+ int i, c;
+
+ *nbins = 1 + (max_build_time / CBT_BIN_WIDTH);
+ histogram = tor_malloc_zero(*nbins * sizeof(build_time_t));
+
+ // calculate histogram
+ for (i = 0; i < CBT_NCIRCUITS_TO_OBSERVE; i++) {
+ if (cbt->circuit_build_times[i] == 0
+ || cbt->circuit_build_times[i] == CBT_BUILD_ABANDONED)
+ continue; /* 0 <-> uninitialized */
+
+ c = (cbt->circuit_build_times[i] / CBT_BIN_WIDTH);
+ histogram[c]++;
+ }
+
+ return histogram;
+}
+
+/**
+ * Return the Pareto start-of-curve parameter Xm.
+ *
+ * Because we are not a true Pareto curve, we compute this as the
+ * weighted average of the N=3 most frequent build time bins.
+ */
+static build_time_t
+circuit_build_times_get_xm(circuit_build_times_t *cbt)
+{
+ build_time_t i, nbins;
+ build_time_t *nth_max_bin;
+ int32_t bin_counts=0;
+ build_time_t ret = 0;
+ uint32_t *histogram = circuit_build_times_create_histogram(cbt, &nbins);
+ int n=0;
+ int num_modes = circuit_build_times_default_num_xm_modes();
+
+ // Only use one mode if < 1000 buildtimes. Not enough data
+ // for multiple.
+ if (cbt->total_build_times < CBT_NCIRCUITS_TO_OBSERVE)
+ num_modes = 1;
+
+ nth_max_bin = (build_time_t*)tor_malloc_zero(num_modes*sizeof(build_time_t));
+
+ for (i = 0; i < nbins; i++) {
+ if (histogram[i] >= histogram[nth_max_bin[0]]) {
+ nth_max_bin[0] = i;
+ }
+
+ for (n = 1; n < num_modes; n++) {
+ if (histogram[i] >= histogram[nth_max_bin[n]] &&
+ (!histogram[nth_max_bin[n-1]]
+ || histogram[i] < histogram[nth_max_bin[n-1]])) {
+ nth_max_bin[n] = i;
+ }
+ }
+ }
+
+ for (n = 0; n < num_modes; n++) {
+ bin_counts += histogram[nth_max_bin[n]];
+ ret += CBT_BIN_TO_MS(nth_max_bin[n])*histogram[nth_max_bin[n]];
+ log_info(LD_CIRC, "Xm mode #%d: %u %u", n, CBT_BIN_TO_MS(nth_max_bin[n]),
+ histogram[nth_max_bin[n]]);
+ }
+
+ ret /= bin_counts;
+ tor_free(histogram);
+ tor_free(nth_max_bin);
+
+ return ret;
+}
+
+/**
+ * Output a histogram of current circuit build times to
+ * the or_state_t state structure.
+ */
+void
+circuit_build_times_update_state(circuit_build_times_t *cbt,
+ or_state_t *state)
+{
+ uint32_t *histogram;
+ build_time_t i = 0;
+ build_time_t nbins = 0;
+ config_line_t **next, *line;
+
+ histogram = circuit_build_times_create_histogram(cbt, &nbins);
+ // write to state
+ config_free_lines(state->BuildtimeHistogram);
+ next = &state->BuildtimeHistogram;
+ *next = NULL;
+
+ state->TotalBuildTimes = cbt->total_build_times;
+ state->CircuitBuildAbandonedCount = 0;
+
+ for (i = 0; i < CBT_NCIRCUITS_TO_OBSERVE; i++) {
+ if (cbt->circuit_build_times[i] == CBT_BUILD_ABANDONED)
+ state->CircuitBuildAbandonedCount++;
+ }
+
+ for (i = 0; i < nbins; i++) {
+ // compress the histogram by skipping the blanks
+ if (histogram[i] == 0) continue;
+ *next = line = tor_malloc_zero(sizeof(config_line_t));
+ line->key = tor_strdup("CircuitBuildTimeBin");
+ line->value = tor_malloc(25);
+ tor_snprintf(line->value, 25, "%d %d",
+ CBT_BIN_TO_MS(i), histogram[i]);
+ next = &(line->next);
+ }
+
+ if (!unit_tests) {
+ if (!get_options()->AvoidDiskWrites)
+ or_state_mark_dirty(get_or_state(), 0);
+ }
+
+ tor_free(histogram);
+}
+
+/**
+ * Shuffle the build times array.
+ *
+ * Stolen from http://en.wikipedia.org/wiki/Fisher\u2013Yates_shuffle
+ */
+static void
+circuit_build_times_shuffle_and_store_array(circuit_build_times_t *cbt,
+ build_time_t *raw_times,
+ int num_times)
+{
+ int n = num_times;
+ if (num_times > CBT_NCIRCUITS_TO_OBSERVE) {
+ log_notice(LD_CIRC, "Decreasing circuit_build_times size from %d to %d",
+ num_times, CBT_NCIRCUITS_TO_OBSERVE);
+ }
+
+ /* This code can only be run on a compact array */
+ while (n-- > 1) {
+ int k = crypto_rand_int(n + 1); /* 0 <= k <= n. */
+ build_time_t tmp = raw_times[k];
+ raw_times[k] = raw_times[n];
+ raw_times[n] = tmp;
+ }
+
+ /* Since the times are now shuffled, take a random CBT_NCIRCUITS_TO_OBSERVE
+ * subset (ie the first CBT_NCIRCUITS_TO_OBSERVE values) */
+ for (n = 0; n < MIN(num_times, CBT_NCIRCUITS_TO_OBSERVE); n++) {
+ circuit_build_times_add_time(cbt, raw_times[n]);
+ }
+}
+
+/**
+ * Filter old synthetic timeouts that were created before the
+ * new right-censored Pareto calculation was deployed.
+ *
+ * Once all clients before 0.2.1.13-alpha are gone, this code
+ * will be unused.
+ */
+static int
+circuit_build_times_filter_timeouts(circuit_build_times_t *cbt)
+{
+ int num_filtered=0, i=0;
+ double timeout_rate = 0;
+ build_time_t max_timeout = 0;
+
+ timeout_rate = circuit_build_times_timeout_rate(cbt);
+ max_timeout = (build_time_t)cbt->close_ms;
+
+ for (i = 0; i < CBT_NCIRCUITS_TO_OBSERVE; i++) {
+ if (cbt->circuit_build_times[i] > max_timeout) {
+ build_time_t replaced = cbt->circuit_build_times[i];
+ num_filtered++;
+ cbt->circuit_build_times[i] = CBT_BUILD_ABANDONED;
+
+ log_debug(LD_CIRC, "Replaced timeout %d with %d", replaced,
+ cbt->circuit_build_times[i]);
+ }
+ }
+
+ log_info(LD_CIRC,
+ "We had %d timeouts out of %d build times, "
+ "and filtered %d above the max of %u",
+ (int)(cbt->total_build_times*timeout_rate),
+ cbt->total_build_times, num_filtered, max_timeout);
+
+ return num_filtered;
+}
+
+/**
+ * Load histogram from <b>state</b>, shuffling the resulting array
+ * after we do so. Use this result to estimate parameters and
+ * calculate the timeout.
+ *
+ * Return -1 on error.
+ */
+int
+circuit_build_times_parse_state(circuit_build_times_t *cbt,
+ or_state_t *state)
+{
+ int tot_values = 0;
+ uint32_t loaded_cnt = 0, N = 0;
+ config_line_t *line;
+ unsigned int i;
+ build_time_t *loaded_times;
+ int err = 0;
+ circuit_build_times_init(cbt);
+
+ if (circuit_build_times_disabled()) {
+ return 0;
+ }
+
+ /* build_time_t 0 means uninitialized */
+ loaded_times = tor_malloc_zero(sizeof(build_time_t)*state->TotalBuildTimes);
+
+ for (line = state->BuildtimeHistogram; line; line = line->next) {
+ smartlist_t *args = smartlist_create();
+ smartlist_split_string(args, line->value, " ",
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ if (smartlist_len(args) < 2) {
+ log_warn(LD_GENERAL, "Unable to parse circuit build times: "
+ "Too few arguments to CircuitBuildTime");
+ err = 1;
+ SMARTLIST_FOREACH(args, char*, cp, tor_free(cp));
+ smartlist_free(args);
+ break;
+ } else {
+ const char *ms_str = smartlist_get(args,0);
+ const char *count_str = smartlist_get(args,1);
+ uint32_t count, k;
+ build_time_t ms;
+ int ok;
+ ms = (build_time_t)tor_parse_ulong(ms_str, 0, 0,
+ CBT_BUILD_TIME_MAX, &ok, NULL);
+ if (!ok) {
+ log_warn(LD_GENERAL, "Unable to parse circuit build times: "
+ "Unparsable bin number");
+ err = 1;
+ SMARTLIST_FOREACH(args, char*, cp, tor_free(cp));
+ smartlist_free(args);
+ break;
+ }
+ count = (uint32_t)tor_parse_ulong(count_str, 0, 0,
+ UINT32_MAX, &ok, NULL);
+ if (!ok) {
+ log_warn(LD_GENERAL, "Unable to parse circuit build times: "
+ "Unparsable bin count");
+ err = 1;
+ SMARTLIST_FOREACH(args, char*, cp, tor_free(cp));
+ smartlist_free(args);
+ break;
+ }
+
+ if (loaded_cnt+count+state->CircuitBuildAbandonedCount
+ > state->TotalBuildTimes) {
+ log_warn(LD_CIRC,
+ "Too many build times in state file. "
+ "Stopping short before %d",
+ loaded_cnt+count);
+ SMARTLIST_FOREACH(args, char*, cp, tor_free(cp));
+ smartlist_free(args);
+ break;
+ }
+
+ for (k = 0; k < count; k++) {
+ loaded_times[loaded_cnt++] = ms;
+ }
+ N++;
+ SMARTLIST_FOREACH(args, char*, cp, tor_free(cp));
+ smartlist_free(args);
+ }
+ }
+
+ log_info(LD_CIRC,
+ "Adding %d timeouts.", state->CircuitBuildAbandonedCount);
+ for (i=0; i < state->CircuitBuildAbandonedCount; i++) {
+ loaded_times[loaded_cnt++] = CBT_BUILD_ABANDONED;
+ }
+
+ if (loaded_cnt != state->TotalBuildTimes) {
+ log_warn(LD_CIRC,
+ "Corrupt state file? Build times count mismatch. "
+ "Read %d times, but file says %d", loaded_cnt,
+ state->TotalBuildTimes);
+ err = 1;
+ circuit_build_times_reset(cbt);
+ goto done;
+ }
+
+ circuit_build_times_shuffle_and_store_array(cbt, loaded_times, loaded_cnt);
+
+ /* Verify that we didn't overwrite any indexes */
+ for (i=0; i < CBT_NCIRCUITS_TO_OBSERVE; i++) {
+ if (!cbt->circuit_build_times[i])
+ break;
+ tot_values++;
+ }
+ log_info(LD_CIRC,
+ "Loaded %d/%d values from %d lines in circuit time histogram",
+ tot_values, cbt->total_build_times, N);
+
+ if (cbt->total_build_times != tot_values
+ || cbt->total_build_times > CBT_NCIRCUITS_TO_OBSERVE) {
+ log_warn(LD_CIRC,
+ "Corrupt state file? Shuffled build times mismatch. "
+ "Read %d times, but file says %d", tot_values,
+ state->TotalBuildTimes);
+ err = 1;
+ circuit_build_times_reset(cbt);
+ goto done;
+ }
+
+ circuit_build_times_set_timeout(cbt);
+
+ if (!state->CircuitBuildAbandonedCount && cbt->total_build_times) {
+ circuit_build_times_filter_timeouts(cbt);
+ }
+
+ done:
+ tor_free(loaded_times);
+ return err ? -1 : 0;
+}
+
+/**
+ * Estimates the Xm and Alpha parameters using
+ * http://en.wikipedia.org/wiki/Pareto_distribution#Parameter_estimation
+ *
+ * The notable difference is that we use mode instead of min to estimate Xm.
+ * This is because our distribution is frechet-like. We claim this is
+ * an acceptable approximation because we are only concerned with the
+ * accuracy of the CDF of the tail.
+ */
+int
+circuit_build_times_update_alpha(circuit_build_times_t *cbt)
+{
+ build_time_t *x=cbt->circuit_build_times;
+ double a = 0;
+ int n=0,i=0,abandoned_count=0;
+ build_time_t max_time=0;
+
+ /* http://en.wikipedia.org/wiki/Pareto_distribution#Parameter_estimation */
+ /* We sort of cheat here and make our samples slightly more pareto-like
+ * and less frechet-like. */
+ cbt->Xm = circuit_build_times_get_xm(cbt);
+
+ tor_assert(cbt->Xm > 0);
+
+ for (i=0; i< CBT_NCIRCUITS_TO_OBSERVE; i++) {
+ if (!x[i]) {
+ continue;
+ }
+
+ if (x[i] < cbt->Xm) {
+ a += tor_mathlog(cbt->Xm);
+ } else if (x[i] == CBT_BUILD_ABANDONED) {
+ abandoned_count++;
+ } else {
+ a += tor_mathlog(x[i]);
+ if (x[i] > max_time)
+ max_time = x[i];
+ }
+ n++;
+ }
+
+ /*
+ * We are erring and asserting here because this can only happen
+ * in codepaths other than startup. The startup state parsing code
+ * performs this same check, and resets state if it hits it. If we
+ * hit it at runtime, something serious has gone wrong.
+ */
+ if (n!=cbt->total_build_times) {
+ log_err(LD_CIRC, "Discrepancy in build times count: %d vs %d", n,
+ cbt->total_build_times);
+ }
+ tor_assert(n==cbt->total_build_times);
+
+ if (max_time <= 0) {
+ /* This can happen if Xm is actually the *maximum* value in the set.
+ * It can also happen if we've abandoned every single circuit somehow.
+ * In either case, tell the caller not to compute a new build timeout. */
+ log_warn(LD_BUG,
+ "Could not determine largest build time (%d). "
+ "Xm is %dms and we've abandoned %d out of %d circuits.", max_time,
+ cbt->Xm, abandoned_count, n);
+ return 0;
+ }
+
+ a += abandoned_count*tor_mathlog(max_time);
+
+ a -= n*tor_mathlog(cbt->Xm);
+ // Estimator comes from Eq #4 in:
+ // "Bayesian estimation based on trimmed samples from Pareto populations"
+ // by Arturo J. Fernández. We are right-censored only.
+ a = (n-abandoned_count)/a;
+
+ cbt->alpha = a;
+
+ return 1;
+}
+
+/**
+ * This is the Pareto Quantile Function. It calculates the point x
+ * in the distribution such that F(x) = quantile (ie quantile*100%
+ * of the mass of the density function is below x on the curve).
+ *
+ * We use it to calculate the timeout and also to generate synthetic
+ * values of time for circuits that timeout before completion.
+ *
+ * See http://en.wikipedia.org/wiki/Quantile_function,
+ * http://en.wikipedia.org/wiki/Inverse_transform_sampling and
+ * http://en.wikipedia.org/wiki/Pareto_distribution#Generating_a_
+ * random_sample_from_Pareto_distribution
+ * That's right. I'll cite wikipedia all day long.
+ *
+ * Return value is in milliseconds.
+ */
+double
+circuit_build_times_calculate_timeout(circuit_build_times_t *cbt,
+ double quantile)
+{
+ double ret;
+ tor_assert(quantile >= 0);
+ tor_assert(1.0-quantile > 0);
+ tor_assert(cbt->Xm > 0);
+
+ ret = cbt->Xm/pow(1.0-quantile,1.0/cbt->alpha);
+ if (ret > INT32_MAX) {
+ ret = INT32_MAX;
+ }
+ tor_assert(ret > 0);
+ return ret;
+}
+
+/** Pareto CDF */
+double
+circuit_build_times_cdf(circuit_build_times_t *cbt, double x)
+{
+ double ret;
+ tor_assert(cbt->Xm > 0);
+ ret = 1.0-pow(cbt->Xm/x,cbt->alpha);
+ tor_assert(0 <= ret && ret <= 1.0);
+ return ret;
+}
+
+/**
+ * Generate a synthetic time using our distribution parameters.
+ *
+ * The return value will be within the [q_lo, q_hi) quantile points
+ * on the CDF.
+ */
+build_time_t
+circuit_build_times_generate_sample(circuit_build_times_t *cbt,
+ double q_lo, double q_hi)
+{
+ double randval = crypto_rand_double();
+ build_time_t ret;
+ double u;
+
+ /* Generate between [q_lo, q_hi) */
+ /*XXXX This is what nextafter is supposed to be for; we should use it on the
+ * platforms that support it. */
+ q_hi -= 1.0/(INT32_MAX);
+
+ tor_assert(q_lo >= 0);
+ tor_assert(q_hi < 1);
+ tor_assert(q_lo < q_hi);
+
+ u = q_lo + (q_hi-q_lo)*randval;
+
+ tor_assert(0 <= u && u < 1.0);
+ /* circuit_build_times_calculate_timeout returns <= INT32_MAX */
+ ret = (build_time_t)
+ tor_lround(circuit_build_times_calculate_timeout(cbt, u));
+ tor_assert(ret > 0);
+ return ret;
+}
+
+/**
+ * Estimate an initial alpha parameter by solving the quantile
+ * function with a quantile point and a specific timeout value.
+ */
+void
+circuit_build_times_initial_alpha(circuit_build_times_t *cbt,
+ double quantile, double timeout_ms)
+{
+ // Q(u) = Xm/((1-u)^(1/a))
+ // Q(0.8) = Xm/((1-0.8))^(1/a)) = CircBuildTimeout
+ // CircBuildTimeout = Xm/((1-0.8))^(1/a))
+ // CircBuildTimeout = Xm*((1-0.8))^(-1/a))
+ // ln(CircBuildTimeout) = ln(Xm)+ln(((1-0.8)))*(-1/a)
+ // -ln(1-0.8)/(ln(CircBuildTimeout)-ln(Xm))=a
+ tor_assert(quantile >= 0);
+ tor_assert(cbt->Xm > 0);
+ cbt->alpha = tor_mathlog(1.0-quantile)/
+ (tor_mathlog(cbt->Xm)-tor_mathlog(timeout_ms));
+ tor_assert(cbt->alpha > 0);
+}
+
+/**
+ * Returns true if we need circuits to be built
+ */
+int
+circuit_build_times_needs_circuits(circuit_build_times_t *cbt)
+{
+ /* Return true if < MIN_CIRCUITS_TO_OBSERVE */
+ return !circuit_build_times_enough_to_compute(cbt);
+}
+
+/**
+ * Returns true if we should build a timeout test circuit
+ * right now.
+ */
+int
+circuit_build_times_needs_circuits_now(circuit_build_times_t *cbt)
+{
+ return circuit_build_times_needs_circuits(cbt) &&
+ approx_time()-cbt->last_circ_at > circuit_build_times_test_frequency();
+}
+
+/**
+ * Called to indicate that the network showed some signs of liveness,
+ * i.e. we received a cell.
+ *
+ * This is used by circuit_build_times_network_check_live() to decide
+ * if we should record the circuit build timeout or not.
+ *
+ * This function is called every time we receive a cell. Avoid
+ * syscalls, events, and other high-intensity work.
+ */
+void
+circuit_build_times_network_is_live(circuit_build_times_t *cbt)
+{
+ time_t now = approx_time();
+ if (cbt->liveness.nonlive_timeouts > 0) {
+ log_notice(LD_CIRC,
+ "Tor now sees network activity. Restoring circuit build "
+ "timeout recording. Network was down for %d seconds "
+ "during %d circuit attempts.",
+ (int)(now - cbt->liveness.network_last_live),
+ cbt->liveness.nonlive_timeouts);
+ }
+ cbt->liveness.network_last_live = now;
+ cbt->liveness.nonlive_timeouts = 0;
+}
+
+/**
+ * Called to indicate that we completed a circuit. Because this circuit
+ * succeeded, it doesn't count as a timeout-after-the-first-hop.
+ *
+ * This is used by circuit_build_times_network_check_changed() to determine
+ * if we had too many recent timeouts and need to reset our learned timeout
+ * to something higher.
+ */
+void
+circuit_build_times_network_circ_success(circuit_build_times_t *cbt)
+{
+ cbt->liveness.timeouts_after_firsthop[cbt->liveness.after_firsthop_idx] = 0;
+ cbt->liveness.after_firsthop_idx++;
+ cbt->liveness.after_firsthop_idx %= cbt->liveness.num_recent_circs;
+}
+
+/**
+ * A circuit just timed out. If it failed after the first hop, record it
+ * in our history for later deciding if the network speed has changed.
+ *
+ * This is used by circuit_build_times_network_check_changed() to determine
+ * if we had too many recent timeouts and need to reset our learned timeout
+ * to something higher.
+ */
+static void
+circuit_build_times_network_timeout(circuit_build_times_t *cbt,
+ int did_onehop)
+{
+ if (did_onehop) {
+ cbt->liveness.timeouts_after_firsthop[cbt->liveness.after_firsthop_idx]=1;
+ cbt->liveness.after_firsthop_idx++;
+ cbt->liveness.after_firsthop_idx %= cbt->liveness.num_recent_circs;
+ }
+}
+
+/**
+ * A circuit was just forcibly closed. If there has been no recent network
+ * activity at all, but this circuit was launched back when we thought the
+ * network was live, increment the number of "nonlive" circuit timeouts.
+ *
+ * This is used by circuit_build_times_network_check_live() to decide
+ * if we should record the circuit build timeout or not.
+ */
+static void
+circuit_build_times_network_close(circuit_build_times_t *cbt,
+ int did_onehop, time_t start_time)
+{
+ time_t now = time(NULL);
+ /*
+ * Check if this is a timeout that was for a circuit that spent its
+ * entire existence during a time where we have had no network activity.
+ */
+ if (cbt->liveness.network_last_live < start_time) {
+ if (did_onehop) {
+ char last_live_buf[ISO_TIME_LEN+1];
+ char start_time_buf[ISO_TIME_LEN+1];
+ char now_buf[ISO_TIME_LEN+1];
+ format_local_iso_time(last_live_buf, cbt->liveness.network_last_live);
+ format_local_iso_time(start_time_buf, start_time);
+ format_local_iso_time(now_buf, now);
+ log_warn(LD_BUG,
+ "Circuit somehow completed a hop while the network was "
+ "not live. Network was last live at %s, but circuit launched "
+ "at %s. It's now %s.", last_live_buf, start_time_buf,
+ now_buf);
+ }
+ cbt->liveness.nonlive_timeouts++;
+ if (cbt->liveness.nonlive_timeouts == 1) {
+ log_notice(LD_CIRC,
+ "Tor has not observed any network activity for the past %d "
+ "seconds. Disabling circuit build timeout code.",
+ (int)(now - cbt->liveness.network_last_live));
+ } else {
+ log_info(LD_CIRC,
+ "Got non-live timeout. Current count is: %d",
+ cbt->liveness.nonlive_timeouts);
+ }
+ }
+}
+
+/**
+ * When the network is not live, we do not record circuit build times.
+ *
+ * The network is considered not live if there has been at least one
+ * circuit build that began and ended (had its close_ms measurement
+ * period expire) since we last received a cell.
+ *
+ * Also has the side effect of rewinding the circuit time history
+ * in the case of recent liveness changes.
+ */
+int
+circuit_build_times_network_check_live(circuit_build_times_t *cbt)
+{
+ if (cbt->liveness.nonlive_timeouts > 0) {
+ return 0;
+ }
+
+ return 1;
+}
+
+/**
+ * Returns true if we have seen more than MAX_RECENT_TIMEOUT_COUNT of
+ * the past RECENT_CIRCUITS time out after the first hop. Used to detect
+ * if the network connection has changed significantly, and if so,
+ * resets our circuit build timeout to the default.
+ *
+ * Also resets the entire timeout history in this case and causes us
+ * to restart the process of building test circuits and estimating a
+ * new timeout.
+ */
+int
+circuit_build_times_network_check_changed(circuit_build_times_t *cbt)
+{
+ int total_build_times = cbt->total_build_times;
+ int timeout_count=0;
+ int i;
+
+ /* how many of our recent circuits made it to the first hop but then
+ * timed out? */
+ for (i = 0; i < cbt->liveness.num_recent_circs; i++) {
+ timeout_count += cbt->liveness.timeouts_after_firsthop[i];
+ }
+
+ /* If 80% of our recent circuits are timing out after the first hop,
+ * we need to re-estimate a new initial alpha and timeout. */
+ if (timeout_count < circuit_build_times_max_timeouts()) {
+ return 0;
+ }
+
+ circuit_build_times_reset(cbt);
+ memset(cbt->liveness.timeouts_after_firsthop, 0,
+ sizeof(*cbt->liveness.timeouts_after_firsthop)*
+ cbt->liveness.num_recent_circs);
+ cbt->liveness.after_firsthop_idx = 0;
+
+ /* Check to see if this has happened before. If so, double the timeout
+ * to give people on abysmally bad network connections a shot at access */
+ if (cbt->timeout_ms >= circuit_build_times_get_initial_timeout()) {
+ if (cbt->timeout_ms > INT32_MAX/2 || cbt->close_ms > INT32_MAX/2) {
+ log_warn(LD_CIRC, "Insanely large circuit build timeout value. "
+ "(timeout = %lfmsec, close = %lfmsec)",
+ cbt->timeout_ms, cbt->close_ms);
+ } else {
+ cbt->timeout_ms *= 2;
+ cbt->close_ms *= 2;
+ }
+ } else {
+ cbt->close_ms = cbt->timeout_ms
+ = circuit_build_times_get_initial_timeout();
+ }
+
+ control_event_buildtimeout_set(cbt, BUILDTIMEOUT_SET_EVENT_RESET);
+
+ log_notice(LD_CIRC,
+ "Network connection speed appears to have changed. Resetting "
+ "timeout to %lds after %d timeouts and %d buildtimes.",
+ tor_lround(cbt->timeout_ms/1000), timeout_count,
+ total_build_times);
+
+ return 1;
+}
+
+/**
+ * Count the number of timeouts in a set of cbt data.
+ */
+double
+circuit_build_times_timeout_rate(const circuit_build_times_t *cbt)
+{
+ int i=0,timeouts=0;
+ for (i = 0; i < CBT_NCIRCUITS_TO_OBSERVE; i++) {
+ if (cbt->circuit_build_times[i] >= cbt->timeout_ms) {
+ timeouts++;
+ }
+ }
+
+ if (!cbt->total_build_times)
+ return 0;
+
+ return ((double)timeouts)/cbt->total_build_times;
+}
+
+/**
+ * Count the number of closed circuits in a set of cbt data.
+ */
+double
+circuit_build_times_close_rate(const circuit_build_times_t *cbt)
+{
+ int i=0,closed=0;
+ for (i = 0; i < CBT_NCIRCUITS_TO_OBSERVE; i++) {
+ if (cbt->circuit_build_times[i] == CBT_BUILD_ABANDONED) {
+ closed++;
+ }
+ }
+
+ if (!cbt->total_build_times)
+ return 0;
+
+ return ((double)closed)/cbt->total_build_times;
+}
+
+/**
+ * Store a timeout as a synthetic value.
+ *
+ * Returns true if the store was successful and we should possibly
+ * update our timeout estimate.
+ */
+int
+circuit_build_times_count_close(circuit_build_times_t *cbt,
+ int did_onehop,
+ time_t start_time)
+{
+ if (circuit_build_times_disabled()) {
+ cbt->close_ms = cbt->timeout_ms
+ = circuit_build_times_get_initial_timeout();
+ return 0;
+ }
+
+ /* Record this force-close to help determine if the network is dead */
+ circuit_build_times_network_close(cbt, did_onehop, start_time);
+
+ /* Only count timeouts if network is live.. */
+ if (!circuit_build_times_network_check_live(cbt)) {
+ return 0;
+ }
+
+ circuit_build_times_add_time(cbt, CBT_BUILD_ABANDONED);
+ return 1;
+}
+
+/**
+ * Update timeout counts to determine if we need to expire
+ * our build time history due to excessive timeouts.
+ *
+ * We do not record any actual time values at this stage;
+ * we are only interested in recording the fact that a timeout
+ * happened. We record the time values via
+ * circuit_build_times_count_close() and circuit_build_times_add_time().
+ */
+void
+circuit_build_times_count_timeout(circuit_build_times_t *cbt,
+ int did_onehop)
+{
+ if (circuit_build_times_disabled()) {
+ cbt->close_ms = cbt->timeout_ms
+ = circuit_build_times_get_initial_timeout();
+ return;
+ }
+
+ /* Register the fact that a timeout just occurred. */
+ circuit_build_times_network_timeout(cbt, did_onehop);
+
+ /* If there are a ton of timeouts, we should reset
+ * the circuit build timeout. */
+ circuit_build_times_network_check_changed(cbt);
+}
+
+/**
+ * Estimate a new timeout based on history and set our timeout
+ * variable accordingly.
+ */
+static int
+circuit_build_times_set_timeout_worker(circuit_build_times_t *cbt)
+{
+ build_time_t max_time;
+ if (!circuit_build_times_enough_to_compute(cbt))
+ return 0;
+
+ if (!circuit_build_times_update_alpha(cbt))
+ return 0;
+
+ cbt->timeout_ms = circuit_build_times_calculate_timeout(cbt,
+ circuit_build_times_quantile_cutoff());
+
+ cbt->close_ms = circuit_build_times_calculate_timeout(cbt,
+ circuit_build_times_close_quantile());
+
+ max_time = circuit_build_times_max(cbt);
+
+ /* Sometimes really fast guard nodes give us such a steep curve
+ * that this ends up being not that much greater than timeout_ms.
+ * Make it be at least 1 min to handle this case. */
+ cbt->close_ms = MAX(cbt->close_ms, circuit_build_times_initial_timeout());
+
+ if (cbt->timeout_ms > max_time) {
+ log_notice(LD_CIRC,
+ "Circuit build timeout of %dms is beyond the maximum build "
+ "time we have ever observed. Capping it to %dms.",
+ (int)cbt->timeout_ms, max_time);
+ cbt->timeout_ms = max_time;
+ }
+
+ if (max_time < INT32_MAX/2 && cbt->close_ms > 2*max_time) {
+ log_notice(LD_CIRC,
+ "Circuit build measurement period of %dms is more than twice "
+ "the maximum build time we have ever observed. Capping it to "
+ "%dms.", (int)cbt->close_ms, 2*max_time);
+ cbt->close_ms = 2*max_time;
+ }
+
+ cbt->have_computed_timeout = 1;
+ return 1;
+}
+
+/**
+ * Exposed function to compute a new timeout. Dispatches events and
+ * also filters out extremely high timeout values.
+ */
+void
+circuit_build_times_set_timeout(circuit_build_times_t *cbt)
+{
+ long prev_timeout = tor_lround(cbt->timeout_ms/1000);
+ double timeout_rate;
+
+ if (!circuit_build_times_set_timeout_worker(cbt))
+ return;
+
+ if (cbt->timeout_ms < circuit_build_times_min_timeout()) {
+ log_warn(LD_CIRC, "Set buildtimeout to low value %lfms. Setting to %dms",
+ cbt->timeout_ms, circuit_build_times_min_timeout());
+ cbt->timeout_ms = circuit_build_times_min_timeout();
+ if (cbt->close_ms < cbt->timeout_ms) {
+ /* This shouldn't happen because of MAX() in timeout_worker above,
+ * but doing it just in case */
+ cbt->close_ms = circuit_build_times_initial_timeout();
+ }
+ }
+
+ control_event_buildtimeout_set(cbt, BUILDTIMEOUT_SET_EVENT_COMPUTED);
+
+ timeout_rate = circuit_build_times_timeout_rate(cbt);
+
+ if (prev_timeout > tor_lround(cbt->timeout_ms/1000)) {
+ log_notice(LD_CIRC,
+ "Based on %d circuit times, it looks like we don't need to "
+ "wait so long for circuits to finish. We will now assume a "
+ "circuit is too slow to use after waiting %ld seconds.",
+ cbt->total_build_times,
+ tor_lround(cbt->timeout_ms/1000));
+ log_info(LD_CIRC,
+ "Circuit timeout data: %lfms, %lfms, Xm: %d, a: %lf, r: %lf",
+ cbt->timeout_ms, cbt->close_ms, cbt->Xm, cbt->alpha,
+ timeout_rate);
+ } else if (prev_timeout < tor_lround(cbt->timeout_ms/1000)) {
+ log_notice(LD_CIRC,
+ "Based on %d circuit times, it looks like we need to wait "
+ "longer for circuits to finish. We will now assume a "
+ "circuit is too slow to use after waiting %ld seconds.",
+ cbt->total_build_times,
+ tor_lround(cbt->timeout_ms/1000));
+ log_info(LD_CIRC,
+ "Circuit timeout data: %lfms, %lfms, Xm: %d, a: %lf, r: %lf",
+ cbt->timeout_ms, cbt->close_ms, cbt->Xm, cbt->alpha,
+ timeout_rate);
+ } else {
+ log_info(LD_CIRC,
+ "Set circuit build timeout to %lds (%lfms, %lfms, Xm: %d, a: %lf,"
+ " r: %lf) based on %d circuit times",
+ tor_lround(cbt->timeout_ms/1000),
+ cbt->timeout_ms, cbt->close_ms, cbt->Xm, cbt->alpha, timeout_rate,
+ cbt->total_build_times);
+ }
+}
+
/** Iterate over values of circ_id, starting from conn-\>next_circ_id,
* and with the high bit specified by conn-\>circ_id_type, until we get
* a circ_id that is not in use by any other circuit on that conn.
@@ -112,21 +1382,21 @@ circuit_list_path_impl(origin_circuit_t *circ, int verbose, int verbose_names)
crypt_path_t *hop;
smartlist_t *elements;
const char *states[] = {"closed", "waiting for keys", "open"};
- char buf[128];
char *s;
elements = smartlist_create();
if (verbose) {
const char *nickname = build_state_get_exit_nickname(circ->build_state);
- tor_snprintf(buf, sizeof(buf), "%s%s circ (length %d%s%s):",
+ char *cp;
+ tor_asprintf(&cp, "%s%s circ (length %d%s%s):",
circ->build_state->is_internal ? "internal" : "exit",
circ->build_state->need_uptime ? " (high-uptime)" : "",
circ->build_state->desired_path_len,
circ->_base.state == CIRCUIT_STATE_OPEN ? "" : ", exit ",
circ->_base.state == CIRCUIT_STATE_OPEN ? "" :
(nickname?nickname:"*unnamed*"));
- smartlist_add(elements, tor_strdup(buf));
+ smartlist_add(elements, cp);
}
hop = circ->cpath;
@@ -148,8 +1418,7 @@ circuit_list_path_impl(origin_circuit_t *circ, int verbose, int verbose_names)
router_get_verbose_nickname(elt, ri);
} else if ((rs = router_get_consensus_status_by_id(id))) {
routerstatus_get_verbose_nickname(elt, rs);
- } else if (hop->extend_info->nickname &&
- is_legal_nickname(hop->extend_info->nickname)) {
+ } else if (is_legal_nickname(hop->extend_info->nickname)) {
elt[0] = '$';
base16_encode(elt+1, HEX_DIGEST_LEN+1, id, DIGEST_LEN);
elt[HEX_DIGEST_LEN+1]= '~';
@@ -217,7 +1486,7 @@ void
circuit_log_path(int severity, unsigned int domain, origin_circuit_t *circ)
{
char *s = circuit_list_path(circ,1);
- log(severity,domain,"%s",s);
+ tor_log(severity,domain,"%s",s);
tor_free(s);
}
@@ -269,7 +1538,7 @@ static int
onion_populate_cpath(origin_circuit_t *circ)
{
int r;
-again:
+ again:
r = onion_extend_cpath(circ);
if (r < 0) {
log_info(LD_CIRC,"Generating cpath hop failed.");
@@ -361,9 +1630,10 @@ circuit_handle_first_hop(origin_circuit_t *circ)
if (!n_conn) {
/* not currently connected in a useful way. */
- const char *name = firsthop->extend_info->nickname ?
+ const char *name = strlen(firsthop->extend_info->nickname) ?
firsthop->extend_info->nickname : fmt_addr(&firsthop->extend_info->addr);
- log_info(LD_CIRC, "Next router is %s: %s ", safe_str(name), msg?msg:"???");
+ log_info(LD_CIRC, "Next router is %s: %s ",
+ safe_str_client(name), msg?msg:"???");
circ->_base.n_hop = extend_info_dup(firsthop->extend_info);
if (should_launch) {
@@ -506,7 +1776,8 @@ circuit_deliver_create_cell(circuit_t *circ, uint8_t cell_type,
cell.circ_id = circ->n_circ_id;
memcpy(cell.payload, payload, ONIONSKIN_CHALLENGE_LEN);
- append_cell_to_circuit_queue(circ, circ->n_conn, &cell, CELL_DIRECTION_OUT);
+ append_cell_to_circuit_queue(circ, circ->n_conn, &cell,
+ CELL_DIRECTION_OUT, 0);
if (CIRCUIT_IS_ORIGIN(circ)) {
/* mark it so it gets better rate limiting treatment. */
@@ -536,7 +1807,7 @@ inform_testing_reachability(void)
"CHECKING_REACHABILITY DIRADDRESS=%s:%d",
me->address, me->dir_port);
}
- log(LOG_NOTICE, LD_OR, "Now checking whether ORPort %s:%d%s %s reachable... "
+ log_notice(LD_OR, "Now checking whether ORPort %s:%d%s %s reachable... "
"(this may take up to %d minutes -- look for log "
"messages indicating success)",
me->address, me->or_port,
@@ -569,6 +1840,18 @@ should_use_create_fast_for_circuit(origin_circuit_t *circ)
return 1;
}
+/** Return true if <b>circ</b> is the type of circuit we want to count
+ * timeouts from. In particular, we want it to have not completed yet
+ * (already completing indicates we cannibalized it), and we want it to
+ * have exactly three hops.
+ */
+int
+circuit_timeout_want_to_count_circ(origin_circuit_t *circ)
+{
+ return !circ->has_opened
+ && circ->build_state->desired_path_len == DEFAULT_ROUTE_LEN;
+}
+
/** This is the backbone function for building circuits.
*
* If circ's first hop is closed, then we need to build a create
@@ -642,15 +1925,42 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
if (!hop) {
/* done building the circuit. whew. */
circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_OPEN);
+ if (circuit_timeout_want_to_count_circ(circ)) {
+ struct timeval end;
+ long timediff;
+ tor_gettimeofday(&end);
+ timediff = tv_mdiff(&circ->_base.highres_created, &end);
+
+ /*
+ * If the circuit build time is much greater than we would have cut
+ * it off at, we probably had a suspend event along this codepath,
+ * and we should discard the value.
+ */
+ if (timediff < 0 || timediff > 2*circ_times.close_ms+1000) {
+ log_notice(LD_CIRC, "Strange value for circuit build time: %ldmsec. "
+ "Assuming clock jump. Purpose %d", timediff,
+ circ->_base.purpose);
+ } else if (!circuit_build_times_disabled()) {
+ /* Only count circuit times if the network is live */
+ if (circuit_build_times_network_check_live(&circ_times)) {
+ circuit_build_times_add_time(&circ_times, (build_time_t)timediff);
+ circuit_build_times_set_timeout(&circ_times);
+ }
+
+ if (circ->_base.purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT) {
+ circuit_build_times_network_circ_success(&circ_times);
+ }
+ }
+ }
log_info(LD_CIRC,"circuit built!");
circuit_reset_failure_count(0);
if (circ->build_state->onehop_tunnel)
control_event_bootstrap(BOOTSTRAP_STATUS_REQUESTING_STATUS, 0);
- if (!has_completed_circuit && !circ->build_state->onehop_tunnel) {
+ if (!can_complete_circuit && !circ->build_state->onehop_tunnel) {
or_options_t *options = get_options();
- has_completed_circuit=1;
+ can_complete_circuit=1;
/* FFFF Log a count of known routers here */
- log(LOG_NOTICE, LD_GENERAL,
+ log_notice(LD_GENERAL,
"Tor has successfully opened a circuit. "
"Looks like client functionality is working.");
control_event_bootstrap(BOOTSTRAP_STATUS_DONE, 0);
@@ -662,6 +1972,10 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
}
circuit_rep_hist_note_result(circ);
circuit_has_opened(circ); /* do other actions as necessary */
+
+ /* We're done with measurement circuits here. Just close them */
+ if (circ->_base.purpose == CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT)
+ circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_FINISHED);
return 0;
}
@@ -705,13 +2019,13 @@ void
circuit_note_clock_jumped(int seconds_elapsed)
{
int severity = server_mode(get_options()) ? LOG_WARN : LOG_NOTICE;
- log(severity, LD_GENERAL, "Your system clock just jumped %d seconds %s; "
+ tor_log(severity, LD_GENERAL, "Your system clock just jumped %d seconds %s; "
"assuming established circuits no longer work.",
seconds_elapsed >=0 ? seconds_elapsed : -seconds_elapsed,
seconds_elapsed >=0 ? "forward" : "backward");
control_event_general_status(LOG_WARN, "CLOCK_JUMPED TIME=%d",
seconds_elapsed);
- has_completed_circuit=0; /* so it'll log when it works again */
+ can_complete_circuit=0; /* so it'll log when it works again */
control_event_client_status(severity, "CIRCUIT_NOT_ESTABLISHED REASON=%s",
"CLOCK_JUMPED");
circuit_mark_all_unused_circs();
@@ -943,10 +2257,9 @@ circuit_finish_handshake(origin_circuit_t *circ, uint8_t reply_type,
return -END_CIRC_REASON_TORPROTOCOL;
}
- if (hop->dh_handshake_state) {
- crypto_dh_free(hop->dh_handshake_state); /* don't need it anymore */
- hop->dh_handshake_state = NULL;
- }
+ crypto_dh_free(hop->dh_handshake_state); /* don't need it anymore */
+ hop->dh_handshake_state = NULL;
+
memset(hop->fast_handshake_state, 0, sizeof(hop->fast_handshake_state));
if (circuit_init_cpath_crypto(hop, keys, 0)<0) {
@@ -1034,8 +2347,8 @@ onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload,
cell_type == CELL_CREATED ? ONIONSKIN_REPLY_LEN : DIGEST_LEN*2);
log_debug(LD_CIRC,"init digest forward 0x%.8x, backward 0x%.8x.",
- (unsigned int)*(uint32_t*)(keys),
- (unsigned int)*(uint32_t*)(keys+20));
+ (unsigned int)get_uint32(keys),
+ (unsigned int)get_uint32(keys+20));
if (circuit_init_cpath_crypto(tmp_cpath, keys, 0)<0) {
log_warn(LD_BUG,"Circuit initialization failed");
tor_free(tmp_cpath);
@@ -1056,7 +2369,7 @@ onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload,
circ->is_first_hop = (cell_type == CELL_CREATED_FAST);
append_cell_to_circuit_queue(TO_CIRCUIT(circ),
- circ->p_conn, &cell, CELL_DIRECTION_IN);
+ circ->p_conn, &cell, CELL_DIRECTION_IN, 0);
log_debug(LD_CIRC,"Finished sending 'created' cell.");
if (!is_local_addr(&circ->p_conn->_base.addr) &&
@@ -1085,7 +2398,7 @@ new_route_len(uint8_t purpose, extend_info_t *exit,
tor_assert(routers);
- routelen = 3;
+ routelen = DEFAULT_ROUTE_LEN;
if (exit &&
purpose != CIRCUIT_PURPOSE_TESTING &&
purpose != CIRCUIT_PURPOSE_S_ESTABLISH_INTRO)
@@ -1150,6 +2463,8 @@ circuit_all_predicted_ports_handled(time_t now, int *need_uptime,
smartlist_t *LongLivedServices = get_options()->LongLivedPorts;
tor_assert(need_uptime);
tor_assert(need_capacity);
+ // Always predict need_capacity
+ *need_capacity = 1;
enough = (smartlist_len(sl) == 0);
for (i = 0; i < smartlist_len(sl); ++i) {
port = smartlist_get(sl, i);
@@ -1172,6 +2487,8 @@ router_handles_some_port(routerinfo_t *router, smartlist_t *needed_ports)
for (i = 0; i < smartlist_len(needed_ports); ++i) {
addr_policy_result_t r;
+ /* alignment issues aren't a worry for this dereference, since
+ needed_ports is explicitly a smartlist of uint16_t's */
port = *(uint16_t *)smartlist_get(needed_ports, i);
tor_assert(port);
r = compare_addr_to_addr_policy(0, port, router->exit_policy);
@@ -1254,9 +2571,16 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
n_supported[i] = -1;
continue; /* skip routers that are known to be down or bad exits */
}
- if (router_is_unreliable(router, need_uptime, need_capacity, 0)) {
+ if (router_is_unreliable(router, need_uptime, need_capacity, 0) &&
+ (!options->ExitNodes ||
+ !routerset_contains_router(options->ExitNodes, router))) {
+ /* FFFF Someday, differentiate between a routerset that names
+ * routers, and a routerset that names countries, and only do this
+ * check if they've asked for specific exit relays. Or if the country
+ * they ask for is rare. Or something. */
n_supported[i] = -1;
- continue; /* skip routers that are not suitable */
+ continue; /* skip routers that are not suitable, unless we have
+ * ExitNodes set, in which case we asked for it */
}
if (!(router->is_valid || options->_AllowInvalid & ALLOW_INVALID_EXIT)) {
/* if it's invalid and we don't want it */
@@ -1281,7 +2605,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
{
if (!ap_stream_wants_exit_attention(conn))
continue; /* Skip everything but APs in CIRCUIT_WAIT */
- if (connection_ap_can_use_exit(TO_EDGE_CONN(conn), router)) {
+ if (connection_ap_can_use_exit(TO_EDGE_CONN(conn), router, 1)) {
++n_supported[i];
// log_fn(LOG_DEBUG,"%s is supported. n_supported[%d] now %d.",
// router->nickname, i, n_supported[i]);
@@ -1323,7 +2647,8 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
routersets_get_disjunction(use, supporting, options->ExitNodes,
options->_ExcludeExitNodesUnion, 1);
- if (smartlist_len(use) == 0 && !options->StrictExitNodes) {
+ if (smartlist_len(use) == 0 && options->ExitNodes &&
+ !options->StrictNodes) { /* give up on exitnodes and try again */
routersets_get_disjunction(use, supporting, NULL,
options->_ExcludeExitNodesUnion, 1);
}
@@ -1335,7 +2660,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
* possibly support any of them. Choose a router at random that satisfies
* at least one predicted exit port. */
- int try;
+ int attempt;
smartlist_t *needed_ports, *supporting, *use;
if (best_support == -1) {
@@ -1348,19 +2673,20 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
tor_free(n_supported);
return choose_good_exit_server_general(dir, 0, 0);
}
- log_notice(LD_CIRC, "All routers are down or won't exit -- choosing a "
- "doomed exit at random.");
+ log_notice(LD_CIRC, "All routers are down or won't exit%s -- "
+ "choosing a doomed exit at random.",
+ options->_ExcludeExitNodesUnion ? " or are Excluded" : "");
}
supporting = smartlist_create();
use = smartlist_create();
needed_ports = circuit_get_unhandled_ports(time(NULL));
- for (try = 0; try < 2; try++) {
+ for (attempt = 0; attempt < 2; attempt++) {
/* try once to pick only from routers that satisfy a needed port,
* then if there are none, pick from any that support exiting. */
for (i = 0; i < smartlist_len(dir->routers); i++) {
router = smartlist_get(dir->routers, i);
if (n_supported[i] != -1 &&
- (try || router_handles_some_port(router, needed_ports))) {
+ (attempt || router_handles_some_port(router, needed_ports))) {
// log_fn(LOG_DEBUG,"Try %d: '%s' is a possibility.",
// try, router->nickname);
smartlist_add(supporting, router);
@@ -1369,12 +2695,14 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
routersets_get_disjunction(use, supporting, options->ExitNodes,
options->_ExcludeExitNodesUnion, 1);
- if (smartlist_len(use) == 0 && !options->StrictExitNodes) {
+ if (smartlist_len(use) == 0 && options->ExitNodes &&
+ !options->StrictNodes) { /* give up on exitnodes and try again */
routersets_get_disjunction(use, supporting, NULL,
options->_ExcludeExitNodesUnion, 1);
}
- /* XXX sometimes the above results in null, when the requested
- * exit node is down. we should pick it anyway. */
+ /* FFF sometimes the above results in null, when the requested
+ * exit node is considered down by the consensus. we should pick
+ * it anyway, since the user asked for it. */
router = routerlist_sl_choose_by_bandwidth(use, WEIGHT_FOR_EXIT);
if (router)
break;
@@ -1392,10 +2720,10 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
log_info(LD_CIRC, "Chose exit server '%s'", router->nickname);
return router;
}
- if (options->StrictExitNodes) {
+ if (options->ExitNodes && options->StrictNodes) {
log_warn(LD_CIRC,
"No specified exit routers seem to be running, and "
- "StrictExitNodes is set: can't choose an exit.");
+ "StrictNodes is set: can't choose an exit.");
}
return NULL;
}
@@ -1426,15 +2754,13 @@ choose_good_exit_server(uint8_t purpose, routerlist_t *dir,
if (options->_AllowInvalid & ALLOW_INVALID_MIDDLE)
flags |= CRN_ALLOW_INVALID;
if (is_internal) /* pick it like a middle hop */
- return router_choose_random_node(NULL, NULL,
- options->ExcludeNodes, flags);
+ return router_choose_random_node(NULL, options->ExcludeNodes, flags);
else
return choose_good_exit_server_general(dir,need_uptime,need_capacity);
case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
if (options->_AllowInvalid & ALLOW_INVALID_RENDEZVOUS)
flags |= CRN_ALLOW_INVALID;
- return router_choose_random_node(NULL, NULL,
- options->ExcludeNodes, flags);
+ return router_choose_random_node(NULL, options->ExcludeNodes, flags);
}
log_warn(LD_BUG,"Unhandled purpose %d", purpose);
tor_fragile_assert();
@@ -1554,8 +2880,7 @@ circuit_append_new_exit(origin_circuit_t *circ, extend_info_t *exit)
state = circ->build_state;
tor_assert(state);
- if (state->chosen_exit)
- extend_info_free(state->chosen_exit);
+ extend_info_free(state->chosen_exit);
state->chosen_exit = extend_info_dup(exit);
++circ->build_state->desired_path_len;
@@ -1677,8 +3002,7 @@ choose_good_middle_server(uint8_t purpose,
flags |= CRN_NEED_CAPACITY;
if (options->_AllowInvalid & ALLOW_INVALID_MIDDLE)
flags |= CRN_ALLOW_INVALID;
- choice = router_choose_random_node(NULL,
- excluded, options->ExcludeNodes, flags);
+ choice = router_choose_random_node(excluded, options->ExcludeNodes, flags);
smartlist_free(excluded);
return choice;
}
@@ -1742,11 +3066,7 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state)
if (options->_AllowInvalid & ALLOW_INVALID_ENTRY)
flags |= CRN_ALLOW_INVALID;
- choice = router_choose_random_node(
- NULL,
- excluded,
- options->ExcludeNodes,
- flags);
+ choice = router_choose_random_node(excluded, options->ExcludeNodes, flags);
smartlist_free(excluded);
return choice;
}
@@ -1867,9 +3187,9 @@ extend_info_from_router(routerinfo_t *r)
void
extend_info_free(extend_info_t *info)
{
- tor_assert(info);
- if (info->onion_key)
- crypto_free_pk_env(info->onion_key);
+ if (!info)
+ return;
+ crypto_free_pk_env(info->onion_key);
tor_free(info);
}
@@ -1928,8 +3248,6 @@ entry_guard_set_status(entry_guard_t *e, routerinfo_t *ri,
char buf[HEX_DIGEST_LEN+1];
int changed = 0;
- tor_assert(options);
-
*reason = NULL;
/* Do we want to mark this guard as bad? */
@@ -1992,35 +3310,58 @@ entry_is_time_to_retry(entry_guard_t *e, time_t now)
* - Listed as either up or never yet contacted;
* - Present in the routerlist;
* - Listed as 'stable' or 'fast' by the current dirserver consensus,
- * if demanded by <b>need_uptime</b> or <b>need_capacity</b>;
- * (This check is currently redundant with the Guard flag, but in
- * the future that might change. Best to leave it in for now.)
+ * if demanded by <b>need_uptime</b> or <b>need_capacity</b>
+ * (unless it's a configured EntryNode);
* - Allowed by our current ReachableORAddresses config option; and
- * - Currently thought to be reachable by us (unless assume_reachable
+ * - Currently thought to be reachable by us (unless <b>assume_reachable</b>
* is true).
+ *
+ * If the answer is no, set *<b>msg</b> to an explanation of why.
*/
static INLINE routerinfo_t *
entry_is_live(entry_guard_t *e, int need_uptime, int need_capacity,
- int assume_reachable)
+ int assume_reachable, const char **msg)
{
routerinfo_t *r;
- if (e->bad_since)
+ or_options_t *options = get_options();
+ tor_assert(msg);
+
+ if (e->bad_since) {
+ *msg = "bad";
return NULL;
+ }
/* no good if it's unreachable, unless assume_unreachable or can_retry. */
if (!assume_reachable && !e->can_retry &&
- e->unreachable_since && !entry_is_time_to_retry(e, time(NULL)))
+ e->unreachable_since && !entry_is_time_to_retry(e, time(NULL))) {
+ *msg = "unreachable";
return NULL;
+ }
r = router_get_by_digest(e->identity);
- if (!r)
+ if (!r) {
+ *msg = "no descriptor";
return NULL;
- if (get_options()->UseBridges && r->purpose != ROUTER_PURPOSE_BRIDGE)
+ }
+ if (get_options()->UseBridges && r->purpose != ROUTER_PURPOSE_BRIDGE) {
+ *msg = "not a bridge";
return NULL;
- if (!get_options()->UseBridges && r->purpose != ROUTER_PURPOSE_GENERAL)
+ }
+ if (!get_options()->UseBridges && r->purpose != ROUTER_PURPOSE_GENERAL) {
+ *msg = "not general-purpose";
return NULL;
- if (router_is_unreliable(r, need_uptime, need_capacity, 0))
+ }
+ if (options->EntryNodes &&
+ routerset_contains_router(options->EntryNodes, r)) {
+ /* they asked for it, they get it */
+ need_uptime = need_capacity = 0;
+ }
+ if (router_is_unreliable(r, need_uptime, need_capacity, 0)) {
+ *msg = "not fast/stable";
return NULL;
- if (!fascist_firewall_allows_or(r))
+ }
+ if (!fascist_firewall_allows_or(r)) {
+ *msg = "unreachable by config";
return NULL;
+ }
return r;
}
@@ -2029,11 +3370,12 @@ static int
num_live_entry_guards(void)
{
int n = 0;
+ const char *msg;
if (! entry_guards)
return 0;
SMARTLIST_FOREACH(entry_guards, entry_guard_t *, entry,
{
- if (entry_is_live(entry, 0, 1, 0))
+ if (entry_is_live(entry, 0, 1, 0, &msg))
++n;
});
return n;
@@ -2057,16 +3399,21 @@ static void
log_entry_guards(int severity)
{
smartlist_t *elements = smartlist_create();
- char buf[1024];
char *s;
SMARTLIST_FOREACH(entry_guards, entry_guard_t *, e,
{
- tor_snprintf(buf, sizeof(buf), "%s (%s%s)",
- e->nickname,
- entry_is_live(e, 0, 1, 0) ? "up " : "down ",
- e->made_contact ? "made-contact" : "never-contacted");
- smartlist_add(elements, tor_strdup(buf));
+ const char *msg = NULL;
+ char *cp;
+ if (entry_is_live(e, 0, 1, 0, &msg))
+ tor_asprintf(&cp, "%s (up %s)",
+ e->nickname,
+ e->made_contact ? "made-contact" : "never-contacted");
+ else
+ tor_asprintf(&cp, "%s (%s, %s)",
+ e->nickname, msg,
+ e->made_contact ? "made-contact" : "never-contacted");
+ smartlist_add(elements, cp);
});
s = smartlist_join_strings(elements, ",", 0, NULL);
@@ -2090,12 +3437,13 @@ control_event_guard_deferred(void)
**/
#if 0
int n = 0;
+ const char *msg;
or_options_t *options = get_options();
if (!entry_guards)
return;
SMARTLIST_FOREACH(entry_guards, entry_guard_t *, entry,
{
- if (entry_is_live(entry, 0, 1, 0)) {
+ if (entry_is_live(entry, 0, 1, 0, &msg)) {
if (n++ == options->NumEntryGuards) {
control_event_guard(entry->nickname, entry->identity, "DEFERRED");
return;
@@ -2157,9 +3505,8 @@ add_an_entry_guard(routerinfo_t *chosen, int reset_status)
/** If the use of entry guards is configured, choose more entry guards
* until we have enough in the list. */
static void
-pick_entry_guards(void)
+pick_entry_guards(or_options_t *options)
{
- or_options_t *options = get_options();
int changed = 0;
tor_assert(entry_guards);
@@ -2181,7 +3528,8 @@ pick_entry_guards(void)
static void
entry_guard_free(entry_guard_t *e)
{
- tor_assert(e);
+ if (!e)
+ return;
tor_free(e->chosen_by_version);
tor_free(e);
}
@@ -2190,10 +3538,9 @@ entry_guard_free(entry_guard_t *e)
* or which was selected by a version of Tor that's known to select
* entry guards badly. */
static int
-remove_obsolete_entry_guards(void)
+remove_obsolete_entry_guards(time_t now)
{
int changed = 0, i;
- time_t now = time(NULL);
for (i = 0; i < smartlist_len(entry_guards); ++i) {
entry_guard_t *entry = smartlist_get(entry_guards, i);
@@ -2253,11 +3600,10 @@ remove_obsolete_entry_guards(void)
* long that we don't think they'll come up again. Return 1 if we
* removed any, or 0 if we did nothing. */
static int
-remove_dead_entry_guards(void)
+remove_dead_entry_guards(time_t now)
{
char dbuf[HEX_DIGEST_LEN+1];
char tbuf[ISO_TIME_LEN+1];
- time_t now = time(NULL);
int i;
int changed = 0;
@@ -2292,19 +3638,17 @@ remove_dead_entry_guards(void)
* think that things are unlisted.
*/
void
-entry_guards_compute_status(void)
+entry_guards_compute_status(or_options_t *options, time_t now)
{
- time_t now;
int changed = 0;
int severity = LOG_DEBUG;
- or_options_t *options;
digestmap_t *reasons;
+
if (! entry_guards)
return;
- options = get_options();
-
- now = time(NULL);
+ if (options->EntryNodes) /* reshuffle the entry guard list if needed */
+ entry_nodes_should_be_added();
reasons = digestmap_new();
SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry)
@@ -2321,7 +3665,7 @@ entry_guards_compute_status(void)
}
SMARTLIST_FOREACH_END(entry);
- if (remove_dead_entry_guards())
+ if (remove_dead_entry_guards(now))
changed = 1;
severity = changed ? LOG_DEBUG : LOG_INFO;
@@ -2329,13 +3673,16 @@ entry_guards_compute_status(void)
if (changed) {
SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry) {
const char *reason = digestmap_get(reasons, entry->identity);
- log_info(LD_CIRC, "Summary: Entry '%s' is %s, %s%s%s, and %s.",
+ const char *live_msg = "";
+ routerinfo_t *r = entry_is_live(entry, 0, 1, 0, &live_msg);
+ log_info(LD_CIRC, "Summary: Entry '%s' is %s, %s%s%s, and %s%s.",
entry->nickname,
entry->unreachable_since ? "unreachable" : "reachable",
entry->bad_since ? "unusable" : "usable",
reason ? ", ": "",
reason ? reason : "",
- entry_is_live(entry, 0, 1, 0) ? "live" : "not live");
+ r ? "live" : "not live / ",
+ r ? "" : live_msg);
} SMARTLIST_FOREACH_END(entry);
log_info(LD_CIRC, " (%d/%d entry guards are usable/new)",
num_live_entry_guards(), smartlist_len(entry_guards));
@@ -2406,6 +3753,7 @@ entry_guard_register_connect_status(const char *digest, int succeeded,
"Removing from the list. %d/%d entry guards usable/new.",
entry->nickname, buf,
num_live_entry_guards()-1, smartlist_len(entry_guards)-1);
+ control_event_guard(entry->nickname, entry->identity, "DROPPED");
entry_guard_free(entry);
smartlist_del_keeporder(entry_guards, idx);
log_entry_guards(LOG_INFO);
@@ -2442,7 +3790,8 @@ entry_guard_register_connect_status(const char *digest, int succeeded,
if (e == entry)
break;
if (e->made_contact) {
- routerinfo_t *r = entry_is_live(e, 0, 1, 1);
+ const char *msg;
+ routerinfo_t *r = entry_is_live(e, 0, 1, 1, &msg);
if (r && e->unreachable_since) {
refuse_conn = 1;
e->can_retry = 1;
@@ -2473,16 +3822,16 @@ static int should_add_entry_nodes = 0;
void
entry_nodes_should_be_added(void)
{
- log_info(LD_CIRC, "New EntryNodes config option detected. Will use.");
+ log_info(LD_CIRC, "EntryNodes config option set. Putting configured "
+ "relays at the front of the entry guard list.");
should_add_entry_nodes = 1;
}
/** Add all nodes in EntryNodes that aren't currently guard nodes to the list
* of guard nodes, at the front. */
static void
-entry_guards_prepend_from_config(void)
+entry_guards_prepend_from_config(or_options_t *options)
{
- or_options_t *options = get_options();
smartlist_t *entry_routers, *entry_fps;
smartlist_t *old_entry_guards_on_list, *old_entry_guards_not_on_list;
tor_assert(entry_guards);
@@ -2497,7 +3846,7 @@ entry_guards_prepend_from_config(void)
return;
}
- if (options->EntryNodes) {
+ {
char *string = routerset_to_string(options->EntryNodes);
log_info(LD_CIRC,"Adding configured EntryNodes '%s'.", string);
tor_free(string);
@@ -2541,8 +3890,9 @@ entry_guards_prepend_from_config(void)
SMARTLIST_FOREACH(entry_routers, routerinfo_t *, ri, {
add_an_entry_guard(ri, 0);
});
- /* Finally, the remaining EntryNodes, unless we're strict */
- if (options->StrictEntryNodes) {
+ /* Finally, the remaining previously configured guards that are not in
+ * EntryNodes, unless we're strict in which case we drop them */
+ if (options->StrictNodes) {
SMARTLIST_FOREACH(old_entry_guards_not_on_list, entry_guard_t *, e,
entry_guard_free(e));
} else {
@@ -2556,16 +3906,30 @@ entry_guards_prepend_from_config(void)
entry_guards_changed();
}
-/** Return 1 if we're fine adding arbitrary routers out of the
- * directory to our entry guard list. Else return 0. */
+/** Return 0 if we're fine adding arbitrary routers out of the
+ * directory to our entry guard list, or return 1 if we have a
+ * list already and we'd prefer to stick to it.
+ */
int
-entry_list_can_grow(or_options_t *options)
+entry_list_is_constrained(or_options_t *options)
{
- if (options->StrictEntryNodes)
- return 0;
+ if (options->EntryNodes)
+ return 1;
if (options->UseBridges)
- return 0;
- return 1;
+ return 1;
+ return 0;
+}
+
+/* Are we dead set against changing our entry guard list, or would we
+ * change it if it means keeping Tor usable? */
+static int
+entry_list_is_totally_static(or_options_t *options)
+{
+ if (options->EntryNodes && options->StrictNodes)
+ return 1;
+ if (options->UseBridges)
+ return 1;
+ return 0;
}
/** Pick a live (up and listed) entry guard from entry_guards. If
@@ -2583,7 +3947,7 @@ choose_random_entry(cpath_build_state_t *state)
routerinfo_t *r = NULL;
int need_uptime = state ? state->need_uptime : 0;
int need_capacity = state ? state->need_capacity : 0;
- int consider_exit_family = 0;
+ int preferred_min, consider_exit_family = 0;
if (chosen_exit) {
smartlist_add(exit_family, chosen_exit);
@@ -2595,38 +3959,62 @@ choose_random_entry(cpath_build_state_t *state)
entry_guards = smartlist_create();
if (should_add_entry_nodes)
- entry_guards_prepend_from_config();
+ entry_guards_prepend_from_config(options);
- if (entry_list_can_grow(options) &&
- (! entry_guards ||
- smartlist_len(entry_guards) < options->NumEntryGuards))
- pick_entry_guards();
+ if (!entry_list_is_constrained(options) &&
+ smartlist_len(entry_guards) < options->NumEntryGuards)
+ pick_entry_guards(options);
retry:
smartlist_clear(live_entry_guards);
SMARTLIST_FOREACH(entry_guards, entry_guard_t *, entry,
{
- r = entry_is_live(entry, need_uptime, need_capacity, 0);
- if (r && (!consider_exit_family || !smartlist_isin(exit_family, r))) {
- smartlist_add(live_entry_guards, r);
- if (!entry->made_contact) {
- /* Always start with the first not-yet-contacted entry
- * guard. Otherwise we might add several new ones, pick
- * the second new one, and now we've expanded our entry
- * guard list without needing to. */
- goto choose_and_finish;
+ const char *msg;
+ r = entry_is_live(entry, need_uptime, need_capacity, 0, &msg);
+ if (!r)
+ continue; /* down, no point */
+ if (consider_exit_family && smartlist_isin(exit_family, r))
+ continue; /* avoid relays that are family members of our exit */
+ if (options->EntryNodes &&
+ !routerset_contains_router(options->EntryNodes, r)) {
+ /* We've come to the end of our preferred entry nodes. */
+ if (smartlist_len(live_entry_guards))
+ goto choose_and_finish; /* only choose from the ones we like */
+ if (options->StrictNodes) {
+ /* in theory this case should never happen, since
+ * entry_guards_prepend_from_config() drops unwanted relays */
+ tor_fragile_assert();
+ } else {
+ log_info(LD_CIRC,
+ "No relays from EntryNodes available. Using others.");
}
- if (smartlist_len(live_entry_guards) >= options->NumEntryGuards)
- break; /* we have enough */
}
+ smartlist_add(live_entry_guards, r);
+ if (!entry->made_contact) {
+ /* Always start with the first not-yet-contacted entry
+ * guard. Otherwise we might add several new ones, pick
+ * the second new one, and now we've expanded our entry
+ * guard list without needing to. */
+ goto choose_and_finish;
+ }
+ if (smartlist_len(live_entry_guards) >= options->NumEntryGuards)
+ break; /* we have enough */
});
- /* Try to have at least 2 choices available. This way we don't
- * get stuck with a single live-but-crummy entry and just keep
- * using him.
- * (We might get 2 live-but-crummy entry guards, but so be it.) */
- if (smartlist_len(live_entry_guards) < 2) {
- if (entry_list_can_grow(options)) {
+ if (entry_list_is_constrained(options)) {
+ /* If we prefer the entry nodes we've got, and we have at least
+ * one choice, that's great. Use it. */
+ preferred_min = 1;
+ } else {
+ /* Try to have at least 2 choices available. This way we don't
+ * get stuck with a single live-but-crummy entry and just keep
+ * using him.
+ * (We might get 2 live-but-crummy entry guards, but so be it.) */
+ preferred_min = 2;
+ }
+
+ if (smartlist_len(live_entry_guards) < preferred_min) {
+ if (!entry_list_is_totally_static(options)) {
/* still no? try adding a new entry then */
/* XXX if guard doesn't imply fast and stable, then we need
* to tell add_an_entry_guard below what we want, or it might
@@ -2651,7 +4039,7 @@ choose_random_entry(cpath_build_state_t *state)
need_capacity = 0;
goto retry;
}
- if (!r && !entry_list_can_grow(options) && consider_exit_family) {
+ if (!r && entry_list_is_constrained(options) && consider_exit_family) {
/* still no? if we're using bridges or have strictentrynodes
* set, and our chosen exit is in the same family as all our
* bridges/entry guards, then be flexible about families. */
@@ -2662,15 +4050,15 @@ choose_random_entry(cpath_build_state_t *state)
}
choose_and_finish:
- if (entry_list_can_grow(options)) {
+ if (entry_list_is_constrained(options)) {
+ /* We need to weight by bandwidth, because our bridges or entryguards
+ * were not already selected proportional to their bandwidth. */
+ r = routerlist_sl_choose_by_bandwidth(live_entry_guards, WEIGHT_FOR_GUARD);
+ } else {
/* We choose uniformly at random here, because choose_good_entry_server()
* already weights its choices by bandwidth, so we don't want to
* *double*-weight our guard selection. */
r = smartlist_choose(live_entry_guards);
- } else {
- /* We need to weight by bandwidth, because our bridges or entryguards
- * were not already selected proportional to their bandwidth. */
- r = routerlist_sl_choose_by_bandwidth(live_entry_guards, WEIGHT_FOR_GUARD);
}
smartlist_free(live_entry_guards);
smartlist_free(exit_family);
@@ -2804,7 +4192,7 @@ entry_guards_parse_state(or_state_t *state, int set, char **msg)
entry_guards_dirty = 0;
/* XXX022 hand new_entry_guards to this func, and move it up a
* few lines, so we don't have to re-dirty it */
- if (remove_obsolete_entry_guards())
+ if (remove_obsolete_entry_guards(now))
entry_guards_dirty = 1;
}
digestmap_free(added_by, _tor_free);
@@ -2903,9 +4291,11 @@ entry_guards_update_state(or_state_t *state)
* */
int
getinfo_helper_entry_guards(control_connection_t *conn,
- const char *question, char **answer)
+ const char *question, char **answer,
+ const char **errmsg)
{
- int use_long_names = conn->use_long_names;
+ (void) conn;
+ (void) errmsg;
if (!strcmp(question,"entry-guards") ||
!strcmp(question,"helper-nodes")) {
@@ -2914,12 +4304,13 @@ getinfo_helper_entry_guards(control_connection_t *conn,
char nbuf[MAX_VERBOSE_NICKNAME_LEN+1];
if (!entry_guards)
entry_guards = smartlist_create();
- SMARTLIST_FOREACH(entry_guards, entry_guard_t *, e,
- {
+ SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, e) {
size_t len = MAX_VERBOSE_NICKNAME_LEN+ISO_TIME_LEN+32;
char *c = tor_malloc(len);
const char *status = NULL;
time_t when = 0;
+ routerinfo_t *ri;
+
if (!e->made_contact) {
status = "never-connected";
} else if (e->bad_since) {
@@ -2928,19 +4319,17 @@ getinfo_helper_entry_guards(control_connection_t *conn,
} else {
status = "up";
}
- if (use_long_names) {
- routerinfo_t *ri = router_get_by_digest(e->identity);
- if (ri) {
- router_get_verbose_nickname(nbuf, ri);
- } else {
- nbuf[0] = '$';
- base16_encode(nbuf+1, sizeof(nbuf)-1, e->identity, DIGEST_LEN);
- /* e->nickname field is not very reliable if we don't know about
- * this router any longer; don't include it. */
- }
+
+ ri = router_get_by_digest(e->identity);
+ if (ri) {
+ router_get_verbose_nickname(nbuf, ri);
} else {
- base16_encode(nbuf, sizeof(nbuf), e->identity, DIGEST_LEN);
+ nbuf[0] = '$';
+ base16_encode(nbuf+1, sizeof(nbuf)-1, e->identity, DIGEST_LEN);
+ /* e->nickname field is not very reliable if we don't know about
+ * this router any longer; don't include it. */
}
+
if (when) {
format_iso_time(tbuf, when);
tor_snprintf(c, len, "%s %s %s\n", nbuf, status, tbuf);
@@ -2948,7 +4337,7 @@ getinfo_helper_entry_guards(control_connection_t *conn,
tor_snprintf(c, len, "%s %s\n", nbuf, status);
}
smartlist_add(sl, c);
- });
+ } SMARTLIST_FOREACH_END(e);
*answer = smartlist_join_strings(sl, "", 0, NULL);
SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
smartlist_free(sl);
@@ -2989,29 +4378,56 @@ clear_bridge_list(void)
* (either by comparing keys if possible, else by comparing addr/port).
* Else return NULL. */
static bridge_info_t *
-routerinfo_get_configured_bridge(routerinfo_t *ri)
+get_configured_bridge_by_addr_port_digest(tor_addr_t *addr, uint16_t port,
+ const char *digest)
{
if (!bridge_list)
return NULL;
SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge)
{
if (tor_digest_is_zero(bridge->identity) &&
- tor_addr_eq_ipv4h(&bridge->addr, ri->addr) &&
- bridge->port == ri->or_port)
+ !tor_addr_compare(&bridge->addr, addr, CMP_EXACT) &&
+ bridge->port == port)
return bridge;
- if (!memcmp(bridge->identity, ri->cache_info.identity_digest,
- DIGEST_LEN))
+ if (!memcmp(bridge->identity, digest, DIGEST_LEN))
return bridge;
}
SMARTLIST_FOREACH_END(bridge);
return NULL;
}
+/** Wrapper around get_configured_bridge_by_addr_port_digest() to look
+ * it up via router descriptor <b>ri</b>. */
+static bridge_info_t *
+get_configured_bridge_by_routerinfo(routerinfo_t *ri)
+{
+ tor_addr_t addr;
+ tor_addr_from_ipv4h(&addr, ri->addr);
+ return get_configured_bridge_by_addr_port_digest(&addr,
+ ri->or_port, ri->cache_info.identity_digest);
+}
+
/** Return 1 if <b>ri</b> is one of our known bridges, else 0. */
int
routerinfo_is_a_configured_bridge(routerinfo_t *ri)
{
- return routerinfo_get_configured_bridge(ri) ? 1 : 0;
+ return get_configured_bridge_by_routerinfo(ri) ? 1 : 0;
+}
+
+/** We made a connection to a router at <b>addr</b>:<b>port</b>
+ * without knowing its digest. Its digest turned out to be <b>digest</b>.
+ * If it was a bridge, and we still don't know its digest, record it.
+ */
+void
+learned_router_identity(tor_addr_t *addr, uint16_t port, const char *digest)
+{
+ bridge_info_t *bridge =
+ get_configured_bridge_by_addr_port_digest(addr, port, digest);
+ if (bridge && tor_digest_is_zero(bridge->identity)) {
+ memcpy(bridge->identity, digest, DIGEST_LEN);
+ log_notice(LD_DIR, "Learned fingerprint %s for bridge %s:%d",
+ hex_str(digest, DIGEST_LEN), fmt_addr(addr), port);
+ }
}
/** Remember a new bridge at <b>addr</b>:<b>port</b>. If <b>digest</b>
@@ -3081,9 +4497,8 @@ retry_bridge_descriptor_fetch_directly(const char *digest)
* descriptor, fetch a new copy of its descriptor -- either directly
* from the bridge or via a bridge authority. */
void
-fetch_bridge_descriptors(time_t now)
+fetch_bridge_descriptors(or_options_t *options, time_t now)
{
- or_options_t *options = get_options();
int num_bridge_auths = get_n_authorities(BRIDGE_AUTHORITY);
int ask_bridge_directly;
int can_use_bridge_authority;
@@ -3151,7 +4566,7 @@ learned_bridge_descriptor(routerinfo_t *ri, int from_cache)
tor_assert(ri->purpose == ROUTER_PURPOSE_BRIDGE);
if (get_options()->UseBridges) {
int first = !any_bridge_descriptors_known();
- bridge_info_t *bridge = routerinfo_get_configured_bridge(ri);
+ bridge_info_t *bridge = get_configured_bridge_by_routerinfo(ri);
time_t now = time(NULL);
ri->is_running = 1;
@@ -3207,26 +4622,38 @@ any_pending_bridge_descriptor_fetches(void)
return 0;
}
-/** Return 1 if we have at least one descriptor for a bridge and
- * all descriptors we know are down. Else return 0. If <b>act</b> is
- * 1, then mark the down bridges up; else just observe and report. */
+/** Return 1 if we have at least one descriptor for an entry guard
+ * (bridge or member of EntryNodes) and all descriptors we know are
+ * down. Else return 0. If <b>act</b> is 1, then mark the down guards
+ * up; else just observe and report. */
static int
-bridges_retry_helper(int act)
+entries_retry_helper(or_options_t *options, int act)
{
routerinfo_t *ri;
int any_known = 0;
int any_running = 0;
+ int purpose = options->UseBridges ?
+ ROUTER_PURPOSE_BRIDGE : ROUTER_PURPOSE_GENERAL;
if (!entry_guards)
entry_guards = smartlist_create();
SMARTLIST_FOREACH(entry_guards, entry_guard_t *, e,
{
ri = router_get_by_digest(e->identity);
- if (ri && ri->purpose == ROUTER_PURPOSE_BRIDGE) {
+ if (ri && ri->purpose == purpose) {
any_known = 1;
if (ri->is_running)
- any_running = 1; /* some bridge is both known and running */
- else if (act) { /* mark it for retry */
- ri->is_running = 1;
+ any_running = 1; /* some entry is both known and running */
+ else if (act) {
+ /* Mark all current connections to this OR as unhealthy, since
+ * otherwise there could be one that started 30 seconds
+ * ago, and in 30 seconds it will time out, causing us to mark
+ * the node down and undermine the retry attempt. We mark even
+ * the established conns, since if the network just came back
+ * we'll want to attach circuits to fresh conns. */
+ connection_or_set_bad_connections(ri->cache_info.identity_digest, 1);
+
+ /* mark this entry node for retry */
+ router_set_status(ri->cache_info.identity_digest, 1);
e->can_retry = 1;
e->bad_since = 0;
}
@@ -3237,19 +4664,21 @@ bridges_retry_helper(int act)
return any_known && !any_running;
}
-/** Do we know any descriptors for our bridges, and are they all
- * down? */
+/** Do we know any descriptors for our bridges / entrynodes, and are
+ * all the ones we have descriptors for down? */
int
-bridges_known_but_down(void)
+entries_known_but_down(or_options_t *options)
{
- return bridges_retry_helper(0);
+ tor_assert(entry_list_is_constrained(options));
+ return entries_retry_helper(options, 0);
}
-/** Mark all down known bridges up. */
+/** Mark all down known bridges / entrynodes up. */
void
-bridges_retry_all(void)
+entries_retry_all(or_options_t *options)
{
- bridges_retry_helper(1);
+ tor_assert(entry_list_is_constrained(options));
+ entries_retry_helper(options, 1);
}
/** Release all storage held by the list of entry guards and related
diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h
new file mode 100644
index 0000000000..a85c410133
--- /dev/null
+++ b/src/or/circuitbuild.h
@@ -0,0 +1,125 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file circuitbuild.h
+ * \brief Header file for circuitbuild.c.
+ **/
+
+#ifndef _TOR_CIRCUITBUILD_H
+#define _TOR_CIRCUITBUILD_H
+
+char *circuit_list_path(origin_circuit_t *circ, int verbose);
+char *circuit_list_path_for_controller(origin_circuit_t *circ);
+void circuit_log_path(int severity, unsigned int domain,
+ origin_circuit_t *circ);
+void circuit_rep_hist_note_result(origin_circuit_t *circ);
+origin_circuit_t *origin_circuit_init(uint8_t purpose, int flags);
+origin_circuit_t *circuit_establish_circuit(uint8_t purpose,
+ extend_info_t *exit,
+ int flags);
+int circuit_handle_first_hop(origin_circuit_t *circ);
+void circuit_n_conn_done(or_connection_t *or_conn, int status);
+int inform_testing_reachability(void);
+int circuit_timeout_want_to_count_circ(origin_circuit_t *circ);
+int circuit_send_next_onion_skin(origin_circuit_t *circ);
+void circuit_note_clock_jumped(int seconds_elapsed);
+int circuit_extend(cell_t *cell, circuit_t *circ);
+int circuit_init_cpath_crypto(crypt_path_t *cpath, const char *key_data,
+ int reverse);
+int circuit_finish_handshake(origin_circuit_t *circ, uint8_t cell_type,
+ const uint8_t *reply);
+int circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer);
+int onionskin_answer(or_circuit_t *circ, uint8_t cell_type,
+ const char *payload, const char *keys);
+int circuit_all_predicted_ports_handled(time_t now, int *need_uptime,
+ int *need_capacity);
+
+int circuit_append_new_exit(origin_circuit_t *circ, extend_info_t *info);
+int circuit_extend_to_new_exit(origin_circuit_t *circ, extend_info_t *info);
+void onion_append_to_cpath(crypt_path_t **head_ptr, crypt_path_t *new_hop);
+extend_info_t *extend_info_alloc(const char *nickname, const char *digest,
+ crypto_pk_env_t *onion_key,
+ const tor_addr_t *addr, uint16_t port);
+extend_info_t *extend_info_from_router(routerinfo_t *r);
+extend_info_t *extend_info_dup(extend_info_t *info);
+void extend_info_free(extend_info_t *info);
+routerinfo_t *build_state_get_exit_router(cpath_build_state_t *state);
+const char *build_state_get_exit_nickname(cpath_build_state_t *state);
+
+void entry_guards_compute_status(or_options_t *options, time_t now);
+int entry_guard_register_connect_status(const char *digest, int succeeded,
+ int mark_relay_status, time_t now);
+void entry_nodes_should_be_added(void);
+int entry_list_is_constrained(or_options_t *options);
+routerinfo_t *choose_random_entry(cpath_build_state_t *state);
+int entry_guards_parse_state(or_state_t *state, int set, char **msg);
+void entry_guards_update_state(or_state_t *state);
+int getinfo_helper_entry_guards(control_connection_t *conn,
+ const char *question, char **answer,
+ const char **errmsg);
+
+void clear_bridge_list(void);
+int routerinfo_is_a_configured_bridge(routerinfo_t *ri);
+void
+learned_router_identity(tor_addr_t *addr, uint16_t port, const char *digest);
+void bridge_add_from_config(const tor_addr_t *addr, uint16_t port,
+ char *digest);
+void retry_bridge_descriptor_fetch_directly(const char *digest);
+void fetch_bridge_descriptors(or_options_t *options, time_t now);
+void learned_bridge_descriptor(routerinfo_t *ri, int from_cache);
+int any_bridge_descriptors_known(void);
+int any_pending_bridge_descriptor_fetches(void);
+int entries_known_but_down(or_options_t *options);
+void entries_retry_all(or_options_t *options);
+
+void entry_guards_free_all(void);
+
+extern circuit_build_times_t circ_times;
+int circuit_build_times_enough_to_compute(circuit_build_times_t *cbt);
+void circuit_build_times_update_state(circuit_build_times_t *cbt,
+ or_state_t *state);
+int circuit_build_times_parse_state(circuit_build_times_t *cbt,
+ or_state_t *state);
+void circuit_build_times_count_timeout(circuit_build_times_t *cbt,
+ int did_onehop);
+int circuit_build_times_count_close(circuit_build_times_t *cbt,
+ int did_onehop, time_t start_time);
+void circuit_build_times_set_timeout(circuit_build_times_t *cbt);
+int circuit_build_times_add_time(circuit_build_times_t *cbt,
+ build_time_t time);
+int circuit_build_times_needs_circuits(circuit_build_times_t *cbt);
+
+int circuit_build_times_needs_circuits_now(circuit_build_times_t *cbt);
+void circuit_build_times_init(circuit_build_times_t *cbt);
+void circuit_build_times_new_consensus_params(circuit_build_times_t *cbt,
+ networkstatus_t *ns);
+double circuit_build_times_timeout_rate(const circuit_build_times_t *cbt);
+double circuit_build_times_close_rate(const circuit_build_times_t *cbt);
+
+#ifdef CIRCUIT_PRIVATE
+double circuit_build_times_calculate_timeout(circuit_build_times_t *cbt,
+ double quantile);
+build_time_t circuit_build_times_generate_sample(circuit_build_times_t *cbt,
+ double q_lo, double q_hi);
+void circuit_build_times_initial_alpha(circuit_build_times_t *cbt,
+ double quantile, double time_ms);
+int circuit_build_times_update_alpha(circuit_build_times_t *cbt);
+double circuit_build_times_cdf(circuit_build_times_t *cbt, double x);
+void circuitbuild_running_unit_tests(void);
+void circuit_build_times_reset(circuit_build_times_t *cbt);
+
+/* Network liveness functions */
+int circuit_build_times_network_check_changed(circuit_build_times_t *cbt);
+#endif
+
+/* Network liveness functions */
+void circuit_build_times_network_is_live(circuit_build_times_t *cbt);
+int circuit_build_times_network_check_live(circuit_build_times_t *cbt);
+void circuit_build_times_network_circ_success(circuit_build_times_t *cbt);
+
+#endif
+
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index b84d7f7623..fb4b69be0d 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -10,6 +10,21 @@
**/
#include "or.h"
+#include "circuitbuild.h"
+#include "circuitlist.h"
+#include "circuituse.h"
+#include "connection.h"
+#include "config.h"
+#include "connection_edge.h"
+#include "connection_or.h"
+#include "control.h"
+#include "networkstatus.h"
+#include "onion.h"
+#include "relay.h"
+#include "rendclient.h"
+#include "rendcommon.h"
+#include "rephist.h"
+#include "routerlist.h"
#include "ht.h"
/********* START VARIABLES **********/
@@ -352,6 +367,8 @@ circuit_purpose_to_controller_string(uint8_t purpose)
case CIRCUIT_PURPOSE_TESTING:
return "TESTING";
+ case CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT:
+ return "MEASURE_TIMEOUT";
case CIRCUIT_PURPOSE_CONTROLLER:
return "CONTROLLER";
@@ -380,10 +397,17 @@ static void
init_circuit_base(circuit_t *circ)
{
circ->timestamp_created = time(NULL);
+ tor_gettimeofday(&circ->highres_created);
circ->package_window = circuit_initial_package_window();
circ->deliver_window = CIRCWINDOW_START;
+ /* Initialize the cell_ewma_t structure */
+ circ->n_cell_ewma.last_adjusted_tick = cell_ewma_get_tick();
+ circ->n_cell_ewma.cell_count = 0.0;
+ circ->n_cell_ewma.heap_index = -1;
+ circ->n_cell_ewma.is_for_p_conn = 0;
+
circuit_add(circ);
}
@@ -408,6 +432,8 @@ origin_circuit_new(void)
init_circuit_base(TO_CIRCUIT(circ));
+ circ_times.last_circ_at = approx_time();
+
return circ;
}
@@ -429,6 +455,16 @@ or_circuit_new(circid_t p_circ_id, or_connection_t *p_conn)
init_circuit_base(TO_CIRCUIT(circ));
+ /* Initialize the cell_ewma_t structure */
+
+ /* Initialize the cell counts to 0 */
+ circ->p_cell_ewma.cell_count = 0.0;
+ circ->p_cell_ewma.last_adjusted_tick = cell_ewma_get_tick();
+ circ->p_cell_ewma.is_for_p_conn = 1;
+
+ /* It's not in any heap yet. */
+ circ->p_cell_ewma.heap_index = -1;
+
return circ;
}
@@ -439,39 +475,37 @@ circuit_free(circuit_t *circ)
{
void *mem;
size_t memlen;
- tor_assert(circ);
+ if (!circ)
+ return;
+
if (CIRCUIT_IS_ORIGIN(circ)) {
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
mem = ocirc;
memlen = sizeof(origin_circuit_t);
tor_assert(circ->magic == ORIGIN_CIRCUIT_MAGIC);
if (ocirc->build_state) {
- if (ocirc->build_state->chosen_exit)
extend_info_free(ocirc->build_state->chosen_exit);
- if (ocirc->build_state->pending_final_cpath)
circuit_free_cpath_node(ocirc->build_state->pending_final_cpath);
}
tor_free(ocirc->build_state);
circuit_free_cpath(ocirc->cpath);
- if (ocirc->intro_key)
- crypto_free_pk_env(ocirc->intro_key);
- if (ocirc->rend_data)
- rend_data_free(ocirc->rend_data);
+
+ crypto_free_pk_env(ocirc->intro_key);
+ rend_data_free(ocirc->rend_data);
} else {
or_circuit_t *ocirc = TO_OR_CIRCUIT(circ);
+ /* Remember cell statistics for this circuit before deallocating. */
+ if (get_options()->CellStatistics)
+ rep_hist_buffer_stats_add_circ(circ, time(NULL));
mem = ocirc;
memlen = sizeof(or_circuit_t);
tor_assert(circ->magic == OR_CIRCUIT_MAGIC);
- if (ocirc->p_crypto)
- crypto_free_cipher_env(ocirc->p_crypto);
- if (ocirc->p_digest)
- crypto_free_digest_env(ocirc->p_digest);
- if (ocirc->n_crypto)
- crypto_free_cipher_env(ocirc->n_crypto);
- if (ocirc->n_digest)
- crypto_free_digest_env(ocirc->n_digest);
+ crypto_free_cipher_env(ocirc->p_crypto);
+ crypto_free_digest_env(ocirc->p_digest);
+ crypto_free_cipher_env(ocirc->n_crypto);
+ crypto_free_digest_env(ocirc->n_digest);
if (ocirc->rend_splice) {
or_circuit_t *other = ocirc->rend_splice;
@@ -487,8 +521,7 @@ circuit_free(circuit_t *circ)
cell_queue_clear(&ocirc->p_conn_cells);
}
- if (circ->n_hop)
- extend_info_free(circ->n_hop);
+ extend_info_free(circ->n_hop);
tor_free(circ->n_conn_onionskin);
/* Remove from map. */
@@ -498,7 +531,7 @@ circuit_free(circuit_t *circ)
* "active" checks will be violated. */
cell_queue_clear(&circ->n_conn_cells);
- memset(circ, 0xAA, memlen); /* poison memory */
+ memset(mem, 0xAA, memlen); /* poison memory */
tor_free(mem);
}
@@ -541,10 +574,10 @@ circuit_free_all(void)
circuit_free(global_circuitlist);
global_circuitlist = next;
}
- if (circuits_pending_or_conns) {
- smartlist_free(circuits_pending_or_conns);
- circuits_pending_or_conns = NULL;
- }
+
+ smartlist_free(circuits_pending_or_conns);
+ circuits_pending_or_conns = NULL;
+
HT_CLEAR(orconn_circid_map, &orconn_circid_circuit_map);
}
@@ -552,18 +585,15 @@ circuit_free_all(void)
static void
circuit_free_cpath_node(crypt_path_t *victim)
{
- if (victim->f_crypto)
- crypto_free_cipher_env(victim->f_crypto);
- if (victim->b_crypto)
- crypto_free_cipher_env(victim->b_crypto);
- if (victim->f_digest)
- crypto_free_digest_env(victim->f_digest);
- if (victim->b_digest)
- crypto_free_digest_env(victim->b_digest);
- if (victim->dh_handshake_state)
- crypto_dh_free(victim->dh_handshake_state);
- if (victim->extend_info)
- extend_info_free(victim->extend_info);
+ if (!victim)
+ return;
+
+ crypto_free_cipher_env(victim->f_crypto);
+ crypto_free_cipher_env(victim->b_crypto);
+ crypto_free_digest_env(victim->f_digest);
+ crypto_free_digest_env(victim->b_digest);
+ crypto_dh_free(victim->dh_handshake_state);
+ extend_info_free(victim->extend_info);
memset(victim, 0xBB, sizeof(crypt_path_t)); /* poison memory */
tor_free(victim);
@@ -892,6 +922,10 @@ circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info,
int need_capacity = (flags & CIRCLAUNCH_NEED_CAPACITY) != 0;
int internal = (flags & CIRCLAUNCH_IS_INTERNAL) != 0;
+ /* Make sure we're not trying to create a onehop circ by
+ * cannibalization. */
+ tor_assert(!(flags & CIRCLAUNCH_ONEHOP_TUNNEL));
+
log_debug(LD_CIRC,
"Hunting for a circ to cannibalize: purpose %d, uptime %d, "
"capacity %d, internal %d",
@@ -907,7 +941,8 @@ circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info,
if ((!need_uptime || circ->build_state->need_uptime) &&
(!need_capacity || circ->build_state->need_capacity) &&
(internal == circ->build_state->is_internal) &&
- circ->remaining_relay_early_cells) {
+ circ->remaining_relay_early_cells &&
+ !circ->build_state->onehop_tunnel) {
if (info) {
/* need to make sure we don't duplicate hops */
crypt_path_t *hop = circ->cpath;
@@ -1083,14 +1118,16 @@ _circuit_mark_for_close(circuit_t *circ, int reason, int line,
tor_assert(ocirc->rend_data);
/* treat this like getting a nack from it */
log_info(LD_REND, "Failed intro circ %s to %s (awaiting ack). "
- "Removing from descriptor.",
- safe_str(ocirc->rend_data->onion_address),
- safe_str(build_state_get_exit_nickname(ocirc->build_state)));
+ "Removing from descriptor.",
+ safe_str_client(ocirc->rend_data->onion_address),
+ safe_str_client(build_state_get_exit_nickname(ocirc->build_state)));
rend_client_remove_intro_point(ocirc->build_state->chosen_exit,
ocirc->rend_data);
}
- if (circ->n_conn)
+ if (circ->n_conn) {
+ circuit_clear_cell_queue(circ, circ->n_conn);
connection_or_send_destroy(circ->n_circ_id, circ->n_conn, reason);
+ }
if (! CIRCUIT_IS_ORIGIN(circ)) {
or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
@@ -1114,8 +1151,10 @@ _circuit_mark_for_close(circuit_t *circ, int reason, int line,
conn->on_circuit = NULL;
}
- if (or_circ->p_conn)
+ if (or_circ->p_conn) {
+ circuit_clear_cell_queue(circ, or_circ->p_conn);
connection_or_send_destroy(or_circ->p_circ_id, or_circ->p_conn, reason);
+ }
} else {
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
edge_connection_t *conn;
@@ -1236,11 +1275,6 @@ assert_circuit_ok(const circuit_t *c)
tor_assert(c == c2);
}
}
-#if 0 /* false now that rendezvous exits are attached to p_streams */
- if (origin_circ)
- for (conn = origin_circ->p_streams; conn; conn = conn->next_stream)
- tor_assert(conn->_base.type == CONN_TYPE_AP);
-#endif
if (or_circ)
for (conn = or_circ->n_streams; conn; conn = conn->next_stream)
tor_assert(conn->_base.type == CONN_TYPE_EXIT);
diff --git a/src/or/circuitlist.h b/src/or/circuitlist.h
new file mode 100644
index 0000000000..caca614c8c
--- /dev/null
+++ b/src/or/circuitlist.h
@@ -0,0 +1,60 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file circuitlist.h
+ * \brief Header file for circuitlist.c.
+ **/
+
+#ifndef _TOR_CIRCUITLIST_H
+#define _TOR_CIRCUITLIST_H
+
+circuit_t * _circuit_get_global_list(void);
+const char *circuit_state_to_string(int state);
+const char *circuit_purpose_to_controller_string(uint8_t purpose);
+void circuit_dump_by_conn(connection_t *conn, int severity);
+void circuit_set_p_circid_orconn(or_circuit_t *circ, circid_t id,
+ or_connection_t *conn);
+void circuit_set_n_circid_orconn(circuit_t *circ, circid_t id,
+ or_connection_t *conn);
+void circuit_set_state(circuit_t *circ, uint8_t state);
+void circuit_close_all_marked(void);
+int32_t circuit_initial_package_window(void);
+origin_circuit_t *origin_circuit_new(void);
+or_circuit_t *or_circuit_new(circid_t p_circ_id, or_connection_t *p_conn);
+circuit_t *circuit_get_by_circid_orconn(circid_t circ_id,
+ or_connection_t *conn);
+int circuit_id_in_use_on_orconn(circid_t circ_id, or_connection_t *conn);
+circuit_t *circuit_get_by_edge_conn(edge_connection_t *conn);
+void circuit_unlink_all_from_or_conn(or_connection_t *conn, int reason);
+origin_circuit_t *circuit_get_by_global_id(uint32_t id);
+origin_circuit_t *circuit_get_by_rend_query_and_purpose(const char *rend_query,
+ uint8_t purpose);
+origin_circuit_t *circuit_get_next_by_pk_and_purpose(origin_circuit_t *start,
+ const char *digest, uint8_t purpose);
+or_circuit_t *circuit_get_rendezvous(const char *cookie);
+or_circuit_t *circuit_get_intro_point(const char *digest);
+origin_circuit_t *circuit_find_to_cannibalize(uint8_t purpose,
+ extend_info_t *info, int flags);
+void circuit_mark_all_unused_circs(void);
+void circuit_expire_all_dirty_circs(void);
+void _circuit_mark_for_close(circuit_t *circ, int reason,
+ int line, const char *file);
+int circuit_get_cpath_len(origin_circuit_t *circ);
+crypt_path_t *circuit_get_cpath_hop(origin_circuit_t *circ, int hopnum);
+void circuit_get_all_pending_on_or_conn(smartlist_t *out,
+ or_connection_t *or_conn);
+int circuit_count_pending_on_or_conn(or_connection_t *or_conn);
+
+#define circuit_mark_for_close(c, reason) \
+ _circuit_mark_for_close((c), (reason), __LINE__, _SHORT_FILE_)
+
+void assert_cpath_layer_ok(const crypt_path_t *cp);
+void assert_circuit_ok(const circuit_t *c);
+void circuit_free_all(void);
+
+#endif
+
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 827c4bbf2b..3af0fb642d 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -10,6 +10,20 @@
**/
#include "or.h"
+#include "circuitbuild.h"
+#include "circuitlist.h"
+#include "circuituse.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_edge.h"
+#include "control.h"
+#include "policies.h"
+#include "rendclient.h"
+#include "rendcommon.h"
+#include "rendservice.h"
+#include "rephist.h"
+#include "router.h"
+#include "routerlist.h"
/********* START VARIABLES **********/
@@ -113,7 +127,7 @@ circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn,
return 0;
}
}
- if (exitrouter && !connection_ap_can_use_exit(conn, exitrouter)) {
+ if (exitrouter && !connection_ap_can_use_exit(conn, exitrouter, 0)) {
/* can't exit from this router */
return 0;
}
@@ -263,16 +277,22 @@ circuit_conforms_to_options(const origin_circuit_t *circ,
void
circuit_expire_building(time_t now)
{
- circuit_t *victim, *circ = global_circuitlist;
- time_t general_cutoff = now - get_options()->CircuitBuildTimeout;
- time_t begindir_cutoff = now - get_options()->CircuitBuildTimeout/2;
+ circuit_t *victim, *next_circ = global_circuitlist;
+ /* circ_times.timeout_ms and circ_times.close_ms are from
+ * circuit_build_times_get_initial_timeout() if we haven't computed
+ * custom timeouts yet */
+ time_t general_cutoff = now - tor_lround(circ_times.timeout_ms/1000);
+ time_t begindir_cutoff = now - tor_lround(circ_times.timeout_ms/2000);
+ time_t fourhop_cutoff = now - tor_lround(4*circ_times.timeout_ms/3000);
+ time_t cannibalize_cutoff = now - tor_lround(circ_times.timeout_ms/2000);
+ time_t close_cutoff = now - tor_lround(circ_times.close_ms/1000);
time_t introcirc_cutoff = begindir_cutoff;
cpath_build_state_t *build_state;
- while (circ) {
+ while (next_circ) {
time_t cutoff;
- victim = circ;
- circ = circ->next;
+ victim = next_circ;
+ next_circ = next_circ->next;
if (!CIRCUIT_IS_ORIGIN(victim) || /* didn't originate here */
victim->marked_for_close) /* don't mess with marked circs */
continue;
@@ -280,10 +300,18 @@ circuit_expire_building(time_t now)
build_state = TO_ORIGIN_CIRCUIT(victim)->build_state;
if (build_state && build_state->onehop_tunnel)
cutoff = begindir_cutoff;
+ else if (build_state && build_state->desired_path_len == 4
+ && !TO_ORIGIN_CIRCUIT(victim)->has_opened)
+ cutoff = fourhop_cutoff;
+ else if (TO_ORIGIN_CIRCUIT(victim)->has_opened)
+ cutoff = cannibalize_cutoff;
else if (victim->purpose == CIRCUIT_PURPOSE_C_INTRODUCING)
cutoff = introcirc_cutoff;
+ else if (victim->purpose == CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT)
+ cutoff = close_cutoff;
else
cutoff = general_cutoff;
+
if (victim->timestamp_created > cutoff)
continue; /* it's still young, leave it alone */
@@ -343,6 +371,54 @@ circuit_expire_building(time_t now)
continue;
break;
}
+ } else { /* circuit not open, consider recording failure as timeout */
+ int first_hop_succeeded = TO_ORIGIN_CIRCUIT(victim)->cpath &&
+ TO_ORIGIN_CIRCUIT(victim)->cpath->state == CPATH_STATE_OPEN;
+
+ if (TO_ORIGIN_CIRCUIT(victim)->p_streams != NULL) {
+ log_warn(LD_BUG, "Circuit %d (purpose %d) has timed out, "
+ "yet has attached streams!",
+ TO_ORIGIN_CIRCUIT(victim)->global_identifier,
+ victim->purpose);
+ tor_fragile_assert();
+ continue;
+ }
+
+ if (circuit_timeout_want_to_count_circ(TO_ORIGIN_CIRCUIT(victim)) &&
+ circuit_build_times_enough_to_compute(&circ_times)) {
+ /* Circuits are allowed to last longer for measurement.
+ * Switch their purpose and wait. */
+ if (victim->purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT) {
+ control_event_circuit_status(TO_ORIGIN_CIRCUIT(victim),
+ CIRC_EVENT_FAILED,
+ END_CIRC_REASON_TIMEOUT);
+ victim->purpose = CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT;
+ /* Record this failure to check for too many timeouts
+ * in a row. This function does not record a time value yet
+ * (we do that later); it only counts the fact that we did
+ * have a timeout. */
+ circuit_build_times_count_timeout(&circ_times,
+ first_hop_succeeded);
+ continue;
+ }
+
+ /*
+ * If the circuit build time is much greater than we would have cut
+ * it off at, we probably had a suspend event along this codepath,
+ * and we should discard the value.
+ */
+ if (now - victim->timestamp_created > 2*circ_times.close_ms/1000+1) {
+ log_notice(LD_CIRC,
+ "Extremely large value for circuit build timeout: %lds. "
+ "Assuming clock jump. Purpose %d",
+ (long)(now - victim->timestamp_created),
+ victim->purpose);
+ } else if (circuit_build_times_count_close(&circ_times,
+ first_hop_succeeded,
+ victim->timestamp_created)) {
+ circuit_build_times_set_timeout(&circ_times);
+ }
+ }
}
if (victim->n_conn)
@@ -357,7 +433,10 @@ circuit_expire_building(time_t now)
circuit_state_to_string(victim->state), victim->purpose);
circuit_log_path(LOG_INFO,LD_CIRC,TO_ORIGIN_CIRCUIT(victim));
- circuit_mark_for_close(victim, END_CIRC_REASON_TIMEOUT);
+ if (victim->purpose == CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT)
+ circuit_mark_for_close(victim, END_CIRC_REASON_MEASUREMENT_EXPIRED);
+ else
+ circuit_mark_for_close(victim, END_CIRC_REASON_TIMEOUT);
}
}
@@ -414,7 +493,7 @@ circuit_stream_is_being_handled(edge_connection_t *conn,
if (exitrouter && (!need_uptime || build_state->need_uptime)) {
int ok;
if (conn) {
- ok = connection_ap_can_use_exit(conn, exitrouter);
+ ok = connection_ap_can_use_exit(conn, exitrouter, 0);
} else {
addr_policy_result_t r = compare_addr_to_addr_policy(
0, port, exitrouter->exit_policy);
@@ -431,11 +510,11 @@ circuit_stream_is_being_handled(edge_connection_t *conn,
}
/** Don't keep more than this many unused open circuits around. */
-#define MAX_UNUSED_OPEN_CIRCUITS 12
+#define MAX_UNUSED_OPEN_CIRCUITS 14
/** Figure out how many circuits we have open that are clean. Make
* sure it's enough for all the upcoming behaviors we predict we'll have.
- * But if we have too many, close the not-so-useful ones.
+ * But put an upper bound on the total number of circuits.
*/
static void
circuit_predict_and_launch_new(void)
@@ -517,6 +596,19 @@ circuit_predict_and_launch_new(void)
circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, flags);
return;
}
+
+ /* 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_needs_circuits_now(&circ_times)) {
+ flags = CIRCLAUNCH_NEED_CAPACITY;
+ log_info(LD_CIRC,
+ "Have %d clean circs need another buildtime test circ.", num);
+ circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, flags);
+ return;
+ }
}
/** Build a new test circuit every 5 minutes */
@@ -624,6 +716,11 @@ circuit_detach_stream(circuit_t *circ, edge_connection_t *conn)
tor_fragile_assert();
}
+/** If we haven't yet decided on a good timeout value for circuit
+ * building, we close idles circuits aggressively so we can get more
+ * data points. */
+#define IDLE_TIMEOUT_WHILE_LEARNING (10*60)
+
/** Find each circuit that has been unused for too long, or dirty
* for too long and has no streams on it: mark it for close.
*/
@@ -631,10 +728,18 @@ static void
circuit_expire_old_circuits_clientside(time_t now)
{
circuit_t *circ;
- time_t cutoff = now - get_options()->CircuitIdleTimeout;
+ time_t cutoff;
+
+ if (circuit_build_times_needs_circuits(&circ_times)) {
+ /* Circuits should be shorter lived if we need more of them
+ * for learning a good build timeout */
+ cutoff = now - IDLE_TIMEOUT_WHILE_LEARNING;
+ } else {
+ cutoff = now - get_options()->CircuitIdleTimeout;
+ }
for (circ = global_circuitlist; circ; circ = circ->next) {
- if (circ->marked_for_close || ! CIRCUIT_IS_ORIGIN(circ))
+ if (circ->marked_for_close || !CIRCUIT_IS_ORIGIN(circ))
continue;
/* If the circuit has been dirty for too long, and there are no streams
* on it, mark it for close.
@@ -647,14 +752,38 @@ circuit_expire_old_circuits_clientside(time_t now)
circ->n_circ_id, (int)(now - circ->timestamp_dirty),
circ->purpose);
circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
- } else if (!circ->timestamp_dirty &&
- circ->state == CIRCUIT_STATE_OPEN &&
- circ->purpose == CIRCUIT_PURPOSE_C_GENERAL) {
+ } else if (!circ->timestamp_dirty && circ->state == CIRCUIT_STATE_OPEN) {
if (circ->timestamp_created < cutoff) {
- log_debug(LD_CIRC,
- "Closing circuit that has been unused for %d seconds.",
- (int)(now - circ->timestamp_created));
- circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
+ if (circ->purpose == CIRCUIT_PURPOSE_C_GENERAL ||
+ circ->purpose == CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT ||
+ circ->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO ||
+ circ->purpose == CIRCUIT_PURPOSE_TESTING ||
+ (circ->purpose >= CIRCUIT_PURPOSE_C_INTRODUCING &&
+ circ->purpose <= CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED) ||
+ circ->purpose == CIRCUIT_PURPOSE_S_CONNECT_REND) {
+ log_debug(LD_CIRC,
+ "Closing circuit that has been unused for %ld seconds.",
+ (long)(now - circ->timestamp_created));
+ circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
+ } else if (!TO_ORIGIN_CIRCUIT(circ)->is_ancient) {
+ /* Server-side rend joined circuits can end up really old, because
+ * they are reused by clients for longer than normal. The client
+ * controls their lifespan. (They never become dirty, because
+ * connection_exit_begin_conn() never marks anything as dirty.)
+ * Similarly, server-side intro circuits last a long time. */
+ if (circ->purpose != CIRCUIT_PURPOSE_S_REND_JOINED &&
+ circ->purpose != CIRCUIT_PURPOSE_S_INTRO) {
+ log_notice(LD_CIRC,
+ "Ancient non-dirty circuit %d is still around after "
+ "%ld seconds. Purpose: %d",
+ TO_ORIGIN_CIRCUIT(circ)->global_identifier,
+ (long)(now - circ->timestamp_created),
+ circ->purpose);
+ /* FFFF implement a new circuit_purpose_to_string() so we don't
+ * just print out a number for circ->purpose */
+ TO_ORIGIN_CIRCUIT(circ)->is_ancient = 1;
+ }
+ }
}
}
}
@@ -794,6 +923,11 @@ circuit_has_opened(origin_circuit_t *circ)
{
control_event_circuit_status(circ, CIRC_EVENT_BUILT, 0);
+ /* Remember that this circuit has finished building. Now if we start
+ * it building again later (e.g. by extending it), we will know not
+ * to consider its build time. */
+ circ->has_opened = 1;
+
switch (TO_CIRCUIT(circ)->purpose) {
case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
rend_client_rendcirc_has_opened(circ);
@@ -846,15 +980,29 @@ circuit_build_failed(origin_circuit_t *circ)
* to blame, blame it. Also, avoid this relay for a while, and
* fail any one-hop directory fetches destined for it. */
const char *n_conn_id = circ->cpath->extend_info->identity_digest;
+ int already_marked = 0;
if (circ->_base.n_conn) {
or_connection_t *n_conn = circ->_base.n_conn;
+ if (n_conn->is_bad_for_new_circs) {
+ /* We only want to blame this router when a fresh healthy
+ * connection fails. So don't mark this router as newly failed,
+ * since maybe this was just an old circuit attempt that's
+ * finally timing out now. Also, there's no need to blow away
+ * circuits/streams/etc, since the failure of an unhealthy conn
+ * doesn't tell us much about whether a healthy conn would
+ * succeed. */
+ already_marked = 1;
+ }
log_info(LD_OR,
"Our circuit failed to get a response from the first hop "
"(%s:%d). I'm going to try to rotate to a better connection.",
n_conn->_base.address, n_conn->_base.port);
n_conn->is_bad_for_new_circs = 1;
+ } else {
+ log_info(LD_OR,
+ "Our circuit died before the first hop with no connection");
}
- if (n_conn_id) {
+ if (n_conn_id && !already_marked) {
entry_guard_register_connect_status(n_conn_id, 0, 1, time(NULL));
/* if there are any one-hop streams waiting on this circuit, fail
* them now so they can retry elsewhere. */
@@ -936,8 +1084,8 @@ circuit_launch_by_router(uint8_t purpose,
if (exit)
info = extend_info_from_router(exit);
circ = circuit_launch_by_extend_info(purpose, info, flags);
- if (info)
- extend_info_free(info);
+
+ extend_info_free(info);
return circ;
}
@@ -1080,15 +1228,17 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
int severity = LOG_NOTICE;
/* FFFF if this is a tunneled directory fetch, don't yell
* as loudly. the user doesn't even know it's happening. */
- if (options->UseBridges && bridges_known_but_down()) {
+ if (entry_list_is_constrained(options) &&
+ entries_known_but_down(options)) {
log_fn(severity, LD_APP|LD_DIR,
- "Application request when we're believed to be "
- "offline. Optimistically trying known bridges again.");
- bridges_retry_all();
+ "Application request when we haven't used client functionality "
+ "lately. Optimistically trying known %s again.",
+ 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're believed to be "
- "offline. Optimistically trying directory fetches again.");
+ "Application request when we haven't used client functionality "
+ "lately. Optimistically trying directory fetches again.");
routerlist_retry_directory_downloads(time(NULL));
}
}
@@ -1111,7 +1261,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
need_uptime)) {
log_notice(LD_APP,
"No Tor server allows exit to %s:%d. Rejecting.",
- safe_str(conn->socks_request->address),
+ safe_str_client(conn->socks_request->address),
conn->socks_request->port);
return -1;
}
@@ -1119,7 +1269,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
/* XXXX022 Duplicates checks in connection_ap_handshake_attach_circuit */
routerinfo_t *router = router_get_by_nickname(conn->chosen_exit_name, 1);
int opt = conn->chosen_exit_optional;
- if (router && !connection_ap_can_use_exit(conn, router)) {
+ if (router && !connection_ap_can_use_exit(conn, router, 0)) {
log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP,
"Requested exit point '%s' would refuse request. %s.",
conn->chosen_exit_name, opt ? "Trying others" : "Closing");
@@ -1152,19 +1302,14 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
if (!extend_info) {
log_info(LD_REND,
"No intro points for '%s': re-fetching service descriptor.",
- safe_str(conn->rend_data->onion_address));
- /* Fetch both, v0 and v2 rend descriptors in parallel. Use whichever
- * arrives first. Exception: When using client authorization, only
- * fetch v2 descriptors.*/
+ safe_str_client(conn->rend_data->onion_address));
rend_client_refetch_v2_renddesc(conn->rend_data);
- if (conn->rend_data->auth_type == REND_NO_AUTH)
- rend_client_refetch_renddesc(conn->rend_data->onion_address);
conn->_base.state = AP_CONN_STATE_RENDDESC_WAIT;
return 0;
}
log_info(LD_REND,"Chose '%s' as intro point for '%s'.",
extend_info->nickname,
- safe_str(conn->rend_data->onion_address));
+ safe_str_client(conn->rend_data->onion_address));
}
/* If we have specified a particular exit node for our
@@ -1193,7 +1338,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
}
if (tor_addr_from_str(&addr, conn->socks_request->address) < 0) {
log_info(LD_DIR, "Broken address %s on tunnel conn. Closing.",
- escaped_safe_str(conn->socks_request->address));
+ escaped_safe_str_client(conn->socks_request->address));
return -1;
}
extend_info = extend_info_alloc(conn->chosen_exit_name+1,
@@ -1235,8 +1380,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
flags);
}
- if (extend_info)
- extend_info_free(extend_info);
+ extend_info_free(extend_info);
if (desired_circuit_purpose != CIRCUIT_PURPOSE_C_GENERAL) {
/* help predict this next time */
@@ -1418,7 +1562,7 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn)
LOG_INFO : LOG_NOTICE;
log_fn(severity, LD_APP,
"Tried for %d seconds to get a connection to %s:%d. Giving up.",
- conn_age, safe_str(conn->socks_request->address),
+ conn_age, safe_str_client(conn->socks_request->address),
conn->socks_request->port);
return -1;
}
@@ -1445,7 +1589,7 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn)
}
return -1;
}
- if (router && !connection_ap_can_use_exit(conn, router)) {
+ if (router && !connection_ap_can_use_exit(conn, router, 0)) {
log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP,
"Requested exit point '%s' would refuse request. %s.",
conn->chosen_exit_name, opt ? "Trying others" : "Closing");
diff --git a/src/or/circuituse.h b/src/or/circuituse.h
new file mode 100644
index 0000000000..269b6c5f8f
--- /dev/null
+++ b/src/or/circuituse.h
@@ -0,0 +1,53 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file circuituse.h
+ * \brief Header file for circuituse.c.
+ **/
+
+#ifndef _TOR_CIRCUITUSE_H
+#define _TOR_CIRCUITUSE_H
+
+void circuit_expire_building(time_t now);
+void circuit_remove_handled_ports(smartlist_t *needed_ports);
+int circuit_stream_is_being_handled(edge_connection_t *conn, uint16_t port,
+ int min);
+int circuit_conforms_to_options(const origin_circuit_t *circ,
+ const or_options_t *options);
+void circuit_build_needed_circs(time_t now);
+void circuit_detach_stream(circuit_t *circ, edge_connection_t *conn);
+
+void circuit_expire_old_circuits_serverside(time_t now);
+
+void reset_bandwidth_test(void);
+int circuit_enough_testing_circs(void);
+
+void circuit_has_opened(origin_circuit_t *circ);
+void circuit_build_failed(origin_circuit_t *circ);
+
+/** Flag to set when a circuit should have only a single hop. */
+#define CIRCLAUNCH_ONEHOP_TUNNEL (1<<0)
+/** Flag to set when a circuit needs to be built of high-uptime nodes */
+#define CIRCLAUNCH_NEED_UPTIME (1<<1)
+/** Flag to set when a circuit needs to be built of high-capacity nodes */
+#define CIRCLAUNCH_NEED_CAPACITY (1<<2)
+/** Flag to set when the last hop of a circuit doesn't need to be an
+ * exit node. */
+#define CIRCLAUNCH_IS_INTERNAL (1<<3)
+origin_circuit_t *circuit_launch_by_extend_info(uint8_t purpose,
+ extend_info_t *info,
+ int flags);
+origin_circuit_t *circuit_launch_by_router(uint8_t purpose,
+ routerinfo_t *exit, int flags);
+void circuit_reset_failure_count(int timeout);
+int connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn,
+ origin_circuit_t *circ,
+ crypt_path_t *cpath);
+int connection_ap_handshake_attach_circuit(edge_connection_t *conn);
+
+#endif
+
diff --git a/src/or/command.c b/src/or/command.c
index 011cc5aa37..beb5d09a9d 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -16,6 +16,19 @@
*/
#include "or.h"
+#include "circuitbuild.h"
+#include "circuitlist.h"
+#include "command.h"
+#include "connection.h"
+#include "connection_or.h"
+#include "config.h"
+#include "control.h"
+#include "cpuworker.h"
+#include "hibernate.h"
+#include "onion.h"
+#include "relay.h"
+#include "router.h"
+#include "routerlist.h"
/** How many CELL_PADDING cells have we received, ever? */
uint64_t stats_n_padding_cells_processed = 0;
@@ -275,7 +288,14 @@ command_process_create_cell(cell_t *cell, or_connection_t *conn)
/* hand it off to the cpuworkers, and then return. */
if (assign_onionskin_to_cpuworker(NULL, circ, onionskin) < 0) {
- log_warn(LD_GENERAL,"Failed to hand off onionskin. Closing.");
+#define WARN_HANDOFF_FAILURE_INTERVAL (6*60*60)
+ static ratelim_t handoff_warning =
+ RATELIM_INIT(WARN_HANDOFF_FAILURE_INTERVAL);
+ char *m;
+ if ((m = rate_limit_log(&handoff_warning, approx_time()))) {
+ log_warn(LD_GENERAL,"Failed to hand off onionskin. Closing.%s",m);
+ tor_free(m);
+ }
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
return;
}
@@ -396,15 +416,18 @@ command_process_relay_cell(cell_t *cell, or_connection_t *conn)
* gotten no more than MAX_RELAY_EARLY_CELLS_PER_CIRCUIT of them. */
if (cell->command == CELL_RELAY_EARLY) {
if (direction == CELL_DIRECTION_IN) {
- /* XXX Allow an unlimited number of inbound relay_early cells for
- * now, for hidden service compatibility. See bug 1038. -RD */
+ /* Allow an unlimited number of inbound relay_early cells,
+ * for hidden service compatibility. There isn't any way to make
+ * a long circuit through inbound relay_early cells anyway. See
+ * bug 1038. -RD */
} else {
or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
if (or_circ->remaining_relay_early_cells == 0) {
log_fn(LOG_PROTOCOL_WARN, LD_OR,
"Received too many RELAY_EARLY cells on circ %d from %s:%d."
" Closing circuit.",
- cell->circ_id, safe_str(conn->_base.address), conn->_base.port);
+ cell->circ_id, safe_str(conn->_base.address),
+ conn->_base.port);
circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
return;
}
@@ -512,7 +535,8 @@ command_process_versions_cell(var_cell_t *cell, or_connection_t *conn)
conn->handshake_state->received_versions = 1;
log_info(LD_OR, "Negotiated version %d with %s:%d; sending NETINFO.",
- highest_supported_version, safe_str(conn->_base.address),
+ highest_supported_version,
+ safe_str_client(conn->_base.address),
conn->_base.port);
tor_assert(conn->link_proto >= 2);
@@ -626,8 +650,8 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn)
else
log_info(LD_OR, "Got good NETINFO cell from %s:%d; OR connection is now "
"open, using protocol version %d",
- safe_str(conn->_base.address), conn->_base.port,
- (int)conn->link_proto);
+ safe_str_client(conn->_base.address),
+ conn->_base.port, (int)conn->link_proto);
assert_connection_ok(TO_CONN(conn),time(NULL));
}
diff --git a/src/or/command.h b/src/or/command.h
new file mode 100644
index 0000000000..1aa56207f6
--- /dev/null
+++ b/src/or/command.h
@@ -0,0 +1,25 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file command.h
+ * \brief Header file for command.c.
+ **/
+
+#ifndef _TOR_COMMAND_H
+#define _TOR_COMMAND_H
+
+void command_process_cell(cell_t *cell, or_connection_t *conn);
+void command_process_var_cell(var_cell_t *cell, or_connection_t *conn);
+
+extern uint64_t stats_n_padding_cells_processed;
+extern uint64_t stats_n_create_cells_processed;
+extern uint64_t stats_n_created_cells_processed;
+extern uint64_t stats_n_relay_cells_processed;
+extern uint64_t stats_n_destroy_cells_processed;
+
+#endif
+
diff --git a/src/or/config.c b/src/or/config.c
index 70b99d7554..e3d5e606f9 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -12,6 +12,28 @@
#define CONFIG_PRIVATE
#include "or.h"
+#include "circuitbuild.h"
+#include "circuitlist.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_edge.h"
+#include "connection_or.h"
+#include "control.h"
+#include "cpuworker.h"
+#include "dirserv.h"
+#include "dirvote.h"
+#include "dns.h"
+#include "geoip.h"
+#include "hibernate.h"
+#include "main.h"
+#include "networkstatus.h"
+#include "policies.h"
+#include "relay.h"
+#include "rendclient.h"
+#include "rendservice.h"
+#include "rephist.h"
+#include "router.h"
+#include "routerlist.h"
#ifdef MS_WINDOWS
#include <shlobj.h>
#endif
@@ -61,11 +83,12 @@ static config_abbrev_t _option_abbrevs[] = {
PLURAL(LongLivedPort),
PLURAL(HiddenServiceNode),
PLURAL(HiddenServiceExcludeNode),
- PLURAL(NumCpu),
+ PLURAL(NumCPU),
PLURAL(RendNode),
PLURAL(RendExcludeNode),
PLURAL(StrictEntryNode),
PLURAL(StrictExitNode),
+ PLURAL(StrictNode),
{ "l", "Log", 1, 0},
{ "AllowUnverifiedNodes", "AllowInvalidNodes", 0, 0},
{ "AutomapHostSuffixes", "AutomapHostsSuffixes", 0, 0},
@@ -83,10 +106,12 @@ static config_abbrev_t _option_abbrevs[] = {
{ "NumEntryNodes", "NumEntryGuards", 0, 0},
{ "ResolvConf", "ServerDNSResolvConfFile", 0, 1},
{ "SearchDomains", "ServerDNSSearchDomains", 0, 1},
- { "ServerDNSAllowBrokenResolvConf", "ServerDNSAllowBrokenConfig", 0, 0 },
+ { "ServerDNSAllowBrokenResolvConf", "ServerDNSAllowBrokenConfig", 0, 0},
{ "PreferTunnelledDirConns", "PreferTunneledDirConns", 0, 0},
{ "BridgeAuthoritativeDirectory", "BridgeAuthoritativeDir", 0, 0},
{ "HashedControlPassword", "__HashedControlSessionPassword", 1, 0},
+ { "StrictEntryNodes", "StrictNodes", 0, 1},
+ { "StrictExitNodes", "StrictNodes", 0, 1},
{ NULL, NULL, 0, 0},
};
@@ -134,6 +159,7 @@ static config_var_t _option_vars[] = {
V(AccountingMax, MEMUNIT, "0 bytes"),
V(AccountingStart, STRING, NULL),
V(Address, STRING, NULL),
+ V(AllowDotExit, BOOL, "0"),
V(AllowInvalidNodes, CSV, "middle,rendezvous"),
V(AllowNonRFC953Hostnames, BOOL, "0"),
V(AllowSingleHopCircuits, BOOL, "0"),
@@ -162,10 +188,15 @@ static config_var_t _option_vars[] = {
V(BridgePassword, STRING, NULL),
V(BridgeRecordUsageByCountry, BOOL, "1"),
V(BridgeRelay, BOOL, "0"),
- V(CircuitBuildTimeout, INTERVAL, "1 minute"),
+ V(CellStatistics, BOOL, "0"),
+ V(LearnCircuitBuildTimeout, BOOL, "1"),
+ V(CircuitBuildTimeout, INTERVAL, "0"),
V(CircuitIdleTimeout, INTERVAL, "1 hour"),
+ V(CircuitStreamTimeout, INTERVAL, "0"),
+ V(CircuitPriorityHalflife, DOUBLE, "-100.0"), /*negative:'Use default'*/
V(ClientDNSRejectInternalAddresses, BOOL,"1"),
V(ClientOnly, BOOL, "0"),
+ V(ConsensusParams, STRING, NULL),
V(ConnLimit, UINT, "1000"),
V(ConstrainedSockets, BOOL, "0"),
V(ConstrainedSockSize, MEMUNIT, "8192"),
@@ -186,18 +217,19 @@ static config_var_t _option_vars[] = {
V(DirPort, UINT, "0"),
V(DirPortFrontPage, FILENAME, NULL),
OBSOLETE("DirPostPeriod"),
-#ifdef ENABLE_GEOIP_STATS
- V(DirRecordUsageByCountry, BOOL, "0"),
- V(DirRecordUsageGranularity, UINT, "4"),
- V(DirRecordUsageRetainIPs, INTERVAL, "14 days"),
- V(DirRecordUsageSaveInterval, INTERVAL, "6 hours"),
-#endif
+ OBSOLETE("DirRecordUsageByCountry"),
+ OBSOLETE("DirRecordUsageGranularity"),
+ OBSOLETE("DirRecordUsageRetainIPs"),
+ OBSOLETE("DirRecordUsageSaveInterval"),
+ V(DirReqStatistics, BOOL, "0"),
VAR("DirServer", LINELIST, DirServers, NULL),
+ V(DisableAllSwap, BOOL, "0"),
V(DNSPort, UINT, "0"),
V(DNSListenAddress, LINELIST, NULL),
V(DownloadExtraInfo, BOOL, "0"),
V(EnforceDistinctSubnets, BOOL, "1"),
V(EntryNodes, ROUTERSET, NULL),
+ V(EntryStatistics, BOOL, "0"),
V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "10 minutes"),
V(ExcludeNodes, ROUTERSET, NULL),
V(ExcludeExitNodes, ROUTERSET, NULL),
@@ -205,12 +237,20 @@ static config_var_t _option_vars[] = {
V(ExitNodes, ROUTERSET, NULL),
V(ExitPolicy, LINELIST, NULL),
V(ExitPolicyRejectPrivate, BOOL, "1"),
+ V(ExitPortStatistics, BOOL, "0"),
+ V(ExtraInfoStatistics, BOOL, "0"),
+
+#if defined (WINCE)
+ V(FallbackNetworkstatusFile, FILENAME, "fallback-consensus"),
+#else
V(FallbackNetworkstatusFile, FILENAME,
SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "fallback-consensus"),
+#endif
V(FascistFirewall, BOOL, "0"),
V(FirewallPorts, CSV, ""),
V(FastFirstHopPK, BOOL, "1"),
V(FetchDirInfoEarly, BOOL, "0"),
+ V(FetchDirInfoExtraEarly, BOOL, "0"),
V(FetchServerDescriptors, BOOL, "1"),
V(FetchHidServDescriptors, BOOL, "1"),
V(FetchUselessDescriptors, BOOL, "0"),
@@ -222,6 +262,8 @@ static config_var_t _option_vars[] = {
#endif
OBSOLETE("Group"),
V(HardwareAccel, BOOL, "0"),
+ V(AccelName, STRING, NULL),
+ V(AccelDir, FILENAME, NULL),
V(HashedControlPassword, LINELIST, NULL),
V(HidServDirectoryV2, BOOL, "1"),
VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL),
@@ -233,11 +275,15 @@ static config_var_t _option_vars[] = {
VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL),
V(HidServAuth, LINELIST, NULL),
V(HSAuthoritativeDir, BOOL, "0"),
- V(HSAuthorityRecordStats, BOOL, "0"),
- V(HttpProxy, STRING, NULL),
- V(HttpProxyAuthenticator, STRING, NULL),
- V(HttpsProxy, STRING, NULL),
- V(HttpsProxyAuthenticator, STRING, NULL),
+ OBSOLETE("HSAuthorityRecordStats"),
+ V(HTTPProxy, STRING, NULL),
+ V(HTTPProxyAuthenticator, STRING, NULL),
+ V(HTTPSProxy, STRING, NULL),
+ V(HTTPSProxyAuthenticator, STRING, NULL),
+ V(Socks4Proxy, STRING, NULL),
+ V(Socks5Proxy, STRING, NULL),
+ V(Socks5ProxyUsername, STRING, NULL),
+ V(Socks5ProxyPassword, STRING, NULL),
OBSOLETE("IgnoreVersion"),
V(KeepalivePeriod, INTERVAL, "5 minutes"),
VAR("Log", LINELIST, Logs, NULL),
@@ -254,17 +300,20 @@ static config_var_t _option_vars[] = {
V(MyFamily, STRING, NULL),
V(NewCircuitPeriod, INTERVAL, "30 seconds"),
VAR("NamingAuthoritativeDirectory",BOOL, NamingAuthoritativeDir, "0"),
- V(NatdListenAddress, LINELIST, NULL),
- V(NatdPort, UINT, "0"),
+ V(NATDListenAddress, LINELIST, NULL),
+ V(NATDPort, UINT, "0"),
V(Nickname, STRING, NULL),
- V(NoPublish, BOOL, "0"),
+ V(WarnUnsafeSocks, BOOL, "1"),
+ OBSOLETE("NoPublish"),
VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
- V(NumCpus, UINT, "1"),
+ V(NumCPUs, UINT, "1"),
V(NumEntryGuards, UINT, "3"),
V(ORListenAddress, LINELIST, NULL),
V(ORPort, UINT, "0"),
V(OutboundBindAddress, STRING, NULL),
OBSOLETE("PathlenCoinWeight"),
+ V(PerConnBWBurst, MEMUNIT, "0"),
+ V(PerConnBWRate, MEMUNIT, "0"),
V(PidFile, STRING, NULL),
V(TestingTorNetwork, BOOL, "0"),
V(PreferTunneledDirConns, BOOL, "1"),
@@ -278,6 +327,7 @@ static config_var_t _option_vars[] = {
V(RecommendedClientVersions, LINELIST, NULL),
V(RecommendedServerVersions, LINELIST, NULL),
OBSOLETE("RedirectExit"),
+ V(RefuseUnknownExits, STRING, "auto"),
V(RejectPlaintextPorts, CSV, ""),
V(RelayBandwidthBurst, MEMUNIT, "0"),
V(RelayBandwidthRate, MEMUNIT, "0"),
@@ -287,8 +337,9 @@ static config_var_t _option_vars[] = {
V(RephistTrackTime, INTERVAL, "24 hours"),
OBSOLETE("RouterFile"),
V(RunAsDaemon, BOOL, "0"),
- V(RunTesting, BOOL, "0"),
- V(SafeLogging, BOOL, "1"),
+// V(RunTesting, BOOL, "0"),
+ OBSOLETE("RunTesting"), // currently unused
+ V(SafeLogging, STRING, "1"),
V(SafeSocks, BOOL, "0"),
V(ServerDNSAllowBrokenConfig, BOOL, "1"),
V(ServerDNSAllowNonRFC953Hostnames, BOOL,"0"),
@@ -304,8 +355,7 @@ static config_var_t _option_vars[] = {
V(SocksPort, UINT, "9050"),
V(SocksTimeout, INTERVAL, "2 minutes"),
OBSOLETE("StatusFetchPeriod"),
- V(StrictEntryNodes, BOOL, "0"),
- V(StrictExitNodes, BOOL, "0"),
+ V(StrictNodes, BOOL, "0"),
OBSOLETE("SysLog"),
V(TestSocks, BOOL, "0"),
OBSOLETE("TestVia"),
@@ -330,6 +380,7 @@ static config_var_t _option_vars[] = {
V(V3AuthDistDelay, INTERVAL, "5 minutes"),
V(V3AuthNIntervalsValid, UINT, "3"),
V(V3AuthUseLegacyKey, BOOL, "0"),
+ V(V3BandwidthsFile, FILENAME, NULL),
VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
V(VirtualAddrNetwork, STRING, "127.192.0.0/10"),
V(WarnPlaintextPorts, CSV, "23,109,110,143"),
@@ -340,6 +391,7 @@ static config_var_t _option_vars[] = {
VAR("__HashedControlSessionPassword", LINELIST, HashedControlSessionPassword,
NULL),
V(MinUptimeHidServDirectoryV2, INTERVAL, "24 hours"),
+
{ NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
};
@@ -362,6 +414,7 @@ static config_var_t testing_tor_network_defaults[] = {
V(TestingV3AuthInitialDistDelay, INTERVAL, "20 seconds"),
V(TestingAuthDirTimeToLearnReachability, INTERVAL, "0 minutes"),
V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "0 minutes"),
+ V(MinUptimeHidServDirectoryV2, INTERVAL, "0 minutes"),
{ NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
};
#undef VAR
@@ -377,6 +430,9 @@ static config_var_t _state_vars[] = {
V(AccountingExpectedUsage, MEMUNIT, NULL),
V(AccountingIntervalStart, ISOTIME, NULL),
V(AccountingSecondsActive, INTERVAL, NULL),
+ V(AccountingSecondsToReachSoftLimit,INTERVAL, NULL),
+ V(AccountingSoftLimitHitAt, ISOTIME, NULL),
+ V(AccountingBytesAtSoftLimit, MEMUNIT, NULL),
VAR("EntryGuard", LINELIST_S, EntryGuards, NULL),
VAR("EntryGuardDownSince", LINELIST_S, EntryGuards, NULL),
@@ -390,12 +446,23 @@ static config_var_t _state_vars[] = {
V(BWHistoryWriteEnds, ISOTIME, NULL),
V(BWHistoryWriteInterval, UINT, "900"),
V(BWHistoryWriteValues, CSV, ""),
+ V(BWHistoryDirReadEnds, ISOTIME, NULL),
+ V(BWHistoryDirReadInterval, UINT, "900"),
+ V(BWHistoryDirReadValues, CSV, ""),
+ V(BWHistoryDirWriteEnds, ISOTIME, NULL),
+ V(BWHistoryDirWriteInterval, UINT, "900"),
+ V(BWHistoryDirWriteValues, CSV, ""),
V(TorVersion, STRING, NULL),
V(LastRotatedOnionKey, ISOTIME, NULL),
V(LastWritten, ISOTIME, NULL),
+ V(TotalBuildTimes, UINT, NULL),
+ V(CircuitBuildAbandonedCount, UINT, "0"),
+ VAR("CircuitBuildTimeBin", LINELIST_S, BuildtimeHistogram, NULL),
+ VAR("BuildtimeHistogram", LINELIST_V, BuildtimeHistogram, NULL),
+
{ NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
};
@@ -410,213 +477,6 @@ typedef struct config_var_description_t {
const char *description;
} config_var_description_t;
-/** Descriptions of the configuration options, to be displayed by online
- * option browsers */
-/* XXXX022 did anybody want this? at all? If not, kill it.*/
-static config_var_description_t options_description[] = {
- /* ==== general options */
- { "AvoidDiskWrites", "If non-zero, try to write to disk less frequently than"
- " we would otherwise." },
- { "BandwidthRate", "A token bucket limits the average incoming bandwidth on "
- "this node to the specified number of bytes per second." },
- { "BandwidthBurst", "Limit the maximum token buffer size (also known as "
- "burst) to the given number of bytes." },
- { "ConnLimit", "Minimum number of simultaneous sockets we must have." },
- { "ConstrainedSockets", "Shrink tx and rx buffers for sockets to avoid "
- "system limits on vservers and related environments. See man page for "
- "more information regarding this option." },
- { "ConstrainedSockSize", "Limit socket buffers to this size when "
- "ConstrainedSockets is enabled." },
- /* ControlListenAddress */
- { "ControlPort", "If set, Tor will accept connections from the same machine "
- "(localhost only) on this port, and allow those connections to control "
- "the Tor process using the Tor Control Protocol (described in "
- "control-spec.txt).", },
- { "CookieAuthentication", "If this option is set to 1, don't allow any "
- "connections to the control port except when the connecting process "
- "can read a file that Tor creates in its data directory." },
- { "DataDirectory", "Store working data, state, keys, and caches here." },
- { "DirServer", "Tor only trusts directories signed with one of these "
- "servers' keys. Used to override the standard list of directory "
- "authorities." },
- /* { "FastFirstHopPK", "" }, */
- /* FetchServerDescriptors, FetchHidServDescriptors,
- * FetchUselessDescriptors */
- { "HardwareAccel", "If set, Tor tries to use hardware crypto accelerators "
- "when it can." },
- /* HashedControlPassword */
- { "HTTPProxy", "Force Tor to make all HTTP directory requests through this "
- "host:port (or host:80 if port is not set)." },
- { "HTTPProxyAuthenticator", "A username:password pair to be used with "
- "HTTPProxy." },
- { "HTTPSProxy", "Force Tor to make all TLS (SSL) connections through this "
- "host:port (or host:80 if port is not set)." },
- { "HTTPSProxyAuthenticator", "A username:password pair to be used with "
- "HTTPSProxy." },
- { "KeepalivePeriod", "Send a padding cell every N seconds to keep firewalls "
- "from closing our connections while Tor is not in use." },
- { "Log", "Where to send logging messages. Format is "
- "minSeverity[-maxSeverity] (stderr|stdout|syslog|file FILENAME)." },
- { "OutboundBindAddress", "Make all outbound connections originate from the "
- "provided IP address (only useful for multiple network interfaces)." },
- { "PIDFile", "On startup, write our PID to this file. On clean shutdown, "
- "remove the file." },
- { "PreferTunneledDirConns", "If non-zero, avoid directory servers that "
- "don't support tunneled connections." },
- /* PreferTunneledDirConns */
- /* ProtocolWarnings */
- /* RephistTrackTime */
- { "RunAsDaemon", "If set, Tor forks and daemonizes to the background when "
- "started. Unix only." },
- { "SafeLogging", "If set to 0, Tor logs potentially sensitive strings "
- "rather than replacing them with the string [scrubbed]." },
- { "TunnelDirConns", "If non-zero, when a directory server we contact "
- "supports it, we will build a one-hop circuit and make an encrypted "
- "connection via its ORPort." },
- { "User", "On startup, setuid to this user." },
-
- /* ==== client options */
- { "AllowInvalidNodes", "Where on our circuits should Tor allow servers "
- "that the directory authorities haven't called \"valid\"?" },
- { "AllowNonRFC953Hostnames", "If set to 1, we don't automatically reject "
- "hostnames for having invalid characters." },
- /* CircuitBuildTimeout, CircuitIdleTimeout */
- { "ClientOnly", "If set to 1, Tor will under no circumstances run as a "
- "server, even if ORPort is enabled." },
- { "EntryNodes", "A list of preferred entry nodes to use for the first hop "
- "in circuits, when possible." },
- /* { "EnforceDistinctSubnets" , "" }, */
- { "ExitNodes", "A list of preferred nodes to use for the last hop in "
- "circuits, when possible." },
- { "ExcludeNodes", "A list of nodes never to use when building a circuit." },
- { "FascistFirewall", "If set, Tor will only create outgoing connections to "
- "servers running on the ports listed in FirewallPorts." },
- { "FirewallPorts", "A list of ports that we can connect to. Only used "
- "when FascistFirewall is set." },
- { "LongLivedPorts", "A list of ports for services that tend to require "
- "high-uptime connections." },
- { "MapAddress", "Force Tor to treat all requests for one address as if "
- "they were for another." },
- { "NewCircuitPeriod", "Force Tor to consider whether to build a new circuit "
- "every NUM seconds." },
- { "MaxCircuitDirtiness", "Do not attach new streams to a circuit that has "
- "been used more than this many seconds ago." },
- /* NatdPort, NatdListenAddress */
- { "NodeFamily", "A list of servers that constitute a 'family' and should "
- "never be used in the same circuit." },
- { "NumEntryGuards", "How many entry guards should we keep at a time?" },
- /* PathlenCoinWeight */
- { "ReachableAddresses", "Addresses we can connect to, as IP/bits:port-port. "
- "By default, we assume all addresses are reachable." },
- /* reachablediraddresses, reachableoraddresses. */
- /* SafeSOCKS */
- { "SOCKSPort", "The port where we listen for SOCKS connections from "
- "applications." },
- { "SOCKSListenAddress", "Bind to this address to listen to connections from "
- "SOCKS-speaking applications." },
- { "SOCKSPolicy", "Set an entry policy to limit which addresses can connect "
- "to the SOCKSPort." },
- /* SocksTimeout */
- { "StrictExitNodes", "If set, Tor will fail to operate when none of the "
- "configured ExitNodes can be used." },
- { "StrictEntryNodes", "If set, Tor will fail to operate when none of the "
- "configured EntryNodes can be used." },
- /* TestSocks */
- { "TrackHostsExit", "Hosts and domains which should, if possible, be "
- "accessed from the same exit node each time we connect to them." },
- { "TrackHostsExitExpire", "Time after which we forget which exit we were "
- "using to connect to hosts in TrackHostsExit." },
- /* "TransPort", "TransListenAddress */
- { "UseEntryGuards", "Set to 0 if we want to pick from the whole set of "
- "servers for the first position in each circuit, rather than picking a "
- "set of 'Guards' to prevent profiling attacks." },
-
- /* === server options */
- { "Address", "The advertised (external) address we should use." },
- /* Accounting* options. */
- /* AssumeReachable */
- { "ContactInfo", "Administrative contact information to advertise for this "
- "server." },
- { "ExitPolicy", "Address/port ranges for which to accept or reject outgoing "
- "connections on behalf of Tor users." },
- /* { "ExitPolicyRejectPrivate, "" }, */
- { "MaxAdvertisedBandwidth", "If set, we will not advertise more than this "
- "amount of bandwidth for our bandwidth rate, regardless of how much "
- "bandwidth we actually detect." },
- { "MaxOnionsPending", "Reject new attempts to extend circuits when we "
- "already have this many pending." },
- { "MyFamily", "Declare a list of other servers as belonging to the same "
- "family as this one, so that clients will not use two from the same "
- "family in the same circuit." },
- { "Nickname", "Set the server nickname." },
- { "NoPublish", "{DEPRECATED}" },
- { "NumCPUs", "How many processes to use at once for public-key crypto." },
- { "ORPort", "Advertise this port to listen for connections from Tor clients "
- "and servers." },
- { "ORListenAddress", "Bind to this address to listen for connections from "
- "clients and servers, instead of the default 0.0.0.0:ORPort." },
- { "PublishServerDescriptor", "Set to 0 to keep the server from "
- "uploading info to the directory authorities." },
- /* ServerDNS: DetectHijacking, ResolvConfFile, SearchDomains */
- { "ShutdownWaitLength", "Wait this long for clients to finish when "
- "shutting down because of a SIGINT." },
-
- /* === directory cache options */
- { "DirPort", "Serve directory information from this port, and act as a "
- "directory cache." },
- { "DirPortFrontPage", "Serve a static html disclaimer on DirPort." },
- { "DirListenAddress", "Bind to this address to listen for connections from "
- "clients and servers, instead of the default 0.0.0.0:DirPort." },
- { "DirPolicy", "Set a policy to limit who can connect to the directory "
- "port." },
-
- /* Authority options: AuthDirBadExit, AuthDirInvalid, AuthDirReject,
- * AuthDirRejectUnlisted, AuthDirListBadExits, AuthoritativeDirectory,
- * DirAllowPrivateAddresses, HSAuthoritativeDir,
- * NamingAuthoritativeDirectory, RecommendedVersions,
- * RecommendedClientVersions, RecommendedServerVersions, RendPostPeriod,
- * RunTesting, V1AuthoritativeDirectory, VersioningAuthoritativeDirectory, */
-
- /* Hidden service options: HiddenService: dir,excludenodes, nodes,
- * options, port. PublishHidServDescriptor */
-
- /* Nonpersistent options: __LeaveStreamsUnattached, __AllDirActionsPrivate */
- { NULL, NULL },
-};
-
-/** Online description of state variables. */
-static config_var_description_t state_description[] = {
- { "AccountingBytesReadInInterval",
- "How many bytes have we read in this accounting period?" },
- { "AccountingBytesWrittenInInterval",
- "How many bytes have we written in this accounting period?" },
- { "AccountingExpectedUsage",
- "How many bytes did we expect to use per minute? (0 for no estimate.)" },
- { "AccountingIntervalStart", "When did this accounting period begin?" },
- { "AccountingSecondsActive", "How long have we been awake in this period?" },
-
- { "BWHistoryReadEnds", "When does the last-recorded read-interval end?" },
- { "BWHistoryReadInterval", "How long is each read-interval (in seconds)?" },
- { "BWHistoryReadValues", "Number of bytes read in each interval." },
- { "BWHistoryWriteEnds", "When does the last-recorded write-interval end?" },
- { "BWHistoryWriteInterval", "How long is each write-interval (in seconds)?"},
- { "BWHistoryWriteValues", "Number of bytes written in each interval." },
-
- { "EntryGuard", "One of the nodes we have chosen as a fixed entry" },
- { "EntryGuardDownSince",
- "The last entry guard has been unreachable since this time." },
- { "EntryGuardUnlistedSince",
- "The last entry guard has been unusable since this time." },
-
- { "LastRotatedOnionKey",
- "The last time at which we changed the medium-term private key used for "
- "building circuits." },
- { "LastWritten", "When was this state file last regenerated?" },
-
- { "TorVersion", "Which version of Tor generated this state file?" },
- { NULL, NULL },
-};
-
/** Type of a callback to validate whether a given configuration is
* well-formed and consistent. See options_trial_assign() for documentation
* of arguments. */
@@ -635,8 +495,6 @@ typedef struct {
config_var_t *vars; /**< List of variables we recognize, their default
* values, and where we stick them in the structure. */
validate_fn_t validate_fn; /**< Function to validate config. */
- /** Documentation for configuration variables. */
- config_var_description_t *descriptions;
/** If present, extra is a LINELIST variable for unrecognized
* lines. Otherwise, unrecognized lines are an error. */
config_var_t *extra;
@@ -700,20 +558,6 @@ static uint64_t config_parse_memunit(const char *s, int *ok);
static int config_parse_interval(const char *s, int *ok);
static void init_libevent(void);
static int opt_streq(const char *s1, const char *s2);
-/** Versions of libevent. */
-typedef enum {
- /* Note: we compare these, so it's important that "old" precede everything,
- * and that "other" come last. */
- LE_OLD=0, LE_10C, LE_10D, LE_10E, LE_11, LE_11A, LE_11B, LE_12, LE_12A,
- LE_13, LE_13A, LE_13B, LE_13C, LE_13D, LE_13E,
- LE_140, LE_141, LE_142, LE_143, LE_144, LE_145, LE_146, LE_147, LE_148,
- LE_1499,
- LE_OTHER
-} le_version_t;
-static le_version_t decode_libevent_version(const char *v, int *bincompat_out);
-#if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
-static void check_libevent_version(const char *m, int server);
-#endif
/** Magic value for or_options_t. */
#define OR_OPTIONS_MAGIC 9090909
@@ -726,7 +570,6 @@ static config_format_t options_format = {
_option_abbrevs,
_option_vars,
(validate_fn_t)options_validate,
- options_description,
NULL
};
@@ -747,7 +590,6 @@ static config_format_t state_format = {
_state_abbrevs,
_state_vars,
(validate_fn_t)or_state_validate,
- state_description,
&state_extra_var,
};
@@ -812,13 +654,13 @@ set_options(or_options_t *new_val, char **msg)
"Acting on config options left us in a broken state. Dying.");
exit(1);
}
- if (old_options)
- config_free(&options_format, old_options);
+
+ config_free(&options_format, old_options);
return 0;
}
-extern const char tor_svn_revision[]; /* from tor_main.c */
+extern const char tor_git_revision[]; /* from tor_main.c */
/** The version of this Tor process, as parsed. */
static char *_version = NULL;
@@ -828,10 +670,10 @@ const char *
get_version(void)
{
if (_version == NULL) {
- if (strlen(tor_svn_revision)) {
- size_t len = strlen(VERSION)+strlen(tor_svn_revision)+8;
+ if (strlen(tor_git_revision)) {
+ size_t len = strlen(VERSION)+strlen(tor_git_revision)+16;
_version = tor_malloc(len);
- tor_snprintf(_version, len, "%s (r%s)", VERSION, tor_svn_revision);
+ tor_snprintf(_version, len, "%s (git-%s)", VERSION, tor_git_revision);
} else {
_version = tor_strdup(VERSION);
}
@@ -844,8 +686,10 @@ get_version(void)
static void
or_options_free(or_options_t *options)
{
- if (options->_ExcludeExitNodesUnion)
- routerset_free(options->_ExcludeExitNodesUnion);
+ if (!options)
+ return;
+
+ routerset_free(options->_ExcludeExitNodesUnion);
config_free(&options_format, options);
}
@@ -854,43 +698,72 @@ or_options_free(or_options_t *options)
void
config_free_all(void)
{
- if (global_options) {
- or_options_free(global_options);
- global_options = NULL;
- }
- if (global_state) {
- config_free(&state_format, global_state);
- global_state = NULL;
- }
- if (global_cmdline_options) {
- config_free_lines(global_cmdline_options);
- global_cmdline_options = NULL;
- }
+ or_options_free(global_options);
+ global_options = NULL;
+
+ config_free(&state_format, global_state);
+ global_state = NULL;
+
+ config_free_lines(global_cmdline_options);
+ global_cmdline_options = NULL;
+
tor_free(torrc_fname);
tor_free(_version);
tor_free(global_dirfrontpagecontents);
}
-/** If options->SafeLogging is on, return a not very useful string,
- * else return address.
+/** Make <b>address</b> -- a piece of information related to our operation as
+ * a client -- safe to log according to the settings in options->SafeLogging,
+ * and return it.
+ *
+ * (We return "[scrubbed]" if SafeLogging is "1", and address otherwise.)
+ */
+const char *
+safe_str_client(const char *address)
+{
+ tor_assert(address);
+ if (get_options()->_SafeLogging == SAFELOG_SCRUB_ALL)
+ return "[scrubbed]";
+ else
+ return address;
+}
+
+/** Make <b>address</b> -- a piece of information of unspecified sensitivity
+ * -- safe to log according to the settings in options->SafeLogging, and
+ * return it.
+ *
+ * (We return "[scrubbed]" if SafeLogging is anything besides "0", and address
+ * otherwise.)
*/
const char *
safe_str(const char *address)
{
tor_assert(address);
- if (get_options()->SafeLogging)
+ if (get_options()->_SafeLogging != SAFELOG_SCRUB_NONE)
return "[scrubbed]";
else
return address;
}
+/** Equivalent to escaped(safe_str_client(address)). See reentrancy note on
+ * escaped(): don't use this outside the main thread, or twice in the same
+ * log statement. */
+const char *
+escaped_safe_str_client(const char *address)
+{
+ if (get_options()->_SafeLogging == SAFELOG_SCRUB_ALL)
+ return "[scrubbed]";
+ else
+ return escaped(address);
+}
+
/** Equivalent to escaped(safe_str(address)). See reentrancy note on
* escaped(): don't use this outside the main thread, or twice in the same
* log statement. */
const char *
escaped_safe_str(const char *address)
{
- if (get_options()->SafeLogging)
+ if (get_options()->_SafeLogging != SAFELOG_SCRUB_NONE)
return "[scrubbed]";
else
return escaped(address);
@@ -1089,10 +962,12 @@ options_act_reversible(or_options_t *old_options, char **msg)
}
/* Launch the listeners. (We do this before we setuid, so we can bind to
- * ports under 1024.) */
- if (retry_all_listeners(replaced_listeners, new_listeners) < 0) {
- *msg = tor_strdup("Failed to bind one of the listener ports.");
- goto rollback;
+ * ports under 1024.) We don't want to rebind if we're hibernating. */
+ if (!we_are_hibernating()) {
+ if (retry_all_listeners(replaced_listeners, new_listeners) < 0) {
+ *msg = tor_strdup("Failed to bind one of the listener ports.");
+ goto rollback;
+ }
}
}
@@ -1106,6 +981,15 @@ options_act_reversible(or_options_t *old_options, char **msg)
}
#endif
+ /* Attempt to lock all current and future memory with mlockall() only once */
+ if (options->DisableAllSwap) {
+ if (tor_mlockall() == -1) {
+ *msg = tor_strdup("DisableAllSwap failure. Do you have proper "
+ "permissions?");
+ goto done;
+ }
+ }
+
/* Setuid/setgid as appropriate */
if (options->User) {
if (switch_id(options->User) != 0) {
@@ -1118,11 +1002,9 @@ options_act_reversible(or_options_t *old_options, char **msg)
/* Ensure data directory is private; create if possible. */
if (check_private_dir(options->DataDirectory,
running_tor ? CPD_CREATE : CPD_CHECK)<0) {
- char buf[1024];
- int tmp = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"Couldn't access/create private data directory \"%s\"",
options->DataDirectory);
- *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
goto done;
/* No need to roll back, since you can't change the value. */
}
@@ -1133,10 +1015,8 @@ options_act_reversible(or_options_t *old_options, char **msg)
tor_snprintf(fn, len, "%s"PATH_SEPARATOR"cached-status",
options->DataDirectory);
if (check_private_dir(fn, running_tor ? CPD_CREATE : CPD_CHECK) < 0) {
- char buf[1024];
- int tmp = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"Couldn't access/create private data directory \"%s\"", fn);
- *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
tor_free(fn);
goto done;
}
@@ -1236,7 +1116,6 @@ get_effective_bwrate(or_options_t *options)
bw = options->MaxAdvertisedBandwidth;
if (options->RelayBandwidthRate > 0 && bw > options->RelayBandwidthRate)
bw = options->RelayBandwidthRate;
-
/* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
return (uint32_t)bw;
}
@@ -1314,14 +1193,14 @@ options_act(or_options_t *old_options)
return 0;
/* Finish backgrounding the process */
- if (running_tor && options->RunAsDaemon) {
+ if (options->RunAsDaemon) {
/* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
finish_daemon(options->DataDirectory);
}
/* Write our PID to the PID file. If we do not have write permissions we
* will log a warning */
- if (running_tor && options->PidFile)
+ if (options->PidFile)
write_pidfile(options->PidFile);
/* Register addressmap directives */
@@ -1354,18 +1233,66 @@ options_act(or_options_t *old_options)
if (accounting_is_enabled(options))
configure_accounting(time(NULL));
+ /* parse RefuseUnknownExits tristate */
+ if (!strcmp(options->RefuseUnknownExits, "0"))
+ options->RefuseUnknownExits_ = 0;
+ else if (!strcmp(options->RefuseUnknownExits, "1"))
+ options->RefuseUnknownExits_ = 1;
+ else if (!strcmp(options->RefuseUnknownExits, "auto"))
+ options->RefuseUnknownExits_ = -1;
+ else {
+ /* Should have caught this in options_validate */
+ return -1;
+ }
+
+ /* Change the cell EWMA settings */
+ cell_ewma_set_scale_factor(options, networkstatus_get_latest_consensus());
+
/* Check for transitions that need action. */
if (old_options) {
- if (options->UseEntryGuards && !old_options->UseEntryGuards) {
+
+ if ((options->UseEntryGuards && !old_options->UseEntryGuards) ||
+ (options->ExcludeNodes &&
+ !routerset_equal(old_options->ExcludeNodes,options->ExcludeNodes)) ||
+ (options->ExcludeExitNodes &&
+ !routerset_equal(old_options->ExcludeExitNodes,
+ options->ExcludeExitNodes)) ||
+ (options->EntryNodes &&
+ !routerset_equal(old_options->EntryNodes, options->EntryNodes)) ||
+ (options->ExitNodes &&
+ !routerset_equal(old_options->ExitNodes, options->ExitNodes)) ||
+ options->StrictNodes != old_options->StrictNodes) {
log_info(LD_CIRC,
- "Switching to entry guards; abandoning previous circuits");
+ "Changed to using entry guards, or changed preferred or "
+ "excluded node lists. Abandoning previous circuits.");
circuit_mark_all_unused_circs();
circuit_expire_all_dirty_circs();
}
+/* How long should we delay counting bridge stats after becoming a bridge?
+ * We use this so we don't count people who used our bridge thinking it is
+ * a relay. If you change this, don't forget to change the log message
+ * below. It's 4 hours (the time it takes to stop being used by clients)
+ * plus some extra time for clock skew. */
+#define RELAY_BRIDGE_STATS_DELAY (6 * 60 * 60)
+
if (! bool_eq(options->BridgeRelay, old_options->BridgeRelay)) {
- log_info(LD_GENERAL, "Bridge status changed. Forgetting GeoIP stats.");
- geoip_remove_old_clients(time(NULL)+(2*60*60));
+ int was_relay = 0;
+ if (options->BridgeRelay) {
+ time_t int_start = time(NULL);
+ if (old_options->ORPort == options->ORPort) {
+ int_start += RELAY_BRIDGE_STATS_DELAY;
+ was_relay = 1;
+ }
+ geoip_bridge_stats_init(int_start);
+ log_info(LD_CONFIG, "We are acting as a bridge now. Starting new "
+ "GeoIP stats interval%s.", was_relay ? " in 6 "
+ "hours from now" : "");
+ } else {
+ geoip_bridge_stats_term();
+ log_info(LD_GENERAL, "We are no longer acting as a bridge. "
+ "Forgetting GeoIP stats.");
+ }
}
if (options_transition_affects_workers(old_options, options)) {
@@ -1377,7 +1304,7 @@ options_act(or_options_t *old_options)
return -1;
}
ip_address_changed(0);
- if (has_completed_circuit || !any_predicted_circuits(time(NULL)))
+ if (can_complete_circuit || !any_predicted_circuits(time(NULL)))
inform_testing_reachability();
}
cpuworkers_rotate();
@@ -1390,6 +1317,10 @@ options_act(or_options_t *old_options)
if (options->V3AuthoritativeDir && !old_options->V3AuthoritativeDir)
init_keys();
+
+ if (options->PerConnBWRate != old_options->PerConnBWRate ||
+ options->PerConnBWBurst != old_options->PerConnBWBurst)
+ connection_or_update_token_buckets(get_connection_array(), options);
}
/* Maybe load geoip file */
@@ -1412,13 +1343,63 @@ options_act(or_options_t *old_options)
geoip_load_file(actual_fname, options);
tor_free(actual_fname);
}
-#ifdef ENABLE_GEOIP_STATS
- log_warn(LD_CONFIG, "We are configured to measure GeoIP statistics, but "
- "the way these statistics are measured has changed "
- "significantly in later versions of Tor. The results may not be "
- "as expected if you are used to later versions. Be sure you "
- "know what you are doing.");
-#endif
+
+ if (options->DirReqStatistics && !geoip_is_loaded()) {
+ /* Check if GeoIP database could be loaded. */
+ log_warn(LD_CONFIG, "Configured to measure directory request "
+ "statistics, but no GeoIP database found!");
+ return -1;
+ }
+
+ if (options->EntryStatistics) {
+ if (should_record_bridge_info(options)) {
+ /* Don't allow measuring statistics on entry guards when configured
+ * as bridge. */
+ log_warn(LD_CONFIG, "Bridges cannot be configured to measure "
+ "additional GeoIP statistics as entry guards.");
+ return -1;
+ } else if (!geoip_is_loaded()) {
+ /* Check if GeoIP database could be loaded. */
+ log_warn(LD_CONFIG, "Configured to measure entry node statistics, "
+ "but no GeoIP database found!");
+ return -1;
+ }
+ }
+
+ if (options->CellStatistics || options->DirReqStatistics ||
+ options->EntryStatistics || options->ExitPortStatistics) {
+ time_t now = time(NULL);
+ if ((!old_options || !old_options->CellStatistics) &&
+ options->CellStatistics)
+ rep_hist_buffer_stats_init(now);
+ if ((!old_options || !old_options->DirReqStatistics) &&
+ options->DirReqStatistics)
+ geoip_dirreq_stats_init(now);
+ if ((!old_options || !old_options->EntryStatistics) &&
+ options->EntryStatistics)
+ geoip_entry_stats_init(now);
+ if ((!old_options || !old_options->ExitPortStatistics) &&
+ options->ExitPortStatistics)
+ rep_hist_exit_stats_init(now);
+ if (!old_options)
+ log_notice(LD_CONFIG, "Configured to measure statistics. Look for "
+ "the *-stats files that will first be written to the "
+ "data directory in 24 hours from now.");
+ }
+
+ if (old_options && old_options->CellStatistics &&
+ !options->CellStatistics)
+ rep_hist_buffer_stats_term();
+ if (old_options && old_options->DirReqStatistics &&
+ !options->DirReqStatistics)
+ geoip_dirreq_stats_term();
+ if (old_options && old_options->EntryStatistics &&
+ !options->EntryStatistics)
+ geoip_entry_stats_term();
+ if (old_options && old_options->ExitPortStatistics &&
+ !options->ExitPortStatistics)
+ rep_hist_exit_stats_term();
+
/* Check if we need to parse and add the EntryNodes config option. */
if (options->EntryNodes &&
(!old_options ||
@@ -1491,7 +1472,10 @@ expand_abbrev(config_format_t *fmt, const char *option, int command_line,
fmt->abbrevs[i].abbreviated,
fmt->abbrevs[i].full);
}
- return fmt->abbrevs[i].full;
+ /* Keep going through the list in case we want to rewrite it more.
+ * (We could imagine recursing here, but I don't want to get the
+ * user into an infinite loop if we craft our list wrong.) */
+ option = fmt->abbrevs[i].full;
}
}
return option;
@@ -1536,7 +1520,10 @@ config_get_commandlines(int argc, char **argv, config_line_t **result)
*new = tor_malloc_zero(sizeof(config_line_t));
s = argv[i];
- while (*s == '-')
+ /* Each keyword may be prefixed with one or two dashes. */
+ if (*s == '-')
+ s++;
+ if (*s == '-')
s++;
(*new)->key = tor_strdup(expand_abbrev(&options_format, s, 1, 1));
@@ -1628,19 +1615,6 @@ config_free_lines(config_line_t *front)
}
}
-/** Return the description for a given configuration variable, or NULL if no
- * description exists. */
-static const char *
-config_find_description(config_format_t *fmt, const char *name)
-{
- int i;
- for (i=0; fmt->descriptions[i].name; ++i) {
- if (!strcasecmp(name, fmt->descriptions[i].name))
- return fmt->descriptions[i].description;
- }
- return NULL;
-}
-
/** If <b>key</b> is a configuration option, return the corresponding
* config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
* warn, and return the corresponding config_var_t. Otherwise return NULL.
@@ -1671,6 +1645,16 @@ config_find_option(config_format_t *fmt, const char *key)
return NULL;
}
+/** Return the number of option entries in <b>fmt</b>. */
+static int
+config_count_options(config_format_t *fmt)
+{
+ int i;
+ for (i=0; fmt->vars[i].name; ++i)
+ ;
+ return i;
+}
+
/*
* Functions to assign config options.
*/
@@ -1684,8 +1668,7 @@ static int
config_assign_value(config_format_t *fmt, or_options_t *options,
config_line_t *c, char **msg)
{
- int i, r, ok;
- char buf[1024];
+ int i, ok;
config_var_t *var;
void *lvalue;
@@ -1701,10 +1684,9 @@ config_assign_value(config_format_t *fmt, or_options_t *options,
case CONFIG_TYPE_UINT:
i = (int)tor_parse_long(c->value, 10, 0, INT_MAX, &ok, NULL);
if (!ok) {
- r = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"Int keyword '%s %s' is malformed or out of bounds.",
c->key, c->value);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
return -1;
}
*(int *)lvalue = i;
@@ -1713,10 +1695,9 @@ config_assign_value(config_format_t *fmt, or_options_t *options,
case CONFIG_TYPE_INTERVAL: {
i = config_parse_interval(c->value, &ok);
if (!ok) {
- r = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"Interval '%s %s' is malformed or out of bounds.",
c->key, c->value);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
return -1;
}
*(int *)lvalue = i;
@@ -1726,10 +1707,9 @@ config_assign_value(config_format_t *fmt, or_options_t *options,
case CONFIG_TYPE_MEMUNIT: {
uint64_t u64 = config_parse_memunit(c->value, &ok);
if (!ok) {
- r = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"Value '%s %s' is malformed or out of bounds.",
c->key, c->value);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
return -1;
}
*(uint64_t *)lvalue = u64;
@@ -1739,10 +1719,9 @@ config_assign_value(config_format_t *fmt, or_options_t *options,
case CONFIG_TYPE_BOOL:
i = (int)tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
if (!ok) {
- r = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"Boolean '%s %s' expects 0 or 1.",
c->key, c->value);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
return -1;
}
*(int *)lvalue = i;
@@ -1760,9 +1739,8 @@ config_assign_value(config_format_t *fmt, or_options_t *options,
case CONFIG_TYPE_ISOTIME:
if (parse_iso_time(c->value, (time_t *)lvalue)) {
- r = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"Invalid time '%s' for keyword '%s'", c->value, c->key);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
return -1;
}
break;
@@ -1773,9 +1751,8 @@ config_assign_value(config_format_t *fmt, or_options_t *options,
}
*(routerset_t**)lvalue = routerset_new();
if (routerset_parse(*(routerset_t**)lvalue, c->value, c->key)<0) {
- tor_snprintf(buf, sizeof(buf), "Invalid exit list '%s' for option '%s'",
+ tor_asprintf(msg, "Invalid exit list '%s' for option '%s'",
c->value, c->key);
- *msg = tor_strdup(buf);
return -1;
}
break;
@@ -1800,9 +1777,8 @@ config_assign_value(config_format_t *fmt, or_options_t *options,
log_warn(LD_CONFIG, "Skipping obsolete configuration option '%s'", c->key);
break;
case CONFIG_TYPE_LINELIST_V:
- r = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"You may not provide a value for virtual option '%s'", c->key);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
return -1;
default:
tor_assert(0);
@@ -1823,7 +1799,7 @@ config_assign_value(config_format_t *fmt, or_options_t *options,
static int
config_assign_line(config_format_t *fmt, or_options_t *options,
config_line_t *c, int use_defaults,
- int clear_first, char **msg)
+ int clear_first, bitarray_t *options_seen, char **msg)
{
config_var_t *var;
@@ -1838,13 +1814,12 @@ config_assign_line(config_format_t *fmt, or_options_t *options,
config_line_append((config_line_t**)lvalue, c->key, c->value);
return 0;
} else {
- char buf[1024];
- int tmp = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"Unknown option '%s'. Failing.", c->key);
- *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
return -1;
}
}
+
/* Put keyword into canonical case. */
if (strcmp(var->name, c->key)) {
tor_free(c->key);
@@ -1867,6 +1842,18 @@ config_assign_line(config_format_t *fmt, or_options_t *options,
return 0;
}
+ if (options_seen && (var->type != CONFIG_TYPE_LINELIST &&
+ var->type != CONFIG_TYPE_LINELIST_S)) {
+ /* We're tracking which options we've seen, and this option is not
+ * supposed to occur more than once. */
+ int var_index = (int)(var - fmt->vars);
+ if (bitarray_is_set(options_seen, var_index)) {
+ log_warn(LD_CONFIG, "Option '%s' used more than once; all but the last "
+ "value will be ignored.", var->name);
+ }
+ bitarray_set(options_seen, var_index);
+ }
+
if (config_assign_value(fmt, options, c, msg) < 0)
return -2;
return 0;
@@ -1967,7 +1954,6 @@ get_assigned_option(config_format_t *fmt, void *options,
{
config_var_t *var;
const void *value;
- char buf[32];
config_line_t *result;
tor_assert(options && key);
@@ -2008,19 +1994,16 @@ get_assigned_option(config_format_t *fmt, void *options,
case CONFIG_TYPE_UINT:
/* This means every or_options_t uint or bool element
* needs to be an int. Not, say, a uint16_t or char. */
- tor_snprintf(buf, sizeof(buf), "%d", *(int*)value);
- result->value = tor_strdup(buf);
+ tor_asprintf(&result->value, "%d", *(int*)value);
escape_val = 0; /* Can't need escape. */
break;
case CONFIG_TYPE_MEMUNIT:
- tor_snprintf(buf, sizeof(buf), U64_FORMAT,
+ tor_asprintf(&result->value, U64_FORMAT,
U64_PRINTF_ARG(*(uint64_t*)value));
- result->value = tor_strdup(buf);
escape_val = 0; /* Can't need escape. */
break;
case CONFIG_TYPE_DOUBLE:
- tor_snprintf(buf, sizeof(buf), "%f", *(double*)value);
- result->value = tor_strdup(buf);
+ tor_asprintf(&result->value, "%f", *(double*)value);
escape_val = 0; /* Can't need escape. */
break;
case CONFIG_TYPE_BOOL:
@@ -2139,6 +2122,8 @@ config_assign(config_format_t *fmt, void *options, config_line_t *list,
int use_defaults, int clear_first, char **msg)
{
config_line_t *p;
+ bitarray_t *options_seen;
+ const int n_options = config_count_options(fmt);
CHECK(fmt, options);
@@ -2158,14 +2143,18 @@ config_assign(config_format_t *fmt, void *options, config_line_t *list,
config_reset_line(fmt, options, p->key, use_defaults);
}
+ options_seen = bitarray_init_zero(n_options);
/* pass 3: assign. */
while (list) {
int r;
if ((r=config_assign_line(fmt, options, list, use_defaults,
- clear_first, msg)))
+ clear_first, options_seen, msg))) {
+ bitarray_free(options_seen);
return r;
+ }
list = list->next;
}
+ bitarray_free(options_seen);
return 0;
}
@@ -2308,20 +2297,10 @@ list_torrc_options(void)
smartlist_t *lines = smartlist_create();
for (i = 0; _option_vars[i].name; ++i) {
config_var_t *var = &_option_vars[i];
- const char *desc;
if (var->type == CONFIG_TYPE_OBSOLETE ||
var->type == CONFIG_TYPE_LINELIST_V)
continue;
- desc = config_find_description(&options_format, var->name);
printf("%s\n", var->name);
- if (desc) {
- wrap_string(lines, desc, 76, " ", " ");
- SMARTLIST_FOREACH(lines, char *, cp, {
- printf("%s", cp);
- tor_free(cp);
- });
- smartlist_clear(lines);
- }
}
smartlist_free(lines);
}
@@ -2340,7 +2319,7 @@ resolve_my_address(int warn_severity, or_options_t *options,
uint32_t *addr_out, char **hostname_out)
{
struct in_addr in;
- uint32_t addr;
+ uint32_t addr; /* host order */
char hostname[256];
int explicit_ip=1;
int explicit_hostname=1;
@@ -2370,8 +2349,8 @@ resolve_my_address(int warn_severity, or_options_t *options,
if (tor_inet_aton(hostname, &in) == 0) {
/* then we have to resolve it */
explicit_ip = 0;
- if (tor_lookup_hostname(hostname, &addr)) {
- uint32_t interface_ip;
+ if (tor_lookup_hostname(hostname, &addr)) { /* failed to resolve */
+ uint32_t interface_ip; /* host order */
if (explicit_hostname) {
log_fn(warn_severity, LD_CONFIG,
@@ -2392,7 +2371,7 @@ resolve_my_address(int warn_severity, or_options_t *options,
log_fn(notice_severity, LD_CONFIG, "Learned IP address '%s' for "
"local interface. Using that.", tmpbuf);
strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
- } else {
+ } else { /* resolved hostname into addr */
in.s_addr = htonl(addr);
if (!explicit_hostname &&
@@ -2566,7 +2545,10 @@ config_free(config_format_t *fmt, void *options)
{
int i;
- tor_assert(options);
+ if (!options)
+ return;
+
+ tor_assert(fmt);
for (i=0; fmt->vars[i].name; ++i)
option_clear(fmt, options, &(fmt->vars[i]));
@@ -2668,6 +2650,8 @@ is_listening_on_low_port(uint16_t port_option,
const config_line_t *listen_options)
{
#ifdef MS_WINDOWS
+ (void) port_option;
+ (void) listen_options;
return 0; /* No port is too low for windows. */
#else
const config_line_t *l;
@@ -2717,7 +2701,6 @@ config_dump(config_format_t *fmt, void *options, int minimal,
config_line_t *line, *assigned;
char *result;
int i;
- const char *desc;
char *msg = NULL;
defaults = config_alloc(fmt);
@@ -2745,24 +2728,13 @@ config_dump(config_format_t *fmt, void *options, int minimal,
option_is_same(fmt, options, defaults, fmt->vars[i].name))
comment_option = 1;
- desc = config_find_description(fmt, fmt->vars[i].name);
line = assigned = get_assigned_option(fmt, options, fmt->vars[i].name, 1);
- if (line && desc) {
- /* Only dump the description if there's something to describe. */
- wrap_string(elements, desc, 78, "# ", "# ");
- }
-
for (; line; line = line->next) {
- size_t len = strlen(line->key) + strlen(line->value) + 5;
char *tmp;
- tmp = tor_malloc(len);
- if (tor_snprintf(tmp, len, "%s%s %s\n",
- comment_option ? "# " : "",
- line->key, line->value)<0) {
- log_err(LD_BUG,"Internal error writing option value");
- tor_assert(0);
- }
+ tor_asprintf(&tmp, "%s%s %s\n",
+ comment_option ? "# " : "",
+ line->key, line->value);
smartlist_add(elements, tmp);
}
config_free_lines(assigned);
@@ -2771,13 +2743,8 @@ config_dump(config_format_t *fmt, void *options, int minimal,
if (fmt->extra) {
line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->var_offset);
for (; line; line = line->next) {
- size_t len = strlen(line->key) + strlen(line->value) + 3;
char *tmp;
- tmp = tor_malloc(len);
- if (tor_snprintf(tmp, len, "%s %s\n", line->key, line->value)<0) {
- log_err(LD_BUG,"Internal error writing option value");
- tor_assert(0);
- }
+ tor_asprintf(&tmp, "%s %s\n", line->key, line->value);
smartlist_add(elements, tmp);
}
}
@@ -2793,7 +2760,7 @@ config_dump(config_format_t *fmt, void *options, int minimal,
* the configuration in <b>options</b>. If <b>minimal</b> is true, do not
* include options that are the same as Tor's defaults.
*/
-static char *
+char *
options_dump(or_options_t *options, int minimal)
{
return config_dump(&options_format, options, minimal, 0);
@@ -2806,7 +2773,6 @@ static int
validate_ports_csv(smartlist_t *sl, const char *name, char **msg)
{
int i;
- char buf[1024];
tor_assert(name);
if (!sl)
@@ -2816,9 +2782,7 @@ validate_ports_csv(smartlist_t *sl, const char *name, char **msg)
{
i = atoi(cp);
if (i < 1 || i > 65535) {
- int r = tor_snprintf(buf, sizeof(buf),
- "Port '%s' out of range in %s", cp, name);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
+ tor_asprintf(msg, "Port '%s' out of range in %s", cp, name);
return -1;
}
});
@@ -2832,18 +2796,15 @@ validate_ports_csv(smartlist_t *sl, const char *name, char **msg)
static int
ensure_bandwidth_cap(uint64_t *value, const char *desc, char **msg)
{
- int r;
- char buf[1024];
if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
/* This handles an understandable special case where somebody says "2gb"
* whereas our actual maximum is 2gb-1 (INT_MAX) */
--*value;
}
if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
- r = tor_snprintf(buf, sizeof(buf), "%s ("U64_FORMAT") must be at most %d",
- desc, U64_PRINTF_ARG(*value),
- ROUTER_MAX_DECLARED_BANDWIDTH);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
+ tor_asprintf(msg, "%s ("U64_FORMAT") must be at most %d",
+ desc, U64_PRINTF_ARG(*value),
+ ROUTER_MAX_DECLARED_BANDWIDTH);
return -1;
}
return 0;
@@ -2894,15 +2855,14 @@ compute_publishserverdescriptor(or_options_t *options)
/** Highest allowable value for RendPostPeriod. */
#define MAX_DIR_PERIOD (MIN_ONION_KEY_LIFETIME/2)
-/** Lowest allowable value for CircuitBuildTimeout; values too low will
- * increase network load because of failing connections being retried, and
- * might prevent users from connecting to the network at all. */
-#define MIN_CIRCUIT_BUILD_TIMEOUT 30
-
/** Lowest allowable value for MaxCircuitDirtiness; if this is too low, Tor
* will generate too many circuits and potentially overload the network. */
#define MIN_MAX_CIRCUIT_DIRTINESS 10
+/** Lowest allowable value for CircuitStreamTimeout; if this is too low, Tor
+ * will generate too many circuits and potentially overload the network. */
+#define MIN_CIRCUIT_STREAM_TIMEOUT 10
+
/** Return 0 if every setting in <b>options</b> is reasonable, and a
* permissible transition from <b>old_options</b>. Else return -1.
* Should have no side effects, except for normalizing the contents of
@@ -2919,10 +2879,9 @@ static int
options_validate(or_options_t *old_options, or_options_t *options,
int from_setconf, char **msg)
{
- int i, r;
+ int i;
config_line_t *cl;
const char *uname = get_uname();
- char buf[1024];
#define REJECT(arg) \
STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
#define COMPLAIN(arg) STMT_BEGIN log(LOG_WARN, LD_CONFIG, arg); STMT_END
@@ -2939,7 +2898,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
!strcmpstart(uname, "Windows Me"))) {
log(LOG_WARN, LD_CONFIG, "Tor is running as a server, but you are "
"running %s; this probably won't work. See "
- "http://wiki.noreply.org/noreply/TheOnionRouter/TorFAQ#ServerOS "
+ "https://wiki.torproject.org/TheOnionRouter/TorFAQ#ServerOS "
"for details.", uname);
}
@@ -2958,8 +2917,8 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (options->TransPort == 0 && options->TransListenAddress != NULL)
REJECT("TransPort must be defined if TransListenAddress is defined.");
- if (options->NatdPort == 0 && options->NatdListenAddress != NULL)
- REJECT("NatdPort must be defined if NatdListenAddress is defined.");
+ if (options->NATDPort == 0 && options->NATDListenAddress != NULL)
+ REJECT("NATDPort must be defined if NATDListenAddress is defined.");
/* Don't gripe about SocksPort 0 with SocksListenAddress set; a standard
* configuration does this. */
@@ -2978,8 +2937,8 @@ options_validate(or_options_t *old_options, or_options_t *options,
old = old_options ? old_options->TransListenAddress : NULL;
tp = "transparent proxy";
} else {
- opt = options->NatdListenAddress;
- old = old_options ? old_options->NatdListenAddress : NULL;
+ opt = options->NATDListenAddress;
+ old = old_options ? old_options->NATDListenAddress : NULL;
tp = "natd proxy";
}
@@ -3017,10 +2976,9 @@ options_validate(or_options_t *old_options, or_options_t *options,
}
} else {
if (!is_legal_nickname(options->Nickname)) {
- r = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"Nickname '%s' is wrong length or contains illegal characters.",
options->Nickname);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
return -1;
}
}
@@ -3037,14 +2995,6 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (options_init_logs(options, 1)<0) /* Validate the log(s) */
REJECT("Failed to validate Log options. See logs for details.");
- if (options->NoPublish) {
- log(LOG_WARN, LD_CONFIG,
- "NoPublish is obsolete. Use PublishServerDescriptor instead.");
- SMARTLIST_FOREACH(options->PublishServerDescriptor, char *, s,
- tor_free(s));
- smartlist_clear(options->PublishServerDescriptor);
- }
-
if (authdir_mode(options)) {
/* confirm that our address isn't broken, so we can complain now */
uint32_t tmp;
@@ -3052,6 +3002,12 @@ options_validate(or_options_t *old_options, or_options_t *options,
REJECT("Failed to resolve/guess local address. See logs for details.");
}
+ if (strcmp(options->RefuseUnknownExits, "0") &&
+ strcmp(options->RefuseUnknownExits, "1") &&
+ strcmp(options->RefuseUnknownExits, "auto")) {
+ REJECT("RefuseUnknownExits must be 0, 1, or auto");
+ }
+
#ifndef MS_WINDOWS
if (options->RunAsDaemon && torrc_fname && path_is_relative(torrc_fname))
REJECT("Can't use a relative path to torrc when RunAsDaemon is set.");
@@ -3066,14 +3022,14 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (options->TransPort < 0 || options->TransPort > 65535)
REJECT("TransPort option out of bounds.");
- if (options->NatdPort < 0 || options->NatdPort > 65535)
- REJECT("NatdPort option out of bounds.");
+ if (options->NATDPort < 0 || options->NATDPort > 65535)
+ REJECT("NATDPort option out of bounds.");
if (options->SocksPort == 0 && options->TransPort == 0 &&
- options->NatdPort == 0 && options->ORPort == 0 &&
+ options->NATDPort == 0 && options->ORPort == 0 &&
options->DNSPort == 0 && !options->RendConfigLines)
log(LOG_WARN, LD_CONFIG,
- "SocksPort, TransPort, NatdPort, DNSPort, and ORPort are all "
+ "SocksPort, TransPort, NATDPort, DNSPort, and ORPort are all "
"undefined, and there aren't any hidden services configured. "
"Tor will still run, but probably won't do anything.");
@@ -3107,19 +3063,11 @@ options_validate(or_options_t *old_options, or_options_t *options,
routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeNodes);
}
- if (options->StrictExitNodes &&
- (!options->ExitNodes) &&
- (!old_options ||
- (old_options->StrictExitNodes != options->StrictExitNodes) ||
- (!routerset_equal(old_options->ExitNodes,options->ExitNodes))))
- COMPLAIN("StrictExitNodes set, but no ExitNodes listed.");
-
- if (options->StrictEntryNodes &&
- (!options->EntryNodes) &&
- (!old_options ||
- (old_options->StrictEntryNodes != options->StrictEntryNodes) ||
- (!routerset_equal(old_options->EntryNodes,options->EntryNodes))))
- COMPLAIN("StrictEntryNodes set, but no EntryNodes listed.");
+ if (options->ExcludeNodes && options->StrictNodes) {
+ COMPLAIN("You have asked to exclude certain relays from all positions "
+ "in your circuits. Expect hidden services and other Tor "
+ "features to be broken in unpredictable ways.");
+ }
if (options->EntryNodes && !routerset_is_list(options->EntryNodes)) {
/* XXXX fix this; see entry_guards_prepend_from_config(). */
@@ -3157,6 +3105,10 @@ options_validate(or_options_t *old_options, or_options_t *options,
options->V3AuthoritativeDir))
REJECT("AuthoritativeDir is set, but none of "
"(Bridge/HS/V1/V2/V3)AuthoritativeDir is set.");
+ /* If we have a v3bandwidthsfile and it's broken, complain on startup */
+ if (options->V3BandwidthsFile && !old_options) {
+ dirserv_read_measured_bandwidths(options->V3BandwidthsFile, NULL);
+ }
}
if (options->AuthoritativeDir && !options->DirPort)
@@ -3168,15 +3120,14 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (options->AuthoritativeDir && options->ClientOnly)
REJECT("Running as authoritative directory, but ClientOnly also set.");
- if (options->HSAuthorityRecordStats && !options->HSAuthoritativeDir)
- REJECT("HSAuthorityRecordStats is set but we're not running as "
- "a hidden service authority.");
+ if (options->FetchDirInfoExtraEarly && !options->FetchDirInfoEarly)
+ REJECT("FetchDirInfoExtraEarly requires that you also set "
+ "FetchDirInfoEarly");
if (options->ConnLimit <= 0) {
- r = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"ConnLimit must be greater than 0, but was set to %d",
options->ConnLimit);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
return -1;
}
@@ -3295,18 +3246,29 @@ options_validate(or_options_t *old_options, or_options_t *options,
else if (!strcasecmp(cp, "rendezvous"))
options->_AllowInvalid |= ALLOW_INVALID_RENDEZVOUS;
else {
- r = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"Unrecognized value '%s' in AllowInvalidNodes", cp);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
return -1;
}
});
}
+ if (!options->SafeLogging ||
+ !strcasecmp(options->SafeLogging, "0")) {
+ options->_SafeLogging = SAFELOG_SCRUB_NONE;
+ } else if (!strcasecmp(options->SafeLogging, "relay")) {
+ options->_SafeLogging = SAFELOG_SCRUB_RELAY;
+ } else if (!strcasecmp(options->SafeLogging, "1")) {
+ options->_SafeLogging = SAFELOG_SCRUB_ALL;
+ } else {
+ tor_asprintf(msg,
+ "Unrecognized value '%s' in SafeLogging",
+ escaped(options->SafeLogging));
+ return -1;
+ }
+
if (compute_publishserverdescriptor(options) < 0) {
- r = tor_snprintf(buf, sizeof(buf),
- "Unrecognized value in PublishServerDescriptor");
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
+ tor_asprintf(msg, "Unrecognized value in PublishServerDescriptor");
return -1;
}
@@ -3326,29 +3288,30 @@ options_validate(or_options_t *old_options, or_options_t *options,
}
if (options->RendPostPeriod < MIN_REND_POST_PERIOD) {
- log(LOG_WARN,LD_CONFIG,"RendPostPeriod option is too short; "
- "raising to %d seconds.", MIN_REND_POST_PERIOD);
+ log_warn(LD_CONFIG, "RendPostPeriod option is too short; "
+ "raising to %d seconds.", MIN_REND_POST_PERIOD);
options->RendPostPeriod = MIN_REND_POST_PERIOD;
}
if (options->RendPostPeriod > MAX_DIR_PERIOD) {
- log(LOG_WARN, LD_CONFIG, "RendPostPeriod is too large; clipping to %ds.",
- MAX_DIR_PERIOD);
+ log_warn(LD_CONFIG, "RendPostPeriod is too large; clipping to %ds.",
+ MAX_DIR_PERIOD);
options->RendPostPeriod = MAX_DIR_PERIOD;
}
- if (options->CircuitBuildTimeout < MIN_CIRCUIT_BUILD_TIMEOUT) {
- log(LOG_WARN, LD_CONFIG, "CircuitBuildTimeout option is too short; "
- "raising to %d seconds.", MIN_CIRCUIT_BUILD_TIMEOUT);
- options->CircuitBuildTimeout = MIN_CIRCUIT_BUILD_TIMEOUT;
- }
-
if (options->MaxCircuitDirtiness < MIN_MAX_CIRCUIT_DIRTINESS) {
- log(LOG_WARN, LD_CONFIG, "MaxCircuitDirtiness option is too short; "
- "raising to %d seconds.", MIN_MAX_CIRCUIT_DIRTINESS);
+ log_warn(LD_CONFIG, "MaxCircuitDirtiness option is too short; "
+ "raising to %d seconds.", MIN_MAX_CIRCUIT_DIRTINESS);
options->MaxCircuitDirtiness = MIN_MAX_CIRCUIT_DIRTINESS;
}
+ if (options->CircuitStreamTimeout &&
+ options->CircuitStreamTimeout < MIN_CIRCUIT_STREAM_TIMEOUT) {
+ log_warn(LD_CONFIG, "CircuitStreamTimeout option is too short; "
+ "raising to %d seconds.", MIN_CIRCUIT_STREAM_TIMEOUT);
+ options->CircuitStreamTimeout = MIN_CIRCUIT_STREAM_TIMEOUT;
+ }
+
if (options->KeepalivePeriod < 1)
REJECT("KeepalivePeriod option must be positive.");
@@ -3367,34 +3330,37 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (ensure_bandwidth_cap(&options->RelayBandwidthBurst,
"RelayBandwidthBurst", msg) < 0)
return -1;
+ if (ensure_bandwidth_cap(&options->PerConnBWRate,
+ "PerConnBWRate", msg) < 0)
+ return -1;
+ if (ensure_bandwidth_cap(&options->PerConnBWBurst,
+ "PerConnBWBurst", msg) < 0)
+ return -1;
if (server_mode(options)) {
if (options->BandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH) {
- r = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"BandwidthRate is set to %d bytes/second. "
"For servers, it must be at least %d.",
(int)options->BandwidthRate,
ROUTER_REQUIRED_MIN_BANDWIDTH);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
return -1;
} else if (options->MaxAdvertisedBandwidth <
ROUTER_REQUIRED_MIN_BANDWIDTH/2) {
- r = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"MaxAdvertisedBandwidth is set to %d bytes/second. "
"For servers, it must be at least %d.",
(int)options->MaxAdvertisedBandwidth,
ROUTER_REQUIRED_MIN_BANDWIDTH/2);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
return -1;
}
if (options->RelayBandwidthRate &&
options->RelayBandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH) {
- r = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"RelayBandwidthRate is set to %d bytes/second. "
"For servers, it must be at least %d.",
(int)options->RelayBandwidthRate,
ROUTER_REQUIRED_MIN_BANDWIDTH);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
return -1;
}
}
@@ -3419,34 +3385,73 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (accounting_parse_options(options, 1)<0)
REJECT("Failed to parse accounting options. See logs for details.");
- if (options->HttpProxy) { /* parse it now */
- if (parse_addr_port(LOG_WARN, options->HttpProxy, NULL,
- &options->HttpProxyAddr, &options->HttpProxyPort) < 0)
- REJECT("HttpProxy failed to parse or resolve. Please fix.");
- if (options->HttpProxyPort == 0) { /* give it a default */
- options->HttpProxyPort = 80;
+ if (options->HTTPProxy) { /* parse it now */
+ if (tor_addr_port_parse(options->HTTPProxy,
+ &options->HTTPProxyAddr, &options->HTTPProxyPort) < 0)
+ REJECT("HTTPProxy failed to parse or resolve. Please fix.");
+ if (options->HTTPProxyPort == 0) { /* give it a default */
+ options->HTTPProxyPort = 80;
+ }
+ }
+
+ if (options->HTTPProxyAuthenticator) {
+ if (strlen(options->HTTPProxyAuthenticator) >= 48)
+ REJECT("HTTPProxyAuthenticator is too long (>= 48 chars).");
+ }
+
+ if (options->HTTPSProxy) { /* parse it now */
+ if (tor_addr_port_parse(options->HTTPSProxy,
+ &options->HTTPSProxyAddr, &options->HTTPSProxyPort) <0)
+ REJECT("HTTPSProxy failed to parse or resolve. Please fix.");
+ if (options->HTTPSProxyPort == 0) { /* give it a default */
+ options->HTTPSProxyPort = 443;
}
}
- if (options->HttpProxyAuthenticator) {
- if (strlen(options->HttpProxyAuthenticator) >= 48)
- REJECT("HttpProxyAuthenticator is too long (>= 48 chars).");
+ if (options->HTTPSProxyAuthenticator) {
+ if (strlen(options->HTTPSProxyAuthenticator) >= 48)
+ REJECT("HTTPSProxyAuthenticator is too long (>= 48 chars).");
}
- if (options->HttpsProxy) { /* parse it now */
- if (parse_addr_port(LOG_WARN, options->HttpsProxy, NULL,
- &options->HttpsProxyAddr, &options->HttpsProxyPort) <0)
- REJECT("HttpsProxy failed to parse or resolve. Please fix.");
- if (options->HttpsProxyPort == 0) { /* give it a default */
- options->HttpsProxyPort = 443;
+ if (options->Socks4Proxy) { /* parse it now */
+ if (tor_addr_port_parse(options->Socks4Proxy,
+ &options->Socks4ProxyAddr,
+ &options->Socks4ProxyPort) <0)
+ REJECT("Socks4Proxy failed to parse or resolve. Please fix.");
+ if (options->Socks4ProxyPort == 0) { /* give it a default */
+ options->Socks4ProxyPort = 1080;
}
}
- if (options->HttpsProxyAuthenticator) {
- if (strlen(options->HttpsProxyAuthenticator) >= 48)
- REJECT("HttpsProxyAuthenticator is too long (>= 48 chars).");
+ if (options->Socks5Proxy) { /* parse it now */
+ if (tor_addr_port_parse(options->Socks5Proxy,
+ &options->Socks5ProxyAddr,
+ &options->Socks5ProxyPort) <0)
+ REJECT("Socks5Proxy failed to parse or resolve. Please fix.");
+ if (options->Socks5ProxyPort == 0) { /* give it a default */
+ options->Socks5ProxyPort = 1080;
+ }
}
+ if (options->Socks4Proxy && options->Socks5Proxy)
+ REJECT("You cannot specify both Socks4Proxy and SOCKS5Proxy");
+
+ if (options->Socks5ProxyUsername) {
+ size_t len;
+
+ len = strlen(options->Socks5ProxyUsername);
+ if (len < 1 || len > 255)
+ REJECT("Socks5ProxyUsername must be between 1 and 255 characters.");
+
+ if (!options->Socks5ProxyPassword)
+ REJECT("Socks5ProxyPassword must be included with Socks5ProxyUsername.");
+
+ len = strlen(options->Socks5ProxyPassword);
+ if (len < 1 || len > 255)
+ REJECT("Socks5ProxyPassword must be between 1 and 255 characters.");
+ } else if (options->Socks5ProxyPassword)
+ REJECT("Socks5ProxyPassword must be included with Socks5ProxyUsername.");
+
if (options->HashedControlPassword) {
smartlist_t *sl = decode_hashed_passwords(options->HashedControlPassword);
if (!sl) {
@@ -3510,6 +3515,13 @@ options_validate(or_options_t *old_options, or_options_t *options,
"upgrade your Tor controller as soon as possible.");
}
+ if (options->CookieAuthFileGroupReadable && !options->CookieAuthFile) {
+ log_warn(LD_CONFIG, "You set the CookieAuthFileGroupReadable but did "
+ "not configure a the path for the cookie file via "
+ "CookieAuthFile. This means your cookie will not be group "
+ "readable.");
+ }
+
if (options->UseEntryGuards && ! options->NumEntryGuards)
REJECT("Cannot enable UseEntryGuards with NumEntryGuards set to 0");
@@ -3543,11 +3555,10 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (options->ConstrainedSockSize < MIN_CONSTRAINED_TCP_BUFFER ||
options->ConstrainedSockSize > MAX_CONSTRAINED_TCP_BUFFER ||
options->ConstrainedSockSize % 1024) {
- r = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"ConstrainedSockSize is invalid. Must be a value between %d and %d "
"in 1024 byte increments.",
MIN_CONSTRAINED_TCP_BUFFER, MAX_CONSTRAINED_TCP_BUFFER);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
return -1;
}
if (options->DirPort) {
@@ -3595,6 +3606,12 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (options->PreferTunneledDirConns && !options->TunnelDirConns)
REJECT("Must set TunnelDirConns if PreferTunneledDirConns is set.");
+ if ((options->Socks4Proxy || options->Socks5Proxy) &&
+ !options->HTTPProxy && !options->PreferTunneledDirConns)
+ REJECT("When Socks4Proxy or Socks5Proxy is configured, "
+ "PreferTunneledDirConns and TunnelDirConns must both be "
+ "set to 1, or HTTPProxy must be configured.");
+
if (options->AutomapHostsSuffixes) {
SMARTLIST_FOREACH(options->AutomapHostsSuffixes, char *, suf,
{
@@ -3609,6 +3626,13 @@ options_validate(or_options_t *old_options, or_options_t *options,
"a non-default set of DirServers.");
}
+ if (options->AllowSingleHopExits && !options->DirServers) {
+ COMPLAIN("You have set AllowSingleHopExits; now your relay will allow "
+ "others to make one-hop exits. However, since by default most "
+ "clients avoid relays that set this option, most clients will "
+ "ignore you.");
+ }
+
/*XXXX022 checking for defaults manually like this is a bit fragile.*/
/* Keep changes to hard-coded values synchronous to man page and default
@@ -3674,6 +3698,26 @@ options_validate(or_options_t *old_options, or_options_t *options,
"testing Tor network!");
}
+ if (options->AccelName && !options->HardwareAccel)
+ options->HardwareAccel = 1;
+ if (options->AccelDir && !options->AccelName)
+ REJECT("Can't use hardware crypto accelerator dir without engine name.");
+
+ if (options->PublishServerDescriptor)
+ SMARTLIST_FOREACH(options->PublishServerDescriptor, const char *, pubdes, {
+ if (!strcmp(pubdes, "1") || !strcmp(pubdes, "0"))
+ if (smartlist_len(options->PublishServerDescriptor) > 1) {
+ COMPLAIN("You have passed a list of multiple arguments to the "
+ "PublishServerDescriptor option that includes 0 or 1. "
+ "0 or 1 should only be used as the sole argument. "
+ "This configuration will be rejected in a future release.");
+ break;
+ }
+ });
+
+ if (options->BridgeRelay == 1 && options->ORPort == 0)
+ REJECT("BridgeRelay is 1, ORPort is 0. This is an invalid combination.");
+
return 0;
#undef REJECT
#undef COMPLAIN
@@ -3712,12 +3756,10 @@ options_transition_allowed(or_options_t *old, or_options_t *new_val,
}
if (strcmp(old->DataDirectory,new_val->DataDirectory)!=0) {
- char buf[1024];
- int r = tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(msg,
"While Tor is running, changing DataDirectory "
"(\"%s\"->\"%s\") is not allowed.",
old->DataDirectory, new_val->DataDirectory);
- *msg = tor_strdup(r >= 0 ? buf : "internal error");
return -1;
}
@@ -3726,19 +3768,22 @@ options_transition_allowed(or_options_t *old, or_options_t *new_val,
return -1;
}
- if (!opt_streq(old->Group, new_val->Group)) {
- *msg = tor_strdup("While Tor is running, changing Group is not allowed.");
+ if ((old->HardwareAccel != new_val->HardwareAccel)
+ || !opt_streq(old->AccelName, new_val->AccelName)
+ || !opt_streq(old->AccelDir, new_val->AccelDir)) {
+ *msg = tor_strdup("While Tor is running, changing OpenSSL hardware "
+ "acceleration engine is not allowed.");
return -1;
}
- if (old->HardwareAccel != new_val->HardwareAccel) {
- *msg = tor_strdup("While Tor is running, changing HardwareAccel is "
- "not allowed.");
+ if (old->TestingTorNetwork != new_val->TestingTorNetwork) {
+ *msg = tor_strdup("While Tor is running, changing TestingTorNetwork "
+ "is not allowed.");
return -1;
}
- if (old->TestingTorNetwork != new_val->TestingTorNetwork) {
- *msg = tor_strdup("While Tor is running, changing TestingTorNetwork "
+ if (old->DisableAllSwap != new_val->DisableAllSwap) {
+ *msg = tor_strdup("While Tor is running, changing DisableAllSwap "
"is not allowed.");
return -1;
}
@@ -3753,7 +3798,7 @@ options_transition_affects_workers(or_options_t *old_options,
or_options_t *new_options)
{
if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
- old_options->NumCpus != new_options->NumCpus ||
+ old_options->NumCPUs != new_options->NumCPUs ||
old_options->ORPort != new_options->ORPort ||
old_options->ServerDNSSearchDomains !=
new_options->ServerDNSSearchDomains ||
@@ -3785,7 +3830,6 @@ options_transition_affects_descriptor(or_options_t *old_options,
old_options->ORPort != new_options->ORPort ||
old_options->DirPort != new_options->DirPort ||
old_options->ClientOnly != new_options->ClientOnly ||
- old_options->NoPublish != new_options->NoPublish ||
old_options->_PublishServerDescriptor !=
new_options->_PublishServerDescriptor ||
get_effective_bwrate(old_options) != get_effective_bwrate(new_options) ||
@@ -3808,6 +3852,7 @@ get_windows_conf_root(void)
{
static int is_set = 0;
static char path[MAX_PATH+1];
+ TCHAR tpath[MAX_PATH] = {0};
LPITEMIDLIST idl;
IMalloc *m;
@@ -3825,7 +3870,7 @@ get_windows_conf_root(void)
#define APPDATA_PATH CSIDL_APPDATA
#endif
if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, APPDATA_PATH, &idl))) {
- GetCurrentDirectory(MAX_PATH, path);
+ getcwd(path,MAX_PATH);
is_set = 1;
log_warn(LD_CONFIG,
"I couldn't find your application data folder: are you "
@@ -3834,8 +3879,15 @@ get_windows_conf_root(void)
return path;
}
/* Convert the path from an "ID List" (whatever that is!) to a path. */
- result = SHGetPathFromIDList(idl, path);
- /* Now we need to free the */
+ result = SHGetPathFromIDList(idl, tpath);
+#ifdef UNICODE
+ wcstombs(path,tpath,MAX_PATH);
+#else
+ strlcpy(path,tpath,sizeof(path));
+#endif
+
+ /* Now we need to free the memory that the path-idl was stored in. In
+ * typical Windows fashion, we can't just call 'free()' on it. */
SHGetMalloc(&m);
if (m) {
m->lpVtbl->Free(m, idl);
@@ -3883,10 +3935,7 @@ check_nickname_list(const char *lst, const char *name, char **msg)
SMARTLIST_FOREACH(sl, const char *, s,
{
if (!is_legal_nickname_or_hexdigest(s)) {
- char buf[1024];
- int tmp = tor_snprintf(buf, sizeof(buf),
- "Invalid nickname '%s' in %s line", s, name);
- *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
+ tor_asprintf(msg, "Invalid nickname '%s' in %s line", s, name);
r = -1;
break;
}
@@ -3910,13 +3959,7 @@ find_torrc_filename(int argc, char **argv,
log(LOG_WARN, LD_CONFIG, "Duplicate -f options on command line.");
tor_free(fname);
}
-#ifdef MS_WINDOWS
- /* XXX one day we might want to extend expand_filename to work
- * under Windows as well. */
- fname = tor_strdup(argv[i+1]);
-#else
fname = expand_filename(argv[i+1]);
-#endif
*using_default_torrc = 0;
++i;
} else if (!strcmp(argv[i],"--ignore-missing-torrc")) {
@@ -4022,6 +4065,12 @@ options_init_from_torrc(int argc, char **argv)
printf("Tor version %s.\n",get_version());
exit(0);
}
+ if (argc > 1 && (!strcmp(argv[1],"--digests"))) {
+ printf("Tor version %s.\n",get_version());
+ printf("%s", libor_get_digests());
+ printf("%s", tor_get_digests());
+ exit(0);
+ }
/* Go through command-line variables */
if (!global_cmdline_options) {
@@ -4189,12 +4238,9 @@ options_init_from_string(const char *cf,
err:
config_free(&options_format, newoptions);
if (*msg) {
- int len = (int)strlen(*msg)+256;
- char *newmsg = tor_malloc(len);
-
- tor_snprintf(newmsg, len, "Failed to parse/validate config: %s", *msg);
- tor_free(*msg);
- *msg = newmsg;
+ char *old_msg = *msg;
+ tor_asprintf(msg, "Failed to parse/validate config: %s", old_msg);
+ tor_free(old_msg);
}
return err;
}
@@ -4582,7 +4628,7 @@ normalize_data_directory(or_options_t *options)
}
/** Check and normalize the value of options->DataDirectory; return 0 if it
- * sane, -1 otherwise. */
+ * is sane, -1 otherwise. */
static int
validate_data_directory(or_options_t *options)
{
@@ -4614,7 +4660,6 @@ write_configuration_file(const char *fname, or_options_t *options)
{
char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
int rename_old = 0, r;
- size_t len;
tor_assert(fname);
@@ -4641,9 +4686,7 @@ write_configuration_file(const char *fname, or_options_t *options)
goto err;
}
- len = strlen(new_conf)+256;
- new_val = tor_malloc(len);
- tor_snprintf(new_val, len, "%s\n%s\n\n%s",
+ tor_asprintf(&new_val, "%s\n%s\n\n%s",
GENERATED_FILE_PREFIX, GENERATED_FILE_COMMENT, new_conf);
if (rename_old) {
@@ -4693,15 +4736,12 @@ write_configuration_file(const char *fname, or_options_t *options)
int
options_save_current(void)
{
- if (torrc_fname) {
- /* This fails if we can't write to our configuration file.
- *
- * If we try falling back to datadirectory or something, we have a better
- * chance of saving the configuration, but a better chance of doing
- * something the user never expected. Let's just warn instead. */
- return write_configuration_file(torrc_fname, get_options());
- }
- return write_configuration_file(get_default_conf_file(), get_options());
+ /* This fails if we can't write to our configuration file.
+ *
+ * If we try falling back to datadirectory or something, we have a better
+ * chance of saving the configuration, but a better chance of doing
+ * something the user never expected. */
+ return write_configuration_file(get_torrc_fname(), get_options());
}
/** Mapping from a unit name to a multiplier for converting that unit into a
@@ -4766,30 +4806,47 @@ static struct unit_table_t time_units[] = {
static uint64_t
config_parse_units(const char *val, struct unit_table_t *u, int *ok)
{
- uint64_t v;
+ uint64_t v = 0;
+ double d = 0;
+ int use_float = 0;
char *cp;
tor_assert(ok);
v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
- if (!*ok)
- return 0;
+ if (!*ok || (cp && *cp == '.')) {
+ d = tor_parse_double(val, 0, UINT64_MAX, ok, &cp);
+ if (!*ok)
+ goto done;
+ use_float = 1;
+ }
+
if (!cp) {
*ok = 1;
- return v;
+ v = use_float ? DBL_TO_U64(d) : v;
+ goto done;
}
- while (TOR_ISSPACE(*cp))
- ++cp;
+
+ cp = (char*) eat_whitespace(cp);
+
for ( ;u->unit;++u) {
if (!strcasecmp(u->unit, cp)) {
- v *= u->multiplier;
+ if (use_float)
+ v = u->multiplier * d;
+ else
+ v *= u->multiplier;
*ok = 1;
- return v;
+ goto done;
}
}
log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
*ok = 0;
- return 0;
+ done:
+
+ if (*ok)
+ return v;
+ else
+ return 0;
}
/** Parse a string in the format "number unit", where unit is a unit of
@@ -4799,7 +4856,8 @@ config_parse_units(const char *val, struct unit_table_t *u, int *ok)
static uint64_t
config_parse_memunit(const char *s, int *ok)
{
- return config_parse_units(s, memory_units, ok);
+ uint64_t u = config_parse_units(s, memory_units, ok);
+ return u;
}
/** Parse a string in the format "number unit", where unit is a unit of time.
@@ -4821,256 +4879,37 @@ config_parse_interval(const char *s, int *ok)
return (int)r;
}
-/* This is what passes for version detection on OSX. We set
- * MACOSX_KQUEUE_IS_BROKEN to true iff we're on a version of OSX before
- * 10.4.0 (aka 1040). */
-#ifdef __APPLE__
-#ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
-#define MACOSX_KQUEUE_IS_BROKEN \
- (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1040)
-#else
-#define MACOSX_KQUEUE_IS_BROKEN 0
-#endif
-#endif
-
/**
* Initialize the libevent library.
*/
static void
init_libevent(void)
{
+ const char *badness=NULL;
+
configure_libevent_logging();
/* If the kernel complains that some method (say, epoll) doesn't
* exist, we don't care about it, since libevent will cope.
*/
suppress_libevent_log_msg("Function not implemented");
-#ifdef __APPLE__
- if (MACOSX_KQUEUE_IS_BROKEN ||
- decode_libevent_version(event_get_version(), NULL) < LE_11B) {
- setenv("EVENT_NOKQUEUE","1",1);
- }
-#endif
- /* In libevent versions before 2.0, it's hard to keep binary compatibility
- * between upgrades, and unpleasant to detect when the version we compiled
- * against is unlike the version we have linked against. Here's how. */
-#if defined(_EVENT_VERSION) && defined(HAVE_EVENT_GET_VERSION)
- /* We have a header-file version and a function-call version. Easy. */
- if (strcmp(_EVENT_VERSION, event_get_version())) {
- int compat1 = -1, compat2 = -1;
- int verybad, prettybad ;
- decode_libevent_version(_EVENT_VERSION, &compat1);
- decode_libevent_version(event_get_version(), &compat2);
- verybad = compat1 != compat2;
- prettybad = (compat1 == -1 || compat2 == -1) && compat1 != compat2;
-
- log(verybad ? LOG_WARN : (prettybad ? LOG_NOTICE : LOG_INFO),
- LD_GENERAL, "We were compiled with headers from version %s "
- "of Libevent, but we're using a Libevent library that says it's "
- "version %s.", _EVENT_VERSION, event_get_version());
- if (verybad)
- log_warn(LD_GENERAL, "This will almost certainly make Tor crash.");
- else if (prettybad)
- log_notice(LD_GENERAL, "If Tor crashes, this might be why.");
- else
- log_info(LD_GENERAL, "I think these versions are binary-compatible.");
- }
-#elif defined(HAVE_EVENT_GET_VERSION)
- /* event_get_version but no _EVENT_VERSION. We might be in 1.4.0-beta or
- earlier, where that's normal. To see whether we were compiled with an
- earlier version, let's see whether the struct event defines MIN_HEAP_IDX.
- */
-#ifdef HAVE_STRUCT_EVENT_MIN_HEAP_IDX
- /* The header files are 1.4.0-beta or later. If the version is not
- * 1.4.0-beta, we are incompatible. */
- {
- if (strcmp(event_get_version(), "1.4.0-beta")) {
- log_warn(LD_GENERAL, "It's a little hard to tell, but you seem to have "
- "Libevent 1.4.0-beta header files, whereas you have linked "
- "against Libevent %s. This will probably make Tor crash.",
- event_get_version());
- }
- }
-#else
- /* Our headers are 1.3e or earlier. If the library version is not 1.4.x or
- later, we're probably fine. */
- {
- const char *v = event_get_version();
- if ((v[0] == '1' && v[2] == '.' && v[3] > '3') || v[0] > '1') {
- log_warn(LD_GENERAL, "It's a little hard to tell, but you seem to have "
- "Libevent header file from 1.3e or earlier, whereas you have "
- "linked against Libevent %s. This will probably make Tor "
- "crash.", event_get_version());
- }
- }
-#endif
+ tor_check_libevent_header_compatibility();
-#elif defined(_EVENT_VERSION)
-#warn "_EVENT_VERSION is defined but not get_event_version(): Libevent is odd."
-#else
- /* Your libevent is ancient. */
-#endif
+ tor_libevent_initialize();
- event_init();
suppress_libevent_log_msg(NULL);
-#if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
- /* Making this a NOTICE for now so we can link bugs to a libevent versions
- * or methods better. */
- log(LOG_NOTICE, LD_GENERAL,
- "Initialized libevent version %s using method %s. Good.",
- event_get_version(), event_get_method());
- check_libevent_version(event_get_method(), get_options()->ORPort != 0);
-#else
- log(LOG_NOTICE, LD_GENERAL,
- "Initialized old libevent (version 1.0b or earlier).");
- log(LOG_WARN, LD_GENERAL,
- "You have a *VERY* old version of libevent. It is likely to be buggy; "
- "please build Tor with a more recent version.");
-#endif
-}
-
-/** Table mapping return value of event_get_version() to le_version_t. */
-static const struct {
- const char *name; le_version_t version; int bincompat;
-} le_version_table[] = {
- /* earlier versions don't have get_version. */
- { "1.0c", LE_10C, 1},
- { "1.0d", LE_10D, 1},
- { "1.0e", LE_10E, 1},
- { "1.1", LE_11, 1 },
- { "1.1a", LE_11A, 1 },
- { "1.1b", LE_11B, 1 },
- { "1.2", LE_12, 1 },
- { "1.2a", LE_12A, 1 },
- { "1.3", LE_13, 1 },
- { "1.3a", LE_13A, 1 },
- { "1.3b", LE_13B, 1 },
- { "1.3c", LE_13C, 1 },
- { "1.3d", LE_13D, 1 },
- { "1.3e", LE_13E, 1 },
- { "1.4.0-beta", LE_140, 2 },
- { "1.4.1-beta", LE_141, 2 },
- { "1.4.2-rc", LE_142, 2 },
- { "1.4.3-stable", LE_143, 2 },
- { "1.4.4-stable", LE_144, 2 },
- { "1.4.5-stable", LE_145, 2 },
- { "1.4.6-stable", LE_146, 2 },
- { "1.4.7-stable", LE_147, 2 },
- { "1.4.8-stable", LE_148, 2 },
- { "1.4.99-trunk", LE_1499, 3 },
- { NULL, LE_OTHER, 0 }
-};
-/** Return the le_version_t for the current version of libevent. If the
- * version is very new, return LE_OTHER. If the version is so old that it
- * doesn't support event_get_version(), return LE_OLD. */
-static le_version_t
-decode_libevent_version(const char *v, int *bincompat_out)
-{
- int i;
- for (i=0; le_version_table[i].name; ++i) {
- if (!strcmp(le_version_table[i].name, v)) {
- if (bincompat_out)
- *bincompat_out = le_version_table[i].bincompat;
- return le_version_table[i].version;
- }
- }
- if (v[0] != '1' && bincompat_out)
- *bincompat_out = 100;
- else if (!strcmpstart(v, "1.4") && bincompat_out)
- *bincompat_out = 2;
- return LE_OTHER;
-}
-
-#if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
-/**
- * Compare the given libevent method and version to a list of versions
- * which are known not to work. Warn the user as appropriate.
- */
-static void
-check_libevent_version(const char *m, int server)
-{
- int buggy = 0, iffy = 0, slow = 0, thread_unsafe = 0;
- le_version_t version;
- const char *v = event_get_version();
- const char *badness = NULL;
- const char *sad_os = "";
-
- version = decode_libevent_version(v, NULL);
-
- /* XXX Would it be worthwhile disabling the methods that we know
- * are buggy, rather than just warning about them and then proceeding
- * to use them? If so, we should probably not wrap this whole thing
- * in HAVE_EVENT_GET_VERSION and HAVE_EVENT_GET_METHOD. -RD */
- /* XXXX The problem is that it's not trivial to get libevent to change it's
- * method once it's initialized, and it's not trivial to tell what method it
- * will use without initializing it. I guess we could preemptively disable
- * buggy libevent modes based on the version _before_ initializing it,
- * though, but then there's no good way (afaict) to warn "I would have used
- * kqueue, but instead I'm using select." -NM */
- if (!strcmp(m, "kqueue")) {
- if (version < LE_11B)
- buggy = 1;
- } else if (!strcmp(m, "epoll")) {
- if (version < LE_11)
- iffy = 1;
- } else if (!strcmp(m, "poll")) {
- if (version < LE_10E)
- buggy = 1;
- else if (version < LE_11)
- slow = 1;
- } else if (!strcmp(m, "select")) {
- if (version < LE_11)
- slow = 1;
- } else if (!strcmp(m, "win32")) {
- if (version < LE_11B)
- buggy = 1;
- }
-
- /* Libevent versions before 1.3b do very badly on operating systems with
- * user-space threading implementations. */
-#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
- if (server && version < LE_13B) {
- thread_unsafe = 1;
- sad_os = "BSD variants";
- }
-#elif defined(__APPLE__) || defined(__darwin__)
- if (server && version < LE_13B) {
- thread_unsafe = 1;
- sad_os = "Mac OS X";
- }
-#endif
-
- if (thread_unsafe) {
- log(LOG_WARN, LD_GENERAL,
- "Libevent version %s often crashes when running a Tor server with %s. "
- "Please use the latest version of libevent (1.3b or later)",v,sad_os);
- badness = "BROKEN";
- } else if (buggy) {
- log(LOG_WARN, LD_GENERAL,
- "There are serious bugs in using %s with libevent %s. "
- "Please use the latest version of libevent.", m, v);
- badness = "BROKEN";
- } else if (iffy) {
- log(LOG_WARN, LD_GENERAL,
- "There are minor bugs in using %s with libevent %s. "
- "You may want to use the latest version of libevent.", m, v);
- badness = "BUGGY";
- } else if (slow && server) {
- log(LOG_WARN, LD_GENERAL,
- "libevent %s can be very slow with %s. "
- "When running a server, please use the latest version of libevent.",
- v,m);
- badness = "SLOW";
- }
+ tor_check_libevent_version(tor_libevent_get_method(),
+ get_options()->ORPort != 0,
+ &badness);
if (badness) {
+ const char *v = tor_libevent_get_version_str();
+ const char *m = tor_libevent_get_method();
control_event_general_status(LOG_WARN,
"BAD_LIBEVENT VERSION=%s METHOD=%s BADNESS=%s RECOVERED=NO",
v, m, badness);
}
-
}
-#endif
/** Return the persistent state struct for this Tor. */
or_state_t *
@@ -5152,22 +4991,61 @@ or_state_validate(or_state_t *old_state, or_state_t *state,
}
/** Replace the current persistent state with <b>new_state</b> */
-static void
+static int
or_state_set(or_state_t *new_state)
{
char *err = NULL;
+ int ret = 0;
tor_assert(new_state);
- if (global_state)
- config_free(&state_format, global_state);
+ config_free(&state_format, global_state);
global_state = new_state;
if (entry_guards_parse_state(global_state, 1, &err)<0) {
log_warn(LD_GENERAL,"%s",err);
tor_free(err);
+ ret = -1;
}
if (rep_hist_load_state(global_state, &err)<0) {
log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
tor_free(err);
+ ret = -1;
+ }
+ if (circuit_build_times_parse_state(&circ_times, global_state) < 0) {
+ ret = -1;
+ }
+ return ret;
+}
+
+/**
+ * Save a broken state file to a backup location.
+ */
+static void
+or_state_save_broken(char *fname)
+{
+ int i;
+ file_status_t status;
+ size_t len = strlen(fname)+16;
+ char *fname2 = tor_malloc(len);
+ for (i = 0; i < 100; ++i) {
+ tor_snprintf(fname2, len, "%s.%d", fname, i);
+ status = file_status(fname2);
+ if (status == FN_NOENT)
+ break;
+ }
+ if (i == 100) {
+ log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
+ "state files to move aside. Discarding the old state file.",
+ fname);
+ unlink(fname);
+ } else {
+ log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
+ "to \"%s\". This could be a bug in Tor; please tell "
+ "the developers.", fname, fname2);
+ if (rename(fname, fname2) < 0) {
+ log_warn(LD_BUG, "Weirdly, I couldn't even move the state aside. The "
+ "OS gave an error of %s", strerror(errno));
+ }
}
+ tor_free(fname2);
}
/** Reload the persistent state from disk, generating a new state as needed.
@@ -5229,31 +5107,8 @@ or_state_load(void)
" This is a bug in Tor.");
goto done;
} else if (badstate && contents) {
- int i;
- file_status_t status;
- size_t len = strlen(fname)+16;
- char *fname2 = tor_malloc(len);
- for (i = 0; i < 100; ++i) {
- tor_snprintf(fname2, len, "%s.%d", fname, i);
- status = file_status(fname2);
- if (status == FN_NOENT)
- break;
- }
- if (i == 100) {
- log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
- "state files to move aside. Discarding the old state file.",
- fname);
- unlink(fname);
- } else {
- log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
- "to \"%s\". This could be a bug in Tor; please tell "
- "the developers.", fname, fname2);
- if (rename(fname, fname2) < 0) {
- log_warn(LD_BUG, "Weirdly, I couldn't even move the state aside. The "
- "OS gave an error of %s", strerror(errno));
- }
- }
- tor_free(fname2);
+ or_state_save_broken(fname);
+
tor_free(contents);
config_free(&state_format, new_state);
@@ -5265,7 +5120,9 @@ or_state_load(void)
} else {
log_info(LD_GENERAL, "Initialized state");
}
- or_state_set(new_state);
+ if (or_state_set(new_state) == -1) {
+ or_state_save_broken(fname);
+ }
new_state = NULL;
if (!contents) {
global_state->next_write = 0;
@@ -5288,7 +5145,6 @@ or_state_save(time_t now)
{
char *state, *contents;
char tbuf[ISO_TIME_LEN+1];
- size_t len;
char *fname;
tor_assert(global_state);
@@ -5300,20 +5156,16 @@ or_state_save(time_t now)
* to avoid redundant writes. */
entry_guards_update_state(global_state);
rep_hist_update_state(global_state);
+ circuit_build_times_update_state(&circ_times, global_state);
if (accounting_is_enabled(get_options()))
accounting_run_housekeeping(now);
- global_state->LastWritten = time(NULL);
tor_free(global_state->TorVersion);
- len = strlen(get_version())+8;
- global_state->TorVersion = tor_malloc(len);
- tor_snprintf(global_state->TorVersion, len, "Tor %s", get_version());
+ tor_asprintf(&global_state->TorVersion, "Tor %s", get_version());
state = config_dump(&state_format, global_state, 1, 0);
- len = strlen(state)+256;
- contents = tor_malloc(len);
format_local_iso_time(tbuf, time(NULL));
- tor_snprintf(contents, len,
+ tor_asprintf(&contents,
"# Tor state file last generated on %s local time\n"
"# Other times below are in GMT\n"
"# You *do not* need to edit this file.\n\n%s",
@@ -5322,10 +5174,13 @@ or_state_save(time_t now)
fname = get_datadir_fname("state");
if (write_str_to_file(fname, contents, 0)<0) {
log_warn(LD_FS, "Unable to write state to file \"%s\"", fname);
+ global_state->LastWritten = -1;
tor_free(fname);
tor_free(contents);
return -1;
}
+
+ global_state->LastWritten = time(NULL);
log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
tor_free(fname);
tor_free(contents);
@@ -5357,18 +5212,18 @@ remove_file_if_very_old(const char *fname, time_t now)
* types. */
int
getinfo_helper_config(control_connection_t *conn,
- const char *question, char **answer)
+ const char *question, char **answer,
+ const char **errmsg)
{
(void) conn;
+ (void) errmsg;
if (!strcmp(question, "config/names")) {
smartlist_t *sl = smartlist_create();
int i;
for (i = 0; _option_vars[i].name; ++i) {
config_var_t *var = &_option_vars[i];
- const char *type, *desc;
+ const char *type;
char *line;
- size_t len;
- desc = config_find_description(&options_format, var->name);
switch (var->type) {
case CONFIG_TYPE_STRING: type = "String"; break;
case CONFIG_TYPE_FILENAME: type = "Filename"; break;
@@ -5389,14 +5244,7 @@ getinfo_helper_config(control_connection_t *conn,
}
if (!type)
continue;
- len = strlen(var->name)+strlen(type)+16;
- if (desc)
- len += strlen(desc);
- line = tor_malloc(len);
- if (desc)
- tor_snprintf(line, len, "%s %s %s\n",var->name,type,desc);
- else
- tor_snprintf(line, len, "%s %s\n",var->name,type);
+ tor_asprintf(&line, "%s %s\n",var->name,type);
smartlist_add(sl, line);
}
*answer = smartlist_join_strings(sl, "", 0, NULL);
diff --git a/src/or/config.h b/src/or/config.h
new file mode 100644
index 0000000000..7a4ba5c60f
--- /dev/null
+++ b/src/or/config.h
@@ -0,0 +1,78 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file config.h
+ * \brief Header file for config.c.
+ **/
+
+#ifndef _TOR_CONFIG_H
+#define _TOR_CONFIG_H
+
+const char *get_dirportfrontpage(void);
+or_options_t *get_options(void);
+int set_options(or_options_t *new_val, char **msg);
+void config_free_all(void);
+const char *safe_str_client(const char *address);
+const char *safe_str(const char *address);
+const char *escaped_safe_str_client(const char *address);
+const char *escaped_safe_str(const char *address);
+const char *get_version(void);
+
+int config_get_lines(const char *string, config_line_t **result);
+void config_free_lines(config_line_t *front);
+setopt_err_t options_trial_assign(config_line_t *list, int use_defaults,
+ int clear_first, char **msg);
+int resolve_my_address(int warn_severity, or_options_t *options,
+ uint32_t *addr, char **hostname_out);
+int is_local_addr(const tor_addr_t *addr) ATTR_PURE;
+void options_init(or_options_t *options);
+char *options_dump(or_options_t *options, int minimal);
+int options_init_from_torrc(int argc, char **argv);
+setopt_err_t options_init_from_string(const char *cf,
+ int command, const char *command_arg, char **msg);
+int option_is_recognized(const char *key);
+const char *option_get_canonical_name(const char *key);
+config_line_t *option_get_assignment(or_options_t *options,
+ const char *key);
+int options_save_current(void);
+const char *get_torrc_fname(void);
+char *options_get_datadir_fname2_suffix(or_options_t *options,
+ const char *sub1, const char *sub2,
+ const char *suffix);
+#define get_datadir_fname2_suffix(sub1, sub2, suffix) \
+ options_get_datadir_fname2_suffix(get_options(), (sub1), (sub2), (suffix))
+/** Return a newly allocated string containing datadir/sub1. See
+ * get_datadir_fname2_suffix. */
+#define get_datadir_fname(sub1) get_datadir_fname2_suffix((sub1), NULL, NULL)
+/** Return a newly allocated string containing datadir/sub1/sub2. See
+ * get_datadir_fname2_suffix. */
+#define get_datadir_fname2(sub1,sub2) \
+ get_datadir_fname2_suffix((sub1), (sub2), NULL)
+/** Return a newly allocated string containing datadir/sub1suffix. See
+ * get_datadir_fname2_suffix. */
+#define get_datadir_fname_suffix(sub1, suffix) \
+ get_datadir_fname2_suffix((sub1), NULL, (suffix))
+
+or_state_t *get_or_state(void);
+int or_state_save(time_t now);
+
+int options_need_geoip_info(or_options_t *options, const char **reason_out);
+int getinfo_helper_config(control_connection_t *conn,
+ const char *question, char **answer,
+ const char **errmsg);
+
+const char *tor_get_digests(void);
+uint32_t get_effective_bwrate(or_options_t *options);
+uint32_t get_effective_bwburst(or_options_t *options);
+
+#ifdef CONFIG_PRIVATE
+/* Used only by config.c and test.c */
+or_options_t *options_new(void);
+#endif
+
+#endif
+
diff --git a/src/or/config_codedigest.c b/src/or/config_codedigest.c
new file mode 100644
index 0000000000..be9eaa331d
--- /dev/null
+++ b/src/or/config_codedigest.c
@@ -0,0 +1,11 @@
+
+const char *tor_get_digests(void);
+
+const char *
+tor_get_digests(void)
+{
+ return ""
+#include "or_sha1.i"
+ ;
+}
+
diff --git a/src/or/connection.c b/src/or/connection.c
index 5036be4507..85cede856c 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -11,6 +11,30 @@
**/
#include "or.h"
+#include "buffers.h"
+#include "circuitbuild.h"
+#include "circuitlist.h"
+#include "circuituse.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_edge.h"
+#include "connection_or.h"
+#include "control.h"
+#include "cpuworker.h"
+#include "directory.h"
+#include "dirserv.h"
+#include "dns.h"
+#include "dnsserv.h"
+#include "geoip.h"
+#include "main.h"
+#include "policies.h"
+#include "reasons.h"
+#include "relay.h"
+#include "rendclient.h"
+#include "rendcommon.h"
+#include "rephist.h"
+#include "router.h"
+#include "routerparse.h"
static connection_t *connection_create_listener(
struct sockaddr *listensockaddr,
@@ -21,7 +45,8 @@ static void connection_init(time_t now, connection_t *conn, int type,
static int connection_init_accepted_conn(connection_t *conn,
uint8_t listener_type);
static int connection_handle_listener_read(connection_t *conn, int new_type);
-static int connection_read_bucket_should_increase(or_connection_t *conn);
+static int connection_bucket_should_increase(int bucket,
+ or_connection_t *conn);
static int connection_finished_flushing(connection_t *conn);
static int connection_flushed_some(connection_t *conn);
static int connection_finished_connecting(connection_t *conn);
@@ -32,6 +57,10 @@ static int connection_process_inbuf(connection_t *conn, int package_partial);
static void client_check_address_changed(int sock);
static void set_constrained_socket_buffers(int sock, int size);
+static const char *connection_proxy_state_to_string(int state);
+static int connection_read_https_proxy_response(connection_t *conn);
+static void connection_send_socks5_connect(connection_t *conn);
+
/** The last IPv4 address that our network interface seemed to have been
* binding to, in host order. We use this to detect when our IP changes. */
static uint32_t last_interface_ip = 0;
@@ -92,8 +121,7 @@ conn_state_to_string(int type, int state)
case CONN_TYPE_OR:
switch (state) {
case OR_CONN_STATE_CONNECTING: return "connect()ing";
- case OR_CONN_STATE_PROXY_FLUSHING: return "proxy flushing";
- case OR_CONN_STATE_PROXY_READING: return "proxy reading";
+ case OR_CONN_STATE_PROXY_HANDSHAKING: return "handshaking (proxy)";
case OR_CONN_STATE_TLS_HANDSHAKING: return "handshaking (TLS)";
case OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING:
return "renegotiating (TLS)";
@@ -177,6 +205,9 @@ or_connection_new(int socket_family)
or_conn->timestamp_last_added_nonpadding = time(NULL);
or_conn->next_circ_id = crypto_rand_int(1<<15);
+ or_conn->active_circuit_pqueue = smartlist_create();
+ or_conn->active_circuit_pqueue_last_recalibrated = cell_ewma_get_tick();
+
return or_conn;
}
@@ -202,6 +233,7 @@ control_connection_new(int socket_family)
tor_malloc_zero(sizeof(control_connection_t));
connection_init(time(NULL),
TO_CONN(control_conn), CONN_TYPE_CONTROL, socket_family);
+ log_notice(LD_CONTROL, "New control connection opened.");
return control_conn;
}
@@ -299,25 +331,6 @@ connection_link_connections(connection_t *conn_a, connection_t *conn_b)
conn_b->linked_conn = conn_a;
}
-/** Tell libevent that we don't care about <b>conn</b> any more. */
-void
-connection_unregister_events(connection_t *conn)
-{
- if (conn->read_event) {
- if (event_del(conn->read_event))
- log_warn(LD_BUG, "Error removing read event for %d", conn->s);
- tor_free(conn->read_event);
- }
- if (conn->write_event) {
- if (event_del(conn->write_event))
- log_warn(LD_BUG, "Error removing write event for %d", conn->s);
- tor_free(conn->write_event);
- }
- if (conn->dns_server_port) {
- dnsserv_close_listener(conn);
- }
-}
-
/** Deallocate memory used by <b>conn</b>. Deallocate its buffers if
* necessary, close its socket if necessary, and mark the directory as dirty
* if <b>conn</b> is an OR or OP connection.
@@ -327,6 +340,9 @@ _connection_free(connection_t *conn)
{
void *mem;
size_t memlen;
+ if (!conn)
+ return;
+
switch (conn->type) {
case CONN_TYPE_OR:
tor_assert(conn->magic == OR_CONNECTION_MAGIC);
@@ -384,14 +400,11 @@ _connection_free(connection_t *conn)
if (connection_speaks_cells(conn)) {
or_connection_t *or_conn = TO_OR_CONN(conn);
- if (or_conn->tls) {
- tor_tls_free(or_conn->tls);
- or_conn->tls = NULL;
- }
- if (or_conn->handshake_state) {
- or_handshake_state_free(or_conn->handshake_state);
- or_conn->handshake_state = NULL;
- }
+ tor_tls_free(or_conn->tls);
+ or_conn->tls = NULL;
+ or_handshake_state_free(or_conn->handshake_state);
+ or_conn->handshake_state = NULL;
+ smartlist_free(or_conn->active_circuit_pqueue);
tor_free(or_conn->nickname);
}
if (CONN_IS_EDGE(conn)) {
@@ -401,8 +414,8 @@ _connection_free(connection_t *conn)
memset(edge_conn->socks_request, 0xcc, sizeof(socks_request_t));
tor_free(edge_conn->socks_request);
}
- if (edge_conn->rend_data)
- rend_data_free(edge_conn->rend_data);
+
+ rend_data_free(edge_conn->rend_data);
}
if (conn->type == CONN_TYPE_CONTROL) {
control_connection_t *control_conn = TO_CONTROL_CONN(conn);
@@ -415,16 +428,15 @@ _connection_free(connection_t *conn)
if (conn->type == CONN_TYPE_DIR) {
dir_connection_t *dir_conn = TO_DIR_CONN(conn);
tor_free(dir_conn->requested_resource);
- if (dir_conn->zlib_state)
- tor_zlib_free(dir_conn->zlib_state);
+
+ tor_zlib_free(dir_conn->zlib_state);
if (dir_conn->fingerprint_stack) {
SMARTLIST_FOREACH(dir_conn->fingerprint_stack, char *, cp, tor_free(cp));
smartlist_free(dir_conn->fingerprint_stack);
}
- if (dir_conn->cached_dir)
- cached_dir_decref(dir_conn->cached_dir);
- if (dir_conn->rend_data)
- rend_data_free(dir_conn->rend_data);
+
+ cached_dir_decref(dir_conn->cached_dir);
+ rend_data_free(dir_conn->rend_data);
}
if (conn->s >= 0) {
@@ -439,7 +451,7 @@ _connection_free(connection_t *conn)
connection_or_remove_from_identity_map(TO_OR_CONN(conn));
}
- memset(conn, 0xAA, memlen); /* poison memory */
+ memset(mem, 0xCC, memlen); /* poison memory */
tor_free(mem);
}
@@ -448,7 +460,8 @@ _connection_free(connection_t *conn)
void
connection_free(connection_t *conn)
{
- tor_assert(conn);
+ if (!conn)
+ return;
tor_assert(!connection_is_on_closeable_list(conn));
tor_assert(!connection_in_array(conn));
if (conn->linked_conn) {
@@ -544,13 +557,6 @@ connection_about_to_close_connection(connection_t *conn)
* failed: forget about this router, and maybe try again. */
connection_dir_request_failed(dir_conn);
}
- if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC && dir_conn->rend_data) {
- /* Give it a try. However, there is no re-fetching for v0 rend
- * descriptors; if the response is empty or the descriptor is
- * unusable, close pending connections (unless a v2 request is
- * still in progress). */
- rend_client_desc_trynow(dir_conn->rend_data->onion_address, 0);
- }
/* If we were trying to fetch a v2 rend desc and did not succeed,
* retry as needed. (If a fetch is successful, the connection state
* is changed to DIR_PURPOSE_HAS_FETCHED_RENDDESC to mark that
@@ -573,7 +579,7 @@ connection_about_to_close_connection(connection_t *conn)
or_options_t *options = get_options();
rep_hist_note_connect_failed(or_conn->identity_digest, now);
entry_guard_register_connect_status(or_conn->identity_digest,0,
- !options->HttpsProxy, now);
+ !options->HTTPSProxy, now);
if (conn->state >= OR_CONN_STATE_TLS_HANDSHAKING) {
int reason = tls_error_to_orconn_end_reason(or_conn->tls_error);
control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED,
@@ -589,7 +595,7 @@ connection_about_to_close_connection(connection_t *conn)
rep_hist_note_disconnect(or_conn->identity_digest, now);
control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED,
tls_error_to_orconn_end_reason(or_conn->tls_error));
- } else if (or_conn->identity_digest) {
+ } else if (!tor_digest_is_zero(or_conn->identity_digest)) {
rep_hist_note_connection_died(or_conn->identity_digest, now);
control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED,
tls_error_to_orconn_end_reason(or_conn->tls_error));
@@ -833,16 +839,16 @@ static void
warn_too_many_conns(void)
{
#define WARN_TOO_MANY_CONNS_INTERVAL (6*60*60)
- static time_t last_warned = 0;
- time_t now = time(NULL);
- int n_conns = get_n_open_sockets();
- if (last_warned + WARN_TOO_MANY_CONNS_INTERVAL < now) {
+ static ratelim_t last_warned = RATELIM_INIT(WARN_TOO_MANY_CONNS_INTERVAL);
+ char *m;
+ if ((m = rate_limit_log(&last_warned, approx_time()))) {
+ int n_conns = get_n_open_sockets();
log_warn(LD_NET,"Failing because we have %d connections already. Please "
- "raise your ulimit -n.", n_conns);
- last_warned = now;
+ "raise your ulimit -n.%s", n_conns, m);
+ tor_free(m);
+ control_event_general_status(LOG_WARN, "TOO_MANY_CONNECTIONS CURRENT=%d",
+ n_conns);
}
- control_event_general_status(LOG_WARN, "TOO_MANY_CONNECTIONS CURRENT=%d",
- n_conns);
}
/** Bind a new non-blocking socket listening to the socket described
@@ -1254,7 +1260,7 @@ connection_connect(connection_t *conn, const char *address,
return -1;
}
- if (options->OutboundBindAddress) {
+ if (options->OutboundBindAddress && !tor_addr_is_loopback(addr)) {
struct sockaddr_in ext_addr;
memset(&ext_addr, 0, sizeof(ext_addr));
@@ -1285,7 +1291,8 @@ connection_connect(connection_t *conn, const char *address,
dest_addr_len = tor_addr_to_sockaddr(addr, port, dest_addr, sizeof(addrbuf));
tor_assert(dest_addr_len > 0);
- log_debug(LD_NET,"Connecting to %s:%u.",escaped_safe_str(address),port);
+ log_debug(LD_NET, "Connecting to %s:%u.",
+ escaped_safe_str_client(address), port);
if (connect(s, dest_addr, dest_addr_len) < 0) {
int e = tor_socket_errno(s);
@@ -1293,7 +1300,8 @@ connection_connect(connection_t *conn, const char *address,
/* yuck. kill it. */
*socket_error = e;
log_info(LD_NET,
- "connect() to %s:%u failed: %s",escaped_safe_str(address),
+ "connect() to %s:%u failed: %s",
+ escaped_safe_str_client(address),
port, tor_socket_strerror(e));
tor_close_socket(s);
return -1;
@@ -1307,7 +1315,8 @@ connection_connect(connection_t *conn, const char *address,
/* it succeeded. we're connected. */
log_fn(inprogress?LOG_DEBUG:LOG_INFO, LD_NET,
- "Connection to %s:%u %s (sock %d).",escaped_safe_str(address),
+ "Connection to %s:%u %s (sock %d).",
+ escaped_safe_str_client(address),
port, inprogress?"in progress":"established", s);
conn->s = s;
if (connection_add(conn) < 0) /* no space, forget it */
@@ -1315,6 +1324,353 @@ connection_connect(connection_t *conn, const char *address,
return inprogress ? 0 : 1;
}
+/** Convert state number to string representation for logging purposes.
+ */
+static const char *
+connection_proxy_state_to_string(int state)
+{
+ static const char *unknown = "???";
+ static const char *states[] = {
+ "PROXY_NONE",
+ "PROXY_HTTPS_WANT_CONNECT_OK",
+ "PROXY_SOCKS4_WANT_CONNECT_OK",
+ "PROXY_SOCKS5_WANT_AUTH_METHOD_NONE",
+ "PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929",
+ "PROXY_SOCKS5_WANT_AUTH_RFC1929_OK",
+ "PROXY_SOCKS5_WANT_CONNECT_OK",
+ "PROXY_CONNECTED",
+ };
+
+ if (state < PROXY_NONE || state > PROXY_CONNECTED)
+ return unknown;
+
+ return states[state];
+}
+
+/** Write a proxy request of <b>type</b> (socks4, socks5, https) to conn
+ * for conn->addr:conn->port, authenticating with the auth details given
+ * in the configuration (if available). SOCKS 5 and HTTP CONNECT proxies
+ * support authentication.
+ *
+ * Returns -1 if conn->addr is incompatible with the proxy protocol, and
+ * 0 otherwise.
+ *
+ * Use connection_read_proxy_handshake() to complete the handshake.
+ */
+int
+connection_proxy_connect(connection_t *conn, int type)
+{
+ or_options_t *options;
+
+ tor_assert(conn);
+
+ options = get_options();
+
+ switch (type) {
+ case PROXY_CONNECT: {
+ char buf[1024];
+ char *base64_authenticator=NULL;
+ const char *authenticator = options->HTTPSProxyAuthenticator;
+
+ /* Send HTTP CONNECT and authentication (if available) in
+ * one request */
+
+ if (authenticator) {
+ base64_authenticator = alloc_http_authenticator(authenticator);
+ if (!base64_authenticator)
+ log_warn(LD_OR, "Encoding https authenticator failed");
+ }
+
+ if (base64_authenticator) {
+ tor_snprintf(buf, sizeof(buf), "CONNECT %s:%d HTTP/1.1\r\n"
+ "Proxy-Authorization: Basic %s\r\n\r\n",
+ fmt_addr(&conn->addr),
+ conn->port, base64_authenticator);
+ tor_free(base64_authenticator);
+ } else {
+ tor_snprintf(buf, sizeof(buf), "CONNECT %s:%d HTTP/1.0\r\n\r\n",
+ fmt_addr(&conn->addr), conn->port);
+ }
+
+ connection_write_to_buf(buf, strlen(buf), conn);
+ conn->proxy_state = PROXY_HTTPS_WANT_CONNECT_OK;
+ break;
+ }
+
+ case PROXY_SOCKS4: {
+ unsigned char buf[9];
+ uint16_t portn;
+ uint32_t ip4addr;
+
+ /* Send a SOCKS4 connect request with empty user id */
+
+ if (tor_addr_family(&conn->addr) != AF_INET) {
+ log_warn(LD_NET, "SOCKS4 client is incompatible with IPv6");
+ return -1;
+ }
+
+ ip4addr = tor_addr_to_ipv4n(&conn->addr);
+ portn = htons(conn->port);
+
+ buf[0] = 4; /* version */
+ buf[1] = SOCKS_COMMAND_CONNECT; /* command */
+ memcpy(buf + 2, &portn, 2); /* port */
+ memcpy(buf + 4, &ip4addr, 4); /* addr */
+ buf[8] = 0; /* userid (empty) */
+
+ connection_write_to_buf((char *)buf, sizeof(buf), conn);
+ conn->proxy_state = PROXY_SOCKS4_WANT_CONNECT_OK;
+ break;
+ }
+
+ case PROXY_SOCKS5: {
+ unsigned char buf[4]; /* fields: vers, num methods, method list */
+
+ /* Send a SOCKS5 greeting (connect request must wait) */
+
+ buf[0] = 5; /* version */
+
+ /* number of auth methods */
+ if (options->Socks5ProxyUsername) {
+ buf[1] = 2;
+ buf[2] = 0x00; /* no authentication */
+ buf[3] = 0x02; /* rfc1929 Username/Passwd auth */
+ conn->proxy_state = PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929;
+ } else {
+ buf[1] = 1;
+ buf[2] = 0x00; /* no authentication */
+ conn->proxy_state = PROXY_SOCKS5_WANT_AUTH_METHOD_NONE;
+ }
+
+ connection_write_to_buf((char *)buf, 2 + buf[1], conn);
+ break;
+ }
+
+ default:
+ log_err(LD_BUG, "Invalid proxy protocol, %d", type);
+ tor_fragile_assert();
+ return -1;
+ }
+
+ log_debug(LD_NET, "set state %s",
+ connection_proxy_state_to_string(conn->proxy_state));
+
+ return 0;
+}
+
+/** Read conn's inbuf. If the http response from the proxy is all
+ * here, make sure it's good news, then return 1. If it's bad news,
+ * return -1. Else return 0 and hope for better luck next time.
+ */
+static int
+connection_read_https_proxy_response(connection_t *conn)
+{
+ char *headers;
+ char *reason=NULL;
+ int status_code;
+ time_t date_header;
+
+ switch (fetch_from_buf_http(conn->inbuf,
+ &headers, MAX_HEADERS_SIZE,
+ NULL, NULL, 10000, 0)) {
+ case -1: /* overflow */
+ log_warn(LD_PROTOCOL,
+ "Your https proxy sent back an oversized response. Closing.");
+ return -1;
+ case 0:
+ log_info(LD_NET,"https proxy response not all here yet. Waiting.");
+ return 0;
+ /* case 1, fall through */
+ }
+
+ if (parse_http_response(headers, &status_code, &date_header,
+ NULL, &reason) < 0) {
+ log_warn(LD_NET,
+ "Unparseable headers from proxy (connecting to '%s'). Closing.",
+ conn->address);
+ tor_free(headers);
+ return -1;
+ }
+ if (!reason) reason = tor_strdup("[no reason given]");
+
+ if (status_code == 200) {
+ log_info(LD_NET,
+ "HTTPS connect to '%s' successful! (200 %s) Starting TLS.",
+ conn->address, escaped(reason));
+ tor_free(reason);
+ return 1;
+ }
+ /* else, bad news on the status code */
+ log_warn(LD_NET,
+ "The https proxy sent back an unexpected status code %d (%s). "
+ "Closing.",
+ status_code, escaped(reason));
+ tor_free(reason);
+ return -1;
+}
+
+/** Send SOCKS5 CONNECT command to <b>conn</b>, copying <b>conn->addr</b>
+ * and <b>conn->port</b> into the request.
+ */
+static void
+connection_send_socks5_connect(connection_t *conn)
+{
+ unsigned char buf[1024];
+ size_t reqsize = 6;
+ uint16_t port = htons(conn->port);
+
+ buf[0] = 5; /* version */
+ buf[1] = SOCKS_COMMAND_CONNECT; /* command */
+ buf[2] = 0; /* reserved */
+
+ if (tor_addr_family(&conn->addr) == AF_INET) {
+ uint32_t addr = tor_addr_to_ipv4n(&conn->addr);
+
+ buf[3] = 1;
+ reqsize += 4;
+ memcpy(buf + 4, &addr, 4);
+ memcpy(buf + 8, &port, 2);
+ } else { /* AF_INET6 */
+ buf[3] = 4;
+ reqsize += 16;
+ memcpy(buf + 4, tor_addr_to_in6(&conn->addr), 16);
+ memcpy(buf + 20, &port, 2);
+ }
+
+ connection_write_to_buf((char *)buf, reqsize, conn);
+
+ conn->proxy_state = PROXY_SOCKS5_WANT_CONNECT_OK;
+}
+
+/** Call this from connection_*_process_inbuf() to advance the proxy
+ * handshake.
+ *
+ * No matter what proxy protocol is used, if this function returns 1, the
+ * handshake is complete, and the data remaining on inbuf may contain the
+ * start of the communication with the requested server.
+ *
+ * Returns 0 if the current buffer contains an incomplete response, and -1
+ * on error.
+ */
+int
+connection_read_proxy_handshake(connection_t *conn)
+{
+ int ret = 0;
+ char *reason = NULL;
+
+ log_debug(LD_NET, "enter state %s",
+ connection_proxy_state_to_string(conn->proxy_state));
+
+ switch (conn->proxy_state) {
+ case PROXY_HTTPS_WANT_CONNECT_OK:
+ ret = connection_read_https_proxy_response(conn);
+ if (ret == 1)
+ conn->proxy_state = PROXY_CONNECTED;
+ break;
+
+ case PROXY_SOCKS4_WANT_CONNECT_OK:
+ ret = fetch_from_buf_socks_client(conn->inbuf,
+ conn->proxy_state,
+ &reason);
+ if (ret == 1)
+ conn->proxy_state = PROXY_CONNECTED;
+ break;
+
+ case PROXY_SOCKS5_WANT_AUTH_METHOD_NONE:
+ ret = fetch_from_buf_socks_client(conn->inbuf,
+ conn->proxy_state,
+ &reason);
+ /* no auth needed, do connect */
+ if (ret == 1) {
+ connection_send_socks5_connect(conn);
+ ret = 0;
+ }
+ break;
+
+ case PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929:
+ ret = fetch_from_buf_socks_client(conn->inbuf,
+ conn->proxy_state,
+ &reason);
+
+ /* send auth if needed, otherwise do connect */
+ if (ret == 1) {
+ connection_send_socks5_connect(conn);
+ ret = 0;
+ } else if (ret == 2) {
+ unsigned char buf[1024];
+ size_t reqsize, usize, psize;
+ const char *user, *pass;
+
+ user = get_options()->Socks5ProxyUsername;
+ pass = get_options()->Socks5ProxyPassword;
+ tor_assert(user && pass);
+
+ /* XXX len of user and pass must be <= 255 !!! */
+ usize = strlen(user);
+ psize = strlen(pass);
+ tor_assert(usize <= 255 && psize <= 255);
+ reqsize = 3 + usize + psize;
+
+ buf[0] = 1; /* negotiation version */
+ buf[1] = usize;
+ memcpy(buf + 2, user, usize);
+ buf[2 + usize] = psize;
+ memcpy(buf + 3 + usize, pass, psize);
+
+ connection_write_to_buf((char *)buf, reqsize, conn);
+
+ conn->proxy_state = PROXY_SOCKS5_WANT_AUTH_RFC1929_OK;
+ ret = 0;
+ }
+ break;
+
+ case PROXY_SOCKS5_WANT_AUTH_RFC1929_OK:
+ ret = fetch_from_buf_socks_client(conn->inbuf,
+ conn->proxy_state,
+ &reason);
+ /* send the connect request */
+ if (ret == 1) {
+ connection_send_socks5_connect(conn);
+ ret = 0;
+ }
+ break;
+
+ case PROXY_SOCKS5_WANT_CONNECT_OK:
+ ret = fetch_from_buf_socks_client(conn->inbuf,
+ conn->proxy_state,
+ &reason);
+ if (ret == 1)
+ conn->proxy_state = PROXY_CONNECTED;
+ break;
+
+ default:
+ log_err(LD_BUG, "Invalid proxy_state for reading, %d",
+ conn->proxy_state);
+ tor_fragile_assert();
+ ret = -1;
+ break;
+ }
+
+ log_debug(LD_NET, "leaving state %s",
+ connection_proxy_state_to_string(conn->proxy_state));
+
+ if (ret < 0) {
+ if (reason) {
+ log_warn(LD_NET, "Proxy Client: unable to connect to %s:%d (%s)",
+ conn->address, conn->port, escaped(reason));
+ tor_free(reason);
+ } else {
+ log_warn(LD_NET, "Proxy Client: unable to connect to %s:%d",
+ conn->address, conn->port);
+ }
+ } else if (ret == 1) {
+ log_info(LD_NET, "Proxy Client: connection to %s:%d successful",
+ conn->address, conn->port);
+ }
+
+ return ret;
+}
+
/**
* Launch any configured listener connections of type <b>type</b>. (A
* listener is configured if <b>port_option</b> is non-zero. If any
@@ -1506,8 +1862,8 @@ retry_all_listeners(smartlist_t *replaced_conns,
replaced_conns, new_conns, 0,
AF_INET)<0)
return -1;
- if (retry_listeners(CONN_TYPE_AP_NATD_LISTENER, options->NatdListenAddress,
- options->NatdPort, "127.0.0.1",
+ if (retry_listeners(CONN_TYPE_AP_NATD_LISTENER, options->NATDListenAddress,
+ options->NATDPort, "127.0.0.1",
replaced_conns, new_conns, 0,
AF_INET)<0)
return -1;
@@ -1643,6 +1999,7 @@ connection_bucket_write_limit(connection_t *conn, time_t now)
int base = connection_speaks_cells(conn) ?
CELL_NETWORK_SIZE : RELAY_PAYLOAD_SIZE;
int priority = conn->type != CONN_TYPE_DIR;
+ int conn_bucket = (int)conn->outbuf_flushlen;
int global_bucket = global_write_bucket;
if (!connection_is_rate_limited(conn)) {
@@ -1650,12 +2007,22 @@ connection_bucket_write_limit(connection_t *conn, time_t now)
return conn->outbuf_flushlen;
}
+ if (connection_speaks_cells(conn)) {
+ /* use the per-conn write limit if it's lower, but if it's less
+ * than zero just use zero */
+ or_connection_t *or_conn = TO_OR_CONN(conn);
+ if (conn->state == OR_CONN_STATE_OPEN)
+ if (or_conn->write_bucket < conn_bucket)
+ conn_bucket = or_conn->write_bucket >= 0 ?
+ or_conn->write_bucket : 0;
+ }
+
if (connection_counts_as_relayed_traffic(conn, now) &&
global_relayed_write_bucket <= global_write_bucket)
global_bucket = global_relayed_write_bucket;
- return connection_bucket_round_robin(base, priority, global_bucket,
- conn->outbuf_flushlen);
+ return connection_bucket_round_robin(base, priority,
+ global_bucket, conn_bucket);
}
/** Return 1 if the global write buckets are low enough that we
@@ -1709,14 +2076,12 @@ global_write_bucket_low(connection_t *conn, size_t attempt, int priority)
return 0;
}
-/** We just read num_read and wrote num_written onto conn.
- * Decrement buckets appropriately. */
+/** We just read <b>num_read</b> and wrote <b>num_written</b> bytes
+ * onto <b>conn</b>. Decrement buckets appropriately. */
static void
connection_buckets_decrement(connection_t *conn, time_t now,
size_t num_read, size_t num_written)
{
- if (!connection_is_rate_limited(conn))
- return; /* local IPs are free */
if (num_written >= INT_MAX || num_read >= INT_MAX) {
log_err(LD_BUG, "Value out of range. num_read=%lu, num_written=%lu, "
"connection type=%s, state=%s",
@@ -1728,10 +2093,24 @@ connection_buckets_decrement(connection_t *conn, time_t now,
tor_fragile_assert();
}
- if (num_read > 0)
+ /* Count bytes of answering direct and tunneled directory requests */
+ if (conn->type == CONN_TYPE_DIR && conn->purpose == DIR_PURPOSE_SERVER) {
+ if (num_read > 0)
+ rep_hist_note_dir_bytes_read(num_read, now);
+ if (num_written > 0)
+ rep_hist_note_dir_bytes_written(num_written, now);
+ }
+
+ if (!connection_is_rate_limited(conn))
+ return; /* local IPs are free */
+ if (num_read > 0) {
rep_hist_note_bytes_read(num_read, now);
- if (num_written > 0)
+ }
+ if (num_written > 0) {
rep_hist_note_bytes_written(num_written, now);
+ }
+ if (conn->type == CONN_TYPE_EXIT)
+ rep_hist_note_exit_bytes(conn->port, num_written, num_read);
if (connection_counts_as_relayed_traffic(conn, now)) {
global_relayed_read_bucket -= (int)num_read;
@@ -1739,8 +2118,10 @@ connection_buckets_decrement(connection_t *conn, time_t now,
}
global_read_bucket -= (int)num_read;
global_write_bucket -= (int)num_written;
- if (connection_speaks_cells(conn) && conn->state == OR_CONN_STATE_OPEN)
+ if (connection_speaks_cells(conn) && conn->state == OR_CONN_STATE_OPEN) {
TO_OR_CONN(conn)->read_bucket -= (int)num_read;
+ TO_OR_CONN(conn)->write_bucket -= (int)num_written;
+ }
}
/** If we have exhausted our global buckets, or the buckets for conn,
@@ -1779,12 +2160,10 @@ connection_consider_empty_write_buckets(connection_t *conn)
} else if (connection_counts_as_relayed_traffic(conn, approx_time()) &&
global_relayed_write_bucket <= 0) {
reason = "global relayed write bucket exhausted. Pausing.";
-#if 0
} else if (connection_speaks_cells(conn) &&
conn->state == OR_CONN_STATE_OPEN &&
TO_OR_CONN(conn)->write_bucket <= 0) {
reason = "connection write bucket exhausted. Pausing.";
-#endif
} else
return; /* all good, no need to stop it */
@@ -1880,14 +2259,19 @@ connection_bucket_refill(int seconds_elapsed, time_t now)
{
if (connection_speaks_cells(conn)) {
or_connection_t *or_conn = TO_OR_CONN(conn);
- if (connection_read_bucket_should_increase(or_conn)) {
+ if (connection_bucket_should_increase(or_conn->read_bucket, or_conn)) {
connection_bucket_refill_helper(&or_conn->read_bucket,
or_conn->bandwidthrate,
or_conn->bandwidthburst,
seconds_elapsed,
"or_conn->read_bucket");
- //log_fn(LOG_DEBUG,"Receiver bucket %d now %d.", i,
- // conn->read_bucket);
+ }
+ if (connection_bucket_should_increase(or_conn->write_bucket, or_conn)) {
+ connection_bucket_refill_helper(&or_conn->write_bucket,
+ or_conn->bandwidthrate,
+ or_conn->bandwidthburst,
+ seconds_elapsed,
+ "or_conn->write_bucket");
}
}
@@ -1908,8 +2292,10 @@ connection_bucket_refill(int seconds_elapsed, time_t now)
if (conn->write_blocked_on_bw == 1
&& global_write_bucket > 0 /* and we're allowed to write */
&& (!connection_counts_as_relayed_traffic(conn, now) ||
- global_relayed_write_bucket > 0)) {
- /* even if we're relayed traffic */
+ global_relayed_write_bucket > 0) /* even if it's relayed traffic */
+ && (!connection_speaks_cells(conn) ||
+ conn->state != OR_CONN_STATE_OPEN ||
+ TO_OR_CONN(conn)->write_bucket > 0)) {
LOG_FN_CONN(conn, (LOG_DEBUG,LD_NET,
"waking up conn (fd %d) for write", conn->s));
conn->write_blocked_on_bw = 0;
@@ -1918,17 +2304,17 @@ connection_bucket_refill(int seconds_elapsed, time_t now)
});
}
-/** Is the receiver bucket for connection <b>conn</b> low enough that we
+/** Is the <b>bucket</b> for connection <b>conn</b> low enough that we
* should add another pile of tokens to it?
*/
static int
-connection_read_bucket_should_increase(or_connection_t *conn)
+connection_bucket_should_increase(int bucket, or_connection_t *conn)
{
tor_assert(conn);
if (conn->_base.state != OR_CONN_STATE_OPEN)
return 0; /* only open connections play the rate limiting game */
- if (conn->read_bucket >= conn->bandwidthburst)
+ if (bucket >= conn->bandwidthburst)
return 0;
return 1;
@@ -1946,8 +2332,8 @@ connection_read_bucket_should_increase(or_connection_t *conn)
* Mark the connection and return -1 if you want to close it, else
* return 0.
*/
-int
-connection_handle_read(connection_t *conn)
+static int
+connection_handle_read_impl(connection_t *conn)
{
int max_to_read=-1, try_to_read;
size_t before, n_read = 0;
@@ -1975,7 +2361,7 @@ connection_handle_read(connection_t *conn)
return 0;
}
-loop_again:
+ loop_again:
try_to_read = max_to_read;
tor_assert(!conn->marked_for_close);
@@ -2016,12 +2402,16 @@ loop_again:
return -1;
}
if (conn->linked_conn) {
- /* The other side's handle_write will never actually get called, so
+ /* The other side's handle_write() will never actually get called, so
* we need to invoke the appropriate callbacks ourself. */
connection_t *linked = conn->linked_conn;
if (n_read) {
- /* Probably a no-op, but hey. */
+ /* Probably a no-op, since linked conns typically don't count for
+ * bandwidth rate limiting. But do it anyway so we can keep stats
+ * accurately. Note that since we read the bytes from conn, and
+ * we're writing the bytes onto the linked connection, we count
+ * these as <i>written</i> bytes. */
connection_buckets_decrement(linked, approx_time(), 0, n_read);
if (connection_flushed_some(linked) < 0)
@@ -2033,7 +2423,7 @@ loop_again:
if (!buf_datalen(linked->outbuf) && conn->active_on_link)
connection_stop_reading_from_linked_conn(conn);
}
- /* If we hit the EOF, call connection_reached_eof. */
+ /* If we hit the EOF, call connection_reached_eof(). */
if (!conn->marked_for_close &&
conn->inbuf_reached_eof &&
connection_reached_eof(conn) < 0) {
@@ -2042,6 +2432,16 @@ loop_again:
return 0;
}
+int
+connection_handle_read(connection_t *conn)
+{
+ int res;
+
+ tor_gettimeofday_cache_clear();
+ res = connection_handle_read_impl(conn);
+ return res;
+}
+
/** Pull in new bytes from conn-\>s or conn-\>linked_conn onto conn-\>inbuf,
* either directly or via TLS. Reduce the token buckets by the number of bytes
* read.
@@ -2075,7 +2475,7 @@ connection_read_to_buf(connection_t *conn, int *max_to_read, int *socket_error)
}
if (connection_speaks_cells(conn) &&
- conn->state > OR_CONN_STATE_PROXY_READING) {
+ conn->state > OR_CONN_STATE_PROXY_HANDSHAKING) {
int pending;
or_connection_t *or_conn = TO_OR_CONN(conn);
size_t initial_size;
@@ -2243,8 +2643,8 @@ connection_outbuf_too_full(connection_t *conn)
* Mark the connection and return -1 if you want to close it, else
* return 0.
*/
-int
-connection_handle_write(connection_t *conn, int force)
+static int
+connection_handle_write_impl(connection_t *conn, int force)
{
int e;
socklen_t len=(socklen_t)sizeof(e);
@@ -2259,7 +2659,7 @@ connection_handle_write(connection_t *conn, int force)
return 0; /* do nothing */
if (conn->in_flushed_some) {
- log_warn(LD_BUG, "called recursively from inside conn->in_flushed_some()");
+ log_warn(LD_BUG, "called recursively from inside conn->in_flushed_some");
return 0;
}
@@ -2303,7 +2703,7 @@ connection_handle_write(connection_t *conn, int force)
: connection_bucket_write_limit(conn, now);
if (connection_speaks_cells(conn) &&
- conn->state > OR_CONN_STATE_PROXY_READING) {
+ conn->state > OR_CONN_STATE_PROXY_HANDSHAKING) {
or_connection_t *or_conn = TO_OR_CONN(conn);
if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING ||
conn->state == OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING) {
@@ -2322,6 +2722,13 @@ connection_handle_write(connection_t *conn, int force)
/* else open, or closing */
result = flush_buf_tls(or_conn->tls, conn->outbuf,
max_to_write, &conn->outbuf_flushlen);
+
+ /* If we just flushed the last bytes, check if this tunneled dir
+ * request is done. */
+ if (buf_datalen(conn->outbuf) == 0 && conn->dirreq_id)
+ geoip_change_dirreq_state(conn->dirreq_id, DIRREQ_TUNNELED,
+ DIRREQ_OR_CONN_BUFFER_FLUSHED);
+
switch (result) {
CASE_TOR_TLS_ERROR_ANY:
case TOR_TLS_CLOSE:
@@ -2341,8 +2748,8 @@ connection_handle_write(connection_t *conn, int force)
if (!connection_is_reading(conn)) {
connection_stop_writing(conn);
conn->write_blocked_on_bw = 1;
- /* we'll start reading again when the next second arrives,
- * and then also start writing again.
+ /* we'll start reading again when we get more tokens in our
+ * read bucket; then we'll start writing again too.
*/
}
/* else no problem, we're already reading */
@@ -2404,6 +2811,15 @@ connection_handle_write(connection_t *conn, int force)
return 0;
}
+int
+connection_handle_write(connection_t *conn, int force)
+{
+ int res;
+ tor_gettimeofday_cache_clear();
+ res = connection_handle_write_impl(conn, force);
+ return res;
+}
+
/** OpenSSL TLS record size is 16383; this is close. The goal here is to
* push data out as soon as we know there's enough for a TLS record, so
* during periods of high load we won't read entire megabytes from
@@ -2577,13 +2993,11 @@ connection_get_by_type_state(int type, int state)
/** Return a connection of type <b>type</b> that has rendquery equal
* to <b>rendquery</b>, and that is not marked for close. If state
- * is non-zero, conn must be of that state too. If rendversion is
- * nonnegative, conn must be fetching that rendversion, too.
+ * is non-zero, conn must be of that state too.
*/
connection_t *
connection_get_by_type_state_rendquery(int type, int state,
- const char *rendquery,
- int rendversion)
+ const char *rendquery)
{
smartlist_t *conns = get_connection_array();
@@ -2598,8 +3012,6 @@ connection_get_by_type_state_rendquery(int type, int state,
(!state || state == conn->state)) {
if (type == CONN_TYPE_DIR &&
TO_DIR_CONN(conn)->rend_data &&
- (rendversion < 0 ||
- rendversion == TO_DIR_CONN(conn)->rend_data->rend_desc_version) &&
!rend_cmp_service_ids(rendquery,
TO_DIR_CONN(conn)->rend_data->onion_address))
return conn;
@@ -2717,10 +3129,10 @@ alloc_http_authenticator(const char *authenticator)
static void
client_check_address_changed(int sock)
{
- uint32_t iface_ip, ip_out;
+ uint32_t iface_ip, ip_out; /* host order */
struct sockaddr_in out_addr;
socklen_t out_addr_len = (socklen_t) sizeof(out_addr);
- uint32_t *ip;
+ uint32_t *ip; /* host order */
if (!last_interface_ip)
get_interface_address(LOG_INFO, &last_interface_ip);
@@ -2734,7 +3146,7 @@ client_check_address_changed(int sock)
return;
}
- /* Okay. If we've used this address previously, we're okay. */
+ /* If we've used this address previously, we're okay. */
ip_out = ntohl(out_addr.sin_addr.s_addr);
SMARTLIST_FOREACH(outgoing_addrs, uint32_t*, ip_ptr,
if (*ip_ptr == ip_out) return;
@@ -3033,7 +3445,7 @@ assert_connection_ok(connection_t *conn, time_t now)
}
// tor_assert(conn->addr && conn->port);
tor_assert(conn->address);
- if (conn->state > OR_CONN_STATE_PROXY_READING)
+ if (conn->state > OR_CONN_STATE_PROXY_HANDSHAKING)
tor_assert(or_conn->tls);
}
diff --git a/src/or/connection.h b/src/or/connection.h
new file mode 100644
index 0000000000..f38927e788
--- /dev/null
+++ b/src/or/connection.h
@@ -0,0 +1,100 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file connection.h
+ * \brief Header file for connection.c.
+ **/
+
+#ifndef _TOR_CONNECTION_H
+#define _TOR_CONNECTION_H
+
+const char *conn_type_to_string(int type);
+const char *conn_state_to_string(int type, int state);
+
+dir_connection_t *dir_connection_new(int socket_family);
+or_connection_t *or_connection_new(int socket_family);
+edge_connection_t *edge_connection_new(int type, int socket_family);
+control_connection_t *control_connection_new(int socket_family);
+connection_t *connection_new(int type, int socket_family);
+
+void connection_link_connections(connection_t *conn_a, connection_t *conn_b);
+void connection_free(connection_t *conn);
+void connection_free_all(void);
+void connection_about_to_close_connection(connection_t *conn);
+void connection_close_immediate(connection_t *conn);
+void _connection_mark_for_close(connection_t *conn,int line, const char *file);
+
+#define connection_mark_for_close(c) \
+ _connection_mark_for_close((c), __LINE__, _SHORT_FILE_)
+
+void connection_expire_held_open(void);
+
+int connection_connect(connection_t *conn, const char *address,
+ const tor_addr_t *addr,
+ uint16_t port, int *socket_error);
+
+int connection_proxy_connect(connection_t *conn, int type);
+int connection_read_proxy_handshake(connection_t *conn);
+
+int retry_all_listeners(smartlist_t *replaced_conns,
+ smartlist_t *new_conns);
+
+ssize_t connection_bucket_write_limit(connection_t *conn, time_t now);
+int global_write_bucket_low(connection_t *conn, size_t attempt, int priority);
+void connection_bucket_init(void);
+void connection_bucket_refill(int seconds_elapsed, time_t now);
+
+int connection_handle_read(connection_t *conn);
+
+int connection_fetch_from_buf(char *string, size_t len, connection_t *conn);
+
+int connection_wants_to_flush(connection_t *conn);
+int connection_outbuf_too_full(connection_t *conn);
+int connection_handle_write(connection_t *conn, int force);
+void _connection_write_to_buf_impl(const char *string, size_t len,
+ connection_t *conn, int zlib);
+static void connection_write_to_buf(const char *string, size_t len,
+ connection_t *conn);
+static void connection_write_to_buf_zlib(const char *string, size_t len,
+ dir_connection_t *conn, int done);
+static INLINE void
+connection_write_to_buf(const char *string, size_t len, connection_t *conn)
+{
+ _connection_write_to_buf_impl(string, len, conn, 0);
+}
+static INLINE void
+connection_write_to_buf_zlib(const char *string, size_t len,
+ dir_connection_t *conn, int done)
+{
+ _connection_write_to_buf_impl(string, len, TO_CONN(conn), done ? -1 : 1);
+}
+
+connection_t *connection_get_by_global_id(uint64_t id);
+
+connection_t *connection_get_by_type(int type);
+connection_t *connection_get_by_type_purpose(int type, int purpose);
+connection_t *connection_get_by_type_addr_port_purpose(int type,
+ const tor_addr_t *addr,
+ uint16_t port, int purpose);
+connection_t *connection_get_by_type_state(int type, int state);
+connection_t *connection_get_by_type_state_rendquery(int type, int state,
+ const char *rendquery);
+
+#define connection_speaks_cells(conn) ((conn)->type == CONN_TYPE_OR)
+int connection_is_listener(connection_t *conn);
+int connection_state_is_open(connection_t *conn);
+int connection_state_is_connecting(connection_t *conn);
+
+char *alloc_http_authenticator(const char *authenticator);
+
+void assert_connection_ok(connection_t *conn, time_t now);
+int connection_or_nonopen_was_started_here(or_connection_t *conn);
+void connection_dump_buffer_mem_stats(int severity);
+void remove_file_if_very_old(const char *fname, time_t now);
+
+#endif
+
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 9ecdf5c7a9..2bfa88e6a9 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -10,6 +10,28 @@
**/
#include "or.h"
+#include "buffers.h"
+#include "circuitlist.h"
+#include "circuituse.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_edge.h"
+#include "connection_or.h"
+#include "control.h"
+#include "dns.h"
+#include "dnsserv.h"
+#include "dirserv.h"
+#include "hibernate.h"
+#include "main.h"
+#include "policies.h"
+#include "reasons.h"
+#include "relay.h"
+#include "rendclient.h"
+#include "rendcommon.h"
+#include "rendservice.h"
+#include "rephist.h"
+#include "router.h"
+#include "routerlist.h"
#ifdef HAVE_LINUX_TYPES_H
#include <linux/types.h>
@@ -125,7 +147,7 @@ connection_edge_process_inbuf(edge_connection_t *conn, int package_partial)
return 0;
case AP_CONN_STATE_OPEN:
case EXIT_CONN_STATE_OPEN:
- if (connection_edge_package_raw_inbuf(conn, package_partial) < 0) {
+ if (connection_edge_package_raw_inbuf(conn, package_partial, NULL) < 0) {
/* (We already sent an end cell if possible) */
connection_mark_for_close(TO_CONN(conn));
return -1;
@@ -330,11 +352,13 @@ connection_edge_finished_connecting(edge_connection_t *edge_conn)
tor_assert(conn->state == EXIT_CONN_STATE_CONNECTING);
log_info(LD_EXIT,"Exit connection to %s:%u (%s) established.",
- escaped_safe_str(conn->address),conn->port,
+ escaped_safe_str(conn->address), conn->port,
safe_str(fmt_addr(&conn->addr)));
+ rep_hist_note_exit_stream_opened(conn->port);
+
conn->state = EXIT_CONN_STATE_OPEN;
- connection_watch_events(conn, EV_READ); /* stop writing, continue reading */
+ connection_watch_events(conn, READ_EVENT); /* stop writing, keep reading */
if (connection_wants_to_flush(conn)) /* in case there are any queued relay
* cells */
connection_start_writing(conn);
@@ -375,13 +399,16 @@ connection_edge_finished_connecting(edge_connection_t *edge_conn)
static int
compute_retry_timeout(edge_connection_t *conn)
{
+ int timeout = get_options()->CircuitStreamTimeout;
+ if (timeout) /* if our config options override the default, use them */
+ return timeout;
if (conn->num_socks_retries < 2) /* try 0 and try 1 */
return 10;
return 15;
}
/** Find all general-purpose AP streams waiting for a response that sent their
- * begin/resolve cell >=15 seconds ago. Detach from their current circuit, and
+ * begin/resolve cell too long ago. Detach from their current circuit, and
* mark their current circuit as unsuitable for new streams. Then call
* connection_ap_handshake_attach_circuit() to attach to a new circuit (if
* available) or launch a new one.
@@ -423,7 +450,8 @@ connection_ap_expire_beginning(void)
log_fn(severity, LD_APP,
"Tried for %d seconds to get a connection to %s:%d. "
"Giving up. (%s)",
- seconds_since_born, safe_str(conn->socks_request->address),
+ seconds_since_born,
+ safe_str_client(conn->socks_request->address),
conn->socks_request->port,
conn_state_to_string(CONN_TYPE_AP, conn->_base.state));
connection_mark_unattached_ap(conn, END_STREAM_REASON_TIMEOUT);
@@ -440,7 +468,7 @@ connection_ap_expire_beginning(void)
circ = circuit_get_by_edge_conn(conn);
if (!circ) { /* it's vanished? */
log_info(LD_APP,"Conn is waiting (address %s), but lost its circ.",
- safe_str(conn->socks_request->address));
+ safe_str_client(conn->socks_request->address));
connection_mark_unattached_ap(conn, END_STREAM_REASON_TIMEOUT);
continue;
}
@@ -450,7 +478,7 @@ connection_ap_expire_beginning(void)
"Rend stream is %d seconds late. Giving up on address"
" '%s.onion'.",
seconds_idle,
- safe_str(conn->socks_request->address));
+ safe_str_client(conn->socks_request->address));
connection_edge_end(conn, END_STREAM_REASON_TIMEOUT);
connection_mark_unattached_ap(conn, END_STREAM_REASON_TIMEOUT);
}
@@ -460,7 +488,8 @@ connection_ap_expire_beginning(void)
log_fn(cutoff < 15 ? LOG_INFO : severity, LD_APP,
"We tried for %d seconds to connect to '%s' using exit '%s'."
" Retrying on a new circuit.",
- seconds_idle, safe_str(conn->socks_request->address),
+ seconds_idle,
+ safe_str_client(conn->socks_request->address),
conn->cpath_layer ?
conn->cpath_layer->extend_info->nickname : "*unnamed*");
/* send an end down the circuit */
@@ -571,14 +600,14 @@ circuit_discard_optional_exit_enclaves(extend_info_t *info)
!edge_conn->chosen_exit_retries)
continue;
r1 = router_get_by_nickname(edge_conn->chosen_exit_name, 0);
- r2 = router_get_by_nickname(info->nickname, 0);
+ r2 = router_get_by_digest(info->identity_digest);
if (!r1 || !r2 || r1 != r2)
continue;
tor_assert(edge_conn->socks_request);
if (edge_conn->chosen_exit_optional) {
log_info(LD_APP, "Giving up on enclave exit '%s' for destination %s.",
- safe_str(edge_conn->chosen_exit_name),
- escaped_safe_str(edge_conn->socks_request->address));
+ safe_str_client(edge_conn->chosen_exit_name),
+ escaped_safe_str_client(edge_conn->socks_request->address));
edge_conn->chosen_exit_optional = 0;
tor_free(edge_conn->chosen_exit_name); /* clears it */
/* if this port is dangerous, warn or reject it now that we don't
@@ -683,7 +712,11 @@ addressmap_init(void)
static void
addressmap_ent_free(void *_ent)
{
- addressmap_entry_t *ent = _ent;
+ addressmap_entry_t *ent;
+ if (!_ent)
+ return;
+
+ ent = _ent;
tor_free(ent->new_address);
tor_free(ent);
}
@@ -692,7 +725,11 @@ addressmap_ent_free(void *_ent)
static void
addressmap_virtaddress_ent_free(void *_ent)
{
- virtaddress_entry_t *ent = _ent;
+ virtaddress_entry_t *ent;
+ if (!_ent)
+ return;
+
+ ent = _ent;
tor_free(ent->ipv4_address);
tor_free(ent->hostname_address);
tor_free(ent);
@@ -782,14 +819,11 @@ addressmap_clean(time_t now)
void
addressmap_free_all(void)
{
- if (addressmap) {
- strmap_free(addressmap, addressmap_ent_free);
- addressmap = NULL;
- }
- if (virtaddress_reversemap) {
- strmap_free(virtaddress_reversemap, addressmap_virtaddress_ent_free);
- virtaddress_reversemap = NULL;
- }
+ strmap_free(addressmap, addressmap_ent_free);
+ addressmap = NULL;
+
+ strmap_free(virtaddress_reversemap, addressmap_virtaddress_ent_free);
+ virtaddress_reversemap = NULL;
}
/** Look at address, and rewrite it until it doesn't want any
@@ -816,9 +850,9 @@ addressmap_rewrite(char *address, size_t maxlen, time_t *expires_out)
return (rewrites > 0); /* done, no rewrite needed */
}
- cp = tor_strdup(escaped_safe_str(ent->new_address));
+ cp = tor_strdup(escaped_safe_str_client(ent->new_address));
log_info(LD_APP, "Addressmap: rewriting %s to %s",
- escaped_safe_str(address), cp);
+ escaped_safe_str_client(address), cp);
if (ent->expires > 1 && ent->expires < expires)
expires = ent->expires;
tor_free(cp);
@@ -826,7 +860,7 @@ addressmap_rewrite(char *address, size_t maxlen, time_t *expires_out)
}
log_warn(LD_CONFIG,
"Loop detected: we've rewritten %s 16 times! Using it as-is.",
- escaped_safe_str(address));
+ escaped_safe_str_client(address));
/* it's fine to rewrite a rewrite, but don't loop forever */
if (expires_out)
*expires_out = TIME_MAX;
@@ -848,9 +882,9 @@ addressmap_rewrite_reverse(char *address, size_t maxlen, time_t *expires_out)
tor_snprintf(s, len, "REVERSE[%s]", address);
ent = strmap_get(addressmap, s);
if (ent) {
- cp = tor_strdup(escaped_safe_str(ent->new_address));
+ cp = tor_strdup(escaped_safe_str_client(ent->new_address));
log_info(LD_APP, "Rewrote reverse lookup %s -> %s",
- escaped_safe_str(s), cp);
+ escaped_safe_str_client(s), cp);
tor_free(cp);
strlcpy(address, ent->new_address, maxlen);
r = 1;
@@ -912,7 +946,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(address), safe_str(new_address), safe_str(ent->new_address));
+ safe_str_client(address),
+ safe_str_client(new_address),
+ safe_str_client(ent->new_address));
tor_free(new_address);
return;
}
@@ -931,7 +967,8 @@ addressmap_register(const char *address, char *new_address, time_t expires,
ent->source = source;
log_info(LD_CONFIG, "Addressmap: (re)mapped '%s' to '%s'",
- safe_str(address), safe_str(ent->new_address));
+ safe_str_client(address),
+ safe_str_client(ent->new_address));
control_event_address_mapped(address, ent->new_address, expires, NULL);
}
@@ -951,7 +988,8 @@ client_dns_incr_failures(const char *address)
if (ent->num_resolve_failures < SHORT_MAX)
++ent->num_resolve_failures; /* don't overflow */
log_info(LD_APP, "Address %s now has %d resolve failures.",
- safe_str(address), ent->num_resolve_failures);
+ safe_str_client(address),
+ ent->num_resolve_failures);
return ent->num_resolve_failures;
}
@@ -1230,8 +1268,10 @@ addressmap_register_virtual_address(int type, char *new_address)
log_warn(LD_BUG,
"Internal confusion: I thought that '%s' was mapped to by "
"'%s', but '%s' really maps to '%s'. This is a harmless bug.",
- safe_str(new_address), safe_str(*addrp), safe_str(*addrp),
- ent?safe_str(ent->new_address):"(nothing)");
+ safe_str_client(new_address),
+ safe_str_client(*addrp),
+ safe_str_client(*addrp),
+ ent?safe_str_client(ent->new_address):"(nothing)");
}
tor_free(*addrp);
@@ -1252,7 +1292,8 @@ addressmap_register_virtual_address(int type, char *new_address)
(type == RESOLVED_TYPE_IPV4) ?
vent->ipv4_address : vent->hostname_address));
log_info(LD_APP, "Map from %s to %s okay.",
- safe_str(*addrp),safe_str(new_address));
+ safe_str_client(*addrp),
+ safe_str_client(new_address));
}
#endif
@@ -1367,6 +1408,26 @@ consider_plaintext_ports(edge_connection_t *conn, uint16_t port)
* different one? */
#define TRACKHOSTEXITS_RETRIES 5
+/** Call connection_ap_handshake_rewrite_and_attach() unless a controller
+ * asked us to leave streams unattached. Return 0 in that case.
+ *
+ * See connection_ap_handshake_rewrite_and_attach()'s
+ * documentation for arguments and return value.
+ */
+int
+connection_ap_rewrite_and_attach_if_allowed(edge_connection_t *conn,
+ origin_circuit_t *circ,
+ crypt_path_t *cpath)
+{
+ or_options_t *options = get_options();
+
+ if (options->LeaveStreamsUnattached) {
+ conn->_base.state = AP_CONN_STATE_CONTROLLER_WAIT;
+ return 0;
+ }
+ return connection_ap_handshake_rewrite_and_attach(conn, circ, cpath);
+}
+
/** Connection <b>conn</b> just finished its socks handshake, or the
* controller asked us to take care of it. If <b>circ</b> is defined,
* then that's where we'll want to attach it. Otherwise we have to
@@ -1400,7 +1461,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
tor_strlower(socks->address); /* normalize it */
strlcpy(orig_address, socks->address, sizeof(orig_address));
log_debug(LD_APP,"Client asked for %s:%d",
- safe_str(socks->address),
+ safe_str_client(socks->address),
socks->port);
if (socks->command == SOCKS_COMMAND_RESOLVE &&
@@ -1417,7 +1478,8 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
RESOLVED_TYPE_IPV4, tor_strdup(socks->address));
tor_assert(new_addr);
log_info(LD_APP, "Automapping %s to %s",
- escaped_safe_str(socks->address), safe_str(new_addr));
+ escaped_safe_str_client(socks->address),
+ safe_str_client(new_addr));
strlcpy(socks->address, new_addr, sizeof(socks->address));
}
}
@@ -1474,7 +1536,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
* information.
*/
log_warn(LD_APP,"Missing mapping for virtual address '%s'. Refusing.",
- socks->address); /* don't safe_str() this yet. */
+ safe_str_client(socks->address));
connection_mark_unattached_ap(conn, END_STREAM_REASON_INTERNAL);
return -1;
}
@@ -1482,11 +1544,12 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
/* Parse the address provided by SOCKS. Modify it in-place if it
* specifies a hidden-service (.onion) or particular exit node (.exit).
*/
- addresstype = parse_extended_hostname(socks->address);
+ addresstype = parse_extended_hostname(socks->address,
+ remapped_to_exit || options->AllowDotExit);
if (addresstype == BAD_HOSTNAME) {
log_warn(LD_APP, "Invalid onion hostname %s; rejecting",
- safe_str(socks->address));
+ safe_str_client(socks->address));
control_event_client_status(LOG_WARN, "SOCKS_BAD_HOSTNAME HOSTNAME=%s",
escaped(socks->address));
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
@@ -1495,7 +1558,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
if (addresstype == EXIT_HOSTNAME) {
/* foo.exit -- modify conn->chosen_exit_node to specify the exit
- * node, and conn->address to hold only the address portion.*/
+ * node, and conn->address to hold only the address portion. */
char *s = strrchr(socks->address,'.');
tor_assert(!automap);
if (s) {
@@ -1506,7 +1569,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
*s = 0;
} else {
log_warn(LD_APP,"Malformed exit address '%s.exit'. Refusing.",
- safe_str(socks->address));
+ safe_str_client(socks->address));
control_event_client_status(LOG_WARN, "SOCKS_BAD_HOSTNAME HOSTNAME=%s",
escaped(socks->address));
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
@@ -1522,7 +1585,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
} else {
log_warn(LD_APP,
"Unrecognized server in exit address '%s.exit'. Refusing.",
- safe_str(socks->address));
+ safe_str_client(socks->address));
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
return -1;
}
@@ -1536,7 +1599,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
escaped(socks->address));
log_warn(LD_APP,
"Destination '%s' seems to be an invalid hostname. Failing.",
- safe_str(socks->address));
+ safe_str_client(socks->address));
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
return -1;
}
@@ -1545,18 +1608,6 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
uint32_t answer;
struct in_addr in;
/* Reply to resolves immediately if we can. */
- if (strlen(socks->address) > RELAY_PAYLOAD_SIZE) {
- log_warn(LD_APP,"Address to be resolved is too large. Failing.");
- control_event_client_status(LOG_WARN, "SOCKS_BAD_HOSTNAME HOSTNAME=%s",
- escaped(socks->address));
- connection_ap_handshake_socks_resolved(conn,
- RESOLVED_TYPE_ERROR_TRANSIENT,
- 0,NULL,-1,TIME_MAX);
- connection_mark_unattached_ap(conn,
- END_STREAM_REASON_SOCKSPROTOCOL |
- END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
- return -1;
- }
if (tor_inet_aton(socks->address, &in)) { /* see if it's an IP already */
/* leave it in network order */
answer = in.s_addr;
@@ -1587,7 +1638,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
if (r) {
log_info(LD_APP,
"Redirecting address %s to exit at enclave router %s",
- safe_str(socks->address), r->nickname);
+ safe_str_client(socks->address), r->nickname);
/* use the hex digest, not nickname, in case there are two
routers with this nickname */
conn->chosen_exit_name =
@@ -1651,12 +1702,12 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
strlcpy(conn->rend_data->onion_address, socks->address,
sizeof(conn->rend_data->onion_address));
log_info(LD_REND,"Got a hidden service request for ID '%s'",
- safe_str(conn->rend_data->onion_address));
+ safe_str_client(conn->rend_data->onion_address));
/* see if we already have it cached */
r = rend_cache_lookup_entry(conn->rend_data->onion_address, -1, &entry);
if (r<0) {
log_warn(LD_BUG,"Invalid service name '%s'",
- safe_str(conn->rend_data->onion_address));
+ safe_str_client(conn->rend_data->onion_address));
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
return -1;
}
@@ -1678,32 +1729,15 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
if (r==0) {
conn->_base.state = AP_CONN_STATE_RENDDESC_WAIT;
log_info(LD_REND, "Unknown descriptor %s. Fetching.",
- safe_str(conn->rend_data->onion_address));
- /* Fetch both, v0 and v2 rend descriptors in parallel. Use whichever
- * arrives first. Exception: When using client authorization, only
- * fetch v2 descriptors.*/
+ safe_str_client(conn->rend_data->onion_address));
rend_client_refetch_v2_renddesc(conn->rend_data);
- if (conn->rend_data->auth_type == REND_NO_AUTH)
- rend_client_refetch_renddesc(conn->rend_data->onion_address);
} else { /* r > 0 */
- if (now - entry->received < NUM_SECONDS_BEFORE_HS_REFETCH) {
- conn->_base.state = AP_CONN_STATE_CIRCUIT_WAIT;
- log_info(LD_REND, "Descriptor is here and fresh enough. Great.");
- if (connection_ap_handshake_attach_circuit(conn) < 0) {
- if (!conn->_base.marked_for_close)
- connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
- return -1;
- }
- } else {
- conn->_base.state = AP_CONN_STATE_RENDDESC_WAIT;
- log_info(LD_REND, "Stale descriptor %s. Re-fetching.",
- safe_str(conn->rend_data->onion_address));
- /* Fetch both, v0 and v2 rend descriptors in parallel. Use whichever
- * arrives first. Exception: When using client authorization, only
- * fetch v2 descriptors.*/
- rend_client_refetch_v2_renddesc(conn->rend_data);
- if (conn->rend_data->auth_type == REND_NO_AUTH)
- rend_client_refetch_renddesc(conn->rend_data->onion_address);
+ conn->_base.state = AP_CONN_STATE_CIRCUIT_WAIT;
+ log_info(LD_REND, "Descriptor is here. Great.");
+ if (connection_ap_handshake_attach_circuit(conn) < 0) {
+ if (!conn->_base.marked_for_close)
+ connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
+ return -1;
}
}
return 0;
@@ -1891,24 +1925,12 @@ connection_ap_handshake_process_socks(edge_connection_t *conn)
return -1;
} /* else socks handshake is done, continue processing */
- if (hostname_is_noconnect_address(socks->address))
- {
- control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
- control_event_stream_status(conn, STREAM_EVENT_CLOSED, 0);
- connection_mark_unattached_ap(conn, END_STREAM_REASON_DONE);
- return -1;
- }
-
if (SOCKS_COMMAND_IS_CONNECT(socks->command))
control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
else
control_event_stream_status(conn, STREAM_EVENT_NEW_RESOLVE, 0);
- if (options->LeaveStreamsUnattached) {
- conn->_base.state = AP_CONN_STATE_CONTROLLER_WAIT;
- return 0;
- }
- return connection_ap_handshake_rewrite_and_attach(conn, NULL, NULL);
+ return connection_ap_rewrite_and_attach_if_allowed(conn, NULL, NULL);
}
/** connection_init_accepted_conn() found a new trans AP conn.
@@ -1922,7 +1944,6 @@ int
connection_ap_process_transparent(edge_connection_t *conn)
{
socks_request_t *socks;
- or_options_t *options = get_options();
tor_assert(conn);
tor_assert(conn->_base.type == CONN_TYPE_AP);
@@ -1946,11 +1967,7 @@ connection_ap_process_transparent(edge_connection_t *conn)
control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
- if (options->LeaveStreamsUnattached) {
- conn->_base.state = AP_CONN_STATE_CONTROLLER_WAIT;
- return 0;
- }
- return connection_ap_handshake_rewrite_and_attach(conn, NULL, NULL);
+ return connection_ap_rewrite_and_attach_if_allowed(conn, NULL, NULL);
}
/** connection_edge_process_inbuf() found a conn in state natd_wait. See if
@@ -1971,7 +1988,6 @@ connection_ap_process_natd(edge_connection_t *conn)
size_t tlen = 30;
int err, port_ok;
socks_request_t *socks;
- or_options_t *options = get_options();
tor_assert(conn);
tor_assert(conn->_base.type == CONN_TYPE_AP);
@@ -1987,13 +2003,13 @@ connection_ap_process_natd(edge_connection_t *conn)
if (err == 0)
return 0;
if (err < 0) {
- log_warn(LD_APP,"Natd handshake failed (DEST too long). Closing");
+ log_warn(LD_APP,"NATD handshake failed (DEST too long). Closing");
connection_mark_unattached_ap(conn, END_STREAM_REASON_INVALID_NATD_DEST);
return -1;
}
if (strcmpstart(tmp_buf, "[DEST ")) {
- log_warn(LD_APP,"Natd handshake was ill-formed; closing. The client "
+ log_warn(LD_APP,"NATD handshake was ill-formed; closing. The client "
"said: %s",
escaped(tmp_buf));
connection_mark_unattached_ap(conn, END_STREAM_REASON_INVALID_NATD_DEST);
@@ -2002,7 +2018,7 @@ connection_ap_process_natd(edge_connection_t *conn)
daddr = tbuf = &tmp_buf[0] + 6; /* after end of "[DEST " */
if (!(tbuf = strchr(tbuf, ' '))) {
- log_warn(LD_APP,"Natd handshake was ill-formed; closing. The client "
+ log_warn(LD_APP,"NATD handshake was ill-formed; closing. The client "
"said: %s",
escaped(tmp_buf));
connection_mark_unattached_ap(conn, END_STREAM_REASON_INVALID_NATD_DEST);
@@ -2016,7 +2032,7 @@ connection_ap_process_natd(edge_connection_t *conn)
socks->port = (uint16_t)
tor_parse_long(tbuf, 10, 1, 65535, &port_ok, &daddr);
if (!port_ok) {
- log_warn(LD_APP,"Natd handshake failed; port %s is ill-formed or out "
+ log_warn(LD_APP,"NATD handshake failed; port %s is ill-formed or out "
"of range.", escaped(tbuf));
connection_mark_unattached_ap(conn, END_STREAM_REASON_INVALID_NATD_DEST);
return -1;
@@ -2027,13 +2043,9 @@ connection_ap_process_natd(edge_connection_t *conn)
control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
- if (options->LeaveStreamsUnattached) {
- conn->_base.state = AP_CONN_STATE_CONTROLLER_WAIT;
- return 0;
- }
conn->_base.state = AP_CONN_STATE_CIRCUIT_WAIT;
- return connection_ap_handshake_rewrite_and_attach(conn, NULL, NULL);
+ return connection_ap_rewrite_and_attach_if_allowed(conn, NULL, NULL);
}
/** Iterate over the two bytes of stream_id until we get one that is not
@@ -2046,7 +2058,7 @@ get_unique_stream_id_by_circ(origin_circuit_t *circ)
streamid_t test_stream_id;
uint32_t attempts=0;
-again:
+ again:
test_stream_id = circ->next_stream_id++;
if (++attempts > 1<<16) {
/* Make sure we don't loop forever if all stream_id's are used. */
@@ -2162,7 +2174,7 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn)
r = tor_addr_parse_reverse_lookup_name(&addr, a, AF_INET, 1);
if (r <= 0) {
log_warn(LD_APP, "Rejecting ill-formed reverse lookup of %s",
- safe_str(a));
+ safe_str_client(a));
connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL);
return -1;
}
@@ -2170,7 +2182,7 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn)
r = tor_addr_to_reverse_lookup_name(inaddr_buf, sizeof(inaddr_buf), &addr);
if (r < 0) {
log_warn(LD_BUG, "Couldn't generate reverse lookup hostname of %s",
- safe_str(a));
+ safe_str_client(a));
connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL);
return -1;
}
@@ -2180,12 +2192,6 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn)
tor_assert(payload_len <= (int)sizeof(inaddr_buf));
}
- if (payload_len > RELAY_PAYLOAD_SIZE) {
- /* This should be impossible: we don't accept addresses this big. */
- connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL);
- return -1;
- }
-
log_debug(LD_APP,
"Sending relay cell to begin stream %d.", ap_conn->stream_id);
@@ -2217,7 +2223,8 @@ connection_ap_make_link(char *address, uint16_t port,
edge_connection_t *conn;
log_info(LD_APP,"Making internal %s tunnel to %s:%d ...",
- want_onehop ? "direct" : "anonymized" , safe_str(address),port);
+ want_onehop ? "direct" : "anonymized",
+ safe_str_client(address), port);
conn = edge_connection_new(CONN_TYPE_AP, AF_INET);
conn->_base.linked = 1; /* so that we can add it safely below. */
@@ -2483,6 +2490,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
char *address=NULL;
uint16_t port;
or_circuit_t *or_circ = NULL;
+ or_options_t *options = get_options();
assert_circuit_ok(circ);
if (!CIRCUIT_IS_ORIGIN(circ))
@@ -2497,7 +2505,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
* that we have a stream connected to a circuit, and we don't connect to a
* circuit until we have a pending/successful resolve. */
- if (!server_mode(get_options()) &&
+ if (!server_mode(options) &&
circ->purpose != CIRCUIT_PURPOSE_S_REND_JOINED) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Relay begin cell at non-server. Closing.");
@@ -2531,21 +2539,30 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
tor_free(address);
return 0;
}
- if (or_circ && or_circ->is_first_hop &&
- !get_options()->AllowSingleHopExits) {
+ if (or_circ && or_circ->p_conn && !options->AllowSingleHopExits &&
+ (or_circ->is_first_hop ||
+ (!connection_or_digest_is_known_relay(
+ or_circ->p_conn->identity_digest) &&
+ should_refuse_unknown_exits(options)))) {
/* Don't let clients use us as a single-hop proxy, unless the user
- * has explicitly allowed that in the config. It attracts attackers
+ * has explicitly allowed that in the config. It attracts attackers
* and users who'd be better off with, well, single-hop proxies.
*/
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
- "Attempt to open a stream on first hop of circuit. Closing.");
+ "Attempt by %s to open a stream %s. Closing.",
+ safe_str(or_circ->p_conn->_base.address),
+ or_circ->is_first_hop ? "on first hop of circuit" :
+ "from unknown relay");
relay_send_end_cell_from_edge(rh.stream_id, circ,
- END_STREAM_REASON_TORPROTOCOL, NULL);
+ or_circ->is_first_hop ?
+ END_STREAM_REASON_TORPROTOCOL :
+ END_STREAM_REASON_MISC,
+ NULL);
tor_free(address);
return 0;
}
} else if (rh.command == RELAY_COMMAND_BEGIN_DIR) {
- if (!directory_permits_begindir_requests(get_options()) ||
+ if (!directory_permits_begindir_requests(options) ||
circ->purpose != CIRCUIT_PURPOSE_OR) {
relay_send_end_cell_from_edge(rh.stream_id, circ,
END_STREAM_REASON_NOTDIRECTORY, NULL);
@@ -2571,6 +2588,11 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
log_debug(LD_EXIT,"Creating new exit connection.");
n_stream = edge_connection_new(CONN_TYPE_EXIT, AF_INET);
+
+ /* Remember the tunneled request ID in the new edge connection, so that
+ * we can measure download times. */
+ TO_CONN(n_stream)->dirreq_id = circ->dirreq_id;
+
n_stream->_base.purpose = EXIT_PURPOSE_CONNECT;
n_stream->stream_id = rh.stream_id;
@@ -2601,7 +2623,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
log_debug(LD_REND,"Finished assigning addr/port");
n_stream->cpath_layer = origin_circ->cpath->prev; /* link it */
- /* add it into the linked list of n_streams on this circuit */
+ /* add it into the linked list of p_streams on this circuit */
n_stream->next_stream = origin_circ->p_streams;
n_stream->on_circuit = circ;
origin_circ->p_streams = n_stream;
@@ -2628,7 +2650,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
if (rh.command == RELAY_COMMAND_BEGIN_DIR) {
tor_assert(or_circ);
if (or_circ->p_conn && !tor_addr_is_null(&or_circ->p_conn->real_addr))
- tor_addr_assign(&n_stream->_base.addr, &or_circ->p_conn->real_addr);
+ tor_addr_copy(&n_stream->_base.addr, &or_circ->p_conn->real_addr);
return connection_exit_connect_dir(n_stream);
}
@@ -2721,7 +2743,7 @@ connection_exit_connect(edge_connection_t *edge_conn)
if (!connection_edge_is_rendezvous_stream(edge_conn) &&
router_compare_to_my_exit_policy(edge_conn)) {
log_info(LD_EXIT,"%s:%d failed exit policy. Closing.",
- escaped_safe_str(conn->address), conn->port);
+ escaped_safe_str_client(conn->address), conn->port);
connection_edge_end(edge_conn, END_STREAM_REASON_EXITPOLICY);
circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn);
connection_free(conn);
@@ -2743,7 +2765,7 @@ connection_exit_connect(edge_connection_t *edge_conn)
case 0:
conn->state = EXIT_CONN_STATE_CONNECTING;
- connection_watch_events(conn, EV_WRITE | EV_READ);
+ connection_watch_events(conn, READ_EVENT | WRITE_EVENT);
/* writable indicates finish;
* readable/error indicates broken link in windows-land. */
return;
@@ -2756,7 +2778,7 @@ connection_exit_connect(edge_connection_t *edge_conn)
log_warn(LD_BUG,"newly connected conn had data waiting!");
// connection_start_writing(conn);
}
- connection_watch_events(conn, EV_READ);
+ connection_watch_events(conn, READ_EVENT);
/* also, deliver a 'connected' cell back through the circuit. */
if (connection_edge_is_rendezvous_stream(edge_conn)) {
@@ -2803,13 +2825,17 @@ connection_exit_connect_dir(edge_connection_t *exitconn)
dirconn = dir_connection_new(AF_INET);
- tor_addr_assign(&dirconn->_base.addr, &exitconn->_base.addr);
+ tor_addr_copy(&dirconn->_base.addr, &exitconn->_base.addr);
dirconn->_base.port = 0;
dirconn->_base.address = tor_strdup(exitconn->_base.address);
dirconn->_base.type = CONN_TYPE_DIR;
dirconn->_base.purpose = DIR_PURPOSE_SERVER;
dirconn->_base.state = DIR_CONN_STATE_SERVER_COMMAND_WAIT;
+ /* Note that the new dir conn belongs to the same tunneled request as
+ * the edge conn, so that we can measure download times. */
+ TO_CONN(dirconn)->dirreq_id = TO_CONN(exitconn)->dirreq_id;
+
connection_link_connections(TO_CONN(dirconn), TO_CONN(exitconn));
if (connection_add(TO_CONN(exitconn))<0) {
@@ -2860,10 +2886,16 @@ connection_edge_is_rendezvous_stream(edge_connection_t *conn)
* to exit from it, or 0 if it probably will not allow it.
* (We might be uncertain if conn's destination address has not yet been
* resolved.)
+ *
+ * If <b>excluded_means_no</b> is 1 and Exclude*Nodes is set and excludes
+ * this relay, return 0.
*/
int
-connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit)
+connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit,
+ int excluded_means_no)
{
+ or_options_t *options = get_options();
+
tor_assert(conn);
tor_assert(conn->_base.type == CONN_TYPE_AP);
tor_assert(conn->socks_request);
@@ -2909,20 +2941,35 @@ connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit)
if (!conn->chosen_exit_name && policy_is_reject_star(exit->exit_policy))
return 0;
}
+ if (options->_ExcludeExitNodesUnion &&
+ (options->StrictNodes || excluded_means_no) &&
+ routerset_contains_router(options->_ExcludeExitNodesUnion, exit)) {
+ /* If we are trying to avoid this node as exit, and we have StrictNodes
+ * set, then this is not a suitable exit. Refuse it.
+ *
+ * If we don't have StrictNodes set, then this function gets called in
+ * two contexts. First, we've got a circuit open and we want to know
+ * whether we can use it. In that case, we somehow built this circuit
+ * despite having the last hop in ExcludeExitNodes, so we should be
+ * willing to use it. Second, we are evaluating whether this is an
+ * acceptable exit for a new circuit. In that case, skip it. */
+ return 0;
+ }
+
return 1;
}
/** If address is of the form "y.onion" with a well-formed handle y:
* Put a NUL after y, lower-case it, and return ONION_HOSTNAME.
*
- * If address is of the form "y.exit":
+ * If address is of the form "y.exit" and <b>allowdotexit</b> is true:
* Put a NUL after y and return EXIT_HOSTNAME.
*
* Otherwise:
* Return NORMAL_HOSTNAME and change nothing.
*/
hostname_type_t
-parse_extended_hostname(char *address)
+parse_extended_hostname(char *address, int allowdotexit)
{
char *s;
char query[REND_SERVICE_ID_LEN_BASE32+1];
@@ -2931,8 +2978,16 @@ parse_extended_hostname(char *address)
if (!s)
return NORMAL_HOSTNAME; /* no dot, thus normal */
if (!strcmp(s+1,"exit")) {
- *s = 0; /* NUL-terminate it */
- return EXIT_HOSTNAME; /* .exit */
+ if (allowdotexit) {
+ *s = 0; /* NUL-terminate it */
+ return EXIT_HOSTNAME; /* .exit */
+ } else {
+ log_warn(LD_APP, "The \".exit\" notation is disabled in Tor due to "
+ "security risks. Set AllowDotExit in your torrc to enable "
+ "it.");
+ /* FFFF send a controller event too to notify Vidalia users */
+ return BAD_HOSTNAME;
+ }
}
if (strcmp(s+1,"onion"))
return NORMAL_HOSTNAME; /* neither .exit nor .onion, thus normal */
@@ -2945,17 +3000,9 @@ parse_extended_hostname(char *address)
if (rend_valid_service_id(query)) {
return ONION_HOSTNAME; /* success */
}
-failed:
+ failed:
/* otherwise, return to previous state and return 0 */
*s = '.';
return BAD_HOSTNAME;
}
-/** Check if the address is of the form "y.noconnect"
- */
-int
-hostname_is_noconnect_address(const char *address)
-{
- return ! strcasecmpend(address, ".noconnect");
-}
-
diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h
new file mode 100644
index 0000000000..cca82022c3
--- /dev/null
+++ b/src/or/connection_edge.h
@@ -0,0 +1,100 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file connection_edge.h
+ * \brief Header file for connection_edge.c.
+ **/
+
+#ifndef _TOR_CONNECTION_EDGE_H
+#define _TOR_CONNECTION_EDGE_H
+
+#define connection_mark_unattached_ap(conn, endreason) \
+ _connection_mark_unattached_ap((conn), (endreason), __LINE__, _SHORT_FILE_)
+
+void _connection_mark_unattached_ap(edge_connection_t *conn, int endreason,
+ int line, const char *file);
+int connection_edge_reached_eof(edge_connection_t *conn);
+int connection_edge_process_inbuf(edge_connection_t *conn,
+ int package_partial);
+int connection_edge_destroy(circid_t circ_id, edge_connection_t *conn);
+int connection_edge_end(edge_connection_t *conn, uint8_t reason);
+int connection_edge_end_errno(edge_connection_t *conn);
+int connection_edge_finished_flushing(edge_connection_t *conn);
+int connection_edge_finished_connecting(edge_connection_t *conn);
+
+int connection_ap_handshake_send_begin(edge_connection_t *ap_conn);
+int connection_ap_handshake_send_resolve(edge_connection_t *ap_conn);
+
+edge_connection_t *connection_ap_make_link(char *address, uint16_t port,
+ const char *digest,
+ int use_begindir, int want_onehop);
+void connection_ap_handshake_socks_reply(edge_connection_t *conn, char *reply,
+ size_t replylen,
+ int endreason);
+void connection_ap_handshake_socks_resolved(edge_connection_t *conn,
+ int answer_type,
+ size_t answer_len,
+ const uint8_t *answer,
+ int ttl,
+ time_t expires);
+
+int connection_exit_begin_conn(cell_t *cell, circuit_t *circ);
+int connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ);
+void connection_exit_connect(edge_connection_t *conn);
+int connection_edge_is_rendezvous_stream(edge_connection_t *conn);
+int connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit,
+ int excluded_means_no);
+void connection_ap_expire_beginning(void);
+void connection_ap_attach_pending(void);
+void connection_ap_fail_onehop(const char *failed_digest,
+ cpath_build_state_t *build_state);
+void circuit_discard_optional_exit_enclaves(extend_info_t *info);
+int connection_ap_detach_retriable(edge_connection_t *conn,
+ origin_circuit_t *circ,
+ int reason);
+int connection_ap_process_transparent(edge_connection_t *conn);
+
+int address_is_invalid_destination(const char *address, int client);
+
+void addressmap_init(void);
+void addressmap_clean(time_t now);
+void addressmap_clear_configured(void);
+void addressmap_clear_transient(void);
+void addressmap_free_all(void);
+int addressmap_rewrite(char *address, size_t maxlen, time_t *expires_out);
+int addressmap_have_mapping(const char *address, int update_timeout);
+
+void addressmap_register(const char *address, char *new_address,
+ time_t expires, addressmap_entry_source_t source);
+int parse_virtual_addr_network(const char *val, int validate_only,
+ char **msg);
+int client_dns_incr_failures(const char *address);
+void client_dns_clear_failures(const char *address);
+void client_dns_set_addressmap(const char *address, uint32_t val,
+ const char *exitname, int ttl);
+const char *addressmap_register_virtual_address(int type, char *new_address);
+void addressmap_get_mappings(smartlist_t *sl, time_t min_expires,
+ time_t max_expires, int want_expiry);
+int connection_ap_rewrite_and_attach_if_allowed(edge_connection_t *conn,
+ origin_circuit_t *circ,
+ crypt_path_t *cpath);
+int connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
+ origin_circuit_t *circ,
+ crypt_path_t *cpath);
+
+/** Possible return values for parse_extended_hostname. */
+typedef enum hostname_type_t {
+ NORMAL_HOSTNAME, ONION_HOSTNAME, EXIT_HOSTNAME, BAD_HOSTNAME
+} hostname_type_t;
+hostname_type_t parse_extended_hostname(char *address, int allowdotexit);
+
+#if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
+int get_pf_socket(void);
+#endif
+
+#endif
+
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index ab0d561962..45266a99b1 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -11,6 +11,22 @@
**/
#include "or.h"
+#include "buffers.h"
+#include "circuitbuild.h"
+#include "command.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_or.h"
+#include "control.h"
+#include "dirserv.h"
+#include "geoip.h"
+#include "main.h"
+#include "networkstatus.h"
+#include "reasons.h"
+#include "relay.h"
+#include "rephist.h"
+#include "router.h"
+#include "routerlist.h"
static int connection_tls_finish_handshake(or_connection_t *conn);
static int connection_or_process_cells_from_inbuf(or_connection_t *conn);
@@ -80,10 +96,8 @@ connection_or_clear_identity_map(void)
}
});
- if (orconn_identity_map) {
- digestmap_free(orconn_identity_map, NULL);
- orconn_identity_map = NULL;
- }
+ digestmap_free(orconn_identity_map, NULL);
+ orconn_identity_map = NULL;
}
/** Change conn->identity_digest to digest, and add conn into
@@ -133,7 +147,7 @@ void
cell_pack(packed_cell_t *dst, const cell_t *src)
{
char *dest = dst->body;
- *(uint16_t*)dest = htons(src->circ_id);
+ set_uint16(dest, htons(src->circ_id));
*(uint8_t*)(dest+2) = src->command;
memcpy(dest+3, src->payload, CELL_PAYLOAD_SIZE);
}
@@ -144,7 +158,7 @@ cell_pack(packed_cell_t *dst, const cell_t *src)
static void
cell_unpack(cell_t *dest, const char *src)
{
- dest->circ_id = ntohs(*(uint16_t*)(src));
+ dest->circ_id = ntohs(get_uint16(src));
dest->command = *(uint8_t*)(src+2);
memcpy(dest->payload, src+3, CELL_PAYLOAD_SIZE);
}
@@ -187,66 +201,6 @@ connection_or_reached_eof(or_connection_t *conn)
return 0;
}
-/** Read conn's inbuf. If the http response from the proxy is all
- * here, make sure it's good news, and begin the tls handshake. If
- * it's bad news, close the connection and return -1. Else return 0
- * and hope for better luck next time.
- */
-static int
-connection_or_read_proxy_response(or_connection_t *or_conn)
-{
- char *headers;
- char *reason=NULL;
- int status_code;
- time_t date_header;
- connection_t *conn = TO_CONN(or_conn);
-
- switch (fetch_from_buf_http(conn->inbuf,
- &headers, MAX_HEADERS_SIZE,
- NULL, NULL, 10000, 0)) {
- case -1: /* overflow */
- log_warn(LD_PROTOCOL,
- "Your https proxy sent back an oversized response. Closing.");
- return -1;
- case 0:
- log_info(LD_OR,"https proxy response not all here yet. Waiting.");
- return 0;
- /* case 1, fall through */
- }
-
- if (parse_http_response(headers, &status_code, &date_header,
- NULL, &reason) < 0) {
- log_warn(LD_OR,
- "Unparseable headers from proxy (connecting to '%s'). Closing.",
- conn->address);
- tor_free(headers);
- return -1;
- }
- if (!reason) reason = tor_strdup("[no reason given]");
-
- if (status_code == 200) {
- log_info(LD_OR,
- "HTTPS connect to '%s' successful! (200 %s) Starting TLS.",
- conn->address, escaped(reason));
- tor_free(reason);
- if (connection_tls_start_handshake(or_conn, 0) < 0) {
- /* TLS handshaking error of some kind. */
- connection_mark_for_close(conn);
-
- return -1;
- }
- return 0;
- }
- /* else, bad news on the status code */
- log_warn(LD_OR,
- "The https proxy sent back an unexpected status code %d (%s). "
- "Closing.",
- status_code, escaped(reason));
- tor_free(reason);
- connection_mark_for_close(conn);
- return -1;
-}
-
/** Handle any new bytes that have come in on connection <b>conn</b>.
* If conn is in 'open' state, hand it to
* connection_or_process_cells_from_inbuf()
@@ -255,11 +209,24 @@ connection_or_read_proxy_response(or_connection_t *or_conn)
int
connection_or_process_inbuf(or_connection_t *conn)
{
+ int ret;
tor_assert(conn);
switch (conn->_base.state) {
- case OR_CONN_STATE_PROXY_READING:
- return connection_or_read_proxy_response(conn);
+ case OR_CONN_STATE_PROXY_HANDSHAKING:
+ ret = connection_read_proxy_handshake(TO_CONN(conn));
+
+ /* start TLS after handshake completion, or deal with error */
+ if (ret == 1) {
+ tor_assert(TO_CONN(conn)->proxy_state == PROXY_CONNECTED);
+ if (connection_tls_start_handshake(conn, 0) < 0)
+ ret = -1;
+ }
+ if (ret < 0) {
+ connection_mark_for_close(TO_CONN(conn));
+ }
+
+ return ret;
case OR_CONN_STATE_OPEN:
case OR_CONN_STATE_OR_HANDSHAKING:
return connection_or_process_cells_from_inbuf(conn);
@@ -285,8 +252,7 @@ connection_or_flushed_some(or_connection_t *conn)
/* If we're under the low water mark, add cells until we're just over the
* high water mark. */
if (datalen < OR_CONN_LOWWATER) {
- ssize_t n = (OR_CONN_HIGHWATER - datalen + CELL_NETWORK_SIZE-1)
- / CELL_NETWORK_SIZE;
+ ssize_t n = CEIL_DIV(OR_CONN_HIGHWATER - datalen, CELL_NETWORK_SIZE);
time_t now = approx_time();
while (conn->active_circuits && n > 0) {
int flushed;
@@ -312,11 +278,7 @@ connection_or_finished_flushing(or_connection_t *conn)
assert_connection_ok(TO_CONN(conn),0);
switch (conn->_base.state) {
- case OR_CONN_STATE_PROXY_FLUSHING:
- log_debug(LD_OR,"finished sending CONNECT to proxy.");
- conn->_base.state = OR_CONN_STATE_PROXY_READING;
- connection_stop_writing(TO_CONN(conn));
- break;
+ case OR_CONN_STATE_PROXY_HANDSHAKING:
case OR_CONN_STATE_OPEN:
case OR_CONN_STATE_OR_HANDSHAKING:
connection_stop_writing(TO_CONN(conn));
@@ -334,37 +296,34 @@ connection_or_finished_flushing(or_connection_t *conn)
int
connection_or_finished_connecting(or_connection_t *or_conn)
{
+ int proxy_type;
connection_t *conn;
tor_assert(or_conn);
conn = TO_CONN(or_conn);
tor_assert(conn->state == OR_CONN_STATE_CONNECTING);
- log_debug(LD_OR,"OR connect() to router at %s:%u finished.",
+ log_debug(LD_HANDSHAKE,"OR connect() to router at %s:%u finished.",
conn->address,conn->port);
control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE, 0);
- if (get_options()->HttpsProxy) {
- char buf[1024];
- char *base64_authenticator=NULL;
- const char *authenticator = get_options()->HttpsProxyAuthenticator;
+ proxy_type = PROXY_NONE;
- if (authenticator) {
- base64_authenticator = alloc_http_authenticator(authenticator);
- if (!base64_authenticator)
- log_warn(LD_OR, "Encoding https authenticator failed");
- }
- if (base64_authenticator) {
- tor_snprintf(buf, sizeof(buf), "CONNECT %s:%d HTTP/1.1\r\n"
- "Proxy-Authorization: Basic %s\r\n\r\n",
- fmt_addr(&conn->addr),
- conn->port, base64_authenticator);
- tor_free(base64_authenticator);
- } else {
- tor_snprintf(buf, sizeof(buf), "CONNECT %s:%d HTTP/1.0\r\n\r\n",
- fmt_addr(&conn->addr), conn->port);
+ if (get_options()->HTTPSProxy)
+ proxy_type = PROXY_CONNECT;
+ else if (get_options()->Socks4Proxy)
+ proxy_type = PROXY_SOCKS4;
+ else if (get_options()->Socks5Proxy)
+ proxy_type = PROXY_SOCKS5;
+
+ if (proxy_type != PROXY_NONE) {
+ /* start proxy handshake */
+ if (connection_proxy_connect(conn, proxy_type) < 0) {
+ connection_mark_for_close(conn);
+ return -1;
}
- connection_write_to_buf(buf, strlen(buf), conn);
- conn->state = OR_CONN_STATE_PROXY_FLUSHING;
+
+ connection_start_reading(conn);
+ conn->state = OR_CONN_STATE_PROXY_HANDSHAKING;
return 0;
}
@@ -376,6 +335,74 @@ connection_or_finished_connecting(or_connection_t *or_conn)
return 0;
}
+/** Return 1 if identity digest <b>id_digest</b> is known to be a
+ * currently or recently running relay. Otherwise return 0. */
+int
+connection_or_digest_is_known_relay(const char *id_digest)
+{
+ if (router_get_consensus_status_by_id(id_digest))
+ return 1; /* It's in the consensus: "yes" */
+ if (router_get_by_digest(id_digest))
+ return 1; /* Not in the consensus, but we have a descriptor for
+ * it. Probably it was in a recent consensus. "Yes". */
+ return 0;
+}
+
+/** Set the per-conn read and write limits for <b>conn</b>. If it's a known
+ * relay, we will rely on the global read and write buckets, so give it
+ * per-conn limits that are big enough they'll never matter. But if it's
+ * not a known relay, first check if we set PerConnBwRate/Burst, then
+ * check if the consensus sets them, else default to 'big enough'.
+ */
+static void
+connection_or_update_token_buckets_helper(or_connection_t *conn, int reset,
+ or_options_t *options)
+{
+ int rate, burst; /* per-connection rate limiting params */
+ if (connection_or_digest_is_known_relay(conn->identity_digest)) {
+ /* It's in the consensus, or we have a descriptor for it meaning it
+ * was probably in a recent consensus. It's a recognized relay:
+ * give it full bandwidth. */
+ rate = (int)options->BandwidthRate;
+ burst = (int)options->BandwidthBurst;
+ } else {
+ /* Not a recognized relay. Squeeze it down based on the suggested
+ * bandwidth parameters in the consensus, but allow local config
+ * options to override. */
+ rate = options->PerConnBWRate ? (int)options->PerConnBWRate :
+ (int)networkstatus_get_param(NULL, "perconnbwrate",
+ (int)options->BandwidthRate);
+ burst = options->PerConnBWBurst ? (int)options->PerConnBWBurst :
+ (int)networkstatus_get_param(NULL, "perconnbwburst",
+ (int)options->BandwidthBurst);
+ }
+
+ conn->bandwidthrate = rate;
+ conn->bandwidthburst = burst;
+ if (reset) { /* set up the token buckets to be full */
+ conn->read_bucket = conn->write_bucket = burst;
+ return;
+ }
+ /* If the new token bucket is smaller, take out the extra tokens.
+ * (If it's larger, don't -- the buckets can grow to reach the cap.) */
+ if (conn->read_bucket > burst)
+ conn->read_bucket = burst;
+ if (conn->write_bucket > burst)
+ conn->write_bucket = burst;
+}
+
+/** Either our set of relays or our per-conn rate limits have changed.
+ * Go through all the OR connections and update their token buckets. */
+void
+connection_or_update_token_buckets(smartlist_t *conns, or_options_t *options)
+{
+ SMARTLIST_FOREACH(conns, connection_t *, conn,
+ {
+ if (connection_speaks_cells(conn))
+ connection_or_update_token_buckets_helper(TO_OR_CONN(conn), 0, options);
+ });
+}
+
/** If we don't necessarily know the router we're connecting to, but we
* have an addr/port/id_digest, then fill in as much as we can. Start
* by checking to see if this describes a router we know. */
@@ -385,11 +412,9 @@ connection_or_init_conn_from_address(or_connection_t *conn,
const char *id_digest,
int started_here)
{
- or_options_t *options = get_options();
routerinfo_t *r = router_get_by_digest(id_digest);
- conn->bandwidthrate = (int)options->BandwidthRate;
- conn->read_bucket = conn->bandwidthburst = (int)options->BandwidthBurst;
connection_or_set_identity_digest(conn, id_digest);
+ connection_or_update_token_buckets_helper(conn, 1, get_options());
conn->_base.port = port;
tor_addr_copy(&conn->_base.addr, addr);
@@ -581,11 +606,24 @@ connection_or_get_for_extend(const char *digest,
#define TIME_BEFORE_OR_CONN_IS_TOO_OLD (60*60*24*7)
/** Given the head of the linked list for all the or_connections with a given
- * identity, set elements of that list as is_bad_for_new_circs() as
- * appropriate. Helper for connection_or_set_bad_connections().
+ * identity, set elements of that list as is_bad_for_new_circs as
+ * appropriate. Helper for connection_or_set_bad_connections().
+ *
+ * Specifically, we set the is_bad_for_new_circs flag on:
+ * - all connections if <b>force</b> is true.
+ * - all connections that are too old.
+ * - all open non-canonical connections for which a canonical connection
+ * exists to the same router.
+ * - all open canonical connections for which a 'better' canonical
+ * connection exists to the same router.
+ * - all open non-canonical connections for which a 'better' non-canonical
+ * connection exists to the same router at the same address.
+ *
+ * See connection_or_is_better() for our idea of what makes one OR connection
+ * better than another.
*/
static void
-connection_or_group_set_badness(or_connection_t *head)
+connection_or_group_set_badness(or_connection_t *head, int force)
{
or_connection_t *or_conn = NULL, *best = NULL;
int n_old = 0, n_inprogress = 0, n_canonical = 0, n_other = 0;
@@ -597,8 +635,9 @@ connection_or_group_set_badness(or_connection_t *head)
if (or_conn->_base.marked_for_close ||
or_conn->is_bad_for_new_circs)
continue;
- if (or_conn->_base.timestamp_created + TIME_BEFORE_OR_CONN_IS_TOO_OLD
- < now) {
+ if (force ||
+ or_conn->_base.timestamp_created + TIME_BEFORE_OR_CONN_IS_TOO_OLD
+ < now) {
log_info(LD_OR,
"Marking OR conn to %s:%d as too old for new circuits "
"(fd %d, %d secs old).",
@@ -631,7 +670,7 @@ connection_or_group_set_badness(or_connection_t *head)
/* We have at least one open canonical connection to this router,
* and this one is open but not canonical. Mark it bad. */
log_info(LD_OR,
- "Marking OR conn to %s:%d as too old for new circuits: "
+ "Marking OR conn to %s:%d as unsuitable for new circuits: "
"(fd %d, %d secs old). It is not canonical, and we have "
"another connection to that OR that is.",
or_conn->_base.address, or_conn->_base.port, or_conn->_base.s,
@@ -671,7 +710,7 @@ connection_or_group_set_badness(or_connection_t *head)
even when we're being forgiving. */
if (best->is_canonical) {
log_info(LD_OR,
- "Marking OR conn to %s:%d as too old for new circuits: "
+ "Marking OR conn to %s:%d as unsuitable for new circuits: "
"(fd %d, %d secs old). We have a better canonical one "
"(fd %d; %d secs old).",
or_conn->_base.address, or_conn->_base.port, or_conn->_base.s,
@@ -681,9 +720,9 @@ connection_or_group_set_badness(or_connection_t *head)
} else if (!tor_addr_compare(&or_conn->real_addr,
&best->real_addr, CMP_EXACT)) {
log_info(LD_OR,
- "Marking OR conn to %s:%d as too old for new circuits: "
- "(fd %d, %d secs old). We have a better one "
- "(fd %d; %d secs old).",
+ "Marking OR conn to %s:%d as unsuitable for new circuits: "
+ "(fd %d, %d secs old). We have a better one with the "
+ "same address (fd %d; %d secs old).",
or_conn->_base.address, or_conn->_base.port, or_conn->_base.s,
(int)(now - or_conn->_base.timestamp_created),
best->_base.s, (int)(now - best->_base.timestamp_created));
@@ -693,27 +732,20 @@ connection_or_group_set_badness(or_connection_t *head)
}
}
-/** Go through all the OR connections, and set the is_bad_for_new_circs
- * flag on:
- * - all connections that are too old.
- * - all open non-canonical connections for which a canonical connection
- * exists to the same router.
- * - all open canonical connections for which a 'better' canonical
- * connection exists to the same router.
- * - all open non-canonical connections for which a 'better' non-canonical
- * connection exists to the same router at the same address.
- *
- * See connection_or_is_better() for our idea of what makes one OR connection
- * better than another.
+/** Go through all the OR connections (or if <b>digest</b> is non-NULL, just
+ * the OR connections with that digest), and set the is_bad_for_new_circs
+ * flag based on the rules in connection_or_group_set_badness() (or just
+ * always set it if <b>force</b> is true).
*/
void
-connection_or_set_bad_connections(void)
+connection_or_set_bad_connections(const char *digest, int force)
{
if (!orconn_identity_map)
return;
DIGESTMAP_FOREACH(orconn_identity_map, identity, or_connection_t *, conn) {
- connection_or_group_set_badness(conn);
+ if (!digest || !memcmp(digest, conn->identity_digest, DIGEST_LEN))
+ connection_or_group_set_badness(conn, force);
} DIGESTMAP_FOREACH_END;
}
@@ -753,6 +785,7 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port,
or_connection_t *conn;
or_options_t *options = get_options();
int socket_error = 0;
+ int using_proxy = 0;
tor_addr_t addr;
tor_assert(_addr);
@@ -771,19 +804,27 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port,
conn->_base.state = OR_CONN_STATE_CONNECTING;
control_event_or_conn_status(conn, OR_CONN_EVENT_LAUNCHED, 0);
- if (options->HttpsProxy) {
- /* we shouldn't connect directly. use the https proxy instead. */
- tor_addr_from_ipv4h(&addr, options->HttpsProxyAddr);
- port = options->HttpsProxyPort;
+ /* use a proxy server if available */
+ if (options->HTTPSProxy) {
+ using_proxy = 1;
+ tor_addr_copy(&addr, &options->HTTPSProxyAddr);
+ port = options->HTTPSProxyPort;
+ } else if (options->Socks4Proxy) {
+ using_proxy = 1;
+ tor_addr_copy(&addr, &options->Socks4ProxyAddr);
+ port = options->Socks4ProxyPort;
+ } else if (options->Socks5Proxy) {
+ using_proxy = 1;
+ tor_addr_copy(&addr, &options->Socks5ProxyAddr);
+ port = options->Socks5ProxyPort;
}
switch (connection_connect(TO_CONN(conn), conn->_base.address,
&addr, port, &socket_error)) {
case -1:
/* If the connection failed immediately, and we're using
- * an https proxy, our https proxy is down. Don't blame the
- * Tor server. */
- if (!options->HttpsProxy)
+ * a proxy, our proxy is down. Don't blame the Tor server. */
+ if (!using_proxy)
entry_guard_register_connect_status(conn->identity_digest,
0, 1, time(NULL));
connection_or_connect_failed(conn,
@@ -792,7 +833,7 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port,
connection_free(TO_CONN(conn));
return NULL;
case 0:
- connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
+ connection_watch_events(TO_CONN(conn), READ_EVENT | WRITE_EVENT);
/* writable indicates finish, readable indicates broken link,
error indicates broken link on windows */
return conn;
@@ -819,13 +860,14 @@ connection_tls_start_handshake(or_connection_t *conn, int receiving)
{
conn->_base.state = OR_CONN_STATE_TLS_HANDSHAKING;
conn->tls = tor_tls_new(conn->_base.s, receiving);
- tor_tls_set_logged_address(conn->tls, escaped_safe_str(conn->_base.address));
+ tor_tls_set_logged_address(conn->tls, // XXX client and relay?
+ escaped_safe_str(conn->_base.address));
if (!conn->tls) {
log_warn(LD_BUG,"tor_tls_new failed. Closing.");
return -1;
}
connection_start_reading(TO_CONN(conn));
- log_debug(LD_OR,"starting TLS handshake on fd %d", conn->_base.s);
+ log_debug(LD_HANDSHAKE,"starting TLS handshake on fd %d", conn->_base.s);
note_crypto_pk_op(receiving ? TLS_HANDSHAKE_S : TLS_HANDSHAKE_C);
if (connection_tls_continue_handshake(conn) < 0) {
@@ -932,23 +974,26 @@ connection_or_nonopen_was_started_here(or_connection_t *conn)
* return -1 if he is lying, broken, or otherwise something is wrong.
*
* If we initiated this connection (<b>started_here</b> is true), make sure
- * the other side sent sent a correctly formed certificate. If I initiated the
+ * the other side sent a correctly formed certificate. If I initiated the
* connection, make sure it's the right guy.
*
* Otherwise (if we _didn't_ initiate this connection), it's okay for
* the certificate to be weird or absent.
*
* If we return 0, and the certificate is as expected, write a hash of the
- * identity key into digest_rcvd, which must have DIGEST_LEN space in it. (If
- * we return -1 this buffer is undefined.) If the certificate is invalid
- * or missing on an incoming connection, we return 0 and set digest_rcvd to
- * DIGEST_LEN 0 bytes.
+ * identity key into <b>digest_rcvd_out</b>, which must have DIGEST_LEN
+ * space in it.
+ * If the certificate is invalid or missing on an incoming connection,
+ * we return 0 and set <b>digest_rcvd_out</b> to DIGEST_LEN NUL bytes.
+ * (If we return -1, the contents of this buffer are undefined.)
*
* As side effects,
* 1) Set conn->circ_id_type according to tor-spec.txt.
* 2) If we're an authdirserver and we initiated the connection: drop all
* descriptors that claim to be on that IP/port but that aren't
* this guy; and note that this guy is reachable.
+ * 3) If this is a bridge and we didn't configure its identity
+ * fingerprint, remember the keyid we just learned.
*/
static int
connection_or_check_valid_tls_handshake(or_connection_t *conn,
@@ -959,19 +1004,23 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
or_options_t *options = get_options();
int severity = server_mode(options) ? LOG_PROTOCOL_WARN : LOG_WARN;
const char *safe_address =
- started_here ? conn->_base.address : safe_str(conn->_base.address);
+ started_here ? conn->_base.address :
+ safe_str_client(conn->_base.address);
const char *conn_type = started_here ? "outgoing" : "incoming";
+ crypto_pk_env_t *our_identity =
+ started_here ? get_tlsclient_identity_key() :
+ get_server_identity_key();
int has_cert = 0, has_identity=0;
check_no_tls_errors();
has_cert = tor_tls_peer_has_cert(conn->tls);
if (started_here && !has_cert) {
- log_info(LD_PROTOCOL,"Tried connecting to router at %s:%d, but it didn't "
+ log_info(LD_HANDSHAKE,"Tried connecting to router at %s:%d, but it didn't "
"send a cert! Closing.",
safe_address, conn->_base.port);
return -1;
} else if (!has_cert) {
- log_debug(LD_PROTOCOL,"Got incoming connection with no certificate. "
+ log_debug(LD_HANDSHAKE,"Got incoming connection with no certificate. "
"That's ok.");
}
check_no_tls_errors();
@@ -980,15 +1029,16 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
int v = tor_tls_verify(started_here?severity:LOG_INFO,
conn->tls, &identity_rcvd);
if (started_here && v<0) {
- log_fn(severity,LD_OR,"Tried connecting to router at %s:%d: It"
+ log_fn(severity,LD_HANDSHAKE,"Tried connecting to router at %s:%d: It"
" has a cert but it's invalid. Closing.",
safe_address, conn->_base.port);
return -1;
} else if (v<0) {
- log_info(LD_PROTOCOL,"Incoming connection gave us an invalid cert "
+ log_info(LD_HANDSHAKE,"Incoming connection gave us an invalid cert "
"chain; ignoring.");
} else {
- log_debug(LD_OR,"The certificate seems to be valid on %s connection "
+ log_debug(LD_HANDSHAKE,
+ "The certificate seems to be valid on %s connection "
"with %s:%d", conn_type, safe_address, conn->_base.port);
}
check_no_tls_errors();
@@ -997,7 +1047,7 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
if (identity_rcvd) {
has_identity = 1;
crypto_pk_get_digest(identity_rcvd, digest_rcvd_out);
- if (crypto_pk_cmp_keys(get_identity_key(), identity_rcvd)<0) {
+ if (crypto_pk_cmp_keys(our_identity, identity_rcvd)<0) {
conn->circ_id_type = CIRC_ID_TYPE_LOWER;
} else {
conn->circ_id_type = CIRC_ID_TYPE_HIGHER;
@@ -1015,9 +1065,13 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
conn->nickname[0] = '$';
base16_encode(conn->nickname+1, HEX_DIGEST_LEN+1,
conn->identity_digest, DIGEST_LEN);
- log_info(LD_OR, "Connected to router %s at %s:%d without knowing "
+ log_info(LD_HANDSHAKE, "Connected to router %s at %s:%d without knowing "
"its key. Hoping for the best.",
conn->nickname, conn->_base.address, conn->_base.port);
+ /* if it's a bridge and we didn't know its identity fingerprint, now
+ * we do -- remember it for future attempts. */
+ learned_router_identity(&conn->_base.addr, conn->_base.port,
+ digest_rcvd_out);
}
if (started_here) {
@@ -1031,7 +1085,7 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
base16_encode(seen, sizeof(seen), digest_rcvd_out, DIGEST_LEN);
base16_encode(expected, sizeof(expected), conn->identity_digest,
DIGEST_LEN);
- log_fn(severity, LD_OR,
+ log_fn(severity, LD_HANDSHAKE,
"Tried connecting to router at %s:%d, but identity key was not "
"as expected: wanted %s but got %s.",
conn->_base.address, conn->_base.port, expected, seen);
@@ -1073,8 +1127,8 @@ connection_tls_finish_handshake(or_connection_t *conn)
char digest_rcvd[DIGEST_LEN];
int started_here = connection_or_nonopen_was_started_here(conn);
- log_debug(LD_OR,"tls handshake with %s done. verifying.",
- safe_str(conn->_base.address));
+ log_debug(LD_HANDSHAKE,"tls handshake with %s done. verifying.",
+ safe_str_client(conn->_base.address));
directory_set_dirty();
@@ -1082,6 +1136,8 @@ connection_tls_finish_handshake(or_connection_t *conn)
digest_rcvd) < 0)
return -1;
+ circuit_build_times_network_is_live(&circ_times);
+
if (tor_tls_used_v1_handshake(conn->tls)) {
conn->link_proto = 1;
if (!started_here) {
@@ -1117,7 +1173,8 @@ connection_init_or_handshake_state(or_connection_t *conn, int started_here)
void
or_handshake_state_free(or_handshake_state_t *state)
{
- tor_assert(state);
+ if (!state)
+ return;
memset(state, 0xBE, sizeof(or_handshake_state_t));
tor_free(state);
}
@@ -1134,6 +1191,7 @@ connection_or_set_state_open(or_connection_t *conn)
control_event_or_conn_status(conn, OR_CONN_EVENT_CONNECTED, 0);
if (started_here) {
+ circuit_build_times_network_is_live(&circ_times);
rep_hist_note_connect_succeeded(conn->identity_digest, now);
if (entry_guard_register_connect_status(conn->identity_digest,
1, 0, now) < 0) {
@@ -1158,10 +1216,10 @@ connection_or_set_state_open(or_connection_t *conn)
}
}
}
- if (conn->handshake_state) {
- or_handshake_state_free(conn->handshake_state);
- conn->handshake_state = NULL;
- }
+
+ or_handshake_state_free(conn->handshake_state);
+ conn->handshake_state = NULL;
+
connection_start_reading(TO_CONN(conn));
circuit_n_conn_done(conn, 1); /* send the pending creates, if any. */
@@ -1235,6 +1293,7 @@ connection_or_process_cells_from_inbuf(or_connection_t *conn)
if (connection_fetch_var_cell_from_buf(conn, &var_cell)) {
if (!var_cell)
return 0; /* not yet. */
+ circuit_build_times_network_is_live(&circ_times);
command_process_var_cell(var_cell, conn);
var_cell_free(var_cell);
} else {
@@ -1244,6 +1303,7 @@ connection_or_process_cells_from_inbuf(or_connection_t *conn)
available? */
return 0; /* not yet */
+ circuit_build_times_network_is_live(&circ_times);
connection_fetch_from_buf(buf, CELL_NETWORK_SIZE, TO_CONN(conn));
/* retrieve cell info from buf (create the host-order struct from the
@@ -1274,10 +1334,6 @@ connection_or_send_destroy(circid_t circ_id, or_connection_t *conn, int reason)
cell.payload[0] = (uint8_t) reason;
log_debug(LD_OR,"Sending destroy (circID %d).", circ_id);
- /* XXXX It's possible that under some circumstances, we want the destroy
- * to take precedence over other data waiting on the circuit's cell queue.
- */
-
connection_or_write_cell_to_buf(&cell, conn);
return 0;
}
diff --git a/src/or/connection_or.h b/src/or/connection_or.h
new file mode 100644
index 0000000000..216a9bd648
--- /dev/null
+++ b/src/or/connection_or.h
@@ -0,0 +1,57 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file connection_or.h
+ * \brief Header file for connection_or.c.
+ **/
+
+#ifndef _TOR_CONNECTION_OR_H
+#define _TOR_CONNECTION_OR_H
+
+void connection_or_remove_from_identity_map(or_connection_t *conn);
+void connection_or_clear_identity_map(void);
+or_connection_t *connection_or_get_for_extend(const char *digest,
+ const tor_addr_t *target_addr,
+ const char **msg_out,
+ int *launch_out);
+void connection_or_set_bad_connections(const char *digest, int force);
+
+int connection_or_reached_eof(or_connection_t *conn);
+int connection_or_process_inbuf(or_connection_t *conn);
+int connection_or_flushed_some(or_connection_t *conn);
+int connection_or_finished_flushing(or_connection_t *conn);
+int connection_or_finished_connecting(or_connection_t *conn);
+int connection_or_digest_is_known_relay(const char *id_digest);
+void connection_or_update_token_buckets(smartlist_t *conns,
+ or_options_t *options);
+
+void connection_or_connect_failed(or_connection_t *conn,
+ int reason, const char *msg);
+or_connection_t *connection_or_connect(const tor_addr_t *addr, uint16_t port,
+ const char *id_digest);
+
+int connection_tls_start_handshake(or_connection_t *conn, int receiving);
+int connection_tls_continue_handshake(or_connection_t *conn);
+
+void or_handshake_state_free(or_handshake_state_t *state);
+int connection_or_set_state_open(or_connection_t *conn);
+void connection_or_write_cell_to_buf(const cell_t *cell,
+ or_connection_t *conn);
+void connection_or_write_var_cell_to_buf(const var_cell_t *cell,
+ or_connection_t *conn);
+int connection_or_send_destroy(circid_t circ_id, or_connection_t *conn,
+ int reason);
+int connection_or_send_netinfo(or_connection_t *conn);
+int is_or_protocol_version_known(uint16_t version);
+
+void cell_pack(packed_cell_t *dest, const cell_t *src);
+void var_cell_pack_header(const var_cell_t *cell, char *hdr_out);
+var_cell_t *var_cell_new(uint16_t payload_len);
+void var_cell_free(var_cell_t *cell);
+
+#endif
+
diff --git a/src/or/control.c b/src/or/control.c
index 7eb2e042f2..ad316c4ebc 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -11,6 +11,26 @@
#define CONTROL_PRIVATE
#include "or.h"
+#include "buffers.h"
+#include "circuitbuild.h"
+#include "circuitlist.h"
+#include "circuituse.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_edge.h"
+#include "control.h"
+#include "directory.h"
+#include "dirserv.h"
+#include "dnsserv.h"
+#include "geoip.h"
+#include "hibernate.h"
+#include "main.h"
+#include "networkstatus.h"
+#include "policies.h"
+#include "reasons.h"
+#include "router.h"
+#include "routerlist.h"
+#include "routerparse.h"
/** Yield true iff <b>s</b> is the state of a control_connection_t that has
* finished authentication and is accepting commands. */
@@ -43,7 +63,8 @@
#define EVENT_STREAM_BANDWIDTH_USED 0x0014
#define EVENT_CLIENTS_SEEN 0x0015
#define EVENT_NEWCONSENSUS 0x0016
-#define _EVENT_MAX 0x0016
+#define EVENT_BUILDTIMEOUT_SET 0x0017
+#define _EVENT_MAX 0x0017
/* If _EVENT_MAX ever hits 0x0020, we need to make the mask wider. */
/** Bitfield: The bit 1&lt;&lt;e is set if <b>any</b> open control
@@ -54,13 +75,9 @@
**/
typedef uint32_t event_mask_t;
-/** An event mask of all the events that controller with the LONG_NAMES option
- * set is interested in receiving. */
-static event_mask_t global_event_mask1long = 0;
-
-/** An event mask of all the events that controller with the SHORT_NAMES option
- * set is interested in receiving. */
-static event_mask_t global_event_mask1short = 0;
+/** An event mask of all the events that any controller is interested in
+ * receiving. */
+static event_mask_t global_event_mask = 0;
/** True iff we have disabled log messages from being sent to the controller */
static int disable_log_messages = 0;
@@ -68,13 +85,7 @@ static int disable_log_messages = 0;
/** Macro: true if any control connection is interested in events of type
* <b>e</b>. */
#define EVENT_IS_INTERESTING(e) \
- ((global_event_mask1long|global_event_mask1short) & (1<<(e)))
-/** Macro: true if any control connection with the LONG_NAMES option is
- * interested in events of type <b>e</b>. */
-#define EVENT_IS_INTERESTING1L(e) (global_event_mask1long & (1<<(e)))
-/** Macro: true if any control connection with the SHORT_NAMES option is
- * interested in events of type <b>e</b>. */
-#define EVENT_IS_INTERESTING1S(e) (global_event_mask1short & (1<<(e)))
+ (global_event_mask & (1<<(e)))
/** If we're using cookie-type authentication, how long should our cookies be?
*/
@@ -95,25 +106,13 @@ static char authentication_cookie[AUTHENTICATION_COOKIE_LEN];
* of this so we can respond to getinfo status/bootstrap-phase queries. */
static char last_sent_bootstrap_message[BOOTSTRAP_MSG_LEN];
-/** Flag for event_format_t. Indicates that we should use the old
- * name format of nickname|hexdigest
- */
-#define SHORT_NAMES 1
-/** Flag for event_format_t. Indicates that we should use the new
- * name format of $hexdigest[=~]nickname
+/** Flag for event_format_t. Indicates that we should use the one standard
+ format.
*/
-#define LONG_NAMES 2
-#define ALL_NAMES (SHORT_NAMES|LONG_NAMES)
-/** Flag for event_format_t. Indicates that we should use the new event
- * format where extra event fields are allowed using a NAME=VAL format. */
-#define EXTENDED_FORMAT 4
-/** Flag for event_format_t. Indicates that we are using the old event format
- * where extra fields aren't allowed. */
-#define NONEXTENDED_FORMAT 8
-#define ALL_FORMATS (EXTENDED_FORMAT|NONEXTENDED_FORMAT)
+#define ALL_FORMATS 1
/** Bit field of flags to select how to format a controller event. Recognized
- * flags are SHORT_NAMES, LONG_NAMES, EXTENDED_FORMAT, NONEXTENDED_FORMAT. */
+ * flag is ALL_FORMATS. */
typedef int event_format_t;
static void connection_printf_to_buf(control_connection_t *conn,
@@ -123,9 +122,6 @@ static void send_control_done(control_connection_t *conn);
static void send_control_event(uint16_t event, event_format_t which,
const char *format, ...)
CHECK_PRINTF(3,4);
-static void send_control_event_extended(uint16_t event, event_format_t which,
- const char *format, ...)
- CHECK_PRINTF(3,4);
static int handle_control_setconf(control_connection_t *conn, uint32_t len,
char *body);
static int handle_control_resetconf(control_connection_t *conn, uint32_t len,
@@ -139,8 +135,6 @@ static int handle_control_setevents(control_connection_t *conn, uint32_t len,
static int handle_control_authenticate(control_connection_t *conn,
uint32_t len,
const char *body);
-static int handle_control_saveconf(control_connection_t *conn, uint32_t len,
- const char *body);
static int handle_control_signal(control_connection_t *conn, uint32_t len,
const char *body);
static int handle_control_mapaddress(control_connection_t *conn, uint32_t len,
@@ -174,7 +168,7 @@ static int handle_control_usefeature(control_connection_t *conn,
const char *body);
static int write_stream_target_to_buf(edge_connection_t *conn, char *buf,
size_t len);
-static void orconn_target_get_name(int long_names, char *buf, size_t len,
+static void orconn_target_get_name(char *buf, size_t len,
or_connection_t *conn);
static char *get_cookie_file(void);
@@ -214,25 +208,19 @@ control_update_global_event_mask(void)
{
smartlist_t *conns = get_connection_array();
event_mask_t old_mask, new_mask;
- old_mask = global_event_mask1short;
- old_mask |= global_event_mask1long;
+ old_mask = global_event_mask;
- global_event_mask1short = 0;
- global_event_mask1long = 0;
+ global_event_mask = 0;
SMARTLIST_FOREACH(conns, connection_t *, _conn,
{
if (_conn->type == CONN_TYPE_CONTROL &&
STATE_IS_OPEN(_conn->state)) {
control_connection_t *conn = TO_CONTROL_CONN(_conn);
- if (conn->use_long_names)
- global_event_mask1long |= conn->event_mask;
- else
- global_event_mask1short |= conn->event_mask;
+ global_event_mask |= conn->event_mask;
}
});
- new_mask = global_event_mask1short;
- new_mask |= global_event_mask1long;
+ new_mask = global_event_mask;
/* Handle the aftermath. Set up the log callback to tell us only what
* we want to hear...*/
@@ -312,7 +300,7 @@ connection_write_str_to_buf(const char *s, control_connection_t *conn)
/** Given a <b>len</b>-character string in <b>data</b>, made of lines
* terminated by CRLF, allocate a new string in *<b>out</b>, and copy the
* contents of <b>data</b> into *<b>out</b>, adding a period before any period
- * that that appears at the start of a line, and adding a period-CRLF line at
+ * that appears at the start of a line, and adding a period-CRLF line at
* the end. Replace all LF characters sequences with CRLF. Return the number
* of bytes in *<b>out</b>.
*/
@@ -542,28 +530,15 @@ send_control_event_string(uint16_t event, event_format_t which,
const char *msg)
{
smartlist_t *conns = get_connection_array();
+ (void)which;
tor_assert(event >= _EVENT_MIN && event <= _EVENT_MAX);
- SMARTLIST_FOREACH(conns, connection_t *, conn,
- {
+ SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
if (conn->type == CONN_TYPE_CONTROL &&
!conn->marked_for_close &&
conn->state == CONTROL_CONN_STATE_OPEN) {
control_connection_t *control_conn = TO_CONTROL_CONN(conn);
- if (control_conn->use_long_names) {
- if (!(which & LONG_NAMES))
- continue;
- } else {
- if (!(which & SHORT_NAMES))
- continue;
- }
- if (control_conn->use_extended_events) {
- if (!(which & EXTENDED_FORMAT))
- continue;
- } else {
- if (!(which & NONEXTENDED_FORMAT))
- continue;
- }
+
if (control_conn->event_mask & (1<<event)) {
int is_err = 0;
connection_write_to_buf(msg, strlen(msg), TO_CONN(control_conn));
@@ -579,7 +554,7 @@ send_control_event_string(uint16_t event, event_format_t which,
connection_handle_write(TO_CONN(control_conn), 1);
}
}
- });
+ } SMARTLIST_FOREACH_END(conn);
}
/** Helper for send_control1_event and send_control1_event_extended:
@@ -587,22 +562,17 @@ send_control_event_string(uint16_t event, event_format_t which,
* <b>event</b>. The event's body is created by the printf-style format in
* <b>format</b>, and other arguments as provided.
*
- * If <b>extended</b> is true, and the format contains a single '@' character,
- * it will be replaced with a space and all text after that character will be
- * sent only to controllers that have enabled extended events.
- *
* Currently the length of the message is limited to 1024 (including the
* ending \\r\\n\\0). */
static void
-send_control_event_impl(uint16_t event, event_format_t which, int extended,
- const char *format, va_list ap)
+send_control_event_impl(uint16_t event, event_format_t which,
+ const char *format, va_list ap)
{
/* This is just a little longer than the longest allowed log message */
#define SEND_CONTROL1_EVENT_BUFFERSIZE 10064
int r;
char buf[SEND_CONTROL1_EVENT_BUFFERSIZE];
size_t len;
- char *cp;
r = tor_vsnprintf(buf, sizeof(buf), format, ap);
if (r<0) {
@@ -618,15 +588,7 @@ send_control_event_impl(uint16_t event, event_format_t which, int extended,
buf[SEND_CONTROL1_EVENT_BUFFERSIZE-3] = '\r';
}
- if (extended && (cp = strchr(buf, '@'))) {
- which &= ~ALL_FORMATS;
- *cp = ' ';
- send_control_event_string(event, which|EXTENDED_FORMAT, buf);
- memcpy(cp, "\r\n\0", 3);
- send_control_event_string(event, which|NONEXTENDED_FORMAT, buf);
- } else {
- send_control_event_string(event, which|ALL_FORMATS, buf);
- }
+ send_control_event_string(event, which|ALL_FORMATS, buf);
}
/** Send an event to all v1 controllers that are listening for code
@@ -641,27 +603,7 @@ send_control_event(uint16_t event, event_format_t which,
{
va_list ap;
va_start(ap, format);
- send_control_event_impl(event, which, 0, format, ap);
- va_end(ap);
-}
-
-/** Send an event to all v1 controllers that are listening for code
- * <b>event</b>. The event's body is created by the printf-style format in
- * <b>format</b>, and other arguments as provided.
- *
- * If the format contains a single '@' character, it will be replaced with a
- * space and all text after that character will be sent only to controllers
- * that have enabled extended events.
- *
- * Currently the length of the message is limited to 1024 (including the
- * ending \\n\\r\\0. */
-static void
-send_control_event_extended(uint16_t event, event_format_t which,
- const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- send_control_event_impl(event, which, 1, format, ap);
+ send_control_event_impl(event, which, format, ap);
va_end(ap);
}
@@ -907,36 +849,37 @@ handle_control_loadconf(control_connection_t *conn, uint32_t len,
retval = options_init_from_string(body, CMD_RUN_TOR, NULL, &errstring);
- if (retval != SETOPT_OK) {
+ if (retval != SETOPT_OK)
log_warn(LD_CONTROL,
"Controller gave us config file that didn't validate: %s",
errstring);
- switch (retval) {
- case SETOPT_ERR_PARSE:
- msg = "552 Invalid config file";
- break;
- case SETOPT_ERR_TRANSITION:
- msg = "553 Transition not allowed";
- break;
- case SETOPT_ERR_SETTING:
- msg = "553 Unable to set option";
- break;
- case SETOPT_ERR_MISC:
- default:
- msg = "550 Unable to load config";
- break;
- case SETOPT_OK:
- tor_fragile_assert();
- break;
- }
+
+ switch (retval) {
+ case SETOPT_ERR_PARSE:
+ msg = "552 Invalid config file";
+ break;
+ case SETOPT_ERR_TRANSITION:
+ msg = "553 Transition not allowed";
+ break;
+ case SETOPT_ERR_SETTING:
+ msg = "553 Unable to set option";
+ break;
+ case SETOPT_ERR_MISC:
+ default:
+ msg = "550 Unable to load config";
+ break;
+ case SETOPT_OK:
+ break;
+ }
+ if (msg) {
if (errstring)
connection_printf_to_buf(conn, "%s: %s\r\n", msg, errstring);
else
connection_printf_to_buf(conn, "%s\r\n", msg);
- tor_free(errstring);
- return 0;
+ } else {
+ send_control_done(conn);
}
- send_control_done(conn);
+ tor_free(errstring);
return 0;
}
@@ -948,7 +891,6 @@ handle_control_setevents(control_connection_t *conn, uint32_t len,
{
uint16_t event_code;
uint32_t event_mask = 0;
- unsigned int extended = 0;
smartlist_t *events = smartlist_create();
(void) len;
@@ -958,7 +900,6 @@ handle_control_setevents(control_connection_t *conn, uint32_t len,
SMARTLIST_FOREACH_BEGIN(events, const char *, ev)
{
if (!strcasecmp(ev, "EXTENDED")) {
- extended = 1;
continue;
} else if (!strcasecmp(ev, "CIRC"))
event_code = EVENT_CIRCUIT_STATUS;
@@ -1002,6 +943,8 @@ handle_control_setevents(control_connection_t *conn, uint32_t len,
event_code = EVENT_CLIENTS_SEEN;
else if (!strcasecmp(ev, "NEWCONSENSUS"))
event_code = EVENT_NEWCONSENSUS;
+ else if (!strcasecmp(ev, "BUILDTIMEOUT_SET"))
+ event_code = EVENT_BUILDTIMEOUT_SET;
else {
connection_printf_to_buf(conn, "552 Unrecognized event \"%s\"\r\n",
ev);
@@ -1016,8 +959,6 @@ handle_control_setevents(control_connection_t *conn, uint32_t len,
smartlist_free(events);
conn->event_mask = event_mask;
- if (extended)
- conn->use_extended_events = 1;
control_update_global_event_mask();
send_control_done(conn);
@@ -1328,7 +1269,7 @@ handle_control_mapaddress(control_connection_t *conn, uint32_t len,
smartlist_add(reply, ans);
log_warn(LD_CONTROL,
"Unable to allocate address for '%s' in MapAddress msg",
- safe_str(line));
+ safe_str_client(line));
} else {
tor_snprintf(ans, anslen, "250-%s=%s", address, to);
smartlist_add(reply, ans);
@@ -1345,7 +1286,8 @@ handle_control_mapaddress(control_connection_t *conn, uint32_t len,
"not of expected form 'foo=bar'.", line);
smartlist_add(reply, ans);
log_info(LD_CONTROL, "Skipping MapAddress '%s': wrong "
- "number of items.", safe_str(line));
+ "number of items.",
+ safe_str_client(line));
}
SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
smartlist_clear(elts);
@@ -1374,13 +1316,15 @@ handle_control_mapaddress(control_connection_t *conn, uint32_t len,
* trivial-to-implement questions. */
static int
getinfo_helper_misc(control_connection_t *conn, const char *question,
- char **answer)
+ char **answer, const char **errmsg)
{
(void) conn;
if (!strcmp(question, "version")) {
*answer = tor_strdup(get_version());
} else if (!strcmp(question, "config-file")) {
*answer = tor_strdup(get_torrc_fname());
+ } else if (!strcmp(question, "config-text")) {
+ *answer = options_dump(get_options(), 1);
} else if (!strcmp(question, "info/names")) {
*answer = list_getinfo_options();
} else if (!strcmp(question, "events/names")) {
@@ -1392,15 +1336,19 @@ getinfo_helper_misc(control_connection_t *conn, const char *question,
*answer = tor_strdup("VERBOSE_NAMES EXTENDED_EVENTS");
} else if (!strcmp(question, "address")) {
uint32_t addr;
- if (router_pick_published_address(get_options(), &addr) < 0)
+ if (router_pick_published_address(get_options(), &addr) < 0) {
+ *errmsg = "Address unknown";
return -1;
+ }
*answer = tor_dup_ip(addr);
} else if (!strcmp(question, "dir-usage")) {
*answer = directory_dump_request_log();
} else if (!strcmp(question, "fingerprint")) {
routerinfo_t *me = router_get_my_routerinfo();
- if (!me)
+ if (!me) {
+ *errmsg = "No routerdesc known; am I really a server?";
return -1;
+ }
*answer = tor_malloc(HEX_DIGEST_LEN+1);
base16_encode(*answer, HEX_DIGEST_LEN+1, me->cache_info.identity_digest,
DIGEST_LEN);
@@ -1461,8 +1409,10 @@ munge_extrainfo_into_routerinfo(const char *ri_body, signed_descriptor_t *ri,
* directory information. */
static int
getinfo_helper_dir(control_connection_t *control_conn,
- const char *question, char **answer)
+ const char *question, char **answer,
+ const char **errmsg)
{
+ (void) control_conn;
if (!strcmpstart(question, "desc/id/")) {
routerinfo_t *ri = router_get_by_hexdigest(question+strlen("desc/id/"));
if (ri) {
@@ -1537,6 +1487,7 @@ getinfo_helper_dir(control_connection_t *control_conn,
log_warn(LD_CONTROL, "getinfo '%s': %s", question, msg);
smartlist_free(descs);
tor_free(url);
+ *errmsg = msg;
return -1;
}
SMARTLIST_FOREACH(descs, signed_descriptor_t *, sd,
@@ -1587,7 +1538,7 @@ getinfo_helper_dir(control_connection_t *control_conn,
}
} else if (!strcmp(question, "dir/status-vote/current/consensus")) { /* v3 */
if (directory_caches_dir_info(get_options())) {
- const cached_dir_t *consensus = dirserv_get_consensus();
+ const cached_dir_t *consensus = dirserv_get_consensus("ns");
if (consensus)
*answer = tor_strdup(consensus->dir);
}
@@ -1598,10 +1549,8 @@ getinfo_helper_dir(control_connection_t *control_conn,
}
} else if (!strcmp(question, "network-status")) { /* v1 */
routerlist_t *routerlist = router_get_routerlist();
- int verbose = control_conn->use_long_names;
if (!routerlist || !routerlist->routers ||
- list_server_status_v1(routerlist->routers, answer,
- verbose ? 2 : 1) < 0) {
+ list_server_status_v1(routerlist->routers, answer, 1) < 0) {
return -1;
}
} else if (!strcmpstart(question, "extra-info/digest/")) {
@@ -1635,8 +1584,10 @@ getinfo_helper_dir(control_connection_t *control_conn,
* current states of things we send events about. */
static int
getinfo_helper_events(control_connection_t *control_conn,
- const char *question, char **answer)
+ const char *question, char **answer,
+ const char **errmsg)
{
+ (void) control_conn;
if (!strcmp(question, "circuit-status")) {
circuit_t *circ;
smartlist_t *status = smartlist_create();
@@ -1647,10 +1598,9 @@ getinfo_helper_events(control_connection_t *control_conn,
const char *purpose;
if (! CIRCUIT_IS_ORIGIN(circ) || circ->marked_for_close)
continue;
- if (control_conn->use_long_names)
- path = circuit_list_path_for_controller(TO_ORIGIN_CIRCUIT(circ));
- else
- path = circuit_list_path(TO_ORIGIN_CIRCUIT(circ),0);
+
+ path = circuit_list_path_for_controller(TO_ORIGIN_CIRCUIT(circ));
+
if (circ->state == CIRCUIT_STATE_OPEN)
state = "BUILT";
else if (strlen(path))
@@ -1728,8 +1678,7 @@ getinfo_helper_events(control_connection_t *control_conn,
} else if (!strcmp(question, "orconn-status")) {
smartlist_t *conns = get_connection_array();
smartlist_t *status = smartlist_create();
- SMARTLIST_FOREACH(conns, connection_t *, base_conn,
- {
+ SMARTLIST_FOREACH_BEGIN(conns, connection_t *, base_conn) {
const char *state;
char *s;
char name[128];
@@ -1744,29 +1693,19 @@ getinfo_helper_events(control_connection_t *control_conn,
state = "LAUNCHED";
else
state = "NEW";
- orconn_target_get_name(control_conn->use_long_names, name, sizeof(name),
- conn);
+ orconn_target_get_name(name, sizeof(name), conn);
slen = strlen(name)+strlen(state)+2;
s = tor_malloc(slen+1);
tor_snprintf(s, slen, "%s %s", name, state);
smartlist_add(status, s);
- });
+ } SMARTLIST_FOREACH_END(base_conn);
*answer = smartlist_join_strings(status, "\r\n", 0, NULL);
SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
smartlist_free(status);
- } else if (!strcmpstart(question, "addr-mappings/") ||
- !strcmpstart(question, "address-mappings/")) {
+ } else if (!strcmpstart(question, "address-mappings/")) {
time_t min_e, max_e;
smartlist_t *mappings;
- int want_expiry = !strcmpstart(question, "address-mappings/");
- if (!strcmpstart(question, "addr-mappings/")) {
- /* XXXX022 This has been deprecated since 0.2.0.3-alpha, and has
- generated a warning since 0.2.1.10-alpha; remove late in 0.2.2.x. */
- log_warn(LD_CONTROL, "Controller used obsolete addr-mappings/ GETINFO "
- "key; use address-mappings/ instead.");
- }
- question += strlen(want_expiry ? "address-mappings/"
- : "addr-mappings/");
+ question += strlen("address-mappings/");
if (!strcmp(question, "all")) {
min_e = 0; max_e = TIME_MAX;
} else if (!strcmp(question, "cache")) {
@@ -1779,7 +1718,7 @@ getinfo_helper_events(control_connection_t *control_conn,
return 0;
}
mappings = smartlist_create();
- addressmap_get_mappings(mappings, min_e, max_e, want_expiry);
+ addressmap_get_mappings(mappings, min_e, max_e, 1);
*answer = smartlist_join_strings(mappings, "\r\n", 0, NULL);
SMARTLIST_FOREACH(mappings, char *, cp, tor_free(cp));
smartlist_free(mappings);
@@ -1787,7 +1726,7 @@ getinfo_helper_events(control_connection_t *control_conn,
/* Note that status/ is not a catch-all for events; there's only supposed
* to be a status GETINFO if there's a corresponding STATUS event. */
if (!strcmp(question, "status/circuit-established")) {
- *answer = tor_strdup(has_completed_circuit ? "1" : "0");
+ *answer = tor_strdup(can_complete_circuit ? "1" : "0");
} else if (!strcmp(question, "status/enough-dir-info")) {
*answer = tor_strdup(router_have_minimum_dir_info() ? "1" : "0");
} else if (!strcmp(question, "status/good-server-descriptor") ||
@@ -1846,21 +1785,12 @@ getinfo_helper_events(control_connection_t *control_conn,
"information", question);
}
} else if (!strcmp(question, "status/clients-seen")) {
- char geoip_start[ISO_TIME_LEN+1];
- size_t answer_len;
- char *geoip_summary = extrainfo_get_client_geoip_summary(time(NULL));
-
- if (!geoip_summary)
+ const char *bridge_stats = geoip_get_bridge_stats_controller(time(NULL));
+ if (!bridge_stats) {
+ *errmsg = "No bridge-client stats available";
return -1;
-
- answer_len = strlen("TimeStarted=\"\" CountrySummary=") +
- ISO_TIME_LEN + strlen(geoip_summary) + 1;
- *answer = tor_malloc(answer_len);
- format_iso_time(geoip_start, geoip_get_history_start());
- tor_snprintf(*answer, answer_len,
- "TimeStarted=\"%s\" CountrySummary=%s",
- geoip_start, geoip_summary);
- tor_free(geoip_summary);
+ }
+ *answer = tor_strdup(bridge_stats);
} else {
return 0;
}
@@ -1870,11 +1800,14 @@ getinfo_helper_events(control_connection_t *control_conn,
/** Callback function for GETINFO: on a given control connection, try to
* answer the question <b>q</b> and store the newly-allocated answer in
- * *<b>a</b>. If there's no answer, or an error occurs, just don't set
- * <b>a</b>. Return 0.
+ * *<b>a</b>. If an internal error occurs, return -1 and optionally set
+ * *<b>error_out</b> to point to an error message to be delivered to the
+ * controller. On success, _or if the key is not recognized_, return 0. Do not
+ * set <b>a</b> if the key is not recognized.
*/
typedef int (*getinfo_helper_t)(control_connection_t *,
- const char *q, char **a);
+ const char *q, char **a,
+ const char **error_out);
/** A single item for the GETINFO question-to-answer-function table. */
typedef struct getinfo_item_t {
@@ -1894,6 +1827,8 @@ typedef struct getinfo_item_t {
static const getinfo_item_t getinfo_items[] = {
ITEM("version", misc, "The current version of Tor."),
ITEM("config-file", misc, "Current location of the \"torrc\" file."),
+ ITEM("config-text", misc,
+ "Return the string that would be written by a saveconf command."),
ITEM("accounting/bytes", accounting,
"Number of bytes read/written so far in the accounting interval."),
ITEM("accounting/bytes-left", accounting,
@@ -1933,7 +1868,6 @@ static const getinfo_item_t getinfo_items[] = {
PREFIX("ns/purpose/", networkstatus,
"Brief summary of router status by purpose (v2 directory format)."),
- PREFIX("unregistered-servers-", dirserv_unregistered, NULL),
ITEM("network-status", dir,
"Brief summary of router status (v1 directory format)"),
ITEM("circuit-status", events, "List of current circuits originating here."),
@@ -1945,14 +1879,6 @@ static const getinfo_item_t getinfo_items[] = {
DOC("address-mappings/config",
"Current address mappings from configuration."),
DOC("address-mappings/control", "Current address mappings from controller."),
- PREFIX("addr-mappings/", events, NULL),
- DOC("addr-mappings/all", "Current address mappings without expiry times."),
- DOC("addr-mappings/cache",
- "Current cached DNS replies without expiry times."),
- DOC("addr-mappings/config",
- "Current address mappings from configuration without expiry times."),
- DOC("addr-mappings/control",
- "Current address mappings from controller without expiry times."),
PREFIX("status/", events, NULL),
DOC("status/circuit-established",
"Whether we think client functionality is working."),
@@ -1988,18 +1914,18 @@ static char *
list_getinfo_options(void)
{
int i;
- char buf[300];
+ char *buf=NULL;
smartlist_t *lines = smartlist_create();
char *ans;
for (i = 0; getinfo_items[i].varname; ++i) {
if (!getinfo_items[i].desc)
continue;
- tor_snprintf(buf, sizeof(buf), "%s%s -- %s\n",
+ tor_asprintf(&buf, "%s%s -- %s\n",
getinfo_items[i].varname,
getinfo_items[i].is_prefix ? "*" : "",
getinfo_items[i].desc);
- smartlist_add(lines, tor_strdup(buf));
+ smartlist_add(lines, buf);
}
smartlist_sort_strings(lines);
@@ -2016,7 +1942,8 @@ list_getinfo_options(void)
* internal error. */
static int
handle_getinfo_helper(control_connection_t *control_conn,
- const char *question, char **answer)
+ const char *question, char **answer,
+ const char **err_out)
{
int i;
*answer = NULL; /* unrecognized key by default */
@@ -2029,7 +1956,7 @@ handle_getinfo_helper(control_connection_t *control_conn,
match = !strcmp(question, getinfo_items[i].varname);
if (match) {
tor_assert(getinfo_items[i].fn);
- return getinfo_items[i].fn(control_conn, question, answer);
+ return getinfo_items[i].fn(control_conn, question, answer, err_out);
}
}
@@ -2051,10 +1978,12 @@ handle_control_getinfo(control_connection_t *conn, uint32_t len,
smartlist_split_string(questions, body, " ",
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- SMARTLIST_FOREACH(questions, const char *, q,
- {
- if (handle_getinfo_helper(conn, q, &ans) < 0) {
- connection_write_str_to_buf("551 Internal error\r\n", conn);
+ SMARTLIST_FOREACH_BEGIN(questions, const char *, q) {
+ const char *errmsg = NULL;
+ if (handle_getinfo_helper(conn, q, &ans, &errmsg) < 0) {
+ if (!errmsg)
+ errmsg = "Internal error";
+ connection_printf_to_buf(conn, "551 %s\r\n", errmsg);
goto done;
}
if (!ans) {
@@ -2063,7 +1992,7 @@ handle_control_getinfo(control_connection_t *conn, uint32_t len,
smartlist_add(answers, tor_strdup(q));
smartlist_add(answers, ans);
}
- });
+ } SMARTLIST_FOREACH_END(q);
if (smartlist_len(unrecognized)) {
for (i=0; i < smartlist_len(unrecognized)-1; ++i)
connection_printf_to_buf(conn,
@@ -2108,12 +2037,12 @@ handle_control_getinfo(control_connection_t *conn, uint32_t len,
static uint8_t
circuit_purpose_from_string(const char *string)
{
- if (!strcmpstart(string, "purpose="))
+ if (!strcasecmpstart(string, "purpose="))
string += strlen("purpose=");
- if (!strcmp(string, "general"))
+ if (!strcasecmp(string, "general"))
return CIRCUIT_PURPOSE_C_GENERAL;
- else if (!strcmp(string, "controller"))
+ else if (!strcasecmp(string, "controller"))
return CIRCUIT_PURPOSE_CONTROLLER;
else
return CIRCUIT_PURPOSE_UNKNOWN;
@@ -2145,6 +2074,31 @@ getargs_helper(const char *command, control_connection_t *conn,
return NULL;
}
+/** Helper. Return the first element of <b>sl</b> at index <b>start_at</b> or
+ * higher that starts with <b>prefix</b>, case-insensitive. Return NULL if no
+ * such element exists. */
+static const char *
+find_element_starting_with(smartlist_t *sl, int start_at, const char *prefix)
+{
+ int i;
+ for (i = start_at; i < smartlist_len(sl); ++i) {
+ const char *elt = smartlist_get(sl, i);
+ if (!strcasecmpstart(elt, prefix))
+ return elt;
+ }
+ return NULL;
+}
+
+/** Helper. Return true iff s is an argument that we should treat as a
+ * key-value pair. */
+static int
+is_keyval_pair(const char *s)
+{
+ /* An argument is a key-value pair if it has an =, and it isn't of the form
+ * $fingeprint=name */
+ return strchr(s, '=') && s[0] != '$';
+}
+
/** Called when we get an EXTENDCIRCUIT message. Try to extend the listed
* circuit, and report success or failure. */
static int
@@ -2160,33 +2114,57 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len,
router_nicknames = smartlist_create();
- args = getargs_helper("EXTENDCIRCUIT", conn, body, 2, -1);
+ args = getargs_helper("EXTENDCIRCUIT", conn, body, 1, -1);
if (!args)
goto done;
zero_circ = !strcmp("0", (char*)smartlist_get(args,0));
- if (!zero_circ && !(circ = get_circ(smartlist_get(args,0)))) {
- connection_printf_to_buf(conn, "552 Unknown circuit \"%s\"\r\n",
- (char*)smartlist_get(args, 0));
- }
- smartlist_split_string(router_nicknames, smartlist_get(args,1), ",", 0, 0);
- if (zero_circ && smartlist_len(args)>2) {
- char *purp = smartlist_get(args,2);
- intended_purpose = circuit_purpose_from_string(purp);
- if (intended_purpose == CIRCUIT_PURPOSE_UNKNOWN) {
- connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n", purp);
+ if (zero_circ) {
+ const char *purp = find_element_starting_with(args, 1, "PURPOSE=");
+
+ if (purp) {
+ intended_purpose = circuit_purpose_from_string(purp);
+ if (intended_purpose == CIRCUIT_PURPOSE_UNKNOWN) {
+ connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n", purp);
+ SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
+ smartlist_free(args);
+ goto done;
+ }
+ }
+
+ if ((smartlist_len(args) == 1) ||
+ (smartlist_len(args) >= 2 && is_keyval_pair(smartlist_get(args, 1)))) {
+ // "EXTENDCIRCUIT 0" || EXTENDCIRCUIT 0 foo=bar"
+ circ = circuit_launch_by_router(intended_purpose, NULL,
+ CIRCLAUNCH_NEED_CAPACITY);
+ if (!circ) {
+ connection_write_str_to_buf("551 Couldn't start circuit\r\n", conn);
+ } else {
+ connection_printf_to_buf(conn, "250 EXTENDED %lu\r\n",
+ (unsigned long)circ->global_identifier);
+ }
SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
smartlist_free(args);
goto done;
}
+ // "EXTENDCIRCUIT 0 router1,router2" ||
+ // "EXTENDCIRCUIT 0 router1,router2 PURPOSE=foo"
}
- SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
- smartlist_free(args);
- if (!zero_circ && !circ) {
+
+ if (!zero_circ && !(circ = get_circ(smartlist_get(args,0)))) {
+ connection_printf_to_buf(conn, "552 Unknown circuit \"%s\"\r\n",
+ (char*)smartlist_get(args, 0));
+ 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));
+ smartlist_free(args);
+
routers = smartlist_create();
SMARTLIST_FOREACH(router_nicknames, const char *, n,
{
@@ -2244,8 +2222,7 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len,
done:
SMARTLIST_FOREACH(router_nicknames, char *, n, tor_free(n));
smartlist_free(router_nicknames);
- if (routers)
- smartlist_free(routers);
+ smartlist_free(routers);
return 0;
}
@@ -2271,7 +2248,7 @@ handle_control_setcircuitpurpose(control_connection_t *conn,
}
{
- char *purp = smartlist_get(args,1);
+ const char *purp = find_element_starting_with(args,1,"PURPOSE=");
new_purpose = circuit_purpose_from_string(purp);
if (new_purpose == CIRCUIT_PURPOSE_UNKNOWN) {
connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n", purp);
@@ -2282,7 +2259,7 @@ handle_control_setcircuitpurpose(control_connection_t *conn,
circ->_base.purpose = new_purpose;
connection_write_str_to_buf("250 OK\r\n", conn);
-done:
+ done:
if (args) {
SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
smartlist_free(args);
@@ -2316,9 +2293,9 @@ handle_control_attachstream(control_connection_t *conn, uint32_t len,
} else if (!zero_circ && !(circ = get_circ(smartlist_get(args, 1)))) {
connection_printf_to_buf(conn, "552 Unknown circuit \"%s\"\r\n",
(char*)smartlist_get(args, 1));
- } else if (circ && smartlist_len(args) > 2) {
- char *hopstring = smartlist_get(args, 2);
- if (!strcasecmpstart(hopstring, "HOP=")) {
+ } else if (circ) {
+ const char *hopstring = find_element_starting_with(args,2,"HOP=");
+ if (hopstring) {
hopstring += strlen("HOP=");
hop = (int) tor_parse_ulong(hopstring, 10, 0, INT_MAX,
&hop_line_ok, NULL);
@@ -2365,7 +2342,7 @@ handle_control_attachstream(control_connection_t *conn, uint32_t len,
char* exit_digest;
if (circ->build_state &&
circ->build_state->chosen_exit &&
- circ->build_state->chosen_exit->identity_digest) {
+ !tor_digest_is_zero(circ->build_state->chosen_exit->identity_digest)) {
exit_digest = circ->build_state->chosen_exit->identity_digest;
r = router_get_by_digest(exit_digest);
}
@@ -2426,9 +2403,9 @@ handle_control_postdescriptor(control_connection_t *conn, uint32_t len,
}
} else if (!strcasecmpstart(option, "cache=")) {
option += strlen("cache=");
- if (!strcmp(option, "no"))
+ if (!strcasecmp(option, "no"))
cache = 0;
- else if (!strcmp(option, "yes"))
+ else if (!strcasecmp(option, "yes"))
cache = 1;
else {
connection_printf_to_buf(conn, "552 Unknown cache request \"%s\"\r\n",
@@ -2610,17 +2587,17 @@ handle_control_resolve(control_connection_t *conn, uint32_t len,
args = smartlist_create();
smartlist_split_string(args, body, " ",
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- if (smartlist_len(args) &&
- !strcasecmp(smartlist_get(args, 0), "mode=reverse")) {
- char *cp = smartlist_get(args, 0);
- smartlist_del_keeporder(args, 0);
- tor_free(cp);
- is_reverse = 1;
+ {
+ const char *modearg = find_element_starting_with(args, 0, "mode=");
+ if (modearg && !strcasecmp(modearg, "mode=reverse"))
+ is_reverse = 1;
}
failed = smartlist_create();
SMARTLIST_FOREACH(args, const char *, arg, {
- if (dnsserv_launch_request(arg, is_reverse)<0)
- smartlist_add(failed, (char*)arg);
+ if (!is_keyval_pair(arg)) {
+ if (dnsserv_launch_request(arg, is_reverse)<0)
+ smartlist_add(failed, (char*)arg);
+ }
});
send_control_done(conn);
@@ -2710,7 +2687,6 @@ handle_control_usefeature(control_connection_t *conn,
const char *body)
{
smartlist_t *args;
- int verbose_names = 0, extended_events = 0;
int bad = 0;
(void) len; /* body is nul-terminated; it's safe to ignore the length */
args = smartlist_create();
@@ -2718,9 +2694,9 @@ handle_control_usefeature(control_connection_t *conn,
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
SMARTLIST_FOREACH(args, const char *, arg, {
if (!strcasecmp(arg, "VERBOSE_NAMES"))
- verbose_names = 1;
+ ;
else if (!strcasecmp(arg, "EXTENDED_EVENTS"))
- extended_events = 1;
+ ;
else {
connection_printf_to_buf(conn, "552 Unrecognized feature \"%s\"\r\n",
arg);
@@ -2730,12 +2706,6 @@ handle_control_usefeature(control_connection_t *conn,
});
if (!bad) {
- if (verbose_names) {
- conn->use_long_names = 1;
- control_update_global_event_mask();
- }
- if (extended_events)
- conn->use_extended_events = 1;
send_control_done(conn);
}
@@ -2885,9 +2855,10 @@ connection_control_process_inbuf(control_connection_t *conn)
&& !TOR_ISSPACE(conn->incoming_cmd[cmd_len]))
++cmd_len;
- data_len -= cmd_len;
conn->incoming_cmd[cmd_len]='\0';
args = conn->incoming_cmd+cmd_len+1;
+ tor_assert(data_len>(size_t)cmd_len);
+ data_len -= (cmd_len+1); /* skip the command and NUL we added after it */
while (*args == ' ' || *args == '\t') {
++args;
--data_len;
@@ -3039,20 +3010,11 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp,
tor_free(reason);
}
- if (EVENT_IS_INTERESTING1S(EVENT_CIRCUIT_STATUS)) {
- char *path = circuit_list_path(circ,0);
- const char *sp = strlen(path) ? " " : "";
- send_control_event_extended(EVENT_CIRCUIT_STATUS, SHORT_NAMES,
- "650 CIRC %lu %s%s%s@%s\r\n",
- (unsigned long)circ->global_identifier,
- status, sp, path, extended_buf);
- tor_free(path);
- }
- if (EVENT_IS_INTERESTING1L(EVENT_CIRCUIT_STATUS)) {
+ {
char *vpath = circuit_list_path_for_controller(circ);
const char *sp = strlen(vpath) ? " " : "";
- send_control_event_extended(EVENT_CIRCUIT_STATUS, LONG_NAMES,
- "650 CIRC %lu %s%s%s@%s\r\n",
+ send_control_event(EVENT_CIRCUIT_STATUS, ALL_FORMATS,
+ "650 CIRC %lu %s%s%s %s\r\n",
(unsigned long)circ->global_identifier,
status, sp, vpath, extended_buf);
tor_free(vpath);
@@ -3131,26 +3093,26 @@ control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp,
char *r = NULL;
if (!reason_str) {
r = tor_malloc(16);
- tor_snprintf(r, 16, "UNKNOWN_%d", reason_code);
+ tor_snprintf(r, 16, " UNKNOWN_%d", reason_code);
reason_str = r;
}
if (reason_code & END_STREAM_REASON_FLAG_REMOTE)
tor_snprintf(reason_buf, sizeof(reason_buf),
- "REASON=END REMOTE_REASON=%s", reason_str);
+ " REASON=END REMOTE_REASON=%s", reason_str);
else
tor_snprintf(reason_buf, sizeof(reason_buf),
- "REASON=%s", reason_str);
+ " REASON=%s", reason_str);
tor_free(r);
} else if (reason_code && tp == STREAM_EVENT_REMAP) {
switch (reason_code) {
case REMAP_STREAM_SOURCE_CACHE:
- strlcpy(reason_buf, "SOURCE=CACHE", sizeof(reason_buf));
+ strlcpy(reason_buf, " SOURCE=CACHE", sizeof(reason_buf));
break;
case REMAP_STREAM_SOURCE_EXIT:
- strlcpy(reason_buf, "SOURCE=EXIT", sizeof(reason_buf));
+ strlcpy(reason_buf, " SOURCE=EXIT", sizeof(reason_buf));
break;
default:
- tor_snprintf(reason_buf, sizeof(reason_buf), "REASON=UNKNOWN_%d",
+ tor_snprintf(reason_buf, sizeof(reason_buf), " REASON=UNKNOWN_%d",
reason_code);
/* XXX do we want SOURCE=UNKNOWN_%d above instead? -RD */
break;
@@ -3158,8 +3120,7 @@ control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp,
}
if (tp == STREAM_EVENT_NEW) {
- tor_snprintf(addrport_buf,sizeof(addrport_buf), "%sSOURCE_ADDR=%s:%d",
- strlen(reason_buf) ? " " : "",
+ tor_snprintf(addrport_buf,sizeof(addrport_buf), " SOURCE_ADDR=%s:%d",
TO_CONN(conn)->address, TO_CONN(conn)->port );
} else {
addrport_buf[0] = '\0';
@@ -3188,8 +3149,8 @@ control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp,
circ = circuit_get_by_edge_conn(conn);
if (circ && CIRCUIT_IS_ORIGIN(circ))
origin_circ = TO_ORIGIN_CIRCUIT(circ);
- send_control_event_extended(EVENT_STREAM_STATUS, ALL_NAMES,
- "650 STREAM "U64_FORMAT" %s %lu %s@%s%s%s\r\n",
+ send_control_event(EVENT_STREAM_STATUS, ALL_FORMATS,
+ "650 STREAM "U64_FORMAT" %s %lu %s%s%s%s\r\n",
U64_PRINTF_ARG(conn->_base.global_identifier), status,
origin_circ?
(unsigned long)origin_circ->global_identifier : 0ul,
@@ -3202,30 +3163,21 @@ control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp,
/** Figure out the best name for the target router of an OR connection
* <b>conn</b>, and write it into the <b>len</b>-character buffer
- * <b>name</b>. Use verbose names if <b>long_names</b> is set. */
+ * <b>name</b>. */
static void
-orconn_target_get_name(int long_names,
- char *name, size_t len, or_connection_t *conn)
-{
- if (! long_names) {
- if (conn->nickname)
- strlcpy(name, conn->nickname, len);
- else
- tor_snprintf(name, len, "%s:%d",
- conn->_base.address, conn->_base.port);
+orconn_target_get_name(char *name, size_t len, or_connection_t *conn)
+{
+ routerinfo_t *ri = router_get_by_digest(conn->identity_digest);
+ if (ri) {
+ tor_assert(len > MAX_VERBOSE_NICKNAME_LEN);
+ router_get_verbose_nickname(name, ri);
+ } else if (! tor_digest_is_zero(conn->identity_digest)) {
+ name[0] = '$';
+ base16_encode(name+1, len-1, conn->identity_digest,
+ DIGEST_LEN);
} else {
- routerinfo_t *ri = router_get_by_digest(conn->identity_digest);
- if (ri) {
- tor_assert(len > MAX_VERBOSE_NICKNAME_LEN);
- router_get_verbose_nickname(name, ri);
- } else if (! tor_digest_is_zero(conn->identity_digest)) {
- name[0] = '$';
- base16_encode(name+1, len-1, conn->identity_digest,
- DIGEST_LEN);
- } else {
- tor_snprintf(name, len, "%s:%d",
- conn->_base.address, conn->_base.port);
- }
+ tor_snprintf(name, len, "%s:%d",
+ conn->_base.address, conn->_base.port);
}
}
@@ -3264,24 +3216,13 @@ control_event_or_conn_status(or_connection_t *conn, or_conn_status_event_t tp,
reason ? " " : "", ncircs);
}
- if (EVENT_IS_INTERESTING1S(EVENT_OR_CONN_STATUS)) {
- orconn_target_get_name(0, name, sizeof(name), conn);
- send_control_event_extended(EVENT_OR_CONN_STATUS, SHORT_NAMES,
- "650 ORCONN %s %s@%s%s%s\r\n",
- name, status,
- reason ? "REASON=" : "",
- orconn_end_reason_to_control_string(reason),
- ncircs_buf);
- }
- if (EVENT_IS_INTERESTING1L(EVENT_OR_CONN_STATUS)) {
- orconn_target_get_name(1, name, sizeof(name), conn);
- send_control_event_extended(EVENT_OR_CONN_STATUS, LONG_NAMES,
- "650 ORCONN %s %s@%s%s%s\r\n",
- name, status,
- reason ? "REASON=" : "",
- orconn_end_reason_to_control_string(reason),
- ncircs_buf);
- }
+ orconn_target_get_name(name, sizeof(name), conn);
+ send_control_event(EVENT_OR_CONN_STATUS, ALL_FORMATS,
+ "650 ORCONN %s %s %s%s%s\r\n",
+ name, status,
+ reason ? "REASON=" : "",
+ orconn_end_reason_to_control_string(reason),
+ ncircs_buf);
return 0;
}
@@ -3296,7 +3237,7 @@ control_event_stream_bandwidth(edge_connection_t *edge_conn)
if (!edge_conn->n_read && !edge_conn->n_written)
return 0;
- send_control_event(EVENT_STREAM_BANDWIDTH_USED, ALL_NAMES,
+ send_control_event(EVENT_STREAM_BANDWIDTH_USED, ALL_FORMATS,
"650 STREAM_BW "U64_FORMAT" %lu %lu\r\n",
U64_PRINTF_ARG(edge_conn->_base.global_identifier),
(unsigned long)edge_conn->n_read,
@@ -3325,7 +3266,7 @@ control_event_stream_bandwidth_used(void)
if (!edge_conn->n_read && !edge_conn->n_written)
continue;
- send_control_event(EVENT_STREAM_BANDWIDTH_USED, ALL_NAMES,
+ send_control_event(EVENT_STREAM_BANDWIDTH_USED, ALL_FORMATS,
"650 STREAM_BW "U64_FORMAT" %lu %lu\r\n",
U64_PRINTF_ARG(edge_conn->_base.global_identifier),
(unsigned long)edge_conn->n_read,
@@ -3345,7 +3286,7 @@ int
control_event_bandwidth_used(uint32_t n_read, uint32_t n_written)
{
if (EVENT_IS_INTERESTING(EVENT_BANDWIDTH_USED)) {
- send_control_event(EVENT_BANDWIDTH_USED, ALL_NAMES,
+ send_control_event(EVENT_BANDWIDTH_USED, ALL_FORMATS,
"650 BW %lu %lu\r\n",
(unsigned long)n_read,
(unsigned long)n_written);
@@ -3415,7 +3356,7 @@ control_event_logmsg(int severity, uint32_t domain, const char *msg)
default: s = "UnknownLogSeverity"; break;
}
++disable_log_messages;
- send_control_event(event, ALL_NAMES, "650 %s %s\r\n", s, b?b:msg);
+ send_control_event(event, ALL_FORMATS, "650 %s %s\r\n", s, b?b:msg);
--disable_log_messages;
tor_free(b);
}
@@ -3428,31 +3369,12 @@ control_event_logmsg(int severity, uint32_t domain, const char *msg)
int
control_event_descriptors_changed(smartlist_t *routers)
{
- size_t len;
char *msg;
- smartlist_t *identities = NULL;
- char buf[HEX_DIGEST_LEN+1];
if (!EVENT_IS_INTERESTING(EVENT_NEW_DESC))
return 0;
- if (EVENT_IS_INTERESTING1S(EVENT_NEW_DESC)) {
- identities = smartlist_create();
- SMARTLIST_FOREACH(routers, routerinfo_t *, r,
- {
- base16_encode(buf,sizeof(buf),r->cache_info.identity_digest,DIGEST_LEN);
- smartlist_add(identities, tor_strdup(buf));
- });
- }
- if (EVENT_IS_INTERESTING1S(EVENT_NEW_DESC)) {
- char *ids = smartlist_join_strings(identities, " ", 0, &len);
- size_t ids_len = strlen(ids)+32;
- msg = tor_malloc(ids_len);
- tor_snprintf(msg, ids_len, "650 NEWDESC %s\r\n", ids);
- send_control_event_string(EVENT_NEW_DESC, SHORT_NAMES|ALL_FORMATS, msg);
- tor_free(ids);
- tor_free(msg);
- }
- if (EVENT_IS_INTERESTING1L(EVENT_NEW_DESC)) {
+
+ {
smartlist_t *names = smartlist_create();
char *ids;
size_t names_len;
@@ -3465,16 +3387,12 @@ control_event_descriptors_changed(smartlist_t *routers)
names_len = strlen(ids)+32;
msg = tor_malloc(names_len);
tor_snprintf(msg, names_len, "650 NEWDESC %s\r\n", ids);
- send_control_event_string(EVENT_NEW_DESC, LONG_NAMES|ALL_FORMATS, msg);
+ send_control_event_string(EVENT_NEW_DESC, ALL_FORMATS, msg);
tor_free(ids);
tor_free(msg);
SMARTLIST_FOREACH(names, char *, cp, tor_free(cp));
smartlist_free(names);
}
- if (identities) {
- SMARTLIST_FOREACH(identities, char *, cp, tor_free(cp));
- smartlist_free(identities);
- }
return 0;
}
@@ -3491,17 +3409,17 @@ control_event_address_mapped(const char *from, const char *to, time_t expires,
return 0;
if (expires < 3 || expires == TIME_MAX)
- send_control_event_extended(EVENT_ADDRMAP, ALL_NAMES,
- "650 ADDRMAP %s %s NEVER@%s\r\n", from, to,
+ send_control_event(EVENT_ADDRMAP, ALL_FORMATS,
+ "650 ADDRMAP %s %s NEVER %s\r\n", from, to,
error?error:"");
else {
char buf[ISO_TIME_LEN+1];
char buf2[ISO_TIME_LEN+1];
format_local_iso_time(buf,expires);
format_iso_time(buf2,expires);
- send_control_event_extended(EVENT_ADDRMAP, ALL_NAMES,
+ send_control_event(EVENT_ADDRMAP, ALL_FORMATS,
"650 ADDRMAP %s %s \"%s\""
- "@%s%sEXPIRES=\"%s\"\r\n",
+ " %s%sEXPIRES=\"%s\"\r\n",
from, to, buf,
error?error:"", error?" ":"",
buf2);
@@ -3541,9 +3459,9 @@ control_event_or_authdir_new_descriptor(const char *action,
buf = tor_malloc(totallen);
strlcpy(buf, firstline, totallen);
strlcpy(buf+strlen(firstline), esc, totallen);
- send_control_event_string(EVENT_AUTHDIR_NEWDESCS, ALL_NAMES|ALL_FORMATS,
+ send_control_event_string(EVENT_AUTHDIR_NEWDESCS, ALL_FORMATS,
buf);
- send_control_event_string(EVENT_AUTHDIR_NEWDESCS, ALL_NAMES|ALL_FORMATS,
+ send_control_event_string(EVENT_AUTHDIR_NEWDESCS, ALL_FORMATS,
"650 OK\r\n");
tor_free(esc);
tor_free(buf);
@@ -3581,8 +3499,8 @@ control_event_networkstatus_changed_helper(smartlist_t *statuses,
SMARTLIST_FOREACH(strs, char *, cp, tor_free(cp));
smartlist_free(strs);
tor_free(s);
- send_control_event_string(event, ALL_NAMES|ALL_FORMATS, esc);
- send_control_event_string(event, ALL_NAMES|ALL_FORMATS,
+ send_control_event_string(event, ALL_FORMATS, esc);
+ send_control_event_string(event, ALL_FORMATS,
"650 OK\r\n");
tor_free(esc);
@@ -3608,6 +3526,55 @@ control_event_newconsensus(const networkstatus_t *consensus)
consensus->routerstatus_list, EVENT_NEWCONSENSUS, "NEWCONSENSUS");
}
+/** Called when we compute a new circuitbuildtimeout */
+int
+control_event_buildtimeout_set(const circuit_build_times_t *cbt,
+ buildtimeout_set_event_t type)
+{
+ const char *type_string = NULL;
+ double qnt = circuit_build_times_quantile_cutoff();
+
+ if (!control_event_is_interesting(EVENT_BUILDTIMEOUT_SET))
+ return 0;
+
+ switch (type) {
+ case BUILDTIMEOUT_SET_EVENT_COMPUTED:
+ type_string = "COMPUTED";
+ break;
+ case BUILDTIMEOUT_SET_EVENT_RESET:
+ type_string = "RESET";
+ qnt = 1.0;
+ break;
+ case BUILDTIMEOUT_SET_EVENT_SUSPENDED:
+ type_string = "SUSPENDED";
+ qnt = 1.0;
+ break;
+ case BUILDTIMEOUT_SET_EVENT_DISCARD:
+ type_string = "DISCARD";
+ qnt = 1.0;
+ break;
+ case BUILDTIMEOUT_SET_EVENT_RESUME:
+ type_string = "RESUME";
+ break;
+ default:
+ type_string = "UNKNOWN";
+ break;
+ }
+
+ send_control_event(EVENT_BUILDTIMEOUT_SET, ALL_FORMATS,
+ "650 BUILDTIMEOUT_SET %s TOTAL_TIMES=%lu "
+ "TIMEOUT_MS=%lu XM=%lu ALPHA=%lf CUTOFF_QUANTILE=%lf "
+ "TIMEOUT_RATE=%lf CLOSE_MS=%lu CLOSE_RATE=%lf\r\n",
+ type_string, (unsigned long)cbt->total_build_times,
+ (unsigned long)cbt->timeout_ms,
+ (unsigned long)cbt->Xm, cbt->alpha, qnt,
+ circuit_build_times_timeout_rate(cbt),
+ (unsigned long)cbt->close_ms,
+ circuit_build_times_close_rate(cbt));
+
+ return 0;
+}
+
/** Called when a single local_routerstatus_t has changed: Sends an NS event
* to any controller that cares. */
int
@@ -3631,7 +3598,7 @@ control_event_networkstatus_changed_single(routerstatus_t *rs)
int
control_event_my_descriptor_changed(void)
{
- send_control_event(EVENT_DESCCHANGED, ALL_NAMES, "650 DESCCHANGED\r\n");
+ send_control_event(EVENT_DESCCHANGED, ALL_FORMATS, "650 DESCCHANGED\r\n");
return 0;
}
@@ -3679,7 +3646,7 @@ control_event_status(int type, int severity, const char *format, va_list args)
return -1;
}
- send_control_event_impl(type, ALL_NAMES|ALL_FORMATS, 0, format_buf, args);
+ send_control_event_impl(type, ALL_FORMATS, format_buf, args);
return 0;
}
@@ -3743,7 +3710,7 @@ control_event_guard(const char *nickname, const char *digest,
if (!EVENT_IS_INTERESTING(EVENT_GUARD))
return 0;
- if (EVENT_IS_INTERESTING1L(EVENT_GUARD)) {
+ {
char buf[MAX_VERBOSE_NICKNAME_LEN+1];
routerinfo_t *ri = router_get_by_digest(digest);
if (ri) {
@@ -3751,13 +3718,9 @@ control_event_guard(const char *nickname, const char *digest,
} else {
tor_snprintf(buf, sizeof(buf), "$%s~%s", hbuf, nickname);
}
- send_control_event(EVENT_GUARD, LONG_NAMES,
+ send_control_event(EVENT_GUARD, ALL_FORMATS,
"650 GUARD ENTRY %s %s\r\n", buf, status);
}
- if (EVENT_IS_INTERESTING1S(EVENT_GUARD)) {
- send_control_event(EVENT_GUARD, SHORT_NAMES,
- "650 GUARD ENTRY $%s %s\r\n", hbuf, status);
- }
return 0;
}
@@ -4008,10 +3971,9 @@ control_event_bootstrap_problem(const char *warn, int reason)
* from recently. Send a copy to the controller in case it wants to
* display it for the user. */
void
-control_event_clients_seen(const char *timestarted, const char *countries)
+control_event_clients_seen(const char *controller_str)
{
send_control_event(EVENT_CLIENTS_SEEN, 0,
- "650 CLIENTS_SEEN TimeStarted=\"%s\" CountrySummary=%s\r\n",
- timestarted, countries);
+ "650 CLIENTS_SEEN %s\r\n", controller_str);
}
diff --git a/src/or/control.h b/src/or/control.h
new file mode 100644
index 0000000000..27ef5c37f7
--- /dev/null
+++ b/src/or/control.h
@@ -0,0 +1,85 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file control.h
+ * \brief Header file for control.c.
+ **/
+
+#ifndef _TOR_CONTROL_H
+#define _TOR_CONTROL_H
+
+void control_update_global_event_mask(void);
+void control_adjust_event_log_severity(void);
+
+/** Log information about the connection <b>conn</b>, protecting it as with
+ * CONN_LOG_PROTECT. Example:
+ *
+ * LOG_FN_CONN(conn, (LOG_DEBUG, "Socket %d wants to write", conn->s));
+ **/
+#define LOG_FN_CONN(conn, args) \
+ CONN_LOG_PROTECT(conn, log_fn args)
+
+int connection_control_finished_flushing(control_connection_t *conn);
+int connection_control_reached_eof(control_connection_t *conn);
+int connection_control_process_inbuf(control_connection_t *conn);
+
+#define EVENT_AUTHDIR_NEWDESCS 0x000D
+#define EVENT_NS 0x000F
+int control_event_is_interesting(int event);
+
+int control_event_circuit_status(origin_circuit_t *circ,
+ circuit_status_event_t e, int reason);
+int control_event_stream_status(edge_connection_t *conn,
+ stream_status_event_t e,
+ int reason);
+int control_event_or_conn_status(or_connection_t *conn,
+ or_conn_status_event_t e, int reason);
+int control_event_bandwidth_used(uint32_t n_read, uint32_t n_written);
+int control_event_stream_bandwidth(edge_connection_t *edge_conn);
+int control_event_stream_bandwidth_used(void);
+void control_event_logmsg(int severity, unsigned int domain, const char *msg);
+int control_event_descriptors_changed(smartlist_t *routers);
+int control_event_address_mapped(const char *from, const char *to,
+ time_t expires, const char *error);
+int control_event_or_authdir_new_descriptor(const char *action,
+ const char *desc,
+ size_t desclen,
+ const char *msg);
+int control_event_my_descriptor_changed(void);
+int control_event_networkstatus_changed(smartlist_t *statuses);
+
+int control_event_newconsensus(const networkstatus_t *consensus);
+int control_event_networkstatus_changed_single(routerstatus_t *rs);
+int control_event_general_status(int severity, const char *format, ...)
+ CHECK_PRINTF(2,3);
+int control_event_client_status(int severity, const char *format, ...)
+ CHECK_PRINTF(2,3);
+int control_event_server_status(int severity, const char *format, ...)
+ CHECK_PRINTF(2,3);
+int control_event_guard(const char *nickname, const char *digest,
+ const char *status);
+int control_event_buildtimeout_set(const circuit_build_times_t *cbt,
+ buildtimeout_set_event_t type);
+
+int init_cookie_authentication(int enabled);
+smartlist_t *decode_hashed_passwords(config_line_t *passwords);
+void disable_control_logging(void);
+void enable_control_logging(void);
+
+void control_event_bootstrap(bootstrap_status_t status, int progress);
+void control_event_bootstrap_problem(const char *warn, int reason);
+
+void control_event_clients_seen(const char *controller_str);
+
+#ifdef CONTROL_PRIVATE
+/* Used only by control.c and test.c */
+size_t write_escaped_data(const char *data, size_t len, char **out);
+size_t read_escaped_data(const char *data, size_t len, char **out);
+#endif
+
+#endif
+
diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c
index fde149978c..ae8d69f6ec 100644
--- a/src/or/cpuworker.c
+++ b/src/or/cpuworker.c
@@ -13,6 +13,15 @@
**/
#include "or.h"
+#include "buffers.h"
+#include "circuitbuild.h"
+#include "circuitlist.h"
+#include "config.h"
+#include "connection.h"
+#include "cpuworker.h"
+#include "main.h"
+#include "onion.h"
+#include "router.h"
/** The maximum number of cpuworker processes we will keep around. */
#define MAX_CPUWORKERS 16
@@ -183,7 +192,7 @@ connection_cpu_process_inbuf(connection_t *conn)
tor_assert(0); /* don't ask me to do handshakes yet */
}
-done_processing:
+ done_processing:
conn->state = CPUWORKER_STATE_IDLE;
num_cpuworkers_busy--;
if (conn->timestamp_created < last_rotation_time) {
@@ -358,7 +367,7 @@ spawn_cpuworker(void)
static void
spawn_enough_cpuworkers(void)
{
- int num_cpuworkers_needed = get_options()->NumCpus;
+ int num_cpuworkers_needed = get_options()->NumCPUs;
if (num_cpuworkers_needed < MIN_CPUWORKERS)
num_cpuworkers_needed = MIN_CPUWORKERS;
diff --git a/src/or/cpuworker.h b/src/or/cpuworker.h
new file mode 100644
index 0000000000..e09703f217
--- /dev/null
+++ b/src/or/cpuworker.h
@@ -0,0 +1,25 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file cpuworker.h
+ * \brief Header file for cpuworker.c.
+ **/
+
+#ifndef _TOR_CPUWORKER_H
+#define _TOR_CPUWORKER_H
+
+void cpu_init(void);
+void cpuworkers_rotate(void);
+int connection_cpu_finished_flushing(connection_t *conn);
+int connection_cpu_reached_eof(connection_t *conn);
+int connection_cpu_process_inbuf(connection_t *conn);
+int assign_onionskin_to_cpuworker(connection_t *cpuworker,
+ or_circuit_t *circ,
+ char *onionskin);
+
+#endif
+
diff --git a/src/or/directory.c b/src/or/directory.c
index 7ec97d48e0..fbdd496c12 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -4,6 +4,26 @@
/* See LICENSE for licensing information */
#include "or.h"
+#include "buffers.h"
+#include "circuitbuild.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_edge.h"
+#include "control.h"
+#include "directory.h"
+#include "dirserv.h"
+#include "dirvote.h"
+#include "geoip.h"
+#include "main.h"
+#include "networkstatus.h"
+#include "policies.h"
+#include "rendclient.h"
+#include "rendcommon.h"
+#include "rephist.h"
+#include "router.h"
+#include "routerlist.h"
+#include "routerparse.h"
+
#if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
#ifndef OPENBSD
#include <malloc.h>
@@ -47,8 +67,10 @@ static void http_set_address_origin(const char *headers, connection_t *conn);
static void connection_dir_download_networkstatus_failed(
dir_connection_t *conn, int status_code);
static void connection_dir_download_routerdesc_failed(dir_connection_t *conn);
+static void connection_dir_bridge_routerdesc_failed(dir_connection_t *conn);
static void connection_dir_download_cert_failed(
dir_connection_t *conn, int status_code);
+static void connection_dir_retry_bridges(smartlist_t *descs);
static void dir_networkstatus_download_failed(smartlist_t *failed,
int status_code);
static void dir_routerdesc_download_failed(smartlist_t *failed,
@@ -92,17 +114,19 @@ static void directory_initiate_command_rend(const char *address,
#define ROUTERDESC_CACHE_LIFETIME (30*60)
#define ROUTERDESC_BY_DIGEST_CACHE_LIFETIME (48*60*60)
#define ROBOTS_CACHE_LIFETIME (24*60*60)
+#define MICRODESC_CACHE_LIFETIME (48*60*60)
/********* END VARIABLES ************/
-/** Return true iff the directory purpose 'purpose' must use an
- * anonymous connection to a directory. */
+/** Return true iff the directory purpose <b>dir_purpose</b> (and if it's
+ * fetching descriptors, it's fetching them for <b>router_purpose</b>)
+ * must use an anonymous connection to a directory. */
static int
purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose)
{
if (get_options()->AllDirActionsPrivate)
return 1;
- if (router_purpose == ROUTER_PURPOSE_BRIDGE && has_completed_circuit)
+ if (router_purpose == ROUTER_PURPOSE_BRIDGE && can_complete_circuit)
return 1; /* if no circuits yet, we may need this info to bootstrap. */
if (dir_purpose == DIR_PURPOSE_UPLOAD_DIR ||
dir_purpose == DIR_PURPOSE_UPLOAD_VOTE ||
@@ -230,7 +254,7 @@ directories_have_accepted_server_descriptor(void)
/** Start a connection to every suitable directory authority, using
* connection purpose 'purpose' and uploading the payload 'payload'
- * (length 'payload_len'). The purpose should be one of
+ * (length 'payload_len'). dir_purpose should be one of
* 'DIR_PURPOSE_UPLOAD_DIR' or 'DIR_PURPOSE_UPLOAD_RENDDESC'.
*
* <b>type</b> specifies what sort of dir authorities (V1, V2,
@@ -560,7 +584,7 @@ connection_dir_request_failed(dir_connection_t *conn)
if (directory_conn_is_self_reachability_test(conn)) {
return; /* this was a test fetch. don't retry. */
}
- if (entry_list_can_grow(get_options()))
+ if (!entry_list_is_constrained(get_options()))
router_set_status(conn->identity_digest, 0); /* don't try him again */
if (conn->_base.purpose == DIR_PURPOSE_FETCH_V2_NETWORKSTATUS) {
log_info(LD_DIR, "Giving up on directory server at '%s'; retrying",
@@ -570,6 +594,8 @@ connection_dir_request_failed(dir_connection_t *conn)
conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO) {
log_info(LD_DIR, "Giving up on directory server at '%s'; retrying",
conn->_base.address);
+ if (conn->router_purpose == ROUTER_PURPOSE_BRIDGE)
+ connection_dir_bridge_routerdesc_failed(conn);
connection_dir_download_routerdesc_failed(conn);
} else if (conn->_base.purpose == DIR_PURPOSE_FETCH_CONSENSUS) {
networkstatus_consensus_download_failed(0);
@@ -614,7 +640,7 @@ connection_dir_download_networkstatus_failed(dir_connection_t *conn,
* failed, and possibly retry them later.*/
smartlist_t *failed = smartlist_create();
dir_split_resource_into_fingerprints(conn->requested_resource+3,
- failed, NULL, 0, 0);
+ failed, NULL, 0);
if (smartlist_len(failed)) {
dir_networkstatus_download_failed(failed, status_code);
SMARTLIST_FOREACH(failed, char *, cp, tor_free(cp));
@@ -623,6 +649,24 @@ connection_dir_download_networkstatus_failed(dir_connection_t *conn,
}
}
+/** Helper: Attempt to fetch directly the descriptors of each bridge
+ * listed in <b>failed</b>.
+ */
+static void
+connection_dir_retry_bridges(smartlist_t *descs)
+{
+ char digest[DIGEST_LEN];
+ SMARTLIST_FOREACH(descs, const char *, cp,
+ {
+ if (base16_decode(digest, DIGEST_LEN, cp, strlen(cp))<0) {
+ log_warn(LD_BUG, "Malformed fingerprint in list: %s",
+ escaped(cp));
+ continue;
+ }
+ retry_bridge_descriptor_fetch_directly(digest);
+ });
+}
+
/** Called when an attempt to download one or more router descriptors
* or extra-info documents on connection <b>conn</b> failed.
*/
@@ -640,6 +684,33 @@ connection_dir_download_routerdesc_failed(dir_connection_t *conn)
(void) conn;
}
+/** Called when an attempt to download a bridge's routerdesc from
+ * one of the authorities failed due to a network error. If
+ * possible attempt to download descriptors from the bridge directly.
+ */
+static void
+connection_dir_bridge_routerdesc_failed(dir_connection_t *conn)
+{
+ smartlist_t *which = NULL;
+
+ /* Requests for bridge descriptors are in the form 'fp/', so ignore
+ anything else. */
+ if (!conn->requested_resource || strcmpstart(conn->requested_resource,"fp/"))
+ return;
+
+ which = smartlist_create();
+ dir_split_resource_into_fingerprints(conn->requested_resource
+ + strlen("fp/"),
+ which, NULL, 0);
+
+ tor_assert(conn->_base.purpose != DIR_PURPOSE_FETCH_EXTRAINFO);
+ if (smartlist_len(which)) {
+ connection_dir_retry_bridges(which);
+ SMARTLIST_FOREACH(which, char *, cp, tor_free(cp));
+ }
+ smartlist_free(which);
+}
+
/** Called when an attempt to fetch a certificate fails. */
static void
connection_dir_download_cert_failed(dir_connection_t *conn, int status)
@@ -651,7 +722,7 @@ connection_dir_download_cert_failed(dir_connection_t *conn, int status)
return;
failed = smartlist_create();
dir_split_resource_into_fingerprints(conn->requested_resource+3,
- failed, NULL, 1, 0);
+ failed, NULL, DSR_HEX);
SMARTLIST_FOREACH(failed, char *, cp,
{
authority_cert_dl_failed(cp, status);
@@ -667,7 +738,7 @@ connection_dir_download_cert_failed(dir_connection_t *conn, int status)
* 1) If or_port is 0, or it's a direct conn and or_port is firewalled
* or we're a dir mirror, no.
* 2) If we prefer to avoid begindir conns, and we're not fetching or
- * publishing a bridge relay descriptor, no.
+ * publishing a bridge relay descriptor, no.
* 3) Else yes.
*/
static int
@@ -746,6 +817,15 @@ directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
log_debug(LD_DIR, "Initiating %s", dir_conn_purpose_to_string(dir_purpose));
+ /* ensure that we don't make direct connections when a SOCKS server is
+ * configured. */
+ if (!anonymized_connection && !use_begindir && !options->HTTPProxy &&
+ (options->Socks4Proxy || options->Socks5Proxy)) {
+ log_warn(LD_DIR, "Cannot connect to a directory server through a "
+ "SOCKS proxy!");
+ return;
+ }
+
conn = dir_connection_new(AF_INET);
/* set up conn so it's got all the data we need to remember */
@@ -770,9 +850,9 @@ directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
if (!anonymized_connection && !use_begindir) {
/* then we want to connect to dirport directly */
- if (options->HttpProxy) {
- tor_addr_from_ipv4h(&addr, options->HttpProxyAddr);
- dir_port = options->HttpProxyPort;
+ if (options->HTTPProxy) {
+ tor_addr_copy(&addr, &options->HTTPProxyAddr);
+ dir_port = options->HTTPProxyPort;
}
switch (connection_connect(TO_CONN(conn), conn->_base.address, &addr,
@@ -793,7 +873,7 @@ directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
payload, payload_len,
supports_conditional_consensus,
if_modified_since);
- connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
+ connection_watch_events(TO_CONN(conn), READ_EVENT | WRITE_EVENT);
/* writable indicates finish, readable indicates broken link,
error indicates broken link in windowsland. */
}
@@ -832,7 +912,7 @@ directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
payload, payload_len,
supports_conditional_consensus,
if_modified_since);
- connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
+ connection_watch_events(TO_CONN(conn), READ_EVENT|WRITE_EVENT);
connection_start_reading(TO_CONN(linked_conn));
}
}
@@ -880,7 +960,7 @@ directory_get_consensus_url(int supports_conditional_consensus)
if (supports_conditional_consensus) {
char *authority_id_list;
- smartlist_t *authority_digets = smartlist_create();
+ smartlist_t *authority_digests = smartlist_create();
SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
trusted_dir_server_t *, ds,
@@ -892,10 +972,10 @@ directory_get_consensus_url(int supports_conditional_consensus)
hex = tor_malloc(2*CONDITIONAL_CONSENSUS_FPR_LEN+1);
base16_encode(hex, 2*CONDITIONAL_CONSENSUS_FPR_LEN+1,
ds->v3_identity_digest, CONDITIONAL_CONSENSUS_FPR_LEN);
- smartlist_add(authority_digets, hex);
+ smartlist_add(authority_digests, hex);
});
- smartlist_sort(authority_digets, _compare_strs);
- authority_id_list = smartlist_join_strings(authority_digets,
+ smartlist_sort(authority_digests, _compare_strs);
+ authority_id_list = smartlist_join_strings(authority_digests,
"+", 0, NULL);
len = strlen(authority_id_list)+64;
@@ -903,8 +983,8 @@ directory_get_consensus_url(int supports_conditional_consensus)
tor_snprintf(url, len, "/tor/status-vote/current/consensus/%s.z",
authority_id_list);
- SMARTLIST_FOREACH(authority_digets, char *, cp, tor_free(cp));
- smartlist_free(authority_digets);
+ SMARTLIST_FOREACH(authority_digests, char *, cp, tor_free(cp));
+ smartlist_free(authority_digests);
tor_free(authority_id_list);
} else {
url = tor_strdup("/tor/status-vote/current/consensus.z");
@@ -913,7 +993,7 @@ directory_get_consensus_url(int supports_conditional_consensus)
}
/** Queue an appropriate HTTP command on conn-\>outbuf. The other args
- * are as in directory_initiate_command.
+ * are as in directory_initiate_command().
*/
static void
directory_send_command(dir_connection_t *conn,
@@ -956,9 +1036,9 @@ directory_send_command(dir_connection_t *conn,
}
/* come up with some proxy lines, if we're using one. */
- if (direct && get_options()->HttpProxy) {
+ if (direct && get_options()->HTTPProxy) {
char *base64_authenticator=NULL;
- const char *authenticator = get_options()->HttpProxyAuthenticator;
+ const char *authenticator = get_options()->HTTPProxyAuthenticator;
tor_snprintf(proxystring, sizeof(proxystring),"http://%s", hoststring);
if (authenticator) {
@@ -1049,31 +1129,10 @@ directory_send_command(dir_connection_t *conn,
httpcommand = "POST";
url = tor_strdup("/tor/post/consensus-signature");
break;
- case DIR_PURPOSE_FETCH_RENDDESC:
- tor_assert(resource);
- tor_assert(!payload);
-
- /* this must be true or we wouldn't be doing the lookup */
- tor_assert(strlen(resource) <= REND_SERVICE_ID_LEN_BASE32);
- /* This breaks the function abstraction. */
- conn->rend_data = tor_malloc_zero(sizeof(rend_data_t));
- strlcpy(conn->rend_data->onion_address, resource,
- sizeof(conn->rend_data->onion_address));
- conn->rend_data->rend_desc_version = 0;
-
- httpcommand = "GET";
- /* Request the most recent versioned descriptor. */
- // (XXXX We were going to switch this to fetch rendezvous1 descriptors,
- // but that never got testing, and it wasn't a good design.)
- len = strlen(resource)+32;
- url = tor_malloc(len);
- tor_snprintf(url, len, "/tor/rendezvous/%s", resource);
- break;
case DIR_PURPOSE_FETCH_RENDDESC_V2:
tor_assert(resource);
tor_assert(strlen(resource) <= REND_DESC_ID_V2_LEN_BASE32);
tor_assert(!payload);
- conn->rend_data->rend_desc_version = 2;
httpcommand = "GET";
len = strlen(resource) + 32;
url = tor_malloc(len);
@@ -1162,7 +1221,7 @@ parse_http_url(const char *headers, char **url)
if (s-tmp >= 3 && !strcmpstart(tmp,"://")) {
tmp = strchr(tmp+3, '/');
if (tmp && tmp < s) {
- log_debug(LD_DIR,"Skipping over 'http[s]://hostname' string");
+ log_debug(LD_DIR,"Skipping over 'http[s]://hostname/' string");
start = tmp;
}
}
@@ -1478,21 +1537,22 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
}
(void) skewed; /* skewed isn't used yet. */
- if (status_code == 503 && body_len < 16) {
- routerstatus_t *rs;
- trusted_dir_server_t *ds;
- log_info(LD_DIR,"Received http status code %d (%s) from server "
- "'%s:%d'. I'll try again soon.",
- status_code, escaped(reason), conn->_base.address,
- conn->_base.port);
- if ((rs = router_get_consensus_status_by_id(conn->identity_digest)))
- rs->last_dir_503_at = now;
- if ((ds = router_get_trusteddirserver_by_digest(conn->identity_digest)))
- ds->fake_status.last_dir_503_at = now;
+ if (status_code == 503) {
+ if (body_len < 16) {
+ routerstatus_t *rs;
+ trusted_dir_server_t *ds;
+ log_info(LD_DIR,"Received http status code %d (%s) from server "
+ "'%s:%d'. I'll try again soon.",
+ status_code, escaped(reason), conn->_base.address,
+ conn->_base.port);
+ if ((rs = router_get_consensus_status_by_id(conn->identity_digest)))
+ rs->last_dir_503_at = now;
+ if ((ds = router_get_trusteddirserver_by_digest(conn->identity_digest)))
+ ds->fake_status.last_dir_503_at = now;
- tor_free(body); tor_free(headers); tor_free(reason);
- return -1;
- } else if (status_code == 503) {
+ tor_free(body); tor_free(headers); tor_free(reason);
+ return -1;
+ }
/* XXXX022 Remove this once every server with bug 539 is obsolete. */
log_info(LD_DIR, "Server at '%s:%d' sent us a 503 response, but included "
"a body anyway. We'll pretend it gave us a 200.",
@@ -1564,7 +1624,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
v2_networkstatus_source_t source;
char *cp;
log_info(LD_DIR,"Received networkstatus objects (size %d) from server "
- "'%s:%d'",(int) body_len, conn->_base.address, conn->_base.port);
+ "'%s:%d'", (int)body_len, conn->_base.address, conn->_base.port);
if (status_code != 200) {
log_warn(LD_DIR,
"Received http status code %d (%s) from server "
@@ -1580,7 +1640,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
source = NS_FROM_DIR_BY_FP;
which = smartlist_create();
dir_split_resource_into_fingerprints(conn->requested_resource+3,
- which, NULL, 0, 0);
+ which, NULL, 0);
} else if (conn->requested_resource &&
!strcmpstart(conn->requested_resource, "all")) {
source = NS_FROM_DIR_ALL;
@@ -1638,8 +1698,8 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
return -1;
}
log_info(LD_DIR,"Received consensus directory (size %d) from server "
- "'%s:%d'",(int) body_len, conn->_base.address, conn->_base.port);
- if ((r=networkstatus_set_current_consensus(body, 0))<0) {
+ "'%s:%d'", (int)body_len, conn->_base.address, conn->_base.port);
+ if ((r=networkstatus_set_current_consensus(body, "ns", 0))<0) {
log_fn(r<-1?LOG_WARN:LOG_INFO, LD_DIR,
"Unable to load consensus directory downloaded from "
"server '%s:%d'. I'll try again soon.",
@@ -1666,9 +1726,11 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
return -1;
}
log_info(LD_DIR,"Received authority certificates (size %d) from server "
- "'%s:%d'",(int) body_len, conn->_base.address, conn->_base.port);
+ "'%s:%d'", (int)body_len, conn->_base.address, conn->_base.port);
if (trusted_dirs_load_certs_from_string(body, 0, 1)<0) {
log_warn(LD_DIR, "Unable to parse fetched certificates");
+ /* if we fetched more than one and only some failed, the successful
+ * ones got flushed to disk so it's safe to call this on them */
connection_dir_download_cert_failed(conn, status_code);
} else {
directory_info_has_arrived(now, 0);
@@ -1679,7 +1741,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
const char *msg;
int st;
log_info(LD_DIR,"Got votes (size %d) from server %s:%d",
- (int) body_len, conn->_base.address, conn->_base.port);
+ (int)body_len, conn->_base.address, conn->_base.port);
if (status_code != 200) {
log_warn(LD_DIR,
"Received http status code %d (%s) from server "
@@ -1699,11 +1761,11 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
if (conn->_base.purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES) {
const char *msg = NULL;
log_info(LD_DIR,"Got detached signatures (size %d) from server %s:%d",
- (int) body_len, conn->_base.address, conn->_base.port);
+ (int)body_len, conn->_base.address, conn->_base.port);
if (status_code != 200) {
log_warn(LD_DIR,
- "Received http status code %d (%s) from server "
- "'%s:%d' while fetching \"/tor/status-vote/consensus-signatures.z\".",
+ "Received http status code %d (%s) from server '%s:%d' while fetching "
+ "\"/tor/status-vote/next/consensus-signatures.z\".",
status_code, escaped(reason), conn->_base.address,
conn->_base.port);
tor_free(body); tor_free(headers); tor_free(reason);
@@ -1731,7 +1793,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
which = smartlist_create();
dir_split_resource_into_fingerprints(conn->requested_resource +
(descriptor_digests ? 2 : 3),
- which, NULL, 0, 0);
+ which, NULL, 0);
n_asked_for = smartlist_len(which);
}
if (status_code != 200) {
@@ -1919,7 +1981,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
/* Success, or at least there's a v2 descriptor already
* present. Notify pending connections about this. */
conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
- rend_client_desc_trynow(conn->rend_data->onion_address, -1);
+ rend_client_desc_trynow(conn->rend_data->onion_address);
}
break;
case 404:
@@ -1966,7 +2028,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
log_info(LD_REND, "Successfully fetched v2 rendezvous "
"descriptor.");
conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
- rend_client_desc_trynow(conn->rend_data->onion_address, -1);
+ rend_client_desc_trynow(conn->rend_data->onion_address);
break;
}
break;
@@ -2009,12 +2071,6 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
"'%s:%d'. Malformed rendezvous descriptor?",
escaped(reason), conn->_base.address, conn->_base.port);
break;
- case 503:
- log_info(LD_REND,"http status 503 (%s) response from dirserver "
- "'%s:%d'. Node is (currently) not acting as v2 hidden "
- "service directory.",
- escaped(reason), conn->_base.address, conn->_base.port);
- break;
default:
log_warn(LD_REND,"http status %d (%s) response unexpected (server "
"'%s:%d').",
@@ -2321,7 +2377,7 @@ directory_dump_request_log(void)
}
#endif
-/** Decide whether a client would accept the consensus we have
+/** Decide whether a client would accept the consensus we have.
*
* Clients can say they only want a consensus if it's signed by more
* than half the authorities in a list. They pass this list in
@@ -2342,31 +2398,32 @@ client_likes_consensus(networkstatus_t *v, const char *want_url)
int need_at_least;
int have = 0;
- dir_split_resource_into_fingerprints(want_url, want_authorities, NULL, 0, 0);
+ dir_split_resource_into_fingerprints(want_url, want_authorities, NULL, 0);
need_at_least = smartlist_len(want_authorities)/2+1;
- SMARTLIST_FOREACH(want_authorities, const char *, d, {
+ SMARTLIST_FOREACH_BEGIN(want_authorities, const char *, d) {
char want_digest[DIGEST_LEN];
size_t want_len = strlen(d)/2;
if (want_len > DIGEST_LEN)
want_len = DIGEST_LEN;
if (base16_decode(want_digest, DIGEST_LEN, d, want_len*2) < 0) {
- log_warn(LD_DIR,"Failed to decode requested authority digest %s.", d);
+ log_fn(LOG_PROTOCOL_WARN, LD_DIR,
+ "Failed to decode requested authority digest %s.", d);
continue;
};
- SMARTLIST_FOREACH(v->voters, networkstatus_voter_info_t *, vi, {
- if (vi->signature &&
+ SMARTLIST_FOREACH_BEGIN(v->voters, networkstatus_voter_info_t *, vi) {
+ if (smartlist_len(vi->sigs) &&
!memcmp(vi->identity_digest, want_digest, want_len)) {
have++;
break;
};
- });
+ } SMARTLIST_FOREACH_END(vi);
/* early exit, if we already have enough */
if (have >= need_at_least)
break;
- });
+ } SMARTLIST_FOREACH_END(d);
SMARTLIST_FOREACH(want_authorities, char *, d, tor_free(d));
smartlist_free(want_authorities);
@@ -2513,9 +2570,12 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
/* v2 or v3 network status fetch. */
smartlist_t *dir_fps = smartlist_create();
int is_v3 = !strcmpstart(url, "/tor/status-vote");
+ geoip_client_action_t act =
+ is_v3 ? GEOIP_CLIENT_NETWORKSTATUS : GEOIP_CLIENT_NETWORKSTATUS_V2;
const char *request_type = NULL;
const char *key = url + strlen("/tor/status/");
long lifetime = NETWORKSTATUS_CACHE_LIFETIME;
+
if (!is_v3) {
dirserv_get_networkstatus_v2_fingerprints(dir_fps, key);
if (!strcmpstart(key, "fp/"))
@@ -2530,18 +2590,44 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
} else {
networkstatus_t *v = networkstatus_get_latest_consensus();
time_t now = time(NULL);
+ const char *want_fps = NULL;
+ char *flavor = NULL;
#define CONSENSUS_URL_PREFIX "/tor/status-vote/current/consensus/"
- if (v &&
- !strcmpstart(url, CONSENSUS_URL_PREFIX) &&
- !client_likes_consensus(v, url + strlen(CONSENSUS_URL_PREFIX))) {
+ #define CONSENSUS_FLAVORED_PREFIX "/tor/status-vote/current/consensus-"
+ /* figure out the flavor if any, and who we wanted to sign the thing */
+ if (!strcmpstart(url, CONSENSUS_FLAVORED_PREFIX)) {
+ const char *f, *cp;
+ f = url + strlen(CONSENSUS_FLAVORED_PREFIX);
+ cp = strchr(f, '/');
+ if (cp) {
+ want_fps = cp+1;
+ flavor = tor_strndup(f, cp-f);
+ } else {
+ flavor = tor_strdup(f);
+ }
+ } else {
+ if (!strcmpstart(url, CONSENSUS_URL_PREFIX))
+ want_fps = url+strlen(CONSENSUS_URL_PREFIX);
+ }
+
+ /* XXXX MICRODESC NM NM should check document of correct flavor */
+ if (v && want_fps &&
+ !client_likes_consensus(v, want_fps)) {
write_http_status_line(conn, 404, "Consensus not signed by sufficient "
"number of requested authorities");
smartlist_free(dir_fps);
+ geoip_note_ns_response(act, GEOIP_REJECT_NOT_ENOUGH_SIGS);
+ tor_free(flavor);
goto done;
}
- smartlist_add(dir_fps, tor_memdup("\0\0\0\0\0\0\0\0\0\0"
- "\0\0\0\0\0\0\0\0\0\0", 20));
+ {
+ char *fp = tor_malloc_zero(DIGEST_LEN);
+ if (flavor)
+ strlcpy(fp, flavor, DIGEST_LEN);
+ tor_free(flavor);
+ smartlist_add(dir_fps, fp);
+ }
request_type = compressed?"v3.z":"v3";
lifetime = (v && v->fresh_until > now) ? v->fresh_until - now : 0;
}
@@ -2549,6 +2635,7 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
if (!smartlist_len(dir_fps)) { /* we failed to create/cache cp */
write_http_status_line(conn, 503, "Network status object unavailable");
smartlist_free(dir_fps);
+ geoip_note_ns_response(act, GEOIP_REJECT_UNAVAILABLE);
goto done;
}
@@ -2556,11 +2643,13 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
write_http_status_line(conn, 404, "Not found");
SMARTLIST_FOREACH(dir_fps, char *, cp, tor_free(cp));
smartlist_free(dir_fps);
+ geoip_note_ns_response(act, GEOIP_REJECT_NOT_FOUND);
goto done;
} else if (!smartlist_len(dir_fps)) {
write_http_status_line(conn, 304, "Not modified");
SMARTLIST_FOREACH(dir_fps, char *, cp, tor_free(cp));
smartlist_free(dir_fps);
+ geoip_note_ns_response(act, GEOIP_REJECT_NOT_MODIFIED);
goto done;
}
@@ -2572,18 +2661,25 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
write_http_status_line(conn, 503, "Directory busy, try again later");
SMARTLIST_FOREACH(dir_fps, char *, fp, tor_free(fp));
smartlist_free(dir_fps);
+ geoip_note_ns_response(act, GEOIP_REJECT_BUSY);
goto done;
}
-#ifdef ENABLE_GEOIP_STATS
{
- geoip_client_action_t act =
- is_v3 ? GEOIP_CLIENT_NETWORKSTATUS : GEOIP_CLIENT_NETWORKSTATUS_V2;
struct in_addr in;
- if (tor_inet_aton((TO_CONN(conn))->address, &in))
+ if (tor_inet_aton((TO_CONN(conn))->address, &in)) {
geoip_note_client_seen(act, ntohl(in.s_addr), time(NULL));
+ geoip_note_ns_response(act, GEOIP_SUCCESS);
+ /* Note that a request for a network status has started, so that we
+ * can measure the download time later on. */
+ if (TO_CONN(conn)->dirreq_id)
+ geoip_start_dirreq(TO_CONN(conn)->dirreq_id, dlen, act,
+ DIRREQ_TUNNELED);
+ else
+ geoip_start_dirreq(TO_CONN(conn)->global_identifier, dlen, act,
+ DIRREQ_DIRECT);
+ }
}
-#endif
// note_request(request_type,dlen);
(void) request_type;
@@ -2619,7 +2715,7 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
const char *item;
tor_assert(!current); /* we handle current consensus specially above,
* since it wants to be spooled. */
- if ((item = dirvote_get_pending_consensus()))
+ if ((item = dirvote_get_pending_consensus(FLAV_NS)))
smartlist_add(items, (char*)item);
} else if (!current && !strcmp(url, "consensus-signatures")) {
/* XXXX the spec says that we should implement
@@ -2645,7 +2741,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
flags = DGV_BY_ID |
(current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
}
- dir_split_resource_into_fingerprints(url, fps, NULL, 1, 1);
+ dir_split_resource_into_fingerprints(url, fps, NULL,
+ DSR_HEX|DSR_SORT_UNIQ);
SMARTLIST_FOREACH(fps, char *, fp, {
if ((d = dirvote_get_vote(fp, flags)))
smartlist_add(dir_items, (cached_dir_t*)d);
@@ -2698,6 +2795,41 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
goto done;
}
+ if (!strcmpstart(url, "/tor/micro/d/")) {
+ smartlist_t *fps = smartlist_create();
+
+ dir_split_resource_into_fingerprints(url+strlen("/tor/micro/d/"),
+ fps, NULL,
+ DSR_DIGEST256|DSR_BASE64|DSR_SORT_UNIQ);
+
+ if (!dirserv_have_any_microdesc(fps)) {
+ write_http_status_line(conn, 404, "Not found");
+ SMARTLIST_FOREACH(fps, char *, fp, tor_free(fp));
+ smartlist_free(fps);
+ goto done;
+ }
+ dlen = dirserv_estimate_microdesc_size(fps, compressed);
+ if (global_write_bucket_low(TO_CONN(conn), dlen, 2)) {
+ log_info(LD_DIRSERV,
+ "Client asked for server descriptors, but we've been "
+ "writing too many bytes lately. Sending 503 Dir busy.");
+ write_http_status_line(conn, 503, "Directory busy, try again later");
+ SMARTLIST_FOREACH(fps, char *, fp, tor_free(fp));
+ smartlist_free(fps);
+ goto done;
+ }
+
+ write_http_response_header(conn, -1, compressed, MICRODESC_CACHE_LIFETIME);
+ conn->dir_spool_src = DIR_SPOOL_MICRODESC;
+ conn->fingerprint_stack = fps;
+
+ if (compressed)
+ conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD);
+
+ connection_dirserv_flushed_some(conn);
+ goto done;
+ }
+
if (!strcmpstart(url,"/tor/server/") ||
(!options->BridgeAuthoritativeDir &&
!options->BridgeRelay && !strcmpstart(url,"/tor/extra/"))) {
@@ -2779,7 +2911,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
} else if (!strcmpstart(url, "/tor/keys/fp/")) {
smartlist_t *fps = smartlist_create();
dir_split_resource_into_fingerprints(url+strlen("/tor/keys/fp/"),
- fps, NULL, 1, 1);
+ fps, NULL,
+ DSR_HEX|DSR_SORT_UNIQ);
SMARTLIST_FOREACH(fps, char *, d, {
authority_cert_t *c = authority_cert_get_newest_by_id(d);
if (c) smartlist_add(certs, c);
@@ -2789,7 +2922,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
} else if (!strcmpstart(url, "/tor/keys/sk/")) {
smartlist_t *fps = smartlist_create();
dir_split_resource_into_fingerprints(url+strlen("/tor/keys/sk/"),
- fps, NULL, 1, 1);
+ fps, NULL,
+ DSR_HEX|DSR_SORT_UNIQ);
SMARTLIST_FOREACH(fps, char *, d, {
authority_cert_t *c = authority_cert_get_by_sk_digest(d);
if (c) smartlist_add(certs, c);
@@ -2891,18 +3025,9 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
note_request("/tor/rendezvous?/", desc_len);
/* need to send descp separately, because it may include NULs */
connection_write_to_buf(descp, desc_len, TO_CONN(conn));
- /* report successful fetch to statistic */
- if (options->HSAuthorityRecordStats) {
- hs_usage_note_fetch_total(query, time(NULL));
- hs_usage_note_fetch_successful(query, time(NULL));
- }
break;
case 0: /* well-formed but not present */
write_http_status_line(conn, 404, "Not found");
- /* report (unsuccessful) fetch to statistic */
- if (options->HSAuthorityRecordStats) {
- hs_usage_note_fetch_total(query, time(NULL));
- }
break;
case -1: /* not well-formed */
write_http_status_line(conn, 400, "Bad request");
@@ -3179,8 +3304,8 @@ directory_handle_command(dir_connection_t *conn)
&body, &body_len, MAX_DIR_UL_SIZE, 0)) {
case -1: /* overflow */
log_warn(LD_DIRSERV,
- "Invalid input from address '%s'. Closing.",
- conn->_base.address);
+ "Request too large from address '%s' to DirPort. Closing.",
+ safe_str(conn->_base.address));
return -1;
case 0:
log_debug(LD_DIRSERV,"command not all here yet.");
@@ -3216,6 +3341,16 @@ connection_dir_finished_flushing(dir_connection_t *conn)
tor_assert(conn);
tor_assert(conn->_base.type == CONN_TYPE_DIR);
+ /* Note that we have finished writing the directory response. For direct
+ * connections this means we're done, for tunneled connections its only
+ * an intermediate step. */
+ if (TO_CONN(conn)->dirreq_id)
+ geoip_change_dirreq_state(TO_CONN(conn)->dirreq_id, DIRREQ_TUNNELED,
+ DIRREQ_FLUSHING_DIR_CONN_FINISHED);
+ else
+ geoip_change_dirreq_state(TO_CONN(conn)->global_identifier,
+ DIRREQ_DIRECT,
+ DIRREQ_FLUSHING_DIR_CONN_FINISHED);
switch (conn->_base.state) {
case DIR_CONN_STATE_CLIENT_SENDING:
log_debug(LD_DIR,"client finished sending command.");
@@ -3398,6 +3533,14 @@ download_status_reset(download_status_t *dls)
dls->next_attempt_at = time(NULL) + schedule[0];
}
+/** Return the number of failures on <b>dls</b> since the last success (if
+ * any). */
+int
+download_status_get_n_failures(const download_status_t *dls)
+{
+ return dls->n_download_failures;
+}
+
/** Called when one or more routerdesc (or extrainfo, if <b>was_extrainfo</b>)
* fetches have failed (with uppercase fingerprints listed in <b>failed</b>,
* either as descriptor digests or as identity digests based on
@@ -3413,16 +3556,8 @@ dir_routerdesc_download_failed(smartlist_t *failed, int status_code,
int server = directory_fetches_from_authorities(get_options());
if (!was_descriptor_digests) {
if (router_purpose == ROUTER_PURPOSE_BRIDGE) {
- tor_assert(!was_extrainfo); /* not supported yet */
- SMARTLIST_FOREACH(failed, const char *, cp,
- {
- if (base16_decode(digest, DIGEST_LEN, cp, strlen(cp))<0) {
- log_warn(LD_BUG, "Malformed fingerprint in list: %s",
- escaped(cp));
- continue;
- }
- retry_bridge_descriptor_fetch_directly(digest);
- });
+ tor_assert(!was_extrainfo);
+ connection_dir_retry_bridges(failed);
}
return; /* FFFF should implement for other-than-router-purpose someday */
}
@@ -3515,19 +3650,37 @@ dir_split_resource_into_fingerprint_pairs(const char *res,
/** Given a directory <b>resource</b> request, containing zero
* or more strings separated by plus signs, followed optionally by ".z", store
* the strings, in order, into <b>fp_out</b>. If <b>compressed_out</b> is
- * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0. If
- * decode_hex is true, then delete all elements that aren't hex digests, and
- * decode the rest. If sort_uniq is true, then sort the list and remove
- * all duplicates.
+ * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0.
+ *
+ * If (flags & DSR_HEX), then delete all elements that aren't hex digests, and
+ * decode the rest. If (flags & DSR_BASE64), then use "-" rather than "+" as
+ * a separator, delete all the elements that aren't base64-encoded digests,
+ * and decode the rest. If (flags & DSR_DIGEST256), these digests should be
+ * 256 bits long; else they should be 160.
+ *
+ * If (flags & DSR_SORT_UNIQ), then sort the list and remove all duplicates.
*/
int
dir_split_resource_into_fingerprints(const char *resource,
smartlist_t *fp_out, int *compressed_out,
- int decode_hex, int sort_uniq)
+ int flags)
{
+ const int decode_hex = flags & DSR_HEX;
+ const int decode_base64 = flags & DSR_BASE64;
+ const int digests_are_256 = flags & DSR_DIGEST256;
+ const int sort_uniq = flags & DSR_SORT_UNIQ;
+
+ const int digest_len = digests_are_256 ? DIGEST256_LEN : DIGEST_LEN;
+ const int hex_digest_len = digests_are_256 ?
+ HEX_DIGEST256_LEN : HEX_DIGEST_LEN;
+ const int base64_digest_len = digests_are_256 ?
+ BASE64_DIGEST256_LEN : BASE64_DIGEST_LEN;
smartlist_t *fp_tmp = smartlist_create();
+
+ tor_assert(!(decode_hex && decode_base64));
tor_assert(fp_out);
- smartlist_split_string(fp_tmp, resource, "+", 0, 0);
+
+ smartlist_split_string(fp_tmp, resource, decode_base64?"-":"+", 0, 0);
if (compressed_out)
*compressed_out = 0;
if (smartlist_len(fp_tmp)) {
@@ -3539,22 +3692,25 @@ dir_split_resource_into_fingerprints(const char *resource,
*compressed_out = 1;
}
}
- if (decode_hex) {
+ if (decode_hex || decode_base64) {
+ const size_t encoded_len = decode_hex ? hex_digest_len : base64_digest_len;
int i;
char *cp, *d = NULL;
for (i = 0; i < smartlist_len(fp_tmp); ++i) {
cp = smartlist_get(fp_tmp, i);
- if (strlen(cp) != HEX_DIGEST_LEN) {
+ if (strlen(cp) != encoded_len) {
log_info(LD_DIR,
"Skipping digest %s with non-standard length.", escaped(cp));
smartlist_del_keeporder(fp_tmp, i--);
goto again;
}
- d = tor_malloc_zero(DIGEST_LEN);
- if (base16_decode(d, DIGEST_LEN, cp, HEX_DIGEST_LEN)<0) {
- log_info(LD_DIR, "Skipping non-decodable digest %s", escaped(cp));
- smartlist_del_keeporder(fp_tmp, i--);
- goto again;
+ d = tor_malloc_zero(digest_len);
+ if (decode_hex ?
+ (base16_decode(d, digest_len, cp, hex_digest_len)<0) :
+ (base64_decode(d, digest_len, cp, base64_digest_len)<0)) {
+ log_info(LD_DIR, "Skipping non-decodable digest %s", escaped(cp));
+ smartlist_del_keeporder(fp_tmp, i--);
+ goto again;
}
smartlist_set(fp_tmp, i, d);
d = NULL;
@@ -3564,26 +3720,18 @@ dir_split_resource_into_fingerprints(const char *resource,
}
}
if (sort_uniq) {
- smartlist_t *fp_tmp2 = smartlist_create();
- int i;
- if (decode_hex)
- smartlist_sort_digests(fp_tmp);
- else
+ if (decode_hex || decode_base64) {
+ if (digests_are_256) {
+ smartlist_sort_digests256(fp_tmp);
+ smartlist_uniq_digests256(fp_tmp);
+ } else {
+ smartlist_sort_digests(fp_tmp);
+ smartlist_uniq_digests(fp_tmp);
+ }
+ } else {
smartlist_sort_strings(fp_tmp);
- if (smartlist_len(fp_tmp))
- smartlist_add(fp_tmp2, smartlist_get(fp_tmp, 0));
- for (i = 1; i < smartlist_len(fp_tmp); ++i) {
- char *cp = smartlist_get(fp_tmp, i);
- char *last = smartlist_get(fp_tmp2, smartlist_len(fp_tmp2)-1);
-
- if ((decode_hex && memcmp(cp, last, DIGEST_LEN))
- || (!decode_hex && strcasecmp(cp, last)))
- smartlist_add(fp_tmp2, cp);
- else
- tor_free(cp);
+ smartlist_uniq_strings(fp_tmp);
}
- smartlist_free(fp_tmp);
- fp_tmp = fp_tmp2;
}
smartlist_add_all(fp_out, fp_tmp);
smartlist_free(fp_tmp);
diff --git a/src/or/directory.h b/src/or/directory.h
new file mode 100644
index 0000000000..6fd2c0beff
--- /dev/null
+++ b/src/or/directory.h
@@ -0,0 +1,110 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file directory.h
+ * \brief Header file for directory.c.
+ **/
+
+#ifndef _TOR_DIRECTORY_H
+#define _TOR_DIRECTORY_H
+
+int directories_have_accepted_server_descriptor(void);
+char *authority_type_to_string(authority_type_t auth);
+void directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
+ authority_type_t type, const char *payload,
+ size_t payload_len, size_t extrainfo_len);
+void directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
+ const char *resource,
+ int pds_flags);
+void directory_get_from_all_authorities(uint8_t dir_purpose,
+ uint8_t router_purpose,
+ const char *resource);
+void directory_initiate_command_routerstatus(routerstatus_t *status,
+ uint8_t dir_purpose,
+ uint8_t router_purpose,
+ int anonymized_connection,
+ const char *resource,
+ const char *payload,
+ size_t payload_len,
+ time_t if_modified_since);
+void directory_initiate_command_routerstatus_rend(routerstatus_t *status,
+ uint8_t dir_purpose,
+ uint8_t router_purpose,
+ int anonymized_connection,
+ const char *resource,
+ const char *payload,
+ size_t payload_len,
+ time_t if_modified_since,
+ const rend_data_t *rend_query);
+
+int parse_http_response(const char *headers, int *code, time_t *date,
+ compress_method_t *compression, char **response);
+
+int connection_dir_is_encrypted(dir_connection_t *conn);
+int connection_dir_reached_eof(dir_connection_t *conn);
+int connection_dir_process_inbuf(dir_connection_t *conn);
+int connection_dir_finished_flushing(dir_connection_t *conn);
+int connection_dir_finished_connecting(dir_connection_t *conn);
+void connection_dir_request_failed(dir_connection_t *conn);
+void directory_initiate_command(const char *address, const tor_addr_t *addr,
+ uint16_t or_port, uint16_t dir_port,
+ int supports_conditional_consensus,
+ int supports_begindir, const char *digest,
+ uint8_t dir_purpose, uint8_t router_purpose,
+ int anonymized_connection,
+ const char *resource,
+ const char *payload, size_t payload_len,
+ time_t if_modified_since);
+
+#define DSR_HEX (1<<0)
+#define DSR_BASE64 (1<<1)
+#define DSR_DIGEST256 (1<<2)
+#define DSR_SORT_UNIQ (1<<3)
+int dir_split_resource_into_fingerprints(const char *resource,
+ smartlist_t *fp_out, int *compressed_out,
+ int flags);
+
+int dir_split_resource_into_fingerprint_pairs(const char *res,
+ smartlist_t *pairs_out);
+char *directory_dump_request_log(void);
+void note_request(const char *key, size_t bytes);
+int router_supports_extrainfo(const char *identity_digest, int is_authority);
+
+time_t download_status_increment_failure(download_status_t *dls,
+ int status_code, const char *item,
+ int server, time_t now);
+/** Increment the failure count of the download_status_t <b>dls</b>, with
+ * the optional status code <b>sc</b>. */
+#define download_status_failed(dls, sc) \
+ download_status_increment_failure((dls), (sc), NULL, \
+ get_options()->DirPort, time(NULL))
+
+void download_status_reset(download_status_t *dls);
+static int download_status_is_ready(download_status_t *dls, time_t now,
+ int max_failures);
+/** Return true iff, as of <b>now</b>, the resource tracked by <b>dls</b> is
+ * ready to get its download reattempted. */
+static INLINE int
+download_status_is_ready(download_status_t *dls, time_t now,
+ int max_failures)
+{
+ return (dls->n_download_failures <= max_failures
+ && dls->next_attempt_at <= now);
+}
+
+static void download_status_mark_impossible(download_status_t *dl);
+/** Mark <b>dl</b> as never downloadable. */
+static INLINE void
+download_status_mark_impossible(download_status_t *dl)
+{
+ dl->n_download_failures = IMPOSSIBLE_TO_DOWNLOAD;
+}
+
+int download_status_get_n_failures(const download_status_t *dls);
+
+#endif
+
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 851fc5cbdd..841c86624b 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -5,6 +5,22 @@
#define DIRSERV_PRIVATE
#include "or.h"
+#include "buffers.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_or.h"
+#include "control.h"
+#include "directory.h"
+#include "dirserv.h"
+#include "dirvote.h"
+#include "hibernate.h"
+#include "microdesc.h"
+#include "networkstatus.h"
+#include "policies.h"
+#include "rephist.h"
+#include "router.h"
+#include "routerlist.h"
+#include "routerparse.h"
/**
* \file dirserv.c
@@ -41,7 +57,7 @@ static time_t the_v2_networkstatus_is_dirty = 1;
static cached_dir_t *the_directory = NULL;
/** For authoritative directories: the current (v1) network status. */
-static cached_dir_t the_runningrouters = { NULL, NULL, 0, 0, 0, -1 };
+static cached_dir_t the_runningrouters;
static void directory_remove_invalid(void);
static cached_dir_t *dirserv_regenerate_directory(void);
@@ -63,13 +79,16 @@ static signed_descriptor_t *get_signed_descriptor_by_fp(const char *fp,
time_t publish_cutoff);
static int dirserv_add_extrainfo(extrainfo_t *ei, const char **msg);
+/************** Measured Bandwidth parsing code ******/
+#define MAX_MEASUREMENT_AGE (3*24*60*60) /* 3 days */
+
/************** Fingerprint handling code ************/
#define FP_NAMED 1 /**< Listed in fingerprint file. */
#define FP_INVALID 2 /**< Believed invalid. */
#define FP_REJECT 4 /**< We will not publish this router. */
#define FP_BADDIR 8 /**< We'll tell clients to avoid using this as a dir. */
-#define FP_BADEXIT 16 /**< We'll tell clients not to use this as an exit. */
+#define FP_BADEXIT 16 /**< We'll tell clients not to use this as an exit. */
#define FP_UNNAMED 32 /**< Another router has this name in fingerprint file. */
/** Encapsulate a nickname and an FP_* status; target of status_by_digest
@@ -99,7 +118,7 @@ authdir_config_new(void)
return list;
}
-/** Add the fingerprint <b>fp</b> for the nickname <b>nickname</b> to
+/** Add the fingerprint <b>fp</b> for <b>nickname</b> to
* the smartlist of fingerprint_entry_t's <b>list</b>. Return 0 if it's
* new, or 1 if we replaced the old value.
*/
@@ -181,8 +200,7 @@ dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk)
* file. The file format is line-based, with each non-blank holding one
* nickname, some space, and a fingerprint for that nickname. On success,
* replace the current fingerprint list with the new list and return 0. On
- * failure, leave the current fingerprint list untouched, and
- * return -1. */
+ * failure, leave the current fingerprint list untouched, and return -1. */
int
dirserv_load_fingerprint_file(void)
{
@@ -368,13 +386,19 @@ dirserv_get_status_impl(const char *id_digest, const char *nickname,
strmap_size(fingerprint_list->fp_by_name),
digestmap_size(fingerprint_list->status_by_digest));
- /* 0.1.1.17-rc was the first version that claimed to be stable, doesn't
- * crash and drop circuits all the time, and is even vaguely compatible with
- * the current network */
- if (platform && !tor_version_as_new_as(platform,"0.1.1.17-rc")) {
+ /* Tor 0.2.0.26-rc is the oldest version that currently caches the right
+ * directory information. Once more of them die off, we should raise this
+ * minimum. */
+ if (platform && !tor_version_as_new_as(platform,"0.2.0.26-rc")) {
if (msg)
*msg = "Tor version is far too old to work.";
return FP_REJECT;
+ } else if (platform && tor_version_as_new_as(platform,"0.2.1.3-alpha")
+ && !tor_version_as_new_as(platform, "0.2.1.19")) {
+ /* These versions mishandled RELAY_EARLY cells on rend circuits. */
+ if (msg)
+ *msg = "Tor version is too buggy to work.";
+ return FP_REJECT;
}
result = dirserv_get_name_status(id_digest, nickname);
@@ -520,7 +544,7 @@ authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
/* Okay. Now check whether the fingerprint is recognized. */
uint32_t status = dirserv_router_get_status(ri, msg);
time_t now;
- int severity = complain ? LOG_NOTICE : LOG_INFO;
+ int severity = (complain && ri->contact_info) ? LOG_NOTICE : LOG_INFO;
tor_assert(msg);
if (status & FP_REJECT)
return -1; /* msg is already set. */
@@ -712,6 +736,10 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg, const char *source)
desc = tor_strndup(ri->cache_info.signed_descriptor_body, desclen);
nickname = tor_strdup(ri->nickname);
+ /* Tell if we're about to need to launch a test if we add this. */
+ ri->needs_retest_if_added =
+ dirserv_should_launch_reachability_test(ri, ri_old);
+
r = router_add_to_routerlist(ri, msg, 0, 0);
if (!WRA_WAS_ADDED(r)) {
/* unless the routerinfo was fine, just out-of-date */
@@ -726,7 +754,7 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg, const char *source)
changed = smartlist_create();
smartlist_add(changed, ri);
- control_event_descriptors_changed(changed);
+ routerlist_descriptors_added(changed, 0);
smartlist_free(changed);
if (!*msg) {
*msg = ri->is_valid ? "Descriptor for valid server accepted" :
@@ -835,46 +863,6 @@ directory_remove_invalid(void)
routerlist_assert_ok(rl);
}
-/** Write a list of unregistered descriptors into a newly allocated
- * string and return it. Used by dirserv operators to keep track of
- * fast nodes that haven't registered.
- */
-int
-getinfo_helper_dirserv_unregistered(control_connection_t *control_conn,
- const char *question, char **answer_out)
-{
- smartlist_t *answerlist;
- char buf[1024];
- char *answer;
- int min_bw = atoi(question);
- routerlist_t *rl = router_get_routerlist();
-
- (void) control_conn;
-
- if (strcmpstart(question, "unregistered-servers-"))
- return 0;
- question += strlen("unregistered-servers-");
-
- answerlist = smartlist_create();
- SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ent, {
- uint32_t r = dirserv_router_get_status(ent, NULL);
- if (router_get_advertised_bandwidth(ent) >= (size_t)min_bw &&
- !(r & FP_NAMED)) {
- /* then log this one */
- tor_snprintf(buf, sizeof(buf),
- "%s: BW %d on '%s'.",
- ent->nickname, router_get_advertised_bandwidth(ent),
- ent->platform ? ent->platform : "");
- smartlist_add(answerlist, tor_strdup(buf));
- }
- });
- answer = smartlist_join_strings(answerlist, "\r\n", 0, NULL);
- SMARTLIST_FOREACH(answerlist, char *, cp, tor_free(cp));
- smartlist_free(answerlist);
- *answer_out = answer;
- return 0;
-}
-
/** Mark the directory as <b>dirty</b> -- when we're next asked for a
* directory, we will rebuild it instead of reusing the most recently
* generated one.
@@ -933,26 +921,54 @@ list_single_server_status(routerinfo_t *desc, int is_live)
return tor_strdup(buf);
}
+static INLINE int
+running_long_enough_to_decide_unreachable(void)
+{
+ return time_of_process_start
+ + get_options()->TestingAuthDirTimeToLearnReachability < approx_time();
+}
+
/** Each server needs to have passed a reachability test no more
* than this number of seconds ago, or he is listed as down in
* the directory. */
#define REACHABLE_TIMEOUT (45*60)
+/** If we tested a router and found it reachable _at least this long_ after it
+ * declared itself hibernating, it is probably done hibernating and we just
+ * missed a descriptor from it. */
+#define HIBERNATION_PUBLICATION_SKEW (60*60)
+
/** Treat a router as alive if
* - It's me, and I'm not hibernating.
* or - We've found it reachable recently. */
void
dirserv_set_router_is_running(routerinfo_t *router, time_t now)
{
+ /*XXXX022 This function is a mess. Separate out the part that calculates
+ whether it's reachable and the part that tells rephist that the router was
+ unreachable.
+ */
int answer;
- if (router_is_me(router) && !we_are_hibernating())
+ if (router_is_me(router)) {
+ /* We always know if we are down ourselves. */
+ answer = ! we_are_hibernating();
+ } else if (router->is_hibernating &&
+ (router->cache_info.published_on +
+ HIBERNATION_PUBLICATION_SKEW) > router->last_reachable) {
+ /* A hibernating router is down unless we (somehow) had contact with it
+ * since it declared itself to be hibernating. */
+ answer = 0;
+ } else if (get_options()->AssumeReachable) {
+ /* If AssumeReachable, everybody is up unless they say they are down! */
answer = 1;
- else
- answer = get_options()->AssumeReachable ||
- now < router->last_reachable + REACHABLE_TIMEOUT;
+ } else {
+ /* Otherwise, a router counts as up if we found it reachable in the last
+ REACHABLE_TIMEOUT seconds. */
+ answer = (now < router->last_reachable + REACHABLE_TIMEOUT);
+ }
- if (!answer) {
+ if (!answer && running_long_enough_to_decide_unreachable()) {
/* not considered reachable. tell rephist. */
rep_hist_note_router_unreachable(router->cache_info.identity_digest, now);
}
@@ -965,7 +981,6 @@ dirserv_set_router_is_running(routerinfo_t *router, time_t now)
* *<b>router_status_out</b>. Return 0 on success, -1 on failure.
*
* If for_controller is true, include the routers with very old descriptors.
- * If for_controller is &gt;1, use the verbose nickname format.
*/
int
list_server_status_v1(smartlist_t *routers, char **router_status_out,
@@ -985,23 +1000,22 @@ list_server_status_v1(smartlist_t *routers, char **router_status_out,
rs_entries = smartlist_create();
- SMARTLIST_FOREACH(routers, routerinfo_t *, ri,
- {
+ SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
if (authdir) {
/* Update router status in routerinfo_t. */
dirserv_set_router_is_running(ri, now);
}
- if (for_controller == 1 || ri->cache_info.published_on >= cutoff)
- smartlist_add(rs_entries, list_single_server_status(ri, ri->is_running));
- else if (for_controller > 2) {
+ if (for_controller) {
char name_buf[MAX_VERBOSE_NICKNAME_LEN+2];
char *cp = name_buf;
if (!ri->is_running)
*cp++ = '!';
router_get_verbose_nickname(cp, ri);
smartlist_add(rs_entries, tor_strdup(name_buf));
+ } else if (ri->cache_info.published_on >= cutoff) {
+ smartlist_add(rs_entries, list_single_server_status(ri, ri->is_running));
}
- });
+ } SMARTLIST_FOREACH_END(ri);
*router_status_out = smartlist_join_strings(rs_entries, " ", 0, NULL);
@@ -1119,7 +1133,8 @@ dirserv_dump_directory_to_string(char **dir_out,
return -1;
}
note_crypto_pk_op(SIGN_DIR);
- if (router_append_dirobj_signature(buf,buf_len,digest,private_key)<0) {
+ if (router_append_dirobj_signature(buf,buf_len,digest,DIGEST_LEN,
+ private_key)<0) {
tor_free(buf);
return -1;
}
@@ -1144,18 +1159,21 @@ directory_fetches_from_authorities(or_options_t *options)
{
routerinfo_t *me;
uint32_t addr;
+ int refuseunknown;
if (options->FetchDirInfoEarly)
return 1;
if (options->BridgeRelay == 1)
return 0;
if (server_mode(options) && router_pick_published_address(options, &addr)<0)
return 1; /* we don't know our IP address; ask an authority. */
- if (options->DirPort == 0)
+ refuseunknown = ! router_my_exit_policy_is_reject_star() &&
+ should_refuse_unknown_exits(options);
+ if (options->DirPort == 0 && !refuseunknown)
return 0;
if (!server_mode(options) || !advertised_server_mode())
return 0;
me = router_get_my_routerinfo();
- if (!me || !me->dir_port)
+ if (!me || (!me->dir_port && !refuseunknown))
return 0; /* if dirport not advertised, return 0 too */
return 1;
}
@@ -1195,7 +1213,14 @@ directory_caches_v2_dir_info(or_options_t *options)
int
directory_caches_dir_info(or_options_t *options)
{
- return options->BridgeRelay != 0 || options->DirPort != 0;
+ if (options->BridgeRelay || options->DirPort)
+ return 1;
+ if (!server_mode(options) || !advertised_server_mode())
+ return 0;
+ /* We need an up-to-date view of network info if we're going to try to
+ * block exit attempts from unknown relays. */
+ return ! router_my_exit_policy_is_reject_star() &&
+ should_refuse_unknown_exits(options);
}
/** Return 1 if we want to allow remote people to ask us directory
@@ -1238,14 +1263,14 @@ directory_too_idle_to_fetch_descriptors(or_options_t *options, time_t now)
static cached_dir_t *cached_directory = NULL;
/** The v1 runningrouters document we'll serve (as a cache or as an authority)
* if requested. */
-static cached_dir_t cached_runningrouters = { NULL, NULL, 0, 0, 0, -1 };
+static cached_dir_t cached_runningrouters;
/** Used for other dirservers' v2 network statuses. Map from hexdigest to
* cached_dir_t. */
static digestmap_t *cached_v2_networkstatus = NULL;
-/** The v3 consensus network status that we're currently serving. */
-static cached_dir_t *cached_v3_networkstatus = NULL;
+/** Map from flavor name to the v3 consensuses that we're currently serving. */
+static strmap_t *cached_consensuses = NULL;
/** Possibly replace the contents of <b>d</b> with the value of
* <b>directory</b> published on <b>when</b>, unless <b>when</b> is older than
@@ -1319,7 +1344,11 @@ clear_cached_dir(cached_dir_t *d)
static void
_free_cached_dir(void *_d)
{
- cached_dir_t *d = (cached_dir_t *)_d;
+ cached_dir_t *d;
+ if (!_d)
+ return;
+
+ d = (cached_dir_t *)_d;
cached_dir_decref(d);
}
@@ -1413,17 +1442,26 @@ dirserv_set_cached_networkstatus_v2(const char *networkstatus,
}
}
-/** Replace the v3 consensus networkstatus that we're serving with
- * <b>networkstatus</b>, published at <b>published</b>. No validation is
- * performed. */
+/** Replace the v3 consensus networkstatus of type <b>flavor_name</b> that
+ * we're serving with <b>networkstatus</b>, published at <b>published</b>. No
+ * validation is performed. */
void
-dirserv_set_cached_networkstatus_v3(const char *networkstatus,
- time_t published)
+dirserv_set_cached_consensus_networkstatus(const char *networkstatus,
+ const char *flavor_name,
+ const digests_t *digests,
+ time_t published)
{
- if (cached_v3_networkstatus)
- cached_dir_decref(cached_v3_networkstatus);
- cached_v3_networkstatus = new_cached_dir(
- tor_strdup(networkstatus), published);
+ cached_dir_t *new_networkstatus;
+ cached_dir_t *old_networkstatus;
+ if (!cached_consensuses)
+ cached_consensuses = strmap_new();
+
+ new_networkstatus = new_cached_dir(tor_strdup(networkstatus), published);
+ memcpy(&new_networkstatus->digests, digests, sizeof(digests_t));
+ old_networkstatus = strmap_set(cached_consensuses, flavor_name,
+ new_networkstatus);
+ if (old_networkstatus)
+ cached_dir_decref(old_networkstatus);
}
/** Remove any v2 networkstatus from the directory cache that was published
@@ -1520,7 +1558,8 @@ dirserv_regenerate_directory(void)
{
char *new_directory=NULL;
- if (dirserv_dump_directory_to_string(&new_directory, get_identity_key())) {
+ if (dirserv_dump_directory_to_string(&new_directory,
+ get_server_identity_key())) {
log_warn(LD_BUG, "Error creating directory.");
tor_free(new_directory);
return NULL;
@@ -1550,7 +1589,7 @@ generate_runningrouters(void)
char digest[DIGEST_LEN];
char published[ISO_TIME_LEN+1];
size_t len;
- crypto_pk_env_t *private_key = get_identity_key();
+ crypto_pk_env_t *private_key = get_server_identity_key();
char *identity_pkey; /* Identity key, DER64-encoded. */
size_t identity_pkey_len;
@@ -1577,7 +1616,8 @@ generate_runningrouters(void)
goto err;
}
note_crypto_pk_op(SIGN_DIR);
- if (router_append_dirobj_signature(s, len, digest, private_key)<0)
+ if (router_append_dirobj_signature(s, len, digest, DIGEST_LEN,
+ private_key)<0)
goto err;
set_cached_dir(&the_runningrouters, s, time(NULL));
@@ -1605,9 +1645,11 @@ dirserv_get_runningrouters(void)
/** Return the latest downloaded consensus networkstatus in encoded, signed,
* optionally compressed format, suitable for sending to clients. */
cached_dir_t *
-dirserv_get_consensus(void)
+dirserv_get_consensus(const char *flavor_name)
{
- return cached_v3_networkstatus;
+ if (!cached_consensuses)
+ return NULL;
+ return strmap_get(cached_consensuses, flavor_name);
}
/** For authoritative directories: the current (v2) network status. */
@@ -1645,7 +1687,7 @@ should_generate_v2_networkstatus(void)
#define TIME_KNOWN_TO_GUARANTEE_FAMILIAR (8*24*60*60)
/** Similarly, every node with sufficient WFU is around enough to be a guard.
*/
-#define WFU_TO_GUARANTEE_GUARD (0.995)
+#define WFU_TO_GUARANTEE_GUARD (0.98)
/* Thresholds for server performance: set by
* dirserv_compute_performance_thresholds, and used by
@@ -1725,7 +1767,7 @@ dirserv_thinks_router_is_unreliable(time_t now,
/** Return true iff <b>router</b> should be assigned the "HSDir" flag.
* Right now this means it advertises support for it, it has a high
- * uptime, and it's currently considered Running.
+ * uptime, it has a DirPort open, and it's currently considered Running.
*
* This function needs to be called after router-\>is_running has
* been set.
@@ -1735,7 +1777,11 @@ dirserv_thinks_router_is_hs_dir(routerinfo_t *router, time_t now)
{
long uptime = real_uptime(router, now);
- return (router->wants_to_be_hs_dir &&
+ /* XXX We shouldn't need to check dir_port, but we do because of
+ * bug 1693. In the future, once relays set wants_to_be_hs_dir
+ * correctly, we can revert to only checking dir_port if router's
+ * version is too old. */
+ return (router->wants_to_be_hs_dir && router->dir_port &&
uptime > get_options()->MinUptimeHidServDirectoryV2 &&
router->is_running);
}
@@ -1790,7 +1836,8 @@ dirserv_compute_performance_thresholds(routerlist_t *rl)
if (router_is_active(ri, now)) {
const char *id = ri->cache_info.identity_digest;
uint32_t bw;
- ri->is_exit = exit_policy_is_general_exit(ri->exit_policy);
+ ri->is_exit = (!router_exit_policy_rejects_all(ri) &&
+ exit_policy_is_general_exit(ri->exit_policy));
uptimes[n_active] = (uint32_t)real_uptime(ri, now);
mtbfs[n_active] = rep_hist_get_stability(id, now);
tks [n_active] = rep_hist_get_weighted_time_known(id, now);
@@ -1897,16 +1944,20 @@ version_from_platform(const char *platform)
* which has at least <b>buf_len</b> free characters. Do NUL-termination.
* Use the same format as in network-status documents. If <b>version</b> is
* non-NULL, add a "v" line for the platform. Return 0 on success, -1 on
- * failure. If <b>first_line_only</b> is true, don't include any flags
- * or version line.
+ * failure.
+ *
+ * The format argument has three possible values:
+ * NS_V2 - Output an entry suitable for a V2 NS opinion document
+ * NS_V3_CONSENSUS - Output the first portion of a V3 NS consensus entry
+ * NS_V3_CONSENSUS_MICRODESC - Output the first portion of a V3 microdesc
+ * consensus entry.
+ * NS_V3_VOTE - Output a complete V3 NS vote
+ * NS_CONTROL_PORT - Output a NS document for the control port
*/
int
routerstatus_format_entry(char *buf, size_t buf_len,
routerstatus_t *rs, const char *version,
- int first_line_only, int v2_format)
-/* XXX: first_line_only and v2_format should probably be be both
- * replaced by a single purpose parameter.
- */
+ routerstatus_format_type_t format)
{
int r;
struct in_addr in;
@@ -1925,10 +1976,11 @@ routerstatus_format_entry(char *buf, size_t buf_len,
tor_inet_ntoa(&in, ipaddr, sizeof(ipaddr));
r = tor_snprintf(buf, buf_len,
- "r %s %s %s %s %s %d %d\n",
+ "r %s %s %s%s%s %s %d %d\n",
rs->nickname,
identity64,
- digest64,
+ (format==NS_V3_CONSENSUS_MICRODESC)?"":digest64,
+ (format==NS_V3_CONSENSUS_MICRODESC)?"":" ",
published,
ipaddr,
(int)rs->or_port,
@@ -1937,7 +1989,12 @@ routerstatus_format_entry(char *buf, size_t buf_len,
log_warn(LD_BUG, "Not enough space in buffer.");
return -1;
}
- if (first_line_only)
+
+ /* TODO: Maybe we want to pass in what we need to build the rest of
+ * this here, instead of in the caller. Then we could use the
+ * networkstatus_type_t values, with an additional control port value
+ * added -MP */
+ if (format == NS_V3_CONSENSUS || format == NS_V3_CONSENSUS_MICRODESC)
return 0;
cp = buf + strlen(buf);
@@ -1974,62 +2031,87 @@ routerstatus_format_entry(char *buf, size_t buf_len,
cp += strlen(cp);
}
- if (!v2_format) {
+ if (format != NS_V2) {
routerinfo_t* desc = router_get_by_digest(rs->identity_digest);
+ uint32_t bw;
+
+ if (format != NS_CONTROL_PORT) {
+ /* Blow up more or less nicely if we didn't get anything or not the
+ * thing we expected.
+ */
+ if (!desc) {
+ char id[HEX_DIGEST_LEN+1];
+ char dd[HEX_DIGEST_LEN+1];
+
+ base16_encode(id, sizeof(id), rs->identity_digest, DIGEST_LEN);
+ base16_encode(dd, sizeof(dd), rs->descriptor_digest, DIGEST_LEN);
+ log_warn(LD_BUG, "Cannot get any descriptor for %s "
+ "(wanted descriptor %s).",
+ id, dd);
+ return -1;
+ };
+
+ /* This assert can fire for the control port, because
+ * it can request NS documents before all descriptors
+ * have been fetched. */
+ if (memcmp(desc->cache_info.signed_descriptor_digest,
+ rs->descriptor_digest,
+ DIGEST_LEN)) {
+ char rl_d[HEX_DIGEST_LEN+1];
+ char rs_d[HEX_DIGEST_LEN+1];
+ char id[HEX_DIGEST_LEN+1];
+
+ base16_encode(rl_d, sizeof(rl_d),
+ desc->cache_info.signed_descriptor_digest, DIGEST_LEN);
+ base16_encode(rs_d, sizeof(rs_d), rs->descriptor_digest, DIGEST_LEN);
+ base16_encode(id, sizeof(id), rs->identity_digest, DIGEST_LEN);
+ log_err(LD_BUG, "descriptor digest in routerlist does not match "
+ "the one in routerstatus: %s vs %s "
+ "(router %s)\n",
+ rl_d, rs_d, id);
+
+ tor_assert(!memcmp(desc->cache_info.signed_descriptor_digest,
+ rs->descriptor_digest,
+ DIGEST_LEN));
+ };
+ }
- /* Blow up more or less nicely if we didn't get anything or not the
- * thing we expected.
- */
- if (!desc) {
- char id[HEX_DIGEST_LEN+1];
- char dd[HEX_DIGEST_LEN+1];
-
- base16_encode(id, sizeof(id), rs->identity_digest, DIGEST_LEN);
- base16_encode(dd, sizeof(dd), rs->descriptor_digest, DIGEST_LEN);
- log_warn(LD_BUG, "Cannot get any descriptor for %s "
- "(wanted descriptor %s).",
- id, dd);
- return -1;
- };
- if (memcmp(desc->cache_info.signed_descriptor_digest,
- rs->descriptor_digest,
- DIGEST_LEN)) {
- char rl_d[HEX_DIGEST_LEN+1];
- char rs_d[HEX_DIGEST_LEN+1];
- char id[HEX_DIGEST_LEN+1];
-
- base16_encode(rl_d, sizeof(rl_d),
- desc->cache_info.signed_descriptor_digest, DIGEST_LEN);
- base16_encode(rs_d, sizeof(rs_d), rs->descriptor_digest, DIGEST_LEN);
- base16_encode(id, sizeof(id), rs->identity_digest, DIGEST_LEN);
- log_err(LD_BUG, "descriptor digest in routerlist does not match "
- "the one in routerstatus: %s vs %s "
- "(router %s)\n",
- rl_d, rs_d, id);
-
- tor_assert(!memcmp(desc->cache_info.signed_descriptor_digest,
- rs->descriptor_digest,
- DIGEST_LEN));
- };
-
+ if (format == NS_CONTROL_PORT && rs->has_bandwidth) {
+ bw = rs->bandwidth;
+ } else {
+ tor_assert(desc);
+ bw = router_get_advertised_bandwidth_capped(desc) / 1000;
+ }
r = tor_snprintf(cp, buf_len - (cp-buf),
- "w Bandwidth=%d\n",
- router_get_advertised_bandwidth_capped(desc) / 1024);
+ "w Bandwidth=%d\n", bw);
+
if (r<0) {
log_warn(LD_BUG, "Not enough space in buffer.");
return -1;
}
cp += strlen(cp);
+ if (format == NS_V3_VOTE && rs->has_measured_bw) {
+ *--cp = '\0'; /* Kill "\n" */
+ r = tor_snprintf(cp, buf_len - (cp-buf),
+ " Measured=%d\n", rs->measured_bw);
+ if (r<0) {
+ log_warn(LD_BUG, "Not enough space in buffer for weight line.");
+ return -1;
+ }
+ cp += strlen(cp);
+ }
- summary = policy_summarize(desc->exit_policy);
- r = tor_snprintf(cp, buf_len - (cp-buf), "p %s\n", summary);
- if (r<0) {
- log_warn(LD_BUG, "Not enough space in buffer.");
+ if (desc) {
+ summary = policy_summarize(desc->exit_policy);
+ r = tor_snprintf(cp, buf_len - (cp-buf), "p %s\n", summary);
+ if (r<0) {
+ log_warn(LD_BUG, "Not enough space in buffer.");
+ tor_free(summary);
+ return -1;
+ }
+ cp += strlen(cp);
tor_free(summary);
- return -1;
}
- cp += strlen(cp);
- tor_free(summary);
}
return 0;
@@ -2132,9 +2214,7 @@ get_possible_sybil_list(const smartlist_t *routers)
/** Extract status information from <b>ri</b> and from other authority
* functions and store it in <b>rs</b>>. If <b>naming</b>, consider setting
- * the named flag in <b>rs</b>. If not <b>exits_can_be_guards</b>, never mark
- * an exit as a guard. If <b>listbadexits</b>, consider setting the badexit
- * flag.
+ * the named flag in <b>rs</b>.
*
* We assume that ri-\>is_running has already been set, e.g. by
* dirserv_set_router_is_running(ri, now);
@@ -2142,8 +2222,8 @@ get_possible_sybil_list(const smartlist_t *routers)
void
set_routerstatus_from_routerinfo(routerstatus_t *rs,
routerinfo_t *ri, time_t now,
- int naming, int exits_can_be_guards,
- int listbadexits, int listbaddirs)
+ int naming, int listbadexits,
+ int listbaddirs)
{
int unstable_version =
!tor_version_as_new_as(ri->platform,"0.1.1.16-rc-cvs");
@@ -2172,11 +2252,10 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
rs->is_valid = ri->is_valid;
if (rs->is_fast &&
- (!rs->is_exit || exits_can_be_guards) &&
(router_get_advertised_bandwidth(ri) >= BANDWIDTH_TO_GUARANTEE_GUARD ||
router_get_advertised_bandwidth(ri) >=
- (exits_can_be_guards ? guard_bandwidth_including_exits :
- guard_bandwidth_excluding_exits))) {
+ MIN(guard_bandwidth_including_exits,
+ guard_bandwidth_excluding_exits))) {
long tk = rep_hist_get_weighted_time_known(
ri->cache_info.identity_digest, now);
double wfu = rep_hist_get_weighted_fractional_uptime(
@@ -2232,6 +2311,177 @@ router_clear_status_flags(routerinfo_t *router)
router->is_bad_exit = router->is_bad_directory = 0;
}
+/**
+ * Helper function to parse out a line in the measured bandwidth file
+ * into a measured_bw_line_t output structure. Returns -1 on failure
+ * or 0 on success.
+ */
+int
+measured_bw_line_parse(measured_bw_line_t *out, const char *orig_line)
+{
+ char *line = tor_strdup(orig_line);
+ char *cp = line;
+ int got_bw = 0;
+ int got_node_id = 0;
+ char *strtok_state; /* lame sauce d'jour */
+ cp = tor_strtok_r(cp, " \t", &strtok_state);
+
+ if (!cp) {
+ log_warn(LD_DIRSERV, "Invalid line in bandwidth file: %s",
+ escaped(orig_line));
+ tor_free(line);
+ return -1;
+ }
+
+ if (orig_line[strlen(orig_line)-1] != '\n') {
+ log_warn(LD_DIRSERV, "Incomplete line in bandwidth file: %s",
+ escaped(orig_line));
+ tor_free(line);
+ return -1;
+ }
+
+ do {
+ if (strcmpstart(cp, "bw=") == 0) {
+ int parse_ok = 0;
+ char *endptr;
+ if (got_bw) {
+ log_warn(LD_DIRSERV, "Double bw= in bandwidth file line: %s",
+ escaped(orig_line));
+ tor_free(line);
+ return -1;
+ }
+ cp+=strlen("bw=");
+
+ out->bw = tor_parse_long(cp, 0, 0, LONG_MAX, &parse_ok, &endptr);
+ if (!parse_ok || (*endptr && !TOR_ISSPACE(*endptr))) {
+ log_warn(LD_DIRSERV, "Invalid bandwidth in bandwidth file line: %s",
+ escaped(orig_line));
+ tor_free(line);
+ return -1;
+ }
+ got_bw=1;
+ } else if (strcmpstart(cp, "node_id=$") == 0) {
+ if (got_node_id) {
+ log_warn(LD_DIRSERV, "Double node_id= in bandwidth file line: %s",
+ escaped(orig_line));
+ tor_free(line);
+ return -1;
+ }
+ cp+=strlen("node_id=$");
+
+ if (strlen(cp) != HEX_DIGEST_LEN ||
+ base16_decode(out->node_id, DIGEST_LEN, cp, HEX_DIGEST_LEN)) {
+ log_warn(LD_DIRSERV, "Invalid node_id in bandwidth file line: %s",
+ escaped(orig_line));
+ tor_free(line);
+ return -1;
+ }
+ strncpy(out->node_hex, cp, sizeof(out->node_hex));
+ got_node_id=1;
+ }
+ } while ((cp = tor_strtok_r(NULL, " \t", &strtok_state)));
+
+ if (got_bw && got_node_id) {
+ tor_free(line);
+ return 0;
+ } else {
+ log_warn(LD_DIRSERV, "Incomplete line in bandwidth file: %s",
+ escaped(orig_line));
+ tor_free(line);
+ return -1;
+ }
+}
+
+/**
+ * Helper function to apply a parsed measurement line to a list
+ * of bandwidth statuses. Returns true if a line is found,
+ * false otherwise.
+ */
+int
+measured_bw_line_apply(measured_bw_line_t *parsed_line,
+ smartlist_t *routerstatuses)
+{
+ routerstatus_t *rs = NULL;
+ if (!routerstatuses)
+ return 0;
+
+ rs = smartlist_bsearch(routerstatuses, parsed_line->node_id,
+ compare_digest_to_routerstatus_entry);
+
+ if (rs) {
+ rs->has_measured_bw = 1;
+ rs->measured_bw = (uint32_t)parsed_line->bw;
+ } else {
+ log_info(LD_DIRSERV, "Node ID %s not found in routerstatus list",
+ parsed_line->node_hex);
+ }
+
+ return rs != NULL;
+}
+
+/**
+ * Read the measured bandwidth file and apply it to the list of
+ * routerstatuses. Returns -1 on error, 0 otherwise.
+ */
+int
+dirserv_read_measured_bandwidths(const char *from_file,
+ smartlist_t *routerstatuses)
+{
+ char line[256];
+ FILE *fp = fopen(from_file, "r");
+ int applied_lines = 0;
+ time_t file_time;
+ int ok;
+ if (fp == NULL) {
+ log_warn(LD_CONFIG, "Can't open bandwidth file at configured location: %s",
+ from_file);
+ return -1;
+ }
+
+ if (!fgets(line, sizeof(line), fp)
+ || !strlen(line) || line[strlen(line)-1] != '\n') {
+ log_warn(LD_DIRSERV, "Long or truncated time in bandwidth file: %s",
+ escaped(line));
+ fclose(fp);
+ return -1;
+ }
+
+ line[strlen(line)-1] = '\0';
+ file_time = tor_parse_ulong(line, 10, 0, ULONG_MAX, &ok, NULL);
+ if (!ok) {
+ log_warn(LD_DIRSERV, "Non-integer time in bandwidth file: %s",
+ escaped(line));
+ fclose(fp);
+ return -1;
+ }
+
+ if ((time(NULL) - file_time) > MAX_MEASUREMENT_AGE) {
+ log_warn(LD_DIRSERV, "Bandwidth measurement file stale. Age: %u",
+ (unsigned)(time(NULL) - file_time));
+ fclose(fp);
+ return -1;
+ }
+
+ if (routerstatuses)
+ smartlist_sort(routerstatuses, compare_routerstatus_entries);
+
+ while (!feof(fp)) {
+ measured_bw_line_t parsed_line;
+ if (fgets(line, sizeof(line), fp) && strlen(line)) {
+ if (measured_bw_line_parse(&parsed_line, line) != -1) {
+ if (measured_bw_line_apply(&parsed_line, routerstatuses) > 0)
+ applied_lines++;
+ }
+ }
+ }
+
+ fclose(fp);
+ log_info(LD_DIRSERV,
+ "Bandwidth measurement file successfully read. "
+ "Applied %d measurements.", applied_lines);
+ return 0;
+}
+
/** Return a new networkstatus_t* containing our current opinion. (For v3
* authorities) */
networkstatus_t *
@@ -2249,22 +2499,18 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
int naming = options->NamingAuthoritativeDir;
int listbadexits = options->AuthDirListBadExits;
int listbaddirs = options->AuthDirListBadDirs;
- int exits_can_be_guards;
routerlist_t *rl = router_get_routerlist();
time_t now = time(NULL);
time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
networkstatus_voter_info_t *voter = NULL;
vote_timing_t timing;
digestmap_t *omit_as_sybil = NULL;
- int vote_on_reachability = 1;
+ const int vote_on_reachability = running_long_enough_to_decide_unreachable();
+ smartlist_t *microdescriptors = NULL;
tor_assert(private_key);
tor_assert(cert);
- if (now - time_of_process_start <
- options->TestingAuthDirTimeToLearnReachability)
- vote_on_reachability = 0;
-
if (resolve_my_address(LOG_WARN, options, &addr, &hostname)<0) {
log_warn(LD_NET, "Couldn't resolve my hostname");
return NULL;
@@ -2299,27 +2545,24 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
dirserv_compute_performance_thresholds(rl);
- /* XXXX We should take steps to keep this from oscillating if
- * total_exit_bandwidth is close to total_bandwidth/3. */
- exits_can_be_guards = total_exit_bandwidth >= (total_bandwidth / 3);
-
routers = smartlist_create();
smartlist_add_all(routers, rl->routers);
routers_sort_by_identity(routers);
omit_as_sybil = get_possible_sybil_list(routers);
routerstatuses = smartlist_create();
+ microdescriptors = smartlist_create();
- SMARTLIST_FOREACH(routers, routerinfo_t *, ri, {
+ SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
if (ri->cache_info.published_on >= cutoff) {
routerstatus_t *rs;
vote_routerstatus_t *vrs;
+ microdesc_t *md;
vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
rs = &vrs->status;
set_routerstatus_from_routerinfo(rs, ri, now,
- naming, exits_can_be_guards,
- listbadexits, listbaddirs);
+ naming, listbadexits, listbaddirs);
if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
clear_status_flags_on_sybil(rs);
@@ -2328,12 +2571,39 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
rs->is_running = 0;
vrs->version = version_from_platform(ri->platform);
+ md = dirvote_create_microdescriptor(ri);
+ if (md) {
+ char buf[128];
+ vote_microdesc_hash_t *h;
+ dirvote_format_microdesc_vote_line(buf, sizeof(buf), md);
+ h = tor_malloc(sizeof(vote_microdesc_hash_t));
+ h->microdesc_hash_line = tor_strdup(buf);
+ h->next = NULL;
+ vrs->microdesc = h;
+ md->last_listed = now;
+ smartlist_add(microdescriptors, md);
+ }
+
smartlist_add(routerstatuses, vrs);
}
- });
+ } SMARTLIST_FOREACH_END(ri);
+
+ {
+ smartlist_t *added =
+ microdescs_add_list_to_cache(get_microdesc_cache(),
+ microdescriptors, SAVED_NOWHERE, 0);
+ smartlist_free(added);
+ smartlist_free(microdescriptors);
+ }
+
smartlist_free(routers);
digestmap_free(omit_as_sybil, NULL);
+ if (options->V3BandwidthsFile) {
+ dirserv_read_measured_bandwidths(options->V3BandwidthsFile,
+ routerstatuses);
+ }
+
v3_out = tor_malloc_zero(sizeof(networkstatus_t));
v3_out->type = NS_TYPE_VOTE;
@@ -2383,15 +2653,22 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
}
smartlist_sort_strings(v3_out->known_flags);
+ if (options->ConsensusParams) {
+ v3_out->net_params = smartlist_create();
+ smartlist_split_string(v3_out->net_params,
+ options->ConsensusParams, NULL, 0, 0);
+ smartlist_sort_strings(v3_out->net_params);
+ }
+
voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
voter->nickname = tor_strdup(options->Nickname);
memcpy(voter->identity_digest, identity_digest, DIGEST_LEN);
+ voter->sigs = smartlist_create();
voter->address = hostname;
voter->addr = addr;
voter->dir_port = options->DirPort;
voter->or_port = options->ORPort;
voter->contact = tor_strdup(contact);
- memcpy(voter->signing_key_digest, signing_key_digest, DIGEST_LEN);
if (options->V3AuthUseLegacyKey) {
authority_cert_t *c = get_my_v3_legacy_cert();
if (c) {
@@ -2435,13 +2712,12 @@ generate_v2_networkstatus_opinion(void)
int versioning = options->VersioningAuthoritativeDir;
int listbaddirs = options->AuthDirListBadDirs;
int listbadexits = options->AuthDirListBadExits;
- int exits_can_be_guards;
const char *contact;
char *version_lines = NULL;
smartlist_t *routers = NULL;
digestmap_t *omit_as_sybil = NULL;
- private_key = get_identity_key();
+ private_key = get_server_identity_key();
if (resolve_my_address(LOG_WARN, options, &addr, &hostname)<0) {
log_warn(LD_NET, "Couldn't resolve my hostname");
@@ -2515,10 +2791,6 @@ generate_v2_networkstatus_opinion(void)
dirserv_compute_performance_thresholds(rl);
- /* XXXX We should take steps to keep this from oscillating if
- * total_exit_bandwidth is close to total_bandwidth/3. */
- exits_can_be_guards = total_exit_bandwidth >= (total_bandwidth / 3);
-
routers = smartlist_create();
smartlist_add_all(routers, rl->routers);
routers_sort_by_identity(routers);
@@ -2531,13 +2803,12 @@ generate_v2_networkstatus_opinion(void)
char *version = version_from_platform(ri->platform);
set_routerstatus_from_routerinfo(&rs, ri, now,
- naming, exits_can_be_guards,
- listbadexits, listbaddirs);
+ naming, listbadexits, listbaddirs);
if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
clear_status_flags_on_sybil(&rs);
- if (routerstatus_format_entry(outp, endp-outp, &rs, version, 0, 1)) {
+ if (routerstatus_format_entry(outp, endp-outp, &rs, version, NS_V2)) {
log_warn(LD_BUG, "Unable to print router status.");
tor_free(version);
goto done;
@@ -2559,7 +2830,8 @@ generate_v2_networkstatus_opinion(void)
outp += strlen(outp);
note_crypto_pk_op(SIGN_DIR);
- if (router_append_dirobj_signature(outp,endp-outp,digest,private_key)<0) {
+ if (router_append_dirobj_signature(outp,endp-outp,digest,DIGEST_LEN,
+ private_key)<0) {
log_warn(LD_BUG, "Unable to sign router status.");
goto done;
}
@@ -2591,10 +2863,8 @@ generate_v2_networkstatus_opinion(void)
tor_free(status);
tor_free(hostname);
tor_free(identity_pkey);
- if (routers)
- smartlist_free(routers);
- if (omit_as_sybil)
- digestmap_free(omit_as_sybil, NULL);
+ smartlist_free(routers);
+ digestmap_free(omit_as_sybil, NULL);
return r;
}
@@ -2642,7 +2912,8 @@ dirserv_get_networkstatus_v2_fingerprints(smartlist_t *result,
log_info(LD_DIRSERV,
"Client requested 'all' network status objects; we have none.");
} else if (!strcmpstart(key, "fp/")) {
- dir_split_resource_into_fingerprints(key+3, result, NULL, 1, 1);
+ dir_split_resource_into_fingerprints(key+3, result, NULL,
+ DSR_HEX|DSR_SORT_UNIQ);
}
}
@@ -2707,10 +2978,12 @@ dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
} else if (!strcmpstart(key, "d/")) {
by_id = 0;
key += strlen("d/");
- dir_split_resource_into_fingerprints(key, fps_out, NULL, 1, 1);
+ dir_split_resource_into_fingerprints(key, fps_out, NULL,
+ DSR_HEX|DSR_SORT_UNIQ);
} else if (!strcmpstart(key, "fp/")) {
key += strlen("fp/");
- dir_split_resource_into_fingerprints(key, fps_out, NULL, 1, 1);
+ dir_split_resource_into_fingerprints(key, fps_out, NULL,
+ DSR_HEX|DSR_SORT_UNIQ);
} else {
*msg = "Key not recognized";
return -1;
@@ -2775,7 +3048,8 @@ dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
} else if (!strcmpstart(key, "/tor/server/d/")) {
smartlist_t *digests = smartlist_create();
key += strlen("/tor/server/d/");
- dir_split_resource_into_fingerprints(key, digests, NULL, 1, 1);
+ dir_split_resource_into_fingerprints(key, digests, NULL,
+ DSR_HEX|DSR_SORT_UNIQ);
SMARTLIST_FOREACH(digests, const char *, d,
{
signed_descriptor_t *sd = router_get_by_descriptor_digest(d);
@@ -2788,7 +3062,8 @@ dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
smartlist_t *digests = smartlist_create();
time_t cutoff = time(NULL) - ROUTER_MAX_AGE_TO_PUBLISH;
key += strlen("/tor/server/fp/");
- dir_split_resource_into_fingerprints(key, digests, NULL, 1, 1);
+ dir_split_resource_into_fingerprints(key, digests, NULL,
+ DSR_HEX|DSR_SORT_UNIQ);
SMARTLIST_FOREACH(digests, const char *, d,
{
if (router_digest_is_me(d)) {
@@ -2857,8 +3132,48 @@ dirserv_orconn_tls_done(const char *address,
* skip testing. */
}
-/** Auth dir server only: if <b>try_all</b> is 1, launch connections to
- * all known routers; else we want to load balance such that we only
+/** Called when we, as an authority, receive a new router descriptor either as
+ * an upload or a download. Used to decide whether to relaunch reachability
+ * testing for the server. */
+int
+dirserv_should_launch_reachability_test(routerinfo_t *ri, routerinfo_t *ri_old)
+{
+ if (!authdir_mode_handles_descs(get_options(), ri->purpose))
+ return 0;
+ if (!ri_old) {
+ /* New router: Launch an immediate reachability test, so we will have an
+ * opinion soon in case we're generating a consensus soon */
+ return 1;
+ }
+ if (ri_old->is_hibernating && !ri->is_hibernating) {
+ /* It just came out of hibernation; launch a reachability test */
+ return 1;
+ }
+ if (! routers_have_same_or_addr(ri, ri_old)) {
+ /* Address or port changed; launch a reachability test */
+ return 1;
+ }
+ return 0;
+}
+
+/** Helper function for dirserv_test_reachability(). Start a TLS
+ * connection to <b>router</b>, and annotate it with when we started
+ * the test. */
+void
+dirserv_single_reachability_test(time_t now, routerinfo_t *router)
+{
+ tor_addr_t router_addr;
+ log_debug(LD_OR,"Testing reachability of %s at %s:%u.",
+ router->nickname, router->address, router->or_port);
+ /* Remember when we started trying to determine reachability */
+ if (!router->testing_since)
+ router->testing_since = now;
+ tor_addr_from_ipv4h(&router_addr, router->addr);
+ connection_or_connect(&router_addr, router->or_port,
+ router->cache_info.identity_digest);
+}
+
+/** Auth dir server only: load balance such that we only
* try a few connections per call.
*
* The load balancing is such that if we get called once every ten
@@ -2866,7 +3181,7 @@ dirserv_orconn_tls_done(const char *address,
* bit over 20 minutes).
*/
void
-dirserv_test_reachability(time_t now, int try_all)
+dirserv_test_reachability(time_t now)
{
/* XXX decide what to do here; see or-talk thread "purging old router
* information, revocation." -NM
@@ -2883,38 +3198,33 @@ dirserv_test_reachability(time_t now, int try_all)
SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, router) {
const char *id_digest = router->cache_info.identity_digest;
- tor_addr_t router_addr;
if (router_is_me(router))
continue;
if (bridge_auth && router->purpose != ROUTER_PURPOSE_BRIDGE)
continue; /* bridge authorities only test reachability on bridges */
// if (router->cache_info.published_on > cutoff)
// continue;
- if (try_all || (((uint8_t)id_digest[0]) % 128) == ctr) {
- log_debug(LD_OR,"Testing reachability of %s at %s:%u.",
- router->nickname, router->address, router->or_port);
- /* Remember when we started trying to determine reachability */
- if (!router->testing_since)
- router->testing_since = now;
- tor_addr_from_ipv4h(&router_addr, router->addr);
- connection_or_connect(&router_addr, router->or_port, id_digest);
+ if ((((uint8_t)id_digest[0]) % 128) == ctr) {
+ dirserv_single_reachability_test(now, router);
}
} SMARTLIST_FOREACH_END(router);
- if (!try_all) /* increment ctr */
- ctr = (ctr + 1) % 128;
+ ctr = (ctr + 1) % 128; /* increment ctr */
}
-/** Given a fingerprint <b>fp</b> which is either set if we're looking
- * for a v2 status, or zeroes if we're looking for a v3 status, return
- * a pointer to the appropriate cached dir object, or NULL if there isn't
- * one available. */
+/** Given a fingerprint <b>fp</b> which is either set if we're looking for a
+ * v2 status, or zeroes if we're looking for a v3 status, or a NUL-padded
+ * flavor name if we want a flavored v3 status, return a pointer to the
+ * appropriate cached dir object, or NULL if there isn't one available. */
static cached_dir_t *
lookup_cached_dir_by_fp(const char *fp)
{
cached_dir_t *d = NULL;
- if (tor_digest_is_zero(fp) && cached_v3_networkstatus)
- d = cached_v3_networkstatus;
- else if (router_digest_is_me(fp) && the_v2_networkstatus)
+ if (tor_digest_is_zero(fp) && cached_consensuses)
+ d = strmap_get(cached_consensuses, "ns");
+ else if (memchr(fp, '\0', DIGEST_LEN) && cached_consensuses &&
+ (d = strmap_get(cached_consensuses, fp))) {
+ /* this here interface is a nasty hack XXXX022 */;
+ } else if (router_digest_is_me(fp) && the_v2_networkstatus)
d = the_v2_networkstatus;
else if (cached_v2_networkstatus)
d = digestmap_get(cached_v2_networkstatus, fp);
@@ -3000,6 +3310,18 @@ dirserv_have_any_serverdesc(smartlist_t *fps, int spool_src)
return 0;
}
+/** Return true iff any of the 256-bit elements in <b>fps</b> is the digest of
+ * a microdescriptor we have. */
+int
+dirserv_have_any_microdesc(const smartlist_t *fps)
+{
+ microdesc_cache_t *cache = get_microdesc_cache();
+ SMARTLIST_FOREACH(fps, const char *, fp,
+ if (microdesc_cache_lookup_by_digest256(cache, fp))
+ return 1);
+ return 0;
+}
+
/** Return an approximate estimate of the number of bytes that will
* be needed to transmit the server descriptors (if is_serverdescs --
* they can be either d/ or fp/ queries) or networkstatus objects (if
@@ -3031,6 +3353,17 @@ dirserv_estimate_data_size(smartlist_t *fps, int is_serverdescs,
return result;
}
+/** Given a list of microdescriptor hashes, guess how many bytes will be
+ * needed to transmit them, and return the guess. */
+size_t
+dirserv_estimate_microdesc_size(const smartlist_t *fps, int compressed)
+{
+ size_t result = smartlist_len(fps) * microdesc_average_size(NULL);
+ if (compressed)
+ result /= 2;
+ return result;
+}
+
/** When we're spooling data onto our outbuf, add more whenever we dip
* below this threshold. */
#define DIRSERV_BUFFER_MIN 16384
@@ -3094,6 +3427,8 @@ connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn)
#endif
body = signed_descriptor_get_body(sd);
if (conn->zlib_state) {
+ /* XXXX022 This 'last' business should actually happen on the last
+ * routerinfo, not on the last fingerprint. */
int last = ! smartlist_len(conn->fingerprint_stack);
connection_write_to_buf_zlib(body, sd->signed_descriptor_len, conn,
last);
@@ -3117,6 +3452,44 @@ connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn)
return 0;
}
+/** Spooling helper: called when we're sending a bunch of microdescriptors,
+ * and the outbuf has become too empty. Pulls some entries from
+ * fingerprint_stack, and writes the corresponding microdescs onto outbuf. If
+ * we run out of entries, flushes the zlib state and sets the spool source to
+ * NONE. Returns 0 on success, negative on failure.
+ */
+static int
+connection_dirserv_add_microdescs_to_outbuf(dir_connection_t *conn)
+{
+ microdesc_cache_t *cache = get_microdesc_cache();
+ while (smartlist_len(conn->fingerprint_stack) &&
+ buf_datalen(conn->_base.outbuf) < DIRSERV_BUFFER_MIN) {
+ char *fp256 = smartlist_pop_last(conn->fingerprint_stack);
+ microdesc_t *md = microdesc_cache_lookup_by_digest256(cache, fp256);
+ tor_free(fp256);
+ if (!md)
+ continue;
+ if (conn->zlib_state) {
+ /* XXXX022 This 'last' business should actually happen on the last
+ * routerinfo, not on the last fingerprint. */
+ int last = !smartlist_len(conn->fingerprint_stack);
+ connection_write_to_buf_zlib(md->body, md->bodylen, conn, last);
+ if (last) {
+ tor_zlib_free(conn->zlib_state);
+ conn->zlib_state = NULL;
+ }
+ } else {
+ connection_write_to_buf(md->body, md->bodylen, TO_CONN(conn));
+ }
+ }
+ if (!smartlist_len(conn->fingerprint_stack)) {
+ conn->dir_spool_src = DIR_SPOOL_NONE;
+ smartlist_free(conn->fingerprint_stack);
+ conn->fingerprint_stack = NULL;
+ }
+ return 0;
+}
+
/** Spooling helper: Called when we're sending a directory or networkstatus,
* and the outbuf has become too empty. Pulls some bytes from
* <b>conn</b>-\>cached_dir-\>dir_z, uncompresses them if appropriate, and
@@ -3199,8 +3572,7 @@ connection_dirserv_add_networkstatus_bytes_to_outbuf(dir_connection_t *conn)
}
} else {
connection_dirserv_finish_spooling(conn);
- if (conn->fingerprint_stack)
- smartlist_free(conn->fingerprint_stack);
+ smartlist_free(conn->fingerprint_stack);
conn->fingerprint_stack = NULL;
return 0;
}
@@ -3224,6 +3596,8 @@ connection_dirserv_flushed_some(dir_connection_t *conn)
case DIR_SPOOL_SERVER_BY_DIGEST:
case DIR_SPOOL_SERVER_BY_FP:
return connection_dirserv_add_servers_to_outbuf(conn);
+ case DIR_SPOOL_MICRODESC:
+ return connection_dirserv_add_microdescs_to_outbuf(conn);
case DIR_SPOOL_CACHED_DIR:
return connection_dirserv_add_dir_bytes_to_outbuf(conn);
case DIR_SPOOL_NETWORKSTATUS:
@@ -3245,10 +3619,10 @@ dirserv_free_all(void)
cached_dir_decref(the_v2_networkstatus);
cached_dir_decref(cached_directory);
clear_cached_dir(&cached_runningrouters);
- if (cached_v2_networkstatus) {
- digestmap_free(cached_v2_networkstatus, _free_cached_dir);
- cached_v2_networkstatus = NULL;
- }
- cached_dir_decref(cached_v3_networkstatus);
+
+ digestmap_free(cached_v2_networkstatus, _free_cached_dir);
+ cached_v2_networkstatus = NULL;
+ strmap_free(cached_consensuses, _free_cached_dir);
+ cached_consensuses = NULL;
}
diff --git a/src/or/dirserv.h b/src/or/dirserv.h
new file mode 100644
index 0000000000..94e4e811d6
--- /dev/null
+++ b/src/or/dirserv.h
@@ -0,0 +1,134 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file dirserv.h
+ * \brief Header file for dirserv.c.
+ **/
+
+#ifndef _TOR_DIRSERV_H
+#define _TOR_DIRSERV_H
+
+/** Maximum length of an exit policy summary. */
+#define MAX_EXITPOLICY_SUMMARY_LEN 1000
+
+/** Maximum allowable length of a version line in a networkstatus. */
+#define MAX_V_LINE_LEN 128
+/** Length of "r Authority BadDirectory BadExit Exit Fast Guard HSDir Named
+ * Running Stable Unnamed V2Dir Valid\n". */
+#define MAX_FLAG_LINE_LEN 96
+/** Length of "w" line for weighting. Currently at most
+ * "w Bandwidth=<uint32t> Measured=<uint32t>\n" */
+#define MAX_WEIGHT_LINE_LEN (12+10+10+10+1)
+/** Maximum length of an exit policy summary line. */
+#define MAX_POLICY_LINE_LEN (3+MAX_EXITPOLICY_SUMMARY_LEN)
+/** Amount of space to allocate for each entry: r, s, and v lines. */
+#define RS_ENTRY_LEN \
+ ( /* first line */ \
+ MAX_NICKNAME_LEN+BASE64_DIGEST_LEN*2+ISO_TIME_LEN+INET_NTOA_BUF_LEN+ \
+ 5*2 /* ports */ + 10 /* punctuation */ + \
+ /* second line */ \
+ MAX_FLAG_LINE_LEN + \
+ /* weight line */ \
+ MAX_WEIGHT_LINE_LEN + \
+ /* p line. */ \
+ MAX_POLICY_LINE_LEN + \
+ /* v line. */ \
+ MAX_V_LINE_LEN \
+ )
+
+#define UNNAMED_ROUTER_NICKNAME "Unnamed"
+
+int connection_dirserv_flushed_some(dir_connection_t *conn);
+
+int dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk);
+int dirserv_load_fingerprint_file(void);
+void dirserv_free_fingerprint_list(void);
+const char *dirserv_get_nickname_by_digest(const char *digest);
+enum was_router_added_t dirserv_add_multiple_descriptors(
+ const char *desc, uint8_t purpose,
+ const char *source,
+ const char **msg);
+enum was_router_added_t dirserv_add_descriptor(routerinfo_t *ri,
+ const char **msg,
+ const char *source);
+void dirserv_set_router_is_running(routerinfo_t *router, time_t now);
+int list_server_status_v1(smartlist_t *routers, char **router_status_out,
+ int for_controller);
+int dirserv_dump_directory_to_string(char **dir_out,
+ crypto_pk_env_t *private_key);
+
+int directory_fetches_from_authorities(or_options_t *options);
+int directory_fetches_dir_info_early(or_options_t *options);
+int directory_fetches_dir_info_later(or_options_t *options);
+int directory_caches_v2_dir_info(or_options_t *options);
+#define directory_caches_v1_dir_info(o) directory_caches_v2_dir_info(o)
+int directory_caches_dir_info(or_options_t *options);
+int directory_permits_begindir_requests(or_options_t *options);
+int directory_permits_controller_requests(or_options_t *options);
+int directory_too_idle_to_fetch_descriptors(or_options_t *options, time_t now);
+
+void directory_set_dirty(void);
+cached_dir_t *dirserv_get_directory(void);
+cached_dir_t *dirserv_get_runningrouters(void);
+cached_dir_t *dirserv_get_consensus(const char *flavor_name);
+void dirserv_set_cached_directory(const char *directory, time_t when,
+ int is_running_routers);
+void dirserv_set_cached_networkstatus_v2(const char *directory,
+ const char *identity,
+ time_t published);
+void dirserv_set_cached_consensus_networkstatus(const char *consensus,
+ const char *flavor_name,
+ const digests_t *digests,
+ time_t published);
+void dirserv_clear_old_networkstatuses(time_t cutoff);
+void dirserv_clear_old_v1_info(time_t now);
+void dirserv_get_networkstatus_v2(smartlist_t *result, const char *key);
+void dirserv_get_networkstatus_v2_fingerprints(smartlist_t *result,
+ const char *key);
+int dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
+ const char **msg,
+ int for_unencrypted_conn,
+ int is_extrainfo);
+int dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
+ const char **msg);
+void dirserv_orconn_tls_done(const char *address,
+ uint16_t or_port,
+ const char *digest_rcvd,
+ int as_advertised);
+int dirserv_should_launch_reachability_test(routerinfo_t *ri,
+ routerinfo_t *ri_old);
+void dirserv_single_reachability_test(time_t now, routerinfo_t *router);
+void dirserv_test_reachability(time_t now);
+int authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
+ int complain);
+int dirserv_would_reject_router(routerstatus_t *rs);
+int dirserv_remove_old_statuses(smartlist_t *fps, time_t cutoff);
+int dirserv_have_any_serverdesc(smartlist_t *fps, int spool_src);
+int dirserv_have_any_microdesc(const smartlist_t *fps);
+size_t dirserv_estimate_data_size(smartlist_t *fps, int is_serverdescs,
+ int compressed);
+size_t dirserv_estimate_microdesc_size(const smartlist_t *fps, int compressed);
+
+int routerstatus_format_entry(char *buf, size_t buf_len,
+ routerstatus_t *rs, const char *platform,
+ routerstatus_format_type_t format);
+void dirserv_free_all(void);
+void cached_dir_decref(cached_dir_t *d);
+cached_dir_t *new_cached_dir(char *s, time_t published);
+
+#ifdef DIRSERV_PRIVATE
+int measured_bw_line_parse(measured_bw_line_t *out, const char *line);
+
+int measured_bw_line_apply(measured_bw_line_t *parsed_line,
+ smartlist_t *routerstatuses);
+#endif
+
+int dirserv_read_measured_bandwidths(const char *from_file,
+ smartlist_t *routerstatuses);
+
+#endif
+
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index 64e07cc0a2..dd36a0f911 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -5,27 +5,72 @@
#define DIRVOTE_PRIVATE
#include "or.h"
+#include "config.h"
+#include "directory.h"
+#include "dirserv.h"
+#include "dirvote.h"
+#include "microdesc.h"
+#include "networkstatus.h"
+#include "policies.h"
+#include "rephist.h"
+#include "router.h"
+#include "routerlist.h"
+#include "routerparse.h"
/**
* \file dirvote.c
* \brief Functions to compute directory consensus, and schedule voting.
**/
-static int dirvote_add_signatures_to_pending_consensus(
+/** A consensus that we have built and are appending signatures to. Once it's
+ * time to publish it, it will become an active consensus if it accumulates
+ * enough signatures. */
+typedef struct pending_consensus_t {
+ /** The body of the consensus that we're currently building. Once we
+ * have it built, it goes into dirserv.c */
+ char *body;
+ /** The parsed in-progress consensus document. */
+ networkstatus_t *consensus;
+} pending_consensus_t;
+
+static int dirvote_add_signatures_to_all_pending_consensuses(
const char *detached_signatures_body,
const char **msg_out);
+static int dirvote_add_signatures_to_pending_consensus(
+ pending_consensus_t *pc,
+ ns_detached_signatures_t *sigs,
+ const char **msg_out);
static char *list_v3_auth_ids(void);
static void dirvote_fetch_missing_votes(void);
static void dirvote_fetch_missing_signatures(void);
static int dirvote_perform_vote(void);
static void dirvote_clear_votes(int all_votes);
-static int dirvote_compute_consensus(void);
+static int dirvote_compute_consensuses(void);
static int dirvote_publish_consensus(void);
+static char *make_consensus_method_list(int low, int high, const char *sep);
+
+/** The highest consensus method that we currently support. */
+#define MAX_SUPPORTED_CONSENSUS_METHOD 10
+
+/** Lowest consensus method that contains a 'directory-footer' marker */
+#define MIN_METHOD_FOR_FOOTER 9
+
+/** Lowest consensus method that contains bandwidth weights */
+#define MIN_METHOD_FOR_BW_WEIGHTS 9
+
+/** Lowest consensus method that contains consensus params */
+#define MIN_METHOD_FOR_PARAMS 7
+
+/** Lowest consensus method that generates microdescriptors */
+#define MIN_METHOD_FOR_MICRODESC 8
/* =====
* Voting
* =====*/
+/* Overestimated. */
+#define MICRODESC_LINE_LEN 80
+
/** Return a new string containing the string representation of the vote in
* <b>v3_ns</b>, signed with our v3 signing key <b>private_signing_key</b>.
* For v3 authorities. */
@@ -44,6 +89,7 @@ format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
uint32_t addr;
routerlist_t *rl = router_get_routerlist();
char *version_lines = NULL;
+ int r;
networkstatus_voter_info_t *voter;
tor_assert(private_signing_key);
@@ -70,20 +116,30 @@ format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
version_lines = tor_malloc(v_len);
cp = version_lines;
if (client_versions) {
- tor_snprintf(cp, v_len-(cp-version_lines),
+ r = tor_snprintf(cp, v_len-(cp-version_lines),
"client-versions %s\n", client_versions);
+ if (r < 0) {
+ log_err(LD_BUG, "Insufficient memory for client-versions line");
+ tor_assert(0);
+ }
cp += strlen(cp);
}
- if (server_versions)
- tor_snprintf(cp, v_len-(cp-version_lines),
+ if (server_versions) {
+ r = tor_snprintf(cp, v_len-(cp-version_lines),
"server-versions %s\n", server_versions);
+ if (r < 0) {
+ log_err(LD_BUG, "Insufficient memory for server-versions line");
+ tor_assert(0);
+ }
+ }
} else {
version_lines = tor_strdup("");
}
len = 8192;
len += strlen(version_lines);
- len += (RS_ENTRY_LEN)*smartlist_len(rl->routers);
+ len += (RS_ENTRY_LEN+MICRODESC_LINE_LEN)*smartlist_len(rl->routers);
+ len += strlen("\ndirectory-footer\n");
len += v3_ns->cert->cache_info.signed_descriptor_len;
status = tor_malloc(len);
@@ -93,17 +149,25 @@ format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
char fu[ISO_TIME_LEN+1];
char vu[ISO_TIME_LEN+1];
char *flags = smartlist_join_strings(v3_ns->known_flags, " ", 0, NULL);
+ char *params;
authority_cert_t *cert = v3_ns->cert;
+ char *methods =
+ make_consensus_method_list(1, MAX_SUPPORTED_CONSENSUS_METHOD, " ");
format_iso_time(published, v3_ns->published);
format_iso_time(va, v3_ns->valid_after);
format_iso_time(fu, v3_ns->fresh_until);
format_iso_time(vu, v3_ns->valid_until);
+ if (v3_ns->net_params)
+ params = smartlist_join_strings(v3_ns->net_params, " ", 0, NULL);
+ else
+ params = tor_strdup("");
+
tor_assert(cert);
- tor_snprintf(status, len,
+ r = tor_snprintf(status, len,
"network-status-version 3\n"
"vote-status %s\n"
- "consensus-methods 1 2 3 4 5\n"
+ "consensus-methods %s\n"
"published %s\n"
"valid-after %s\n"
"fresh-until %s\n"
@@ -111,24 +175,38 @@ format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
"voting-delay %d %d\n"
"%s" /* versions */
"known-flags %s\n"
+ "params %s\n"
"dir-source %s %s %s %s %d %d\n"
"contact %s\n",
v3_ns->type == NS_TYPE_VOTE ? "vote" : "opinion",
+ methods,
published, va, fu, vu,
v3_ns->vote_seconds, v3_ns->dist_seconds,
version_lines,
flags,
+ params,
voter->nickname, fingerprint, voter->address,
- ipaddr, voter->dir_port, voter->or_port, voter->contact);
+ ipaddr, voter->dir_port, voter->or_port, voter->contact);
+ if (r < 0) {
+ log_err(LD_BUG, "Insufficient memory for network status line");
+ tor_assert(0);
+ }
+
+ tor_free(params);
tor_free(flags);
+ tor_free(methods);
outp = status + strlen(status);
endp = status + len;
if (!tor_digest_is_zero(voter->legacy_id_digest)) {
char fpbuf[HEX_DIGEST_LEN+1];
base16_encode(fpbuf, sizeof(fpbuf), voter->legacy_id_digest, DIGEST_LEN);
- tor_snprintf(outp, endp-outp, "legacy-dir-key %s\n", fpbuf);
+ r = tor_snprintf(outp, endp-outp, "legacy-dir-key %s\n", fpbuf);
+ if (r < 0) {
+ log_err(LD_BUG, "Insufficient memory for legacy-dir-key line");
+ tor_assert(0);
+ }
outp += strlen(outp);
}
@@ -139,15 +217,32 @@ format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
outp += cert->cache_info.signed_descriptor_len;
}
- SMARTLIST_FOREACH(v3_ns->routerstatus_list, vote_routerstatus_t *, vrs,
- {
+ SMARTLIST_FOREACH_BEGIN(v3_ns->routerstatus_list, vote_routerstatus_t *,
+ vrs) {
+ vote_microdesc_hash_t *h;
if (routerstatus_format_entry(outp, endp-outp, &vrs->status,
- vrs->version, 0, 0) < 0) {
+ vrs->version, NS_V3_VOTE) < 0) {
log_warn(LD_BUG, "Unable to print router status.");
goto err;
}
outp += strlen(outp);
- });
+
+ for (h = vrs->microdesc; h; h = h->next) {
+ size_t mlen = strlen(h->microdesc_hash_line);
+ if (outp+mlen >= endp) {
+ log_warn(LD_BUG, "Can't fit microdesc line in vote.");
+ }
+ memcpy(outp, h->microdesc_hash_line, mlen+1);
+ outp += strlen(outp);
+ }
+ } SMARTLIST_FOREACH_END(vrs);
+
+ r = tor_snprintf(outp, endp-outp, "directory-footer\n");
+ if (r < 0) {
+ log_err(LD_BUG, "Insufficient memory for directory-footer line");
+ tor_assert(0);
+ }
+ outp += strlen(outp);
{
char signing_key_fingerprint[FINGERPRINT_LEN+1];
@@ -170,10 +265,10 @@ format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
outp += strlen(outp);
}
- if (router_get_networkstatus_v3_hash(status, digest)<0)
+ if (router_get_networkstatus_v3_hash(status, digest, DIGEST_SHA1)<0)
goto err;
note_crypto_pk_op(SIGN_DIR);
- if (router_append_dirobj_signature(outp,endp-outp,digest,
+ if (router_append_dirobj_signature(outp,endp-outp,digest, DIGEST_LEN,
private_signing_key)<0) {
log_warn(LD_BUG, "Unable to sign networkstatus vote.");
goto err;
@@ -216,6 +311,20 @@ get_voter(const networkstatus_t *vote)
return smartlist_get(vote->voters, 0);
}
+/** Return the signature made by <b>voter</b> using the algorithm
+ * <b>alg</b>, or NULL if none is found. */
+document_signature_t *
+voter_get_sig_by_algorithm(const networkstatus_voter_info_t *voter,
+ digest_algorithm_t alg)
+{
+ if (!voter->sigs)
+ return NULL;
+ SMARTLIST_FOREACH(voter->sigs, document_signature_t *, sig,
+ if (sig->alg == alg)
+ return sig);
+ return NULL;
+}
+
/** Temporary structure used in constructing a list of dir-source entries
* for a consensus. One of these is generated for every vote, and one more
* for every legacy key in each vote. */
@@ -275,34 +384,8 @@ get_frequent_members(smartlist_t *out, smartlist_t *in, int min)
/** Given a sorted list of strings <b>lst</b>, return the member that appears
* most. Break ties in favor of later-occurring members. */
-static const char *
-get_most_frequent_member(smartlist_t *lst)
-{
- const char *most_frequent = NULL;
- int most_frequent_count = 0;
-
- const char *cur = NULL;
- int count = 0;
-
- SMARTLIST_FOREACH(lst, const char *, s,
- {
- if (cur && !strcmp(s, cur)) {
- ++count;
- } else {
- if (count >= most_frequent_count) {
- most_frequent = cur;
- most_frequent_count = count;
- }
- cur = s;
- count = 1;
- }
- });
- if (count >= most_frequent_count) {
- most_frequent = cur;
- most_frequent_count = count;
- }
- return most_frequent;
-}
+#define get_most_frequent_member(lst) \
+ smartlist_get_most_frequent_string(lst)
/** Return 0 if and only if <b>a</b> and <b>b</b> are routerstatuses
* that come from the same routerinfo, with the same derived elements.
@@ -344,7 +427,8 @@ _compare_vote_rs(const void **_a, const void **_b)
* in favor of smaller descriptor digest.
*/
static vote_routerstatus_t *
-compute_routerstatus_consensus(smartlist_t *votes)
+compute_routerstatus_consensus(smartlist_t *votes, int consensus_method,
+ char *microdesc_digest256_out)
{
vote_routerstatus_t *most = NULL, *cur = NULL;
int most_n = 0, cur_n = 0;
@@ -380,18 +464,45 @@ compute_routerstatus_consensus(smartlist_t *votes)
}
tor_assert(most);
+
+ if (consensus_method >= MIN_METHOD_FOR_MICRODESC &&
+ microdesc_digest256_out) {
+ smartlist_t *digests = smartlist_create();
+ const char *best_microdesc_digest;
+ SMARTLIST_FOREACH_BEGIN(votes, vote_routerstatus_t *, rs) {
+ char d[DIGEST256_LEN];
+ if (compare_vote_rs(rs, most))
+ continue;
+ if (!vote_routerstatus_find_microdesc_hash(d, rs, consensus_method,
+ DIGEST_SHA256))
+ smartlist_add(digests, tor_memdup(d, sizeof(d)));
+ } SMARTLIST_FOREACH_END(rs);
+ smartlist_sort_digests256(digests);
+ best_microdesc_digest = smartlist_get_most_frequent_digest256(digests);
+ if (best_microdesc_digest)
+ memcpy(microdesc_digest256_out, best_microdesc_digest, DIGEST256_LEN);
+ SMARTLIST_FOREACH(digests, char *, cp, tor_free(cp));
+ smartlist_free(digests);
+ }
+
return most;
}
-/** Given a list of strings in <b>lst</b>, set the DIGEST_LEN-byte digest at
- * <b>digest_out</b> to the hash of the concatenation of those strings. */
+/** Given a list of strings in <b>lst</b>, set the <b>len_out</b>-byte digest
+ * at <b>digest_out</b> to the hash of the concatenation of those strings,
+ * computed with the algorithm <b>alg</b>. */
static void
-hash_list_members(char *digest_out, smartlist_t *lst)
+hash_list_members(char *digest_out, size_t len_out,
+ smartlist_t *lst, digest_algorithm_t alg)
{
- crypto_digest_env_t *d = crypto_new_digest_env();
+ crypto_digest_env_t *d;
+ if (alg == DIGEST_SHA1)
+ d = crypto_new_digest_env();
+ else
+ d = crypto_new_digest256_env(alg);
SMARTLIST_FOREACH(lst, const char *, cp,
crypto_digest_add_bytes(d, cp, strlen(cp)));
- crypto_digest_get_digest(d, digest_out, DIGEST_LEN);
+ crypto_digest_get_digest(d, digest_out, len_out);
crypto_free_digest_env(d);
}
@@ -455,7 +566,31 @@ compute_consensus_method(smartlist_t *votes)
static int
consensus_method_is_supported(int method)
{
- return (method >= 1) && (method <= 5);
+ return (method >= 1) && (method <= MAX_SUPPORTED_CONSENSUS_METHOD);
+}
+
+/** Return a newly allocated string holding the numbers between low and high
+ * (inclusive) that are supported consensus methods. */
+static char *
+make_consensus_method_list(int low, int high, const char *separator)
+{
+ char *list;
+
+ char b[32];
+ int i;
+ smartlist_t *lst;
+ lst = smartlist_create();
+ for (i = low; i <= high; ++i) {
+ if (!consensus_method_is_supported(i))
+ continue;
+ tor_snprintf(b, sizeof(b), "%d", i);
+ smartlist_add(lst, tor_strdup(b));
+ }
+ list = smartlist_join_strings(lst, separator, 0, NULL);
+ tor_assert(list);
+ SMARTLIST_FOREACH(lst, char *, cp, tor_free(cp));
+ smartlist_free(lst);
+ return list;
}
/** Helper: given <b>lst</b>, a list of version strings such that every
@@ -475,6 +610,728 @@ compute_consensus_versions_list(smartlist_t *lst, int n_versioning)
return result;
}
+/** Helper: given a list of valid networkstatus_t, return a new string
+ * containing the contents of the consensus network parameter set.
+ */
+/* private */ char *
+dirvote_compute_params(smartlist_t *votes)
+{
+ int i;
+ int32_t *vals;
+
+ int cur_param_len;
+ const char *cur_param;
+ const char *eq;
+ char *result;
+
+ const int n_votes = smartlist_len(votes);
+ smartlist_t *output;
+ smartlist_t *param_list = smartlist_create();
+
+ /* We require that the parameter lists in the votes are well-formed: that
+ is, that their keywords are unique and sorted, and that their values are
+ between INT32_MIN and INT32_MAX inclusive. This should be guaranteed by
+ the parsing code. */
+
+ vals = tor_malloc(sizeof(int)*n_votes);
+
+ SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) {
+ if (!v->net_params)
+ continue;
+ smartlist_add_all(param_list, v->net_params);
+ } SMARTLIST_FOREACH_END(v);
+
+ if (smartlist_len(param_list) == 0) {
+ tor_free(vals);
+ smartlist_free(param_list);
+ return NULL;
+ }
+
+ smartlist_sort_strings(param_list);
+ i = 0;
+ cur_param = smartlist_get(param_list, 0);
+ eq = strchr(cur_param, '=');
+ tor_assert(eq);
+ cur_param_len = (int)(eq+1 - cur_param);
+
+ output = smartlist_create();
+
+ SMARTLIST_FOREACH_BEGIN(param_list, const char *, param) {
+ const char *next_param;
+ int ok=0;
+ eq = strchr(param, '=');
+ tor_assert(i<n_votes);
+ vals[i++] = (int32_t)
+ tor_parse_long(eq+1, 10, INT32_MIN, INT32_MAX, &ok, NULL);
+ tor_assert(ok);
+
+ if (param_sl_idx+1 == smartlist_len(param_list))
+ next_param = NULL;
+ else
+ next_param = smartlist_get(param_list, param_sl_idx+1);
+ if (!next_param || strncmp(next_param, param, cur_param_len)) {
+ /* We've reached the end of a series. */
+ int32_t median = median_int32(vals, i);
+ char *out_string = tor_malloc(64+cur_param_len);
+ memcpy(out_string, param, cur_param_len);
+ tor_snprintf(out_string+cur_param_len,64, "%ld", (long)median);
+ smartlist_add(output, out_string);
+
+ i = 0;
+ if (next_param) {
+ eq = strchr(next_param, '=');
+ cur_param_len = (int)(eq+1 - next_param);
+ }
+ }
+ } SMARTLIST_FOREACH_END(param);
+
+ result = smartlist_join_strings(output, " ", 0, NULL);
+ SMARTLIST_FOREACH(output, char *, cp, tor_free(cp));
+ smartlist_free(output);
+ smartlist_free(param_list);
+ tor_free(vals);
+ return result;
+}
+
+#define RANGE_CHECK(a,b,c,d,e,f,g,mx) \
+ ((a) >= 0 && (a) <= (mx) && (b) >= 0 && (b) <= (mx) && \
+ (c) >= 0 && (c) <= (mx) && (d) >= 0 && (d) <= (mx) && \
+ (e) >= 0 && (e) <= (mx) && (f) >= 0 && (f) <= (mx) && \
+ (g) >= 0 && (g) <= (mx))
+
+#define CHECK_EQ(a, b, margin) \
+ ((a)-(b) >= 0 ? (a)-(b) <= (margin) : (b)-(a) <= (margin))
+
+typedef enum {
+ BW_WEIGHTS_NO_ERROR = 0,
+ BW_WEIGHTS_RANGE_ERROR = 1,
+ BW_WEIGHTS_SUMG_ERROR = 2,
+ BW_WEIGHTS_SUME_ERROR = 3,
+ BW_WEIGHTS_SUMD_ERROR = 4,
+ BW_WEIGHTS_BALANCE_MID_ERROR = 5,
+ BW_WEIGHTS_BALANCE_EG_ERROR = 6
+} bw_weights_error_t;
+
+/**
+ * Verify that any weightings satisfy the balanced formulas.
+ */
+static bw_weights_error_t
+networkstatus_check_weights(int64_t Wgg, int64_t Wgd, int64_t Wmg,
+ int64_t Wme, int64_t Wmd, int64_t Wee,
+ int64_t Wed, int64_t scale, int64_t G,
+ int64_t M, int64_t E, int64_t D, int64_t T,
+ int64_t margin, int do_balance) {
+ bw_weights_error_t berr = BW_WEIGHTS_NO_ERROR;
+
+ // Wed + Wmd + Wgd == 1
+ if (!CHECK_EQ(Wed + Wmd + Wgd, scale, margin)) {
+ berr = BW_WEIGHTS_SUMD_ERROR;
+ goto out;
+ }
+
+ // Wmg + Wgg == 1
+ if (!CHECK_EQ(Wmg + Wgg, scale, margin)) {
+ berr = BW_WEIGHTS_SUMG_ERROR;
+ goto out;
+ }
+
+ // Wme + Wee == 1
+ if (!CHECK_EQ(Wme + Wee, scale, margin)) {
+ berr = BW_WEIGHTS_SUME_ERROR;
+ goto out;
+ }
+
+ // Verify weights within range 0->1
+ if (!RANGE_CHECK(Wgg, Wgd, Wmg, Wme, Wmd, Wed, Wee, scale)) {
+ berr = BW_WEIGHTS_RANGE_ERROR;
+ goto out;
+ }
+
+ if (do_balance) {
+ // Wgg*G + Wgd*D == Wee*E + Wed*D, already scaled
+ if (!CHECK_EQ(Wgg*G + Wgd*D, Wee*E + Wed*D, (margin*T)/3)) {
+ berr = BW_WEIGHTS_BALANCE_EG_ERROR;
+ goto out;
+ }
+
+ // Wgg*G + Wgd*D == M*scale + Wmd*D + Wme*E + Wmg*G, already scaled
+ if (!CHECK_EQ(Wgg*G + Wgd*D, M*scale + Wmd*D + Wme*E + Wmg*G,
+ (margin*T)/3)) {
+ berr = BW_WEIGHTS_BALANCE_MID_ERROR;
+ goto out;
+ }
+ }
+
+ out:
+ if (berr) {
+ log_info(LD_DIR,
+ "Bw weight mismatch %d. G="I64_FORMAT" M="I64_FORMAT
+ " E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT
+ " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
+ " Wgd=%d Wgg=%d Wme=%d Wmg=%d",
+ berr,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ (int)Wmd, (int)Wme, (int)Wmg, (int)Wed, (int)Wee,
+ (int)Wgd, (int)Wgg, (int)Wme, (int)Wmg);
+ }
+
+ return berr;
+}
+
+/**
+ * This function computes the bandwidth weights for consensus method 10.
+ *
+ * It returns true if weights could be computed, false otherwise.
+ */
+static int
+networkstatus_compute_bw_weights_v10(smartlist_t *chunks, int64_t G,
+ int64_t M, int64_t E, int64_t D,
+ int64_t T, int64_t weight_scale)
+{
+ bw_weights_error_t berr = 0;
+ int64_t Wgg = -1, Wgd = -1;
+ int64_t Wmg = -1, Wme = -1, Wmd = -1;
+ int64_t Wed = -1, Wee = -1;
+ const char *casename;
+ char buf[512];
+ int r;
+
+ if (G <= 0 || M <= 0 || E <= 0 || D <= 0) {
+ log_warn(LD_DIR, "Consensus with empty bandwidth: "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
+ " D="I64_FORMAT" T="I64_FORMAT,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ return 0;
+ }
+
+ /*
+ * Computed from cases in 3.4.3 of dir-spec.txt
+ *
+ * 1. Neither are scarce
+ * 2. Both Guard and Exit are scarce
+ * a. R+D <= S
+ * b. R+D > S
+ * 3. One of Guard or Exit is scarce
+ * a. S+D < T/3
+ * b. S+D >= T/3
+ */
+ if (3*E >= T && 3*G >= T) { // E >= T/3 && G >= T/3
+ /* Case 1: Neither are scarce. */
+ casename = "Case 1 (Wgd=Wmd=Wed)";
+ Wgd = weight_scale/3;
+ Wed = weight_scale/3;
+ Wmd = weight_scale/3;
+ Wee = (weight_scale*(E+G+M))/(3*E);
+ Wme = weight_scale - Wee;
+ Wmg = (weight_scale*(2*G-E-M))/(3*G);
+ Wgg = weight_scale - Wmg;
+
+ berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed,
+ weight_scale, G, M, E, D, T, 10, 1);
+
+ if (berr) {
+ log_warn(LD_DIR,
+ "Bw Weights error %d for %s v10. G="I64_FORMAT" M="I64_FORMAT
+ " E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT
+ " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
+ " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
+ berr, casename,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ (int)Wmd, (int)Wme, (int)Wmg, (int)Wed, (int)Wee,
+ (int)Wgd, (int)Wgg, (int)Wme, (int)Wmg, (int)weight_scale);
+ return 0;
+ }
+ } else if (3*E < T && 3*G < T) { // E < T/3 && G < T/3
+ int64_t R = MIN(E, G);
+ int64_t S = MAX(E, G);
+ /*
+ * Case 2: Both Guards and Exits are scarce
+ * Balance D between E and G, depending upon
+ * D capacity and scarcity.
+ */
+ if (R+D < S) { // Subcase a
+ Wgg = weight_scale;
+ Wee = weight_scale;
+ Wmg = 0;
+ Wme = 0;
+ Wmd = 0;
+ if (E < G) {
+ casename = "Case 2a (E scarce)";
+ Wed = weight_scale;
+ Wgd = 0;
+ } else { /* E >= G */
+ casename = "Case 2a (G scarce)";
+ Wed = 0;
+ Wgd = weight_scale;
+ }
+ } else { // Subcase b: R+D >= S
+ casename = "Case 2b1 (Wgg=1, Wmd=Wgd)";
+ Wee = (weight_scale*(E - G + M))/E;
+ Wed = (weight_scale*(D - 2*E + 4*G - 2*M))/(3*D);
+ Wme = (weight_scale*(G-M))/E;
+ Wmg = 0;
+ Wgg = weight_scale;
+ Wmd = (weight_scale - Wed)/2;
+ Wgd = (weight_scale - Wed)/2;
+
+ berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed,
+ weight_scale, G, M, E, D, T, 10, 1);
+
+ if (berr) {
+ casename = "Case 2b2 (Wgg=1, Wee=1)";
+ Wgg = weight_scale;
+ Wee = weight_scale;
+ Wed = (weight_scale*(D - 2*E + G + M))/(3*D);
+ Wmd = (weight_scale*(D - 2*M + G + E))/(3*D);
+ Wme = 0;
+ Wmg = 0;
+
+ if (Wmd < 0) { // Can happen if M > T/3
+ casename = "Case 2b3 (Wmd=0)";
+ Wmd = 0;
+ log_warn(LD_DIR,
+ "Too much Middle bandwidth on the network to calculate "
+ "balanced bandwidth-weights. Consider increasing the "
+ "number of Guard nodes by lowering the requirements.");
+ }
+ Wgd = weight_scale - Wed - Wmd;
+ berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
+ Wed, weight_scale, G, M, E, D, T, 10, 1);
+ }
+ if (berr != BW_WEIGHTS_NO_ERROR &&
+ berr != BW_WEIGHTS_BALANCE_MID_ERROR) {
+ log_warn(LD_DIR,
+ "Bw Weights error %d for %s v10. G="I64_FORMAT" M="I64_FORMAT
+ " E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT
+ " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
+ " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
+ berr, casename,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ (int)Wmd, (int)Wme, (int)Wmg, (int)Wed, (int)Wee,
+ (int)Wgd, (int)Wgg, (int)Wme, (int)Wmg, (int)weight_scale);
+ return 0;
+ }
+ }
+ } else { // if (E < T/3 || G < T/3) {
+ int64_t S = MIN(E, G);
+ // Case 3: Exactly one of Guard or Exit is scarce
+ if (!(3*E < T || 3*G < T) || !(3*G >= T || 3*E >= T)) {
+ log_warn(LD_BUG,
+ "Bw-Weights Case 3 v10 but with G="I64_FORMAT" M="
+ I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ }
+
+ if (3*(S+D) < T) { // Subcase a: S+D < T/3
+ if (G < E) {
+ casename = "Case 3a (G scarce)";
+ Wgg = Wgd = weight_scale;
+ Wmd = Wed = Wmg = 0;
+ // Minor subcase, if E is more scarce than M,
+ // keep its bandwidth in place.
+ if (E < M) Wme = 0;
+ else Wme = (weight_scale*(E-M))/(2*E);
+ Wee = weight_scale-Wme;
+ } else { // G >= E
+ casename = "Case 3a (E scarce)";
+ Wee = Wed = weight_scale;
+ Wmd = Wgd = Wme = 0;
+ // Minor subcase, if G is more scarce than M,
+ // keep its bandwidth in place.
+ if (G < M) Wmg = 0;
+ else Wmg = (weight_scale*(G-M))/(2*G);
+ Wgg = weight_scale-Wmg;
+ }
+ } else { // Subcase b: S+D >= T/3
+ // D != 0 because S+D >= T/3
+ if (G < E) {
+ casename = "Case 3bg (G scarce, Wgg=1, Wmd == Wed)";
+ Wgg = weight_scale;
+ Wgd = (weight_scale*(D - 2*G + E + M))/(3*D);
+ Wmg = 0;
+ Wee = (weight_scale*(E+M))/(2*E);
+ Wme = weight_scale - Wee;
+ Wmd = (weight_scale - Wgd)/2;
+ Wed = (weight_scale - Wgd)/2;
+
+ berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
+ Wed, weight_scale, G, M, E, D, T, 10, 1);
+ } else { // G >= E
+ casename = "Case 3be (E scarce, Wee=1, Wmd == Wgd)";
+ Wee = weight_scale;
+ Wed = (weight_scale*(D - 2*E + G + M))/(3*D);
+ Wme = 0;
+ Wgg = (weight_scale*(G+M))/(2*G);
+ Wmg = weight_scale - Wgg;
+ Wmd = (weight_scale - Wed)/2;
+ Wgd = (weight_scale - Wed)/2;
+
+ berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
+ Wed, weight_scale, G, M, E, D, T, 10, 1);
+ }
+ if (berr) {
+ log_warn(LD_DIR,
+ "Bw Weights error %d for %s v10. G="I64_FORMAT" M="I64_FORMAT
+ " E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT
+ " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
+ " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
+ berr, casename,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ (int)Wmd, (int)Wme, (int)Wmg, (int)Wed, (int)Wee,
+ (int)Wgd, (int)Wgg, (int)Wme, (int)Wmg, (int)weight_scale);
+ return 0;
+ }
+ }
+ }
+
+ /* We cast down the weights to 32 bit ints on the assumption that
+ * weight_scale is ~= 10000. We need to ensure a rogue authority
+ * doesn't break this assumption to rig our weights */
+ tor_assert(0 < weight_scale && weight_scale < INT32_MAX);
+
+ /*
+ * Provide Wgm=Wgg, Wmm=1, Wem=Wee, Weg=Wed. May later determine
+ * that middle nodes need different bandwidth weights for dirport traffic,
+ * or that weird exit policies need special weight, or that bridges
+ * need special weight.
+ *
+ * NOTE: This list is sorted.
+ */
+ r = tor_snprintf(buf, sizeof(buf),
+ "bandwidth-weights Wbd=%d Wbe=%d Wbg=%d Wbm=%d "
+ "Wdb=%d "
+ "Web=%d Wed=%d Wee=%d Weg=%d Wem=%d "
+ "Wgb=%d Wgd=%d Wgg=%d Wgm=%d "
+ "Wmb=%d Wmd=%d Wme=%d Wmg=%d Wmm=%d\n",
+ (int)Wmd, (int)Wme, (int)Wmg, (int)weight_scale,
+ (int)weight_scale,
+ (int)weight_scale, (int)Wed, (int)Wee, (int)Wed, (int)Wee,
+ (int)weight_scale, (int)Wgd, (int)Wgg, (int)Wgg,
+ (int)weight_scale, (int)Wmd, (int)Wme, (int)Wmg, (int)weight_scale);
+ if (r<0) {
+ log_warn(LD_BUG,
+ "Not enough space in buffer for bandwidth-weights line.");
+ *buf = '\0';
+ return 0;
+ }
+ smartlist_add(chunks, tor_strdup(buf));
+
+ log_notice(LD_CIRC, "Computed bandwidth weights for %s with v10: "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ return 1;
+}
+/**
+ * This function computes the bandwidth weights for consensus method 9.
+ *
+ * It has been obsoleted in favor of consensus method 10.
+ */
+static void
+networkstatus_compute_bw_weights_v9(smartlist_t *chunks, int64_t G, int64_t M,
+ int64_t E, int64_t D, int64_t T,
+ int64_t weight_scale)
+{
+ int64_t Wgg = -1, Wgd = -1;
+ int64_t Wmg = -1, Wme = -1, Wmd = -1;
+ int64_t Wed = -1, Wee = -1;
+ const char *casename;
+ char buf[512];
+ int r;
+
+ if (G <= 0 || M <= 0 || E <= 0 || D <= 0) {
+ log_warn(LD_DIR, "Consensus with empty bandwidth: "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
+ " D="I64_FORMAT" T="I64_FORMAT,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ return;
+ }
+
+ /*
+ * Computed from cases in 3.4.3 of dir-spec.txt
+ *
+ * 1. Neither are scarce
+ * 2. Both Guard and Exit are scarce
+ * a. R+D <= S
+ * b. R+D > S
+ * 3. One of Guard or Exit is scarce
+ * a. S+D < T/3
+ * b. S+D >= T/3
+ */
+ if (3*E >= T && 3*G >= T) { // E >= T/3 && G >= T/3
+ bw_weights_error_t berr = 0;
+ /* Case 1: Neither are scarce.
+ *
+ * Attempt to ensure that we have a large amount of exit bandwidth
+ * in the middle position.
+ */
+ casename = "Case 1 (Wme*E = Wmd*D)";
+ Wgg = (weight_scale*(D+E+G+M))/(3*G);
+ if (D==0) Wmd = 0;
+ else Wmd = (weight_scale*(2*D + 2*E - G - M))/(6*D);
+ Wme = (weight_scale*(2*D + 2*E - G - M))/(6*E);
+ Wee = (weight_scale*(-2*D + 4*E + G + M))/(6*E);
+ Wgd = 0;
+ Wmg = weight_scale - Wgg;
+ Wed = weight_scale - Wmd;
+
+ berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed,
+ weight_scale, G, M, E, D, T, 10, 1);
+
+ if (berr) {
+ log_warn(LD_DIR, "Bw Weights error %d for case %s. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
+ " D="I64_FORMAT" T="I64_FORMAT,
+ berr, casename,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ }
+ } else if (3*E < T && 3*G < T) { // E < T/3 && G < T/3
+ int64_t R = MIN(E, G);
+ int64_t S = MAX(E, G);
+ /*
+ * Case 2: Both Guards and Exits are scarce
+ * Balance D between E and G, depending upon
+ * D capacity and scarcity.
+ */
+ if (R+D < S) { // Subcase a
+ Wgg = weight_scale;
+ Wee = weight_scale;
+ Wmg = 0;
+ Wme = 0;
+ Wmd = 0;
+ if (E < G) {
+ casename = "Case 2a (E scarce)";
+ Wed = weight_scale;
+ Wgd = 0;
+ } else { /* E >= G */
+ casename = "Case 2a (G scarce)";
+ Wed = 0;
+ Wgd = weight_scale;
+ }
+ } else { // Subcase b: R+D > S
+ bw_weights_error_t berr = 0;
+ casename = "Case 2b (Wme*E == Wmd*D)";
+ if (D != 0) {
+ Wgg = weight_scale;
+ Wgd = (weight_scale*(D + E - 2*G + M))/(3*D); // T/3 >= G (Ok)
+ Wmd = (weight_scale*(D + E + G - 2*M))/(6*D); // T/3 >= M
+ Wme = (weight_scale*(D + E + G - 2*M))/(6*E);
+ Wee = (weight_scale*(-D + 5*E - G + 2*M))/(6*E); // 2E+M >= T/3
+ Wmg = 0;
+ Wed = weight_scale - Wgd - Wmd;
+
+ berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed,
+ weight_scale, G, M, E, D, T, 10, 1);
+ }
+
+ if (D == 0 || berr) { // Can happen if M > T/3
+ casename = "Case 2b (E=G)";
+ Wgg = weight_scale;
+ Wee = weight_scale;
+ Wmg = 0;
+ Wme = 0;
+ Wmd = 0;
+ if (D == 0) Wgd = 0;
+ else Wgd = (weight_scale*(D+E-G))/(2*D);
+ Wed = weight_scale - Wgd;
+ berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
+ Wed, weight_scale, G, M, E, D, T, 10, 1);
+ }
+ if (berr != BW_WEIGHTS_NO_ERROR &&
+ berr != BW_WEIGHTS_BALANCE_MID_ERROR) {
+ log_warn(LD_DIR, "Bw Weights error %d for case %s. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
+ " D="I64_FORMAT" T="I64_FORMAT,
+ berr, casename,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ }
+ }
+ } else { // if (E < T/3 || G < T/3) {
+ int64_t S = MIN(E, G);
+ // Case 3: Exactly one of Guard or Exit is scarce
+ if (!(3*E < T || 3*G < T) || !(3*G >= T || 3*E >= T)) {
+ log_warn(LD_BUG,
+ "Bw-Weights Case 3 but with G="I64_FORMAT" M="
+ I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ }
+
+ if (3*(S+D) < T) { // Subcase a: S+D < T/3
+ if (G < E) {
+ casename = "Case 3a (G scarce)";
+ Wgg = Wgd = weight_scale;
+ Wmd = Wed = Wmg = 0;
+ // Minor subcase, if E is more scarce than M,
+ // keep its bandwidth in place.
+ if (E < M) Wme = 0;
+ else Wme = (weight_scale*(E-M))/(2*E);
+ Wee = weight_scale-Wme;
+ } else { // G >= E
+ casename = "Case 3a (E scarce)";
+ Wee = Wed = weight_scale;
+ Wmd = Wgd = Wme = 0;
+ // Minor subcase, if G is more scarce than M,
+ // keep its bandwidth in place.
+ if (G < M) Wmg = 0;
+ else Wmg = (weight_scale*(G-M))/(2*G);
+ Wgg = weight_scale-Wmg;
+ }
+ } else { // Subcase b: S+D >= T/3
+ bw_weights_error_t berr = 0;
+ // D != 0 because S+D >= T/3
+ if (G < E) {
+ casename = "Case 3b (G scarce, Wme*E == Wmd*D)";
+ Wgd = (weight_scale*(D + E - 2*G + M))/(3*D);
+ Wmd = (weight_scale*(D + E + G - 2*M))/(6*D);
+ Wme = (weight_scale*(D + E + G - 2*M))/(6*E);
+ Wee = (weight_scale*(-D + 5*E - G + 2*M))/(6*E);
+ Wgg = weight_scale;
+ Wmg = 0;
+ Wed = weight_scale - Wgd - Wmd;
+
+ berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
+ Wed, weight_scale, G, M, E, D, T, 10, 1);
+ } else { // G >= E
+ casename = "Case 3b (E scarce, Wme*E == Wmd*D)";
+ Wgg = (weight_scale*(D + E + G + M))/(3*G);
+ Wmd = (weight_scale*(2*D + 2*E - G - M))/(6*D);
+ Wme = (weight_scale*(2*D + 2*E - G - M))/(6*E);
+ Wee = (weight_scale*(-2*D + 4*E + G + M))/(6*E);
+ Wgd = 0;
+ Wmg = weight_scale - Wgg;
+ Wed = weight_scale - Wmd;
+
+ berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
+ Wed, weight_scale, G, M, E, D, T, 10, 1);
+ }
+ if (berr) {
+ log_warn(LD_DIR, "Bw Weights error %d for case %s. "
+ "G="I64_FORMAT" M="I64_FORMAT
+ " E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT,
+ berr, casename,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ }
+ }
+ }
+
+ /* We cast down the weights to 32 bit ints on the assumption that
+ * weight_scale is ~= 10000. We need to ensure a rogue authority
+ * doesn't break this assumption to rig our weights */
+ tor_assert(0 < weight_scale && weight_scale < INT32_MAX);
+
+ if (Wgg < 0 || Wgg > weight_scale) {
+ log_warn(LD_DIR, "Bw %s: Wgg="I64_FORMAT"! G="I64_FORMAT
+ " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename, I64_PRINTF_ARG(Wgg),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+
+ Wgg = MAX(MIN(Wgg, weight_scale), 0);
+ }
+ if (Wgd < 0 || Wgd > weight_scale) {
+ log_warn(LD_DIR, "Bw %s: Wgd="I64_FORMAT"! G="I64_FORMAT
+ " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename, I64_PRINTF_ARG(Wgd),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ Wgd = MAX(MIN(Wgd, weight_scale), 0);
+ }
+ if (Wmg < 0 || Wmg > weight_scale) {
+ log_warn(LD_DIR, "Bw %s: Wmg="I64_FORMAT"! G="I64_FORMAT
+ " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename, I64_PRINTF_ARG(Wmg),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ Wmg = MAX(MIN(Wmg, weight_scale), 0);
+ }
+ if (Wme < 0 || Wme > weight_scale) {
+ log_warn(LD_DIR, "Bw %s: Wme="I64_FORMAT"! G="I64_FORMAT
+ " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename, I64_PRINTF_ARG(Wme),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ Wme = MAX(MIN(Wme, weight_scale), 0);
+ }
+ if (Wmd < 0 || Wmd > weight_scale) {
+ log_warn(LD_DIR, "Bw %s: Wmd="I64_FORMAT"! G="I64_FORMAT
+ " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename, I64_PRINTF_ARG(Wmd),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ Wmd = MAX(MIN(Wmd, weight_scale), 0);
+ }
+ if (Wee < 0 || Wee > weight_scale) {
+ log_warn(LD_DIR, "Bw %s: Wee="I64_FORMAT"! G="I64_FORMAT
+ " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename, I64_PRINTF_ARG(Wee),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ Wee = MAX(MIN(Wee, weight_scale), 0);
+ }
+ if (Wed < 0 || Wed > weight_scale) {
+ log_warn(LD_DIR, "Bw %s: Wed="I64_FORMAT"! G="I64_FORMAT
+ " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename, I64_PRINTF_ARG(Wed),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ Wed = MAX(MIN(Wed, weight_scale), 0);
+ }
+
+ // Add consensus weight keywords
+ smartlist_add(chunks, tor_strdup("bandwidth-weights "));
+ /*
+ * Provide Wgm=Wgg, Wmm=1, Wem=Wee, Weg=Wed. May later determine
+ * that middle nodes need different bandwidth weights for dirport traffic,
+ * or that weird exit policies need special weight, or that bridges
+ * need special weight.
+ *
+ * NOTE: This list is sorted.
+ */
+ r = tor_snprintf(buf, sizeof(buf),
+ "Wbd=%d Wbe=%d Wbg=%d Wbm=%d "
+ "Wdb=%d "
+ "Web=%d Wed=%d Wee=%d Weg=%d Wem=%d "
+ "Wgb=%d Wgd=%d Wgg=%d Wgm=%d "
+ "Wmb=%d Wmd=%d Wme=%d Wmg=%d Wmm=%d\n",
+ (int)Wmd, (int)Wme, (int)Wmg, (int)weight_scale,
+ (int)weight_scale,
+ (int)weight_scale, (int)Wed, (int)Wee, (int)Wed, (int)Wee,
+ (int)weight_scale, (int)Wgd, (int)Wgg, (int)Wgg,
+ (int)weight_scale, (int)Wmd, (int)Wme, (int)Wmg, (int)weight_scale);
+ if (r<0) {
+ log_warn(LD_BUG,
+ "Not enough space in buffer for bandwidth-weights line.");
+ *buf = '\0';
+ }
+ smartlist_add(chunks, tor_strdup(buf));
+ log_notice(LD_CIRC, "Computed bandwidth weights for %s with v9: "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+}
+
/** Given a list of vote networkstatus_t in <b>votes</b>, our public
* authority <b>identity_key</b>, our private authority <b>signing_key</b>,
* and the number of <b>total_authorities</b> that we believe exist in our
@@ -489,18 +1346,27 @@ networkstatus_compute_consensus(smartlist_t *votes,
crypto_pk_env_t *identity_key,
crypto_pk_env_t *signing_key,
const char *legacy_id_key_digest,
- crypto_pk_env_t *legacy_signing_key)
+ crypto_pk_env_t *legacy_signing_key,
+ consensus_flavor_t flavor)
{
smartlist_t *chunks;
char *result = NULL;
int consensus_method;
-
time_t valid_after, fresh_until, valid_until;
int vote_seconds, dist_seconds;
char *client_versions = NULL, *server_versions = NULL;
smartlist_t *flags;
+ const char *flavor_name;
+ int64_t G=0, M=0, E=0, D=0, T=0; /* For bandwidth weights */
+ const routerstatus_format_type_t rs_format =
+ flavor == FLAV_NS ? NS_V3_CONSENSUS : NS_V3_CONSENSUS_MICRODESC;
+ char *params = NULL;
+ int added_weights = 0;
+ tor_assert(flavor == FLAV_NS || flavor == FLAV_MICRODESC);
tor_assert(total_authorities >= smartlist_len(votes));
+ flavor_name = networkstatus_get_flavor_name(flavor);
+
if (!smartlist_len(votes)) {
log_warn(LD_DIR, "Can't compute a consensus from no votes.");
return NULL;
@@ -593,7 +1459,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
chunks = smartlist_create();
{
- char buf[1024];
+ char *buf=NULL;
char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
vu_buf[ISO_TIME_LEN+1];
char *flaglist;
@@ -602,16 +1468,20 @@ networkstatus_compute_consensus(smartlist_t *votes,
format_iso_time(vu_buf, valid_until);
flaglist = smartlist_join_strings(flags, " ", 0, NULL);
- smartlist_add(chunks, tor_strdup("network-status-version 3\n"
- "vote-status consensus\n"));
+ tor_asprintf(&buf, "network-status-version 3%s%s\n"
+ "vote-status consensus\n",
+ flavor == FLAV_NS ? "" : " ",
+ flavor == FLAV_NS ? "" : flavor_name);
+
+ smartlist_add(chunks, buf);
if (consensus_method >= 2) {
- tor_snprintf(buf, sizeof(buf), "consensus-method %d\n",
+ tor_asprintf(&buf, "consensus-method %d\n",
consensus_method);
- smartlist_add(chunks, tor_strdup(buf));
+ smartlist_add(chunks, buf);
}
- tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(&buf,
"valid-after %s\n"
"fresh-until %s\n"
"valid-until %s\n"
@@ -622,18 +1492,26 @@ networkstatus_compute_consensus(smartlist_t *votes,
va_buf, fu_buf, vu_buf,
vote_seconds, dist_seconds,
client_versions, server_versions, flaglist);
- smartlist_add(chunks, tor_strdup(buf));
+ smartlist_add(chunks, buf);
tor_free(flaglist);
}
+ if (consensus_method >= MIN_METHOD_FOR_PARAMS) {
+ params = dirvote_compute_params(votes);
+ if (params) {
+ smartlist_add(chunks, tor_strdup("params "));
+ smartlist_add(chunks, params);
+ smartlist_add(chunks, tor_strdup("\n"));
+ }
+ }
+
/* Sort the votes. */
smartlist_sort(votes, _compare_votes_by_authority_id);
/* Add the authority sections. */
{
smartlist_t *dir_sources = smartlist_create();
- SMARTLIST_FOREACH(votes, networkstatus_t *, v,
- {
+ SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) {
dir_src_ent_t *e = tor_malloc_zero(sizeof(dir_src_ent_t));
e->v = v;
e->digest = get_voter(v)->identity_digest;
@@ -647,18 +1525,17 @@ networkstatus_compute_consensus(smartlist_t *votes,
e_legacy->is_legacy = 1;
smartlist_add(dir_sources, e_legacy);
}
- });
+ } SMARTLIST_FOREACH_END(v);
smartlist_sort(dir_sources, _compare_dir_src_ents_by_authority_id);
- SMARTLIST_FOREACH(dir_sources, const dir_src_ent_t *, e,
- {
- char buf[1024];
+ SMARTLIST_FOREACH_BEGIN(dir_sources, const dir_src_ent_t *, e) {
struct in_addr in;
char ip[INET_NTOA_BUF_LEN];
char fingerprint[HEX_DIGEST_LEN+1];
char votedigest[HEX_DIGEST_LEN+1];
networkstatus_t *v = e->v;
networkstatus_voter_info_t *voter = get_voter(v);
+ char *buf = NULL;
if (e->is_legacy)
tor_assert(consensus_method >= 2);
@@ -669,22 +1546,22 @@ networkstatus_compute_consensus(smartlist_t *votes,
base16_encode(votedigest, sizeof(votedigest), voter->vote_digest,
DIGEST_LEN);
- tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(&buf,
"dir-source %s%s %s %s %s %d %d\n",
voter->nickname, e->is_legacy ? "-legacy" : "",
fingerprint, voter->address, ip,
voter->dir_port,
voter->or_port);
- smartlist_add(chunks, tor_strdup(buf));
+ smartlist_add(chunks, buf);
if (! e->is_legacy) {
- tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(&buf,
"contact %s\n"
"vote-digest %s\n",
voter->contact,
votedigest);
- smartlist_add(chunks, tor_strdup(buf));
+ smartlist_add(chunks, buf);
}
- });
+ } SMARTLIST_FOREACH_END(e);
SMARTLIST_FOREACH(dir_sources, dir_src_ent_t *, e, tor_free(e));
smartlist_free(dir_sources);
}
@@ -701,7 +1578,10 @@ networkstatus_compute_consensus(smartlist_t *votes,
smartlist_t *versions = smartlist_create();
smartlist_t *exitsummaries = smartlist_create();
uint32_t *bandwidths = tor_malloc(sizeof(uint32_t) * smartlist_len(votes));
+ uint32_t *measured_bws = tor_malloc(sizeof(uint32_t) *
+ smartlist_len(votes));
int num_bandwidths;
+ int num_mbws;
int *n_voter_flags; /* n_voter_flags[j] is the number of flags that
* votes[j] knows about. */
@@ -813,10 +1693,12 @@ networkstatus_compute_consensus(smartlist_t *votes,
const char *chosen_name = NULL;
int exitsummary_disagreement = 0;
int is_named = 0, is_unnamed = 0, is_running = 0;
+ int is_guard = 0, is_exit = 0;
int naming_conflict = 0;
int n_listing = 0;
int i;
- char buf[256];
+ char *buf=NULL;
+ char microdesc_digest[DIGEST256_LEN];
/* Of the next-to-be-considered digest in each voter, which is first? */
SMARTLIST_FOREACH(votes, networkstatus_t *, v, {
@@ -835,6 +1717,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
smartlist_clear(chosen_flags);
smartlist_clear(versions);
num_bandwidths = 0;
+ num_mbws = 0;
/* Okay, go through all the entries for this digest. */
SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) {
@@ -868,6 +1751,9 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
/* count bandwidths */
+ if (rs->status.has_measured_bw)
+ measured_bws[num_mbws++] = rs->status.measured_bw;
+
if (rs->status.has_bandwidth)
bandwidths[num_bandwidths++] = rs->status.bandwidth;
} SMARTLIST_FOREACH_END(v);
@@ -879,7 +1765,9 @@ networkstatus_compute_consensus(smartlist_t *votes,
/* Figure out the most popular opinion of what the most recent
* routerinfo and its contents are. */
- rs = compute_routerstatus_consensus(matching_descs);
+ memset(microdesc_digest, 0, sizeof(microdesc_digest));
+ rs = compute_routerstatus_consensus(matching_descs, consensus_method,
+ microdesc_digest);
/* Copy bits of that into rs_out. */
tor_assert(!memcmp(lowest_id, rs->status.identity_digest, DIGEST_LEN));
memcpy(rs_out.identity_digest, lowest_id, DIGEST_LEN);
@@ -925,7 +1813,11 @@ networkstatus_compute_consensus(smartlist_t *votes,
} else {
if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2) {
smartlist_add(chosen_flags, (char*)fl);
- if (!strcmp(fl, "Running"))
+ if (!strcmp(fl, "Exit"))
+ is_exit = 1;
+ else if (!strcmp(fl, "Guard"))
+ is_guard = 1;
+ else if (!strcmp(fl, "Running"))
is_running = 1;
}
}
@@ -945,11 +1837,31 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
/* Pick a bandwidth */
- if (consensus_method >= 5 && num_bandwidths > 0) {
+ if (consensus_method >= 6 && num_mbws > 2) {
+ rs_out.has_bandwidth = 1;
+ rs_out.bandwidth = median_uint32(measured_bws, num_mbws);
+ } else if (consensus_method >= 5 && num_bandwidths > 0) {
rs_out.has_bandwidth = 1;
rs_out.bandwidth = median_uint32(bandwidths, num_bandwidths);
}
+ if (consensus_method >= MIN_METHOD_FOR_BW_WEIGHTS) {
+ if (rs_out.has_bandwidth) {
+ T += rs_out.bandwidth;
+ if (is_exit && is_guard)
+ D += rs_out.bandwidth;
+ else if (is_exit)
+ E += rs_out.bandwidth;
+ else if (is_guard)
+ G += rs_out.bandwidth;
+ else
+ M += rs_out.bandwidth;
+ } else {
+ log_warn(LD_BUG, "Missing consensus bandwidth for router %s",
+ rs_out.nickname);
+ }
+ }
+
/* Ok, we already picked a descriptor digest we want to list
* previously. Now we want to use the exit policy summary from
* that descriptor. If everybody plays nice all the voters who
@@ -1034,11 +1946,23 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
}
- /* Okay!! Now we can write the descriptor... */
- /* First line goes into "buf". */
- routerstatus_format_entry(buf, sizeof(buf), &rs_out, NULL, 1, 0);
- smartlist_add(chunks, tor_strdup(buf));
- /* Second line is all flags. The "\n" is missing. */
+ {
+ char buf[4096];
+ /* Okay!! Now we can write the descriptor... */
+ /* First line goes into "buf". */
+ routerstatus_format_entry(buf, sizeof(buf), &rs_out, NULL,
+ rs_format);
+ smartlist_add(chunks, tor_strdup(buf));
+ }
+ /* Now an m line, if applicable. */
+ if (flavor == FLAV_MICRODESC &&
+ !tor_digest256_is_zero(microdesc_digest)) {
+ char m[BASE64_DIGEST256_LEN+1], *cp;
+ digest256_to_base64(m, microdesc_digest);
+ tor_asprintf(&cp, "m %s\n", m);
+ smartlist_add(chunks, cp);
+ }
+ /* Next line is all flags. The "\n" is missing. */
smartlist_add(chunks,
smartlist_join_strings(chosen_flags, " ", 0, NULL));
/* Now the version line. */
@@ -1049,24 +1973,16 @@ networkstatus_compute_consensus(smartlist_t *votes,
smartlist_add(chunks, tor_strdup("\n"));
/* Now the weight line. */
if (rs_out.has_bandwidth) {
- int r = tor_snprintf(buf, sizeof(buf),
- "w Bandwidth=%d\n", rs_out.bandwidth);
- if (r<0) {
- log_warn(LD_BUG, "Not enough space in buffer for weight line.");
- *buf = '\0';
- }
- smartlist_add(chunks, tor_strdup(buf));
- };
+ char *cp=NULL;
+ tor_asprintf(&cp, "w Bandwidth=%d\n", rs_out.bandwidth);
+ smartlist_add(chunks, cp);
+ }
+
/* Now the exitpolicy summary line. */
- if (rs_out.has_exitsummary) {
- char buf[MAX_POLICY_LINE_LEN+1];
- int r = tor_snprintf(buf, sizeof(buf), "p %s\n", rs_out.exitsummary);
- if (r<0) {
- log_warn(LD_BUG, "Not enough space in buffer for exitpolicy line.");
- *buf = '\0';
- }
- smartlist_add(chunks, tor_strdup(buf));
- };
+ if (rs_out.has_exitsummary && flavor == FLAV_NS) {
+ tor_asprintf(&buf, "p %s\n", rs_out.exitsummary);
+ smartlist_add(chunks, buf);
+ }
/* And the loop is over and we move on to the next router */
}
@@ -1087,34 +2003,97 @@ networkstatus_compute_consensus(smartlist_t *votes,
smartlist_free(versions);
smartlist_free(exitsummaries);
tor_free(bandwidths);
+ tor_free(measured_bws);
+ }
+
+ if (consensus_method >= MIN_METHOD_FOR_FOOTER) {
+ /* Starting with consensus method 9, we clearly mark the directory
+ * footer region */
+ smartlist_add(chunks, tor_strdup("directory-footer\n"));
+ }
+
+ if (consensus_method >= MIN_METHOD_FOR_BW_WEIGHTS) {
+ int64_t weight_scale = BW_WEIGHT_SCALE;
+ char *bw_weight_param = NULL;
+
+ // Parse params, extract BW_WEIGHT_SCALE if present
+ // DO NOT use consensus_param_bw_weight_scale() in this code!
+ // The consensus is not formed yet!
+ if (params) {
+ if (strcmpstart(params, "bwweightscale=") == 0)
+ bw_weight_param = params;
+ else
+ bw_weight_param = strstr(params, " bwweightscale=");
+ }
+
+ if (bw_weight_param) {
+ int ok=0;
+ char *eq = strchr(bw_weight_param, '=');
+ if (eq) {
+ weight_scale = tor_parse_long(eq+1, 10, INT32_MIN, INT32_MAX, &ok,
+ NULL);
+ if (!ok) {
+ log_warn(LD_DIR, "Bad element '%s' in bw weight param",
+ escaped(bw_weight_param));
+ weight_scale = BW_WEIGHT_SCALE;
+ }
+ } else {
+ log_warn(LD_DIR, "Bad element '%s' in bw weight param",
+ escaped(bw_weight_param));
+ weight_scale = BW_WEIGHT_SCALE;
+ }
+ }
+
+ if (consensus_method < 10) {
+ networkstatus_compute_bw_weights_v9(chunks, G, M, E, D, T, weight_scale);
+ added_weights = 1;
+ } else {
+ added_weights = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D,
+ T, weight_scale);
+ }
}
/* Add a signature. */
{
- char digest[DIGEST_LEN];
+ char digest[DIGEST256_LEN];
char fingerprint[HEX_DIGEST_LEN+1];
char signing_key_fingerprint[HEX_DIGEST_LEN+1];
+ digest_algorithm_t digest_alg =
+ flavor == FLAV_NS ? DIGEST_SHA1 : DIGEST_SHA256;
+ size_t digest_len =
+ flavor == FLAV_NS ? DIGEST_LEN : DIGEST256_LEN;
+ const char *algname = crypto_digest_algorithm_get_name(digest_alg);
+ char *buf = NULL;
+ char sigbuf[4096];
- char buf[4096];
smartlist_add(chunks, tor_strdup("directory-signature "));
/* Compute the hash of the chunks. */
- hash_list_members(digest, chunks);
+ hash_list_members(digest, digest_len, chunks, digest_alg);
/* Get the fingerprints */
crypto_pk_get_fingerprint(identity_key, fingerprint, 0);
crypto_pk_get_fingerprint(signing_key, signing_key_fingerprint, 0);
/* add the junk that will go at the end of the line. */
- tor_snprintf(buf, sizeof(buf), "%s %s\n", fingerprint,
- signing_key_fingerprint);
+ if (flavor == FLAV_NS) {
+ tor_asprintf(&buf, "%s %s\n", fingerprint,
+ signing_key_fingerprint);
+ } else {
+ tor_asprintf(&buf, "%s %s %s\n",
+ algname, fingerprint,
+ signing_key_fingerprint);
+ }
+ smartlist_add(chunks, buf);
/* And the signature. */
- if (router_append_dirobj_signature(buf, sizeof(buf), digest,
+ sigbuf[0] = '\0';
+ if (router_append_dirobj_signature(sigbuf, sizeof(sigbuf),
+ digest, digest_len,
signing_key)) {
log_warn(LD_BUG, "Couldn't sign consensus networkstatus.");
return NULL; /* This leaks, but it should never happen. */
}
- smartlist_add(chunks, tor_strdup(buf));
+ smartlist_add(chunks, tor_strdup(sigbuf));
if (legacy_id_key_digest && legacy_signing_key && consensus_method >= 3) {
smartlist_add(chunks, tor_strdup("directory-signature "));
@@ -1122,14 +2101,23 @@ networkstatus_compute_consensus(smartlist_t *votes,
legacy_id_key_digest, DIGEST_LEN);
crypto_pk_get_fingerprint(legacy_signing_key,
signing_key_fingerprint, 0);
- tor_snprintf(buf, sizeof(buf), "%s %s\n", fingerprint,
- signing_key_fingerprint);
- if (router_append_dirobj_signature(buf, sizeof(buf), digest,
+ if (flavor == FLAV_NS) {
+ tor_asprintf(&buf, "%s %s\n", fingerprint,
+ signing_key_fingerprint);
+ } else {
+ tor_asprintf(&buf, "%s %s %s\n",
+ algname, fingerprint,
+ signing_key_fingerprint);
+ }
+ smartlist_add(chunks, buf);
+ sigbuf[0] = '\0';
+ if (router_append_dirobj_signature(sigbuf, sizeof(sigbuf),
+ digest, digest_len,
legacy_signing_key)) {
log_warn(LD_BUG, "Couldn't sign consensus networkstatus.");
return NULL; /* This leaks, but it should never happen. */
}
- smartlist_add(chunks, tor_strdup(buf));
+ smartlist_add(chunks, tor_strdup(sigbuf));
}
}
@@ -1146,11 +2134,15 @@ networkstatus_compute_consensus(smartlist_t *votes,
networkstatus_t *c;
if (!(c = networkstatus_parse_vote_from_string(result, NULL,
NS_TYPE_CONSENSUS))) {
- log_err(LD_BUG,"Generated a networkstatus consensus we couldn't "
+ log_err(LD_BUG, "Generated a networkstatus consensus we couldn't "
"parse.");
tor_free(result);
return NULL;
}
+ // Verify balancing parameters
+ if (consensus_method >= MIN_METHOD_FOR_BW_WEIGHTS && added_weights) {
+ networkstatus_verify_bw_weights(c);
+ }
networkstatus_vote_free(c);
}
@@ -1171,10 +2163,14 @@ networkstatus_add_detached_signatures(networkstatus_t *target,
const char **msg_out)
{
int r = 0;
+ const char *flavor;
+ smartlist_t *siglist;
tor_assert(sigs);
tor_assert(target);
tor_assert(target->type == NS_TYPE_CONSENSUS);
+ flavor = networkstatus_get_flavor_name(target->flavor);
+
/* Do the times seem right? */
if (target->valid_after != sigs->valid_after) {
*msg_out = "Valid-After times do not match "
@@ -1191,79 +2187,179 @@ networkstatus_add_detached_signatures(networkstatus_t *target,
"when adding detached signatures to consensus";
return -1;
}
- /* Are they the same consensus? */
- if (memcmp(target->networkstatus_digest, sigs->networkstatus_digest,
- DIGEST_LEN)) {
- *msg_out = "Digest mismatch when adding detached signatures to consensus";
+ siglist = strmap_get(sigs->signatures, flavor);
+ if (!siglist) {
+ *msg_out = "No signatures for given consensus flavor";
return -1;
}
- /* For each voter in src... */
- SMARTLIST_FOREACH_BEGIN(sigs->signatures, networkstatus_voter_info_t *,
- src_voter) {
- char voter_identity[HEX_DIGEST_LEN+1];
- networkstatus_voter_info_t *target_voter =
- networkstatus_get_voter_by_id(target, src_voter->identity_digest);
- authority_cert_t *cert = NULL;
-
- base16_encode(voter_identity, sizeof(voter_identity),
- src_voter->identity_digest, DIGEST_LEN);
- log_info(LD_DIR, "Looking at signature from %s", voter_identity);
- /* If the target doesn't know about this voter, then forget it. */
- if (!target_voter) {
- log_info(LD_DIR, "We do not know about %s", voter_identity);
- continue;
+ /** Make sure all the digests we know match, and at least one matches. */
+ {
+ digests_t *digests = strmap_get(sigs->digests, flavor);
+ int n_matches = 0;
+ digest_algorithm_t alg;
+ if (!digests) {
+ *msg_out = "No digests for given consensus flavor";
+ return -1;
+ }
+ for (alg = DIGEST_SHA1; alg < N_DIGEST_ALGORITHMS; ++alg) {
+ if (!tor_mem_is_zero(digests->d[alg], DIGEST256_LEN)) {
+ if (!memcmp(target->digests.d[alg], digests->d[alg], DIGEST256_LEN)) {
+ ++n_matches;
+ } else {
+ *msg_out = "Mismatched digest.";
+ return -1;
+ }
}
+ }
+ if (!n_matches) {
+ *msg_out = "No regognized digests for given consensus flavor";
+ }
+ }
- /* If the target already has a good signature from this voter, then skip
- * this one. */
- if (target_voter->good_signature) {
- log_info(LD_DIR, "We already have a good signature from %s",
- voter_identity);
- continue;
- }
+ /* For each voter in src... */
+ SMARTLIST_FOREACH_BEGIN(siglist, document_signature_t *, sig) {
+ char voter_identity[HEX_DIGEST_LEN+1];
+ networkstatus_voter_info_t *target_voter =
+ networkstatus_get_voter_by_id(target, sig->identity_digest);
+ authority_cert_t *cert = NULL;
+ const char *algorithm;
+ document_signature_t *old_sig = NULL;
+
+ algorithm = crypto_digest_algorithm_get_name(sig->alg);
+
+ base16_encode(voter_identity, sizeof(voter_identity),
+ sig->identity_digest, DIGEST_LEN);
+ log_info(LD_DIR, "Looking at signature from %s using %s", voter_identity,
+ algorithm);
+ /* If the target doesn't know about this voter, then forget it. */
+ if (!target_voter) {
+ log_info(LD_DIR, "We do not know any voter with ID %s", voter_identity);
+ continue;
+ }
- /* Try checking the signature if we haven't already. */
- if (!src_voter->good_signature && !src_voter->bad_signature) {
- cert = authority_cert_get_by_digests(src_voter->identity_digest,
- src_voter->signing_key_digest);
- if (cert) {
- networkstatus_check_voter_signature(target, src_voter, cert);
- }
+ old_sig = voter_get_sig_by_algorithm(target_voter, sig->alg);
+
+ /* If the target already has a good signature from this voter, then skip
+ * this one. */
+ if (old_sig && old_sig->good_signature) {
+ log_info(LD_DIR, "We already have a good signature from %s using %s",
+ voter_identity, algorithm);
+ continue;
+ }
+
+ /* Try checking the signature if we haven't already. */
+ if (!sig->good_signature && !sig->bad_signature) {
+ cert = authority_cert_get_by_digests(sig->identity_digest,
+ sig->signing_key_digest);
+ if (cert)
+ networkstatus_check_document_signature(target, sig, cert);
+ }
+
+ /* If this signature is good, or we don't have any signature yet,
+ * then maybe add it. */
+ if (sig->good_signature || !old_sig || old_sig->bad_signature) {
+ log_info(LD_DIR, "Adding signature from %s with %s", voter_identity,
+ algorithm);
+ ++r;
+ if (old_sig) {
+ smartlist_remove(target_voter->sigs, old_sig);
+ document_signature_free(old_sig);
}
+ smartlist_add(target_voter->sigs, document_signature_dup(sig));
+ } else {
+ log_info(LD_DIR, "Not adding signature from %s", voter_identity);
+ }
+ } SMARTLIST_FOREACH_END(sig);
+
+ return r;
+}
+
+/** Return a newly allocated string containing all the signatures on
+ * <b>consensus</b> by all voters. If <b>for_detached_signatures</b> is true,
+ * then the signatures will be put in a detached signatures document, so
+ * prefix any non-NS-flavored signatures with "additional-signature" rather
+ * than "directory-signature". */
+static char *
+networkstatus_format_signatures(networkstatus_t *consensus,
+ int for_detached_signatures)
+{
+ smartlist_t *elements;
+ char buf[4096];
+ char *result = NULL;
+ int n_sigs = 0;
+ const consensus_flavor_t flavor = consensus->flavor;
+ const char *flavor_name = networkstatus_get_flavor_name(flavor);
+ const char *keyword;
+
+ if (for_detached_signatures && flavor != FLAV_NS)
+ keyword = "additional-signature";
+ else
+ keyword = "directory-signature";
+
+ elements = smartlist_create();
- /* If this signature is good, or we don't have any signature yet,
- * then add it. */
- if (src_voter->good_signature || !target_voter->signature) {
- log_info(LD_DIR, "Adding signature from %s", voter_identity);
- ++r;
- tor_free(target_voter->signature);
- target_voter->signature =
- tor_memdup(src_voter->signature, src_voter->signature_len);
- memcpy(target_voter->signing_key_digest, src_voter->signing_key_digest,
- DIGEST_LEN);
- target_voter->signature_len = src_voter->signature_len;
- target_voter->good_signature = src_voter->good_signature;
- target_voter->bad_signature = src_voter->bad_signature;
+ SMARTLIST_FOREACH_BEGIN(consensus->voters, networkstatus_voter_info_t *, v) {
+ SMARTLIST_FOREACH_BEGIN(v->sigs, document_signature_t *, sig) {
+ char sk[HEX_DIGEST_LEN+1];
+ char id[HEX_DIGEST_LEN+1];
+ if (!sig->signature || sig->bad_signature)
+ continue;
+ ++n_sigs;
+ base16_encode(sk, sizeof(sk), sig->signing_key_digest, DIGEST_LEN);
+ base16_encode(id, sizeof(id), sig->identity_digest, DIGEST_LEN);
+ if (flavor == FLAV_NS) {
+ tor_snprintf(buf, sizeof(buf),
+ "%s %s %s\n-----BEGIN SIGNATURE-----\n",
+ keyword, id, sk);
} else {
- log_info(LD_DIR, "Not adding signature from %s", voter_identity);
+ const char *digest_name =
+ crypto_digest_algorithm_get_name(sig->alg);
+ tor_snprintf(buf, sizeof(buf),
+ "%s%s%s %s %s %s\n-----BEGIN SIGNATURE-----\n",
+ keyword,
+ for_detached_signatures ? " " : "",
+ for_detached_signatures ? flavor_name : "",
+ digest_name, id, sk);
}
- } SMARTLIST_FOREACH_END(src_voter);
+ smartlist_add(elements, tor_strdup(buf));
+ base64_encode(buf, sizeof(buf), sig->signature, sig->signature_len);
+ strlcat(buf, "-----END SIGNATURE-----\n", sizeof(buf));
+ smartlist_add(elements, tor_strdup(buf));
+ } SMARTLIST_FOREACH_END(sig);
+ } SMARTLIST_FOREACH_END(v);
- return r;
+ result = smartlist_join_strings(elements, "", 0, NULL);
+ SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
+ smartlist_free(elements);
+ if (!n_sigs)
+ tor_free(result);
+ return result;
}
/** Return a newly allocated string holding the detached-signatures document
- * corresponding to the signatures on <b>consensus</b>. */
+ * corresponding to the signatures on <b>consensuses</b>, which must contain
+ * exactly one FLAV_NS consensus, and no more than one consensus for each
+ * other flavor. */
char *
-networkstatus_get_detached_signatures(networkstatus_t *consensus)
+networkstatus_get_detached_signatures(smartlist_t *consensuses)
{
smartlist_t *elements;
char buf[4096];
- char *result = NULL;
- int n_sigs = 0;
- tor_assert(consensus);
- tor_assert(consensus->type == NS_TYPE_CONSENSUS);
+ char *result = NULL, *sigs = NULL;
+ networkstatus_t *consensus_ns = NULL;
+ tor_assert(consensuses);
+
+ SMARTLIST_FOREACH(consensuses, networkstatus_t *, ns, {
+ tor_assert(ns);
+ tor_assert(ns->type == NS_TYPE_CONSENSUS);
+ if (ns && ns->flavor == FLAV_NS)
+ consensus_ns = ns;
+ });
+ if (!consensus_ns) {
+ log_warn(LD_BUG, "No NS consensus given.");
+ return NULL;
+ }
elements = smartlist_create();
@@ -1272,10 +2368,11 @@ networkstatus_get_detached_signatures(networkstatus_t *consensus)
vu_buf[ISO_TIME_LEN+1];
char d[HEX_DIGEST_LEN+1];
- base16_encode(d, sizeof(d), consensus->networkstatus_digest, DIGEST_LEN);
- format_iso_time(va_buf, consensus->valid_after);
- format_iso_time(fu_buf, consensus->fresh_until);
- format_iso_time(vu_buf, consensus->valid_until);
+ base16_encode(d, sizeof(d),
+ consensus_ns->digests.d[DIGEST_SHA1], DIGEST_LEN);
+ format_iso_time(va_buf, consensus_ns->valid_after);
+ format_iso_time(fu_buf, consensus_ns->fresh_until);
+ format_iso_time(vu_buf, consensus_ns->valid_until);
tor_snprintf(buf, sizeof(buf),
"consensus-digest %s\n"
@@ -1285,45 +2382,89 @@ networkstatus_get_detached_signatures(networkstatus_t *consensus)
smartlist_add(elements, tor_strdup(buf));
}
- SMARTLIST_FOREACH(consensus->voters, networkstatus_voter_info_t *, v,
- {
- char sk[HEX_DIGEST_LEN+1];
- char id[HEX_DIGEST_LEN+1];
- if (!v->signature || v->bad_signature)
+ /* Get all the digests for the non-FLAV_NS consensuses */
+ SMARTLIST_FOREACH_BEGIN(consensuses, networkstatus_t *, ns) {
+ const char *flavor_name = networkstatus_get_flavor_name(ns->flavor);
+ int alg;
+ if (ns->flavor == FLAV_NS)
+ continue;
+
+ /* start with SHA256; we don't include SHA1 for anything but the basic
+ * consensus. */
+ for (alg = DIGEST_SHA256; alg < N_DIGEST_ALGORITHMS; ++alg) {
+ char d[HEX_DIGEST256_LEN+1];
+ const char *alg_name =
+ crypto_digest_algorithm_get_name(alg);
+ if (tor_mem_is_zero(ns->digests.d[alg], DIGEST256_LEN))
continue;
- ++n_sigs;
- base16_encode(sk, sizeof(sk), v->signing_key_digest, DIGEST_LEN);
- base16_encode(id, sizeof(id), v->identity_digest, DIGEST_LEN);
- tor_snprintf(buf, sizeof(buf),
- "directory-signature %s %s\n-----BEGIN SIGNATURE-----\n",
- id, sk);
- smartlist_add(elements, tor_strdup(buf));
- base64_encode(buf, sizeof(buf), v->signature, v->signature_len);
- strlcat(buf, "-----END SIGNATURE-----\n", sizeof(buf));
+ base16_encode(d, sizeof(d), ns->digests.d[alg], DIGEST256_LEN);
+ tor_snprintf(buf, sizeof(buf), "additional-digest %s %s %s\n",
+ flavor_name, alg_name, d);
smartlist_add(elements, tor_strdup(buf));
- });
+ }
+ } SMARTLIST_FOREACH_END(ns);
+
+ /* Now get all the sigs for non-FLAV_NS consensuses */
+ SMARTLIST_FOREACH_BEGIN(consensuses, networkstatus_t *, ns) {
+ char *sigs;
+ if (ns->flavor == FLAV_NS)
+ continue;
+ sigs = networkstatus_format_signatures(ns, 1);
+ if (!sigs) {
+ log_warn(LD_DIR, "Couldn't format signatures");
+ goto err;
+ }
+ smartlist_add(elements, sigs);
+ } SMARTLIST_FOREACH_END(ns);
- result = smartlist_join_strings(elements, "", 0, NULL);
+ /* Now add the FLAV_NS consensus signatrures. */
+ sigs = networkstatus_format_signatures(consensus_ns, 1);
+ if (!sigs)
+ goto err;
+ smartlist_add(elements, sigs);
+ result = smartlist_join_strings(elements, "", 0, NULL);
+ err:
SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
smartlist_free(elements);
- if (!n_sigs)
- tor_free(result);
return result;
}
+/** Return a newly allocated string holding a detached-signatures document for
+ * all of the in-progress consensuses in the <b>n_flavors</b>-element array at
+ * <b>pending</b>. */
+static char *
+get_detached_signatures_from_pending_consensuses(pending_consensus_t *pending,
+ int n_flavors)
+{
+ int flav;
+ char *signatures;
+ smartlist_t *c = smartlist_create();
+ for (flav = 0; flav < n_flavors; ++flav) {
+ if (pending[flav].consensus)
+ smartlist_add(c, pending[flav].consensus);
+ }
+ signatures = networkstatus_get_detached_signatures(c);
+ smartlist_free(c);
+ return signatures;
+}
+
/** Release all storage held in <b>s</b>. */
void
ns_detached_signatures_free(ns_detached_signatures_t *s)
{
+ if (!s)
+ return;
if (s->signatures) {
- SMARTLIST_FOREACH(s->signatures, networkstatus_voter_info_t *, v,
- {
- tor_free(v->signature);
- tor_free(v);
- });
- smartlist_free(s->signatures);
+ STRMAP_FOREACH(s->signatures, flavor, smartlist_t *, sigs) {
+ SMARTLIST_FOREACH(sigs, document_signature_t *, sig,
+ document_signature_free(sig));
+ smartlist_free(sigs);
+ } STRMAP_FOREACH_END;
+ strmap_free(s->signatures, NULL);
+ strmap_free(s->digests, _tor_free);
}
+
tor_free(s);
}
@@ -1513,7 +2654,7 @@ dirvote_act(or_options_t *options, time_t now)
if (voting_schedule.voting_ends < now &&
!voting_schedule.have_built_consensus) {
log_notice(LD_DIR, "Time to compute a consensus.");
- dirvote_compute_consensus();
+ dirvote_compute_consensuses();
/* XXXX We will want to try again later if we haven't got enough
* votes yet. Implement this if it turns out to ever happen. */
voting_schedule.have_built_consensus = 1;
@@ -1550,14 +2691,13 @@ static smartlist_t *pending_vote_list = NULL;
/** List of pending_vote_t for the previous vote. After we've used them to
* build a consensus, the votes go here for the next period. */
static smartlist_t *previous_vote_list = NULL;
-/** The body of the consensus that we're currently building. Once we
- * have it built, it goes into dirserv.c */
-static char *pending_consensus_body = NULL;
+
+static pending_consensus_t pending_consensuses[N_CONSENSUS_FLAVORS];
+
/** The detached signatures for the consensus that we're currently
* building. */
static char *pending_consensus_signatures = NULL;
-/** The parsed in-progress consensus document. */
-static networkstatus_t *pending_consensus = NULL;
+
/** List of ns_detached_signatures_t: hold signatures that get posted to us
* before we have generated the consensus on our own. */
static smartlist_t *pending_consensus_signature_list = NULL;
@@ -1651,15 +2791,39 @@ dirvote_fetch_missing_votes(void)
static void
dirvote_fetch_missing_signatures(void)
{
- if (!pending_consensus)
+ int need_any = 0;
+ int i;
+ for (i=0; i < N_CONSENSUS_FLAVORS; ++i) {
+ networkstatus_t *consensus = pending_consensuses[i].consensus;
+ if (!consensus ||
+ networkstatus_check_consensus_signature(consensus, -1) == 1) {
+ /* We have no consensus, or we have one that's signed by everybody. */
+ continue;
+ }
+ need_any = 1;
+ }
+ if (!need_any)
return;
- if (networkstatus_check_consensus_signature(pending_consensus, -1) == 1)
- return; /* we have a signature from everybody. */
directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
0, NULL);
}
+/** Release all storage held by pending consensuses (those waiting for
+ * signatures). */
+static void
+dirvote_clear_pending_consensuses(void)
+{
+ int i;
+ for (i = 0; i < N_CONSENSUS_FLAVORS; ++i) {
+ pending_consensus_t *pc = &pending_consensuses[i];
+ tor_free(pc->body);
+
+ networkstatus_vote_free(pc->consensus);
+ pc->consensus = NULL;
+ }
+}
+
/** Drop all currently pending votes, consensus, and detached signatures. */
static void
dirvote_clear_votes(int all_votes)
@@ -1697,12 +2861,8 @@ dirvote_clear_votes(int all_votes)
tor_free(cp));
smartlist_clear(pending_consensus_signature_list);
}
- tor_free(pending_consensus_body);
tor_free(pending_consensus_signatures);
- if (pending_consensus) {
- networkstatus_vote_free(pending_consensus);
- pending_consensus = NULL;
- }
+ dirvote_clear_pending_consensuses();
}
/** Return a newly allocated string containing the hex-encoded v3 authority
@@ -1760,7 +2920,13 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out)
}
tor_assert(smartlist_len(vote->voters) == 1);
vi = get_voter(vote);
- tor_assert(vi->good_signature == 1);
+ {
+ int any_sig_good = 0;
+ SMARTLIST_FOREACH(vi->sigs, document_signature_t *, sig,
+ if (sig->good_signature)
+ any_sig_good = 1);
+ tor_assert(any_sig_good);
+ }
ds = trusteddirserver_get_by_v3_auth_digest(vi->identity_digest);
if (!ds) {
char *keys = list_v3_auth_ids();
@@ -1797,6 +2963,9 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out)
goto err;
}
+ /* Fetch any new router descriptors we just learned about */
+ update_consensus_router_descriptor_downloads(time(NULL), 1, vote);
+
/* Now see whether we already have a vote from this authority. */
SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v, {
if (! memcmp(v->vote->cert->cache_info.identity_digest,
@@ -1805,7 +2974,8 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out)
networkstatus_voter_info_t *vi_old = get_voter(v->vote);
if (!memcmp(vi_old->vote_digest, vi->vote_digest, DIGEST_LEN)) {
/* Ah, it's the same vote. Not a problem. */
- log_info(LD_DIR, "Discarding a vote we already have.");
+ log_info(LD_DIR, "Discarding a vote we already have (from %s).",
+ vi->address);
if (*status_out < 200)
*status_out = 200;
goto discard;
@@ -1832,7 +3002,7 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out)
goto err;
}
}
- });
+ });
pending_vote = tor_malloc_zero(sizeof(pending_vote_t));
pending_vote->vote_body = new_cached_dir(tor_strndup(vote_body,
@@ -1856,8 +3026,7 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out)
*status_out = 400;
discard:
- if (vote)
- networkstatus_vote_free(vote);
+ networkstatus_vote_free(vote);
if (end_of_vote && !strcmpstart(end_of_vote, "network-status-version ")) {
vote_body = end_of_vote;
@@ -1884,14 +3053,18 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out)
* pending_consensus: it won't be ready to be published until we have
* everybody else's signatures collected too. (V3 Authority only) */
static int
-dirvote_compute_consensus(void)
+dirvote_compute_consensuses(void)
{
/* Have we got enough votes to try? */
- int n_votes, n_voters;
+ int n_votes, n_voters, n_vote_running = 0;
smartlist_t *votes = NULL, *votestrings = NULL;
char *consensus_body = NULL, *signatures = NULL, *votefile;
networkstatus_t *consensus = NULL;
authority_cert_t *my_cert;
+ pending_consensus_t pending[N_CONSENSUS_FLAVORS];
+ int flav;
+
+ memset(pending, 0, sizeof(pending));
if (!pending_vote_list)
pending_vote_list = smartlist_create();
@@ -1903,6 +3076,19 @@ dirvote_compute_consensus(void)
"%d of %d", n_votes, n_voters/2);
goto err;
}
+ tor_assert(pending_vote_list);
+ SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v, {
+ if (smartlist_string_isin(v->vote->known_flags, "Running"))
+ n_vote_running++;
+ });
+ if (!n_vote_running) {
+ /* See task 1066. */
+ log_warn(LD_DIR, "Nobody has voted on the Running flag. Generating "
+ "and publishing a consensus without Running nodes "
+ "would make many clients stop working. Not "
+ "generating a consensus!");
+ goto err;
+ }
if (!(my_cert = get_my_v3_authority_cert())) {
log_warn(LD_DIR, "Can't generate consensus without a certificate.");
@@ -1931,6 +3117,7 @@ dirvote_compute_consensus(void)
char legacy_dbuf[DIGEST_LEN];
crypto_pk_env_t *legacy_sign=NULL;
char *legacy_id_digest = NULL;
+ int n_generated = 0;
if (get_options()->V3AuthUseLegacyKey) {
authority_cert_t *cert = get_my_v3_legacy_cert();
legacy_sign = get_my_v3_legacy_signing_key();
@@ -1939,39 +3126,58 @@ dirvote_compute_consensus(void)
legacy_id_digest = legacy_dbuf;
}
}
- consensus_body = networkstatus_compute_consensus(
+
+ for (flav = 0; flav < N_CONSENSUS_FLAVORS; ++flav) {
+ const char *flavor_name = networkstatus_get_flavor_name(flav);
+ consensus_body = networkstatus_compute_consensus(
votes, n_voters,
my_cert->identity_key,
- get_my_v3_authority_signing_key(), legacy_id_digest, legacy_sign);
- }
- if (!consensus_body) {
- log_warn(LD_DIR, "Couldn't generate a consensus at all!");
- goto err;
- }
- consensus = networkstatus_parse_vote_from_string(consensus_body, NULL,
- NS_TYPE_CONSENSUS);
- if (!consensus) {
- log_warn(LD_DIR, "Couldn't parse consensus we generated!");
- goto err;
+ get_my_v3_authority_signing_key(), legacy_id_digest, legacy_sign,
+ flav);
+
+ if (!consensus_body) {
+ log_warn(LD_DIR, "Couldn't generate a %s consensus at all!",
+ flavor_name);
+ continue;
+ }
+ consensus = networkstatus_parse_vote_from_string(consensus_body, NULL,
+ NS_TYPE_CONSENSUS);
+ if (!consensus) {
+ log_warn(LD_DIR, "Couldn't parse %s consensus we generated!",
+ flavor_name);
+ tor_free(consensus_body);
+ continue;
+ }
+
+ /* 'Check' our own signature, to mark it valid. */
+ networkstatus_check_consensus_signature(consensus, -1);
+
+ pending[flav].body = consensus_body;
+ pending[flav].consensus = consensus;
+ n_generated++;
+ consensus_body = NULL;
+ consensus = NULL;
+ }
+ if (!n_generated) {
+ log_warn(LD_DIR, "Couldn't generate any consensus flavors at all.");
+ goto err;
+ }
}
- /* 'Check' our own signature, to mark it valid. */
- networkstatus_check_consensus_signature(consensus, -1);
- signatures = networkstatus_get_detached_signatures(consensus);
+ signatures = get_detached_signatures_from_pending_consensuses(
+ pending, N_CONSENSUS_FLAVORS);
+
if (!signatures) {
log_warn(LD_DIR, "Couldn't extract signatures.");
goto err;
}
- tor_free(pending_consensus_body);
- pending_consensus_body = consensus_body;
+ dirvote_clear_pending_consensuses();
+ memcpy(pending_consensuses, pending, sizeof(pending));
+
tor_free(pending_consensus_signatures);
pending_consensus_signatures = signatures;
- if (pending_consensus)
- networkstatus_vote_free(pending_consensus);
- pending_consensus = consensus;
-
if (pending_consensus_signature_list) {
int n_sigs = 0;
/* we may have gotten signatures for this consensus before we built
@@ -1979,7 +3185,7 @@ dirvote_compute_consensus(void)
SMARTLIST_FOREACH(pending_consensus_signature_list, char *, sig,
{
const char *msg = NULL;
- int r = dirvote_add_signatures_to_pending_consensus(sig, &msg);
+ int r = dirvote_add_signatures_to_all_pending_consensuses(sig, &msg);
if (r >= 0)
n_sigs += r;
else
@@ -2003,10 +3209,10 @@ dirvote_compute_consensus(void)
strlen(pending_consensus_signatures), 0);
log_notice(LD_DIR, "Signature(s) posted.");
+ smartlist_free(votes);
return 0;
err:
- if (votes)
- smartlist_free(votes);
+ smartlist_free(votes);
tor_free(consensus_body);
tor_free(signatures);
networkstatus_vote_free(consensus);
@@ -2015,76 +3221,62 @@ dirvote_compute_consensus(void)
}
/** Helper: we just got the <b>detached_signatures_body</b> sent to us as
- * signatures on the currently pending consensus. Add them to the consensus
+ * signatures on the currently pending consensus. Add them to <b>pc</b>
* as appropriate. Return the number of signatures added. (?) */
static int
dirvote_add_signatures_to_pending_consensus(
- const char *detached_signatures_body,
+ pending_consensus_t *pc,
+ ns_detached_signatures_t *sigs,
const char **msg_out)
{
- ns_detached_signatures_t *sigs = NULL;
+ const char *flavor_name;
int r = -1;
- tor_assert(detached_signatures_body);
- tor_assert(msg_out);
-
/* Only call if we have a pending consensus right now. */
- tor_assert(pending_consensus);
- tor_assert(pending_consensus_body);
+ tor_assert(pc->consensus);
+ tor_assert(pc->body);
tor_assert(pending_consensus_signatures);
+ flavor_name = networkstatus_get_flavor_name(pc->consensus->flavor);
*msg_out = NULL;
- if (!(sigs = networkstatus_parse_detached_signatures(
- detached_signatures_body, NULL))) {
- *msg_out = "Couldn't parse detached signatures.";
- goto err;
+ {
+ smartlist_t *sig_list = strmap_get(sigs->signatures, flavor_name);
+ log_info(LD_DIR, "Have %d signatures for adding to %s consensus.",
+ sig_list ? smartlist_len(sig_list) : 0, flavor_name);
}
-
- log_info(LD_DIR, "Have %d signatures for adding to consensus.",
- smartlist_len(sigs->signatures));
- r = networkstatus_add_detached_signatures(pending_consensus,
- sigs, msg_out);
+ r = networkstatus_add_detached_signatures(pc->consensus, sigs, msg_out);
log_info(LD_DIR,"Added %d signatures to consensus.", r);
if (r >= 1) {
- char *new_detached =
- networkstatus_get_detached_signatures(pending_consensus);
- const char *src;
+ char *new_signatures =
+ networkstatus_format_signatures(pc->consensus, 0);
char *dst, *dst_end;
size_t new_consensus_len;
- if (!new_detached) {
+ if (!new_signatures) {
*msg_out = "No signatures to add";
goto err;
}
new_consensus_len =
- strlen(pending_consensus_body) + strlen(new_detached) + 1;
- pending_consensus_body = tor_realloc(pending_consensus_body,
- new_consensus_len);
- dst_end = pending_consensus_body + new_consensus_len;
- dst = strstr(pending_consensus_body, "directory-signature ");
+ strlen(pc->body) + strlen(new_signatures) + 1;
+ pc->body = tor_realloc(pc->body, new_consensus_len);
+ dst_end = pc->body + new_consensus_len;
+ dst = strstr(pc->body, "directory-signature ");
tor_assert(dst);
- src = strstr(new_detached, "directory-signature ");
- tor_assert(src);
- strlcpy(dst, src, dst_end-dst);
+ strlcpy(dst, new_signatures, dst_end-dst);
/* We remove this block once it has failed to crash for a while. But
* unless it shows up in profiles, we're probably better leaving it in,
* just in case we break detached signature processing at some point. */
{
- ns_detached_signatures_t *sigs =
- networkstatus_parse_detached_signatures(new_detached, NULL);
networkstatus_t *v = networkstatus_parse_vote_from_string(
- pending_consensus_body, NULL,
+ pc->body, NULL,
NS_TYPE_CONSENSUS);
- tor_assert(sigs);
- ns_detached_signatures_free(sigs);
tor_assert(v);
networkstatus_vote_free(v);
}
- tor_free(pending_consensus_signatures);
- pending_consensus_signatures = new_detached;
*msg_out = "Signatures added";
+ tor_free(new_signatures);
} else if (r == 0) {
*msg_out = "Signatures ignored";
} else {
@@ -2096,8 +3288,62 @@ dirvote_add_signatures_to_pending_consensus(
if (!*msg_out)
*msg_out = "Unrecognized error while adding detached signatures.";
done:
- if (sigs)
- ns_detached_signatures_free(sigs);
+ return r;
+}
+
+static int
+dirvote_add_signatures_to_all_pending_consensuses(
+ const char *detached_signatures_body,
+ const char **msg_out)
+{
+ int r=0, i, n_added = 0, errors = 0;
+ ns_detached_signatures_t *sigs;
+ tor_assert(detached_signatures_body);
+ tor_assert(msg_out);
+ tor_assert(pending_consensus_signatures);
+
+ if (!(sigs = networkstatus_parse_detached_signatures(
+ detached_signatures_body, NULL))) {
+ *msg_out = "Couldn't parse detached signatures.";
+ goto err;
+ }
+
+ for (i = 0; i < N_CONSENSUS_FLAVORS; ++i) {
+ int res;
+ pending_consensus_t *pc = &pending_consensuses[i];
+ if (!pc->consensus)
+ continue;
+ res = dirvote_add_signatures_to_pending_consensus(pc, sigs, msg_out);
+ if (res < 0)
+ errors++;
+ else
+ n_added += res;
+ }
+
+ if (errors && !n_added) {
+ r = -1;
+ goto err;
+ }
+
+ if (n_added && pending_consensuses[FLAV_NS].consensus) {
+ char *new_detached =
+ get_detached_signatures_from_pending_consensuses(
+ pending_consensuses, N_CONSENSUS_FLAVORS);
+ if (new_detached) {
+ tor_free(pending_consensus_signatures);
+ pending_consensus_signatures = new_detached;
+ }
+ }
+
+ r = n_added;
+ goto done;
+ err:
+ if (!*msg_out)
+ *msg_out = "Unrecognized error while adding detached signatures.";
+ done:
+ ns_detached_signatures_free(sigs);
+ /* XXXX NM Check how return is used. We can now have an error *and*
+ signatures added. */
return r;
}
@@ -2110,10 +3356,10 @@ dirvote_add_signatures(const char *detached_signatures_body,
const char *source,
const char **msg)
{
- if (pending_consensus) {
+ if (pending_consensuses[FLAV_NS].consensus) {
log_notice(LD_DIR, "Got a signature from %s. "
"Adding it to the pending consensus.", source);
- return dirvote_add_signatures_to_pending_consensus(
+ return dirvote_add_signatures_to_all_pending_consensuses(
detached_signatures_body, msg);
} else {
log_notice(LD_DIR, "Got a signature from %s. "
@@ -2132,17 +3378,25 @@ dirvote_add_signatures(const char *detached_signatures_body,
static int
dirvote_publish_consensus(void)
{
- /* Can we actually publish it yet? */
- if (!pending_consensus ||
- networkstatus_check_consensus_signature(pending_consensus, 1)<0) {
- log_warn(LD_DIR, "Not enough info to publish pending consensus");
- return -1;
- }
+ int i;
+
+ /* Now remember all the other consensuses as if we were a directory cache. */
+ for (i = 0; i < N_CONSENSUS_FLAVORS; ++i) {
+ pending_consensus_t *pending = &pending_consensuses[i];
+ const char *name;
+ name = networkstatus_get_flavor_name(i);
+ tor_assert(name);
+ if (!pending->consensus ||
+ networkstatus_check_consensus_signature(pending->consensus, 1)<0) {
+ log_warn(LD_DIR, "Not enough info to publish pending %s consensus",name);
+ continue;
+ }
- if (networkstatus_set_current_consensus(pending_consensus_body, 0))
- log_warn(LD_DIR, "Error publishing consensus");
- else
- log_notice(LD_DIR, "Consensus published.");
+ if (networkstatus_set_current_consensus(pending->body, name, 0))
+ log_warn(LD_DIR, "Error publishing %s consensus", name);
+ else
+ log_notice(LD_DIR, "Published %s consensus", name);
+ }
return 0;
}
@@ -2152,20 +3406,16 @@ void
dirvote_free_all(void)
{
dirvote_clear_votes(1);
- /* now empty as a result of clear_pending_votes. */
+ /* now empty as a result of dirvote_clear_votes(). */
smartlist_free(pending_vote_list);
pending_vote_list = NULL;
smartlist_free(previous_vote_list);
previous_vote_list = NULL;
- tor_free(pending_consensus_body);
+ dirvote_clear_pending_consensuses();
tor_free(pending_consensus_signatures);
- if (pending_consensus) {
- networkstatus_vote_free(pending_consensus);
- pending_consensus = NULL;
- }
if (pending_consensus_signature_list) {
- /* now empty as a result of clear_pending_votes. */
+ /* now empty as a result of dirvote_clear_votes(). */
smartlist_free(pending_consensus_signature_list);
pending_consensus_signature_list = NULL;
}
@@ -2177,13 +3427,14 @@ dirvote_free_all(void)
/** Return the body of the consensus that we're currently trying to build. */
const char *
-dirvote_get_pending_consensus(void)
+dirvote_get_pending_consensus(consensus_flavor_t flav)
{
- return pending_consensus_body;
+ tor_assert(((int)flav) >= 0 && flav < N_CONSENSUS_FLAVORS);
+ return pending_consensuses[flav].body;
}
/** Return the signatures that we know for the consensus that we're currently
- * trying to build */
+ * trying to build. */
const char *
dirvote_get_pending_detached_signatures(void)
{
@@ -2229,15 +3480,147 @@ dirvote_get_vote(const char *fp, int flags)
} else {
if (pending_vote_list && include_pending) {
SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv,
- if (!memcmp(pv->vote->networkstatus_digest, fp, DIGEST_LEN))
+ if (!memcmp(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN))
return pv->vote_body);
}
if (previous_vote_list && include_previous) {
SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, pv,
- if (!memcmp(pv->vote->networkstatus_digest, fp, DIGEST_LEN))
+ if (!memcmp(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN))
return pv->vote_body);
}
}
return NULL;
}
+/** Construct and return a new microdescriptor from a routerinfo <b>ri</b>.
+ *
+ * XXX Right now, there is only one way to generate microdescriptors from
+ * router descriptors. This may change in future consensus methods. If so,
+ * we'll need an internal way to remember which method we used, and ask for a
+ * particular method.
+ **/
+microdesc_t *
+dirvote_create_microdescriptor(const routerinfo_t *ri)
+{
+ microdesc_t *result = NULL;
+ char *key = NULL, *summary = NULL, *family = NULL;
+ char buf[1024];
+ size_t keylen;
+ char *out = buf, *end = buf+sizeof(buf);
+
+ if (crypto_pk_write_public_key_to_string(ri->onion_pkey, &key, &keylen)<0)
+ goto done;
+ summary = policy_summarize(ri->exit_policy);
+ if (ri->declared_family)
+ family = smartlist_join_strings(ri->declared_family, " ", 0, NULL);
+
+ if (tor_snprintf(out, end-out, "onion-key\n%s", key)<0)
+ goto done;
+ out += strlen(out);
+ if (family) {
+ if (tor_snprintf(out, end-out, "family %s\n", family)<0)
+ goto done;
+ out += strlen(out);
+ }
+ if (summary && strcmp(summary, "reject 1-65535")) {
+ if (tor_snprintf(out, end-out, "p %s\n", summary)<0)
+ goto done;
+ out += strlen(out);
+ }
+ *out = '\0'; /* Make sure it's nul-terminated. This should be a no-op */
+
+ {
+ smartlist_t *lst = microdescs_parse_from_string(buf, out, 0, 1);
+ if (smartlist_len(lst) != 1) {
+ log_warn(LD_DIR, "We generated a microdescriptor we couldn't parse.");
+ SMARTLIST_FOREACH(lst, microdesc_t *, md, microdesc_free(md));
+ smartlist_free(lst);
+ goto done;
+ }
+ result = smartlist_get(lst, 0);
+ smartlist_free(lst);
+ }
+
+ done:
+ tor_free(key);
+ tor_free(summary);
+ tor_free(family);
+ return result;
+}
+
+/** Cached space-separated string to hold */
+static char *microdesc_consensus_methods = NULL;
+
+/** Format the appropriate vote line to describe the microdescriptor <b>md</b>
+ * in a consensus vote document. Write it into the <b>out_len</b>-byte buffer
+ * in <b>out</b>. Return -1 on failure and the number of characters written
+ * on success. */
+ssize_t
+dirvote_format_microdesc_vote_line(char *out, size_t out_len,
+ const microdesc_t *md)
+{
+ char d64[BASE64_DIGEST256_LEN+1];
+ if (!microdesc_consensus_methods) {
+ microdesc_consensus_methods =
+ make_consensus_method_list(MIN_METHOD_FOR_MICRODESC,
+ MAX_SUPPORTED_CONSENSUS_METHOD,
+ ",");
+ tor_assert(microdesc_consensus_methods);
+ }
+ if (digest256_to_base64(d64, md->digest)<0)
+ return -1;
+
+ if (tor_snprintf(out, out_len, "m %s sha256=%s\n",
+ microdesc_consensus_methods, d64)<0)
+ return -1;
+
+ return strlen(out);
+}
+
+/** If <b>vrs</b> has a hash made for the consensus method <b>method</b> with
+ * the digest algorithm <b>alg</b>, decode it and copy it into
+ * <b>digest256_out</b> and return 0. Otherwise return -1. */
+int
+vote_routerstatus_find_microdesc_hash(char *digest256_out,
+ const vote_routerstatus_t *vrs,
+ int method,
+ digest_algorithm_t alg)
+{
+ /* XXXX only returns the sha256 method. */
+ const vote_microdesc_hash_t *h;
+ char mstr[64];
+ size_t mlen;
+ char dstr[64];
+
+ tor_snprintf(mstr, sizeof(mstr), "%d", method);
+ mlen = strlen(mstr);
+ tor_snprintf(dstr, sizeof(dstr), " %s=",
+ crypto_digest_algorithm_get_name(alg));
+
+ for (h = vrs->microdesc; h; h = h->next) {
+ const char *cp = h->microdesc_hash_line;
+ size_t num_len;
+ /* cp looks like \d+(,\d+)* (digesttype=val )+ . Let's hunt for mstr in
+ * the first part. */
+ while (1) {
+ num_len = strspn(cp, "1234567890");
+ if (num_len == mlen && !memcmp(mstr, cp, mlen)) {
+ /* This is the line. */
+ char buf[BASE64_DIGEST256_LEN+1];
+ /* XXXX ignores extraneous stuff if the digest is too long. This
+ * seems harmless enough, right? */
+ cp = strstr(cp, dstr);
+ if (!cp)
+ return -1;
+ cp += strlen(dstr);
+ strlcpy(buf, cp, sizeof(buf));
+ return digest256_from_base64(digest256_out, buf);
+ }
+ if (num_len == 0 || cp[num_len] != ',')
+ break;
+ cp += num_len + 1;
+ }
+ }
+ return -1;
+}
+
diff --git a/src/or/dirvote.h b/src/or/dirvote.h
new file mode 100644
index 0000000000..e384dc53b3
--- /dev/null
+++ b/src/or/dirvote.h
@@ -0,0 +1,93 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file dirvote.h
+ * \brief Header file for dirvote.c.
+ **/
+
+#ifndef _TOR_DIRVOTE_H
+#define _TOR_DIRVOTE_H
+
+/** Lowest allowable value for VoteSeconds. */
+#define MIN_VOTE_SECONDS 20
+/** Lowest allowable value for DistSeconds. */
+#define MIN_DIST_SECONDS 20
+/** Smallest allowable voting interval. */
+#define MIN_VOTE_INTERVAL 300
+
+/** Precision multiplier for the Bw weights */
+#define BW_WEIGHT_SCALE 10000
+
+void dirvote_free_all(void);
+
+/* vote manipulation */
+char *networkstatus_compute_consensus(smartlist_t *votes,
+ int total_authorities,
+ crypto_pk_env_t *identity_key,
+ crypto_pk_env_t *signing_key,
+ const char *legacy_identity_key_digest,
+ crypto_pk_env_t *legacy_signing_key,
+ consensus_flavor_t flavor);
+int networkstatus_add_detached_signatures(networkstatus_t *target,
+ ns_detached_signatures_t *sigs,
+ const char **msg_out);
+char *networkstatus_get_detached_signatures(smartlist_t *consensuses);
+void ns_detached_signatures_free(ns_detached_signatures_t *s);
+
+/* cert manipulation */
+authority_cert_t *authority_cert_dup(authority_cert_t *cert);
+
+/* vote scheduling */
+void dirvote_get_preferred_voting_intervals(vote_timing_t *timing_out);
+time_t dirvote_get_start_of_next_interval(time_t now, int interval);
+void dirvote_recalculate_timing(or_options_t *options, time_t now);
+void dirvote_act(or_options_t *options, time_t now);
+
+/* invoked on timers and by outside triggers. */
+struct pending_vote_t * dirvote_add_vote(const char *vote_body,
+ const char **msg_out,
+ int *status_out);
+int dirvote_add_signatures(const char *detached_signatures_body,
+ const char *source,
+ const char **msg_out);
+
+/* Item access */
+const char *dirvote_get_pending_consensus(consensus_flavor_t flav);
+const char *dirvote_get_pending_detached_signatures(void);
+#define DGV_BY_ID 1
+#define DGV_INCLUDE_PENDING 2
+#define DGV_INCLUDE_PREVIOUS 4
+const cached_dir_t *dirvote_get_vote(const char *fp, int flags);
+void set_routerstatus_from_routerinfo(routerstatus_t *rs,
+ routerinfo_t *ri, time_t now,
+ int naming, int listbadexits,
+ int listbaddirs);
+void router_clear_status_flags(routerinfo_t *ri);
+networkstatus_t *
+dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
+ authority_cert_t *cert);
+
+microdesc_t *dirvote_create_microdescriptor(const routerinfo_t *ri);
+ssize_t dirvote_format_microdesc_vote_line(char *out, size_t out_len,
+ const microdesc_t *md);
+
+int vote_routerstatus_find_microdesc_hash(char *digest256_out,
+ const vote_routerstatus_t *vrs,
+ int method,
+ digest_algorithm_t alg);
+document_signature_t *voter_get_sig_by_algorithm(
+ const networkstatus_voter_info_t *voter,
+ digest_algorithm_t alg);
+
+#ifdef DIRVOTE_PRIVATE
+char *format_networkstatus_vote(crypto_pk_env_t *private_key,
+ networkstatus_t *v3_ns);
+char *dirvote_compute_params(smartlist_t *votes);
+#endif
+
+#endif
+
diff --git a/src/or/dns.c b/src/or/dns.c
index 98eb27f8b3..4e319b7d83 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -12,8 +12,63 @@
**/
#include "or.h"
+#include "circuitlist.h"
+#include "circuituse.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_edge.h"
+#include "control.h"
+#include "dns.h"
+#include "main.h"
+#include "policies.h"
+#include "relay.h"
+#include "router.h"
#include "ht.h"
+#ifdef HAVE_EVENT2_DNS_H
+#include <event2/event.h>
+#include <event2/dns.h>
+#else
+#include <event.h>
#include "eventdns.h"
+#ifndef HAVE_EVDNS_SET_DEFAULT_OUTGOING_BIND_ADDRESS
+#define HAVE_EVDNS_SET_DEFAULT_OUTGOING_BIND_ADDRESS
+#endif
+#endif
+
+#ifndef HAVE_EVENT2_DNS_H
+struct evdns_base;
+struct evdns_request;
+#define evdns_base_new(x,y) tor_malloc(1)
+#define evdns_base_clear_nameservers_and_suspend(base) \
+ evdns_clear_nameservers_and_suspend()
+#define evdns_base_search_clear(base) evdns_search_clear()
+#define evdns_base_set_default_outgoing_bind_address(base, a, len) \
+ evdns_set_default_outgoing_bind_address((a),(len))
+#define evdns_base_resolv_conf_parse(base, options, fname) \
+ evdns_resolv_conf_parse((options), (fname))
+#define evdns_base_count_nameservers(base) \
+ evdns_count_nameservers()
+#define evdns_base_resume(base) \
+ evdns_resume()
+#define evdns_base_config_windows_nameservers(base) \
+ evdns_config_windows_nameservers()
+#define evdns_base_set_option_(base, opt, val) \
+ evdns_set_option((opt),(val),DNS_OPTIONS_ALL)
+#define evdns_base_resolve_ipv4(base, addr, options, cb, ptr) \
+ ((evdns_resolve_ipv4(addr, options, cb, ptr)<0) ? NULL : ((void*)1))
+#define evdns_base_resolve_reverse(base, addr, options, cb, ptr) \
+ ((evdns_resolve_reverse(addr, options, cb, ptr)<0) ? NULL : ((void*)1))
+#define evdns_base_resolve_reverse_ipv6(base, addr, options, cb, ptr) \
+ ((evdns_resolve_reverse_ipv6(addr, options, cb, ptr)<0) ? NULL : ((void*)1))
+
+#elif defined(LIBEVENT_VERSION_NUMBER) && LIBEVENT_VERSION_NUMBER < 0x02000303
+#define evdns_base_set_option_(base, opt, val) \
+ evdns_base_set_option((base), (opt),(val),DNS_OPTIONS_ALL)
+
+#else
+#define evdns_base_set_option_ evdns_base_set_option
+
+#endif
/** Longest hostname we're willing to resolve. */
#define MAX_ADDRESSLEN 256
@@ -28,6 +83,9 @@
#define DNS_RESOLVE_FAILED_PERMANENT 2
#define DNS_RESOLVE_SUCCEEDED 3
+/** Our evdns_base; this structure handles all our name lookups. */
+static struct evdns_base *the_evdns_base = NULL;
+
/** Have we currently configured nameservers with eventdns? */
static int nameservers_configured = 0;
/** Did our most recent attempt to configure nameservers with eventdns fail? */
@@ -89,6 +147,8 @@ typedef struct cached_resolve_t {
uint32_t ttl; /**< What TTL did the nameserver tell us? */
/** Connections that want to know when we get an answer for this resolve. */
pending_connection_t *pending_connections;
+ /** Position of this element in the heap*/
+ int minheap_idx;
} cached_resolve_t;
static void purge_expired_resolves(time_t now);
@@ -211,8 +271,16 @@ dns_reset(void)
{
or_options_t *options = get_options();
if (! server_mode(options)) {
- evdns_clear_nameservers_and_suspend();
- evdns_search_clear();
+
+ if (!the_evdns_base) {
+ if (!(the_evdns_base = evdns_base_new(tor_libevent_get_base(), 0))) {
+ log_err(LD_BUG, "Couldn't create an evdns_base");
+ return -1;
+ }
+ }
+
+ evdns_base_clear_nameservers_and_suspend(the_evdns_base);
+ evdns_base_search_clear(the_evdns_base);
nameservers_configured = 0;
tor_free(resolv_conf_fname);
resolv_conf_mtime = 0;
@@ -262,6 +330,8 @@ dns_get_expiry_ttl(uint32_t ttl)
static void
_free_cached_resolve(cached_resolve_t *r)
{
+ if (!r)
+ return;
while (r->pending_connections) {
pending_connection_t *victim = r->pending_connections;
r->pending_connections = victim->next;
@@ -303,6 +373,7 @@ set_expiry(cached_resolve_t *resolve, time_t expires)
resolve->expire = expires;
smartlist_pqueue_add(cached_resolve_pqueue,
_compare_cached_resolves_by_expiry,
+ STRUCT_OFFSET(cached_resolve_t, minheap_idx),
resolve);
}
@@ -325,8 +396,7 @@ dns_free_all(void)
_free_cached_resolve(item);
}
HT_CLEAR(cache_map, &cache_root);
- if (cached_resolve_pqueue)
- smartlist_free(cached_resolve_pqueue);
+ smartlist_free(cached_resolve_pqueue);
cached_resolve_pqueue = NULL;
tor_free(resolv_conf_fname);
}
@@ -349,7 +419,8 @@ purge_expired_resolves(time_t now)
if (resolve->expire > now)
break;
smartlist_pqueue_pop(cached_resolve_pqueue,
- _compare_cached_resolves_by_expiry);
+ _compare_cached_resolves_by_expiry,
+ STRUCT_OFFSET(cached_resolve_t, minheap_idx));
if (resolve->state == CACHE_STATE_PENDING) {
log_debug(LD_EXIT,
@@ -393,7 +464,7 @@ purge_expired_resolves(time_t now)
log_err(LD_BUG, "The expired resolve we purged didn't match any in"
" the cache. Tried to purge %s (%p); instead got %s (%p).",
resolve->address, (void*)resolve,
- removed ? removed->address : "NULL", (void*)remove);
+ removed ? removed->address : "NULL", (void*)removed);
}
tor_assert(removed == resolve);
} else {
@@ -611,7 +682,7 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
* know the answer. */
if (tor_addr_from_str(&addr, exitconn->_base.address) >= 0) {
if (tor_addr_family(&addr) == AF_INET) {
- tor_addr_assign(&exitconn->_base.addr, &addr);
+ tor_addr_copy(&exitconn->_base.addr, &addr);
exitconn->address_ttl = DEFAULT_DNS_TTL;
return 1;
} else {
@@ -711,6 +782,7 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
resolve = tor_malloc_zero(sizeof(cached_resolve_t));
resolve->magic = CACHED_RESOLVE_MAGIC;
resolve->state = CACHE_STATE_PENDING;
+ resolve->minheap_idx = -1;
resolve->is_reverse = is_reverse;
strlcpy(resolve->address, exitconn->_base.address, sizeof(resolve->address));
@@ -807,7 +879,8 @@ connection_dns_remove(edge_connection_t *conn)
tor_free(pend);
log_debug(LD_EXIT, "First connection (fd %d) no longer waiting "
"for resolve of %s",
- conn->_base.s, escaped_safe_str(conn->_base.address));
+ conn->_base.s,
+ escaped_safe_str(conn->_base.address));
return;
} else {
for ( ; pend->next; pend = pend->next) {
@@ -1108,6 +1181,14 @@ configure_nameservers(int force)
conf_fname = "/etc/resolv.conf";
#endif
+ if (!the_evdns_base) {
+ if (!(the_evdns_base = evdns_base_new(tor_libevent_get_base(), 0))) {
+ log_err(LD_BUG, "Couldn't create an evdns_base");
+ return -1;
+ }
+ }
+
+#ifdef HAVE_EVDNS_SET_DEFAULT_OUTGOING_BIND_ADDRESS
if (options->OutboundBindAddress) {
tor_addr_t addr;
if (tor_addr_from_str(&addr, options->OutboundBindAddress) < 0) {
@@ -1122,16 +1203,13 @@ configure_nameservers(int force)
log_warn(LD_BUG, "Couldn't convert outbound bind address to sockaddr."
" Ignoring.");
} else {
- evdns_set_default_outgoing_bind_address((struct sockaddr *)&ss,
- socklen);
+ evdns_base_set_default_outgoing_bind_address(the_evdns_base,
+ (struct sockaddr *)&ss,
+ socklen);
}
}
}
-
- if (options->ServerDNSRandomizeCase)
- evdns_set_option("randomize-case:", "1", DNS_OPTIONS_ALL);
- else
- evdns_set_option("randomize-case:", "0", DNS_OPTIONS_ALL);
+#endif
evdns_set_log_fn(evdns_log_cb);
if (conf_fname) {
@@ -1146,16 +1224,17 @@ configure_nameservers(int force)
return 0;
}
if (nameservers_configured) {
- evdns_search_clear();
- evdns_clear_nameservers_and_suspend();
+ evdns_base_search_clear(the_evdns_base);
+ evdns_base_clear_nameservers_and_suspend(the_evdns_base);
}
log_info(LD_EXIT, "Parsing resolver configuration in '%s'", conf_fname);
- if ((r = evdns_resolv_conf_parse(DNS_OPTIONS_ALL, conf_fname))) {
+ if ((r = evdns_base_resolv_conf_parse(the_evdns_base,
+ DNS_OPTIONS_ALL, conf_fname))) {
log_warn(LD_EXIT, "Unable to parse '%s', or no nameservers in '%s' (%d)",
conf_fname, conf_fname, r);
goto err;
}
- if (evdns_count_nameservers() == 0) {
+ if (evdns_base_count_nameservers(the_evdns_base) == 0) {
log_warn(LD_EXIT, "Unable to find any nameservers in '%s'.", conf_fname);
goto err;
}
@@ -1163,38 +1242,47 @@ configure_nameservers(int force)
resolv_conf_fname = tor_strdup(conf_fname);
resolv_conf_mtime = st.st_mtime;
if (nameservers_configured)
- evdns_resume();
+ evdns_base_resume(the_evdns_base);
}
#ifdef MS_WINDOWS
else {
if (nameservers_configured) {
- evdns_search_clear();
- evdns_clear_nameservers_and_suspend();
+ evdns_base_search_clear(the_evdns_base);
+ evdns_base_clear_nameservers_and_suspend(the_evdns_base);
}
- if (evdns_config_windows_nameservers()) {
+ if (evdns_base_config_windows_nameservers(the_evdns_base)) {
log_warn(LD_EXIT,"Could not config nameservers.");
goto err;
}
- if (evdns_count_nameservers() == 0) {
+ if (evdns_base_count_nameservers(the_evdns_base) == 0) {
log_warn(LD_EXIT, "Unable to find any platform nameservers in "
"your Windows configuration.");
goto err;
}
if (nameservers_configured)
- evdns_resume();
+ evdns_base_resume(the_evdns_base);
tor_free(resolv_conf_fname);
resolv_conf_mtime = 0;
}
#endif
- if (evdns_count_nameservers() == 1) {
- evdns_set_option("max-timeouts:", "16", DNS_OPTIONS_ALL);
- evdns_set_option("timeout:", "10", DNS_OPTIONS_ALL);
+#define SET(k,v) evdns_base_set_option_(the_evdns_base, (k), (v))
+
+ if (evdns_base_count_nameservers(the_evdns_base) == 1) {
+ SET("max-timeouts:", "16");
+ SET("timeout:", "10");
} else {
- evdns_set_option("max-timeouts:", "3", DNS_OPTIONS_ALL);
- evdns_set_option("timeout:", "5", DNS_OPTIONS_ALL);
+ SET("max-timeouts:", "3");
+ SET("timeout:", "5");
}
+ if (options->ServerDNSRandomizeCase)
+ SET("randomize-case:", "1");
+ else
+ SET("randomize-case:", "0");
+
+#undef SET
+
dns_servers_relaunch_checks();
nameservers_configured = 1;
@@ -1292,6 +1380,7 @@ static int
launch_resolve(edge_connection_t *exitconn)
{
char *addr = tor_strdup(exitconn->_base.address);
+ struct evdns_request *req = NULL;
tor_addr_t a;
int r;
int options = get_options()->ServerDNSSearchDomains ? 0
@@ -1307,28 +1396,34 @@ launch_resolve(edge_connection_t *exitconn)
r = tor_addr_parse_reverse_lookup_name(
&a, exitconn->_base.address, AF_UNSPEC, 0);
+
+ tor_assert(the_evdns_base);
if (r == 0) {
log_info(LD_EXIT, "Launching eventdns request for %s",
escaped_safe_str(exitconn->_base.address));
- r = evdns_resolve_ipv4(exitconn->_base.address, options,
- evdns_callback, addr);
+ req = evdns_base_resolve_ipv4(the_evdns_base,
+ exitconn->_base.address, options,
+ evdns_callback, addr);
} else if (r == 1) {
log_info(LD_EXIT, "Launching eventdns reverse request for %s",
escaped_safe_str(exitconn->_base.address));
if (tor_addr_family(&a) == AF_INET)
- r = evdns_resolve_reverse(tor_addr_to_in(&a), DNS_QUERY_NO_SEARCH,
+ req = evdns_base_resolve_reverse(the_evdns_base,
+ tor_addr_to_in(&a), DNS_QUERY_NO_SEARCH,
evdns_callback, addr);
else
- r = evdns_resolve_reverse_ipv6(tor_addr_to_in6(&a), DNS_QUERY_NO_SEARCH,
+ req = evdns_base_resolve_reverse_ipv6(the_evdns_base,
+ tor_addr_to_in6(&a), DNS_QUERY_NO_SEARCH,
evdns_callback, addr);
} else if (r == -1) {
log_warn(LD_BUG, "Somehow a malformed in-addr.arpa address reached here.");
}
- if (r) {
- log_warn(LD_EXIT, "eventdns rejected address %s: error %d.",
- escaped_safe_str(addr), r);
- r = evdns_err_is_transient(r) ? -2 : -1;
+ r = 0;
+ if (!req) {
+ log_warn(LD_EXIT, "eventdns rejected address %s.",
+ escaped_safe_str(addr));
+ r = -1;
tor_free(addr); /* There is no evdns request in progress; stop
* addr from getting leaked. */
}
@@ -1449,8 +1544,8 @@ evdns_wildcard_check_callback(int result, char type, int count, int ttl,
}
log(dns_wildcard_one_notice_given ? LOG_INFO : LOG_NOTICE, LD_EXIT,
"Your DNS provider gave an answer for \"%s\", which "
- "is not supposed to exist. Apparently they are hijacking "
- "DNS failures. Trying to correct for this. We've noticed %d "
+ "is not supposed to exist. Apparently they are hijacking "
+ "DNS failures. Trying to correct for this. We've noticed %d "
"possibly bad address%s so far.",
string_address, strmap_size(dns_wildcard_response_count),
(strmap_size(dns_wildcard_response_count) == 1) ? "" : "es");
@@ -1466,17 +1561,20 @@ static void
launch_wildcard_check(int min_len, int max_len, const char *suffix)
{
char *addr;
- int r;
+ struct evdns_request *req;
addr = crypto_random_hostname(min_len, max_len, "", suffix);
log_info(LD_EXIT, "Testing whether our DNS server is hijacking nonexistent "
"domains with request for bogus hostname \"%s\"", addr);
- r = evdns_resolve_ipv4(/* This "addr" tells us which address to resolve */
+ tor_assert(the_evdns_base);
+ req = evdns_base_resolve_ipv4(
+ the_evdns_base,
+ /* This "addr" tells us which address to resolve */
addr,
DNS_QUERY_NO_SEARCH, evdns_wildcard_check_callback,
/* This "addr" is an argument to the callback*/ addr);
- if (r) {
+ if (!req) {
/* There is no evdns request in progress; stop addr from getting leaked */
tor_free(addr);
}
@@ -1488,6 +1586,7 @@ static void
launch_test_addresses(int fd, short event, void *args)
{
or_options_t *options = get_options();
+ struct evdns_request *req;
(void)fd;
(void)event;
(void)args;
@@ -1499,14 +1598,19 @@ launch_test_addresses(int fd, short event, void *args)
* be an exit server.*/
if (!options->ServerDNSTestAddresses)
return;
- SMARTLIST_FOREACH(options->ServerDNSTestAddresses, const char *, address,
- {
- int r = evdns_resolve_ipv4(address, DNS_QUERY_NO_SEARCH, evdns_callback,
- tor_strdup(address));
- if (r)
- log_info(LD_EXIT, "eventdns rejected test address %s: error %d",
- escaped_safe_str(address), r);
- });
+ tor_assert(the_evdns_base);
+ SMARTLIST_FOREACH_BEGIN(options->ServerDNSTestAddresses,
+ const char *, address) {
+ char *a = tor_strdup(address);
+ req = evdns_base_resolve_ipv4(the_evdns_base,
+ address, DNS_QUERY_NO_SEARCH, evdns_callback, a);
+
+ if (!req) {
+ log_info(LD_EXIT, "eventdns rejected test address %s",
+ escaped_safe_str(address));
+ tor_free(a);
+ }
+ } SMARTLIST_FOREACH_END(address);
}
#define N_WILDCARD_CHECKS 2
@@ -1547,7 +1651,7 @@ dns_launch_wildcard_checks(void)
void
dns_launch_correctness_checks(void)
{
- static struct event launch_event;
+ static struct event *launch_event = NULL;
struct timeval timeout;
if (!get_options()->ServerDNSDetectHijacking)
return;
@@ -1555,10 +1659,12 @@ dns_launch_correctness_checks(void)
/* Wait a while before launching requests for test addresses, so we can
* get the results from checking for wildcarding. */
- evtimer_set(&launch_event, launch_test_addresses, NULL);
+ if (! launch_event)
+ launch_event = tor_evtimer_new(tor_libevent_get_base(),
+ launch_test_addresses, NULL);
timeout.tv_sec = 30;
timeout.tv_usec = 0;
- if (evtimer_add(&launch_event, &timeout)<0) {
+ if (evtimer_add(launch_event, &timeout)<0) {
log_warn(LD_BUG, "Couldn't add timer for checking for dns hijacking");
}
}
@@ -1574,10 +1680,9 @@ dns_seems_to_be_broken(void)
void
dns_reset_correctness_checks(void)
{
- if (dns_wildcard_response_count) {
- strmap_free(dns_wildcard_response_count, _tor_free);
- dns_wildcard_response_count = NULL;
- }
+ strmap_free(dns_wildcard_response_count, _tor_free);
+ dns_wildcard_response_count = NULL;
+
n_wildcard_requests = 0;
if (dns_wildcard_list) {
@@ -1622,6 +1727,30 @@ assert_resolve_ok(cached_resolve_t *resolve)
}
}
+/** Return the number of DNS cache entries as an int */
+static int
+dns_cache_entry_count(void)
+{
+ return HT_SIZE(&cache_root);
+}
+
+/** Log memory information about our internal DNS cache at level 'severity'. */
+void
+dump_dns_mem_usage(int severity)
+{
+ /* This should never be larger than INT_MAX. */
+ int hash_count = dns_cache_entry_count();
+ size_t hash_mem = sizeof(struct cached_resolve_t) * hash_count;
+ hash_mem += HT_MEM_USAGE(&cache_root);
+
+ /* Print out the count and estimated size of our &cache_root. It undercounts
+ hostnames in cached reverse resolves.
+ */
+ log(severity, LD_MM, "Our DNS cache has %d entries.", hash_count);
+ log(severity, LD_MM, "Our DNS cache size is approximately %u bytes.",
+ (unsigned)hash_mem);
+}
+
#ifdef DEBUG_DNS_CACHE
/** Exit with an assertion if the DNS cache is corrupt. */
static void
@@ -1642,7 +1771,8 @@ _assert_cache_ok(void)
return;
smartlist_pqueue_assert_ok(cached_resolve_pqueue,
- _compare_cached_resolves_by_expiry);
+ _compare_cached_resolves_by_expiry,
+ STRUCT_OFFSET(cached_resolve_t, minheap_idx));
SMARTLIST_FOREACH(cached_resolve_pqueue, cached_resolve_t *, res,
{
diff --git a/src/or/dns.h b/src/or/dns.h
new file mode 100644
index 0000000000..c4fd4d1fb7
--- /dev/null
+++ b/src/or/dns.h
@@ -0,0 +1,31 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file dns.h
+ * \brief Header file for dns.c.
+ **/
+
+#ifndef _TOR_DNS_H
+#define _TOR_DNS_H
+
+int dns_init(void);
+int has_dns_init_failed(void);
+void dns_free_all(void);
+uint32_t dns_clip_ttl(uint32_t ttl);
+int dns_reset(void);
+void connection_dns_remove(edge_connection_t *conn);
+void assert_connection_edge_not_dns_pending(edge_connection_t *conn);
+void assert_all_pending_dns_resolves_ok(void);
+void dns_cancel_pending_resolve(const char *question);
+int dns_resolve(edge_connection_t *exitconn);
+void dns_launch_correctness_checks(void);
+int dns_seems_to_be_broken(void);
+void dns_reset_correctness_checks(void);
+void dump_dns_mem_usage(int severity);
+
+#endif
+
diff --git a/src/or/dnsserv.c b/src/or/dnsserv.c
index bceaa462b3..ad4f4122bc 100644
--- a/src/or/dnsserv.c
+++ b/src/or/dnsserv.c
@@ -9,7 +9,21 @@
**/
#include "or.h"
+#include "dnsserv.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_edge.h"
+#include "control.h"
+#include "main.h"
+#include "policies.h"
+#ifdef HAVE_EVENT2_DNS_H
+#include <event2/dns.h>
+#include <event2/dns_compat.h>
+/* XXXX022 this implies we want an improved evdns */
+#include <event2/dns_struct.h>
+#else
#include "eventdns.h"
+#endif
/** Helper function: called by evdns whenever the client sends a request to our
* DNSPort. We need to eventually answer the request <b>req</b>.
@@ -85,12 +99,7 @@ evdns_server_callback(struct evdns_server_request *req, void *_data)
evdns_server_request_respond(req, DNS_ERR_NONE);
return;
}
- if (q->type == EVDNS_TYPE_A) {
- /* Refuse any attempt to resolve a noconnect address, right now. */
- if (hostname_is_noconnect_address(q->name)) {
- err = DNS_ERR_REFUSED;
- }
- } else {
+ if (q->type != EVDNS_TYPE_A) {
tor_assert(q->type == EVDNS_TYPE_PTR);
}
@@ -132,17 +141,18 @@ evdns_server_callback(struct evdns_server_request *req, void *_data)
control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
- /* Now, throw the connection over to get rewritten (which will answer it
- * immediately if it's in the cache, or completely bogus, or automapped),
- * and then attached to a circuit. */
+ /* Now, unless a controller asked us to leave streams unattached,
+ * throw the connection over to get rewritten (which will
+ * answer it immediately if it's in the cache, or completely bogus, or
+ * automapped), and then attached to a circuit. */
log_info(LD_APP, "Passing request for %s to rewrite_and_attach.",
- escaped_safe_str(q->name));
+ escaped_safe_str_client(q->name));
q_name = tor_strdup(q->name); /* q could be freed in rewrite_and_attach */
- connection_ap_handshake_rewrite_and_attach(conn, NULL, NULL);
+ connection_ap_rewrite_and_attach_if_allowed(conn, NULL, NULL);
/* Now, the connection is marked if it was bad. */
- log_info(LD_APP, "Passed request for %s to rewrite_and_attach.",
- escaped_safe_str(q_name));
+ log_info(LD_APP, "Passed request for %s to rewrite_and_attach_if_allowed.",
+ escaped_safe_str_client(q_name));
tor_free(q_name);
}
@@ -177,17 +187,18 @@ dnsserv_launch_request(const char *name, int reverse)
return -1;
}
- /* Now, throw the connection over to get rewritten (which will answer it
- * immediately if it's in the cache, or completely bogus, or automapped),
- * and then attached to a circuit. */
+ /* Now, unless a controller asked us to leave streams unattached,
+ * throw the connection over to get rewritten (which will
+ * answer it immediately if it's in the cache, or completely bogus, or
+ * automapped), and then attached to a circuit. */
log_info(LD_APP, "Passing request for %s to rewrite_and_attach.",
- escaped_safe_str(name));
+ escaped_safe_str_client(name));
q_name = tor_strdup(name); /* q could be freed in rewrite_and_attach */
- connection_ap_handshake_rewrite_and_attach(conn, NULL, NULL);
+ connection_ap_rewrite_and_attach_if_allowed(conn, NULL, NULL);
/* Now, the connection is marked if it was bad. */
- log_info(LD_APP, "Passed request for %s to rewrite_and_attach.",
- escaped_safe_str(q_name));
+ log_info(LD_APP, "Passed request for %s to rewrite_and_attach_if_allowed.",
+ escaped_safe_str_client(q_name));
tor_free(q_name);
return 0;
}
@@ -297,8 +308,8 @@ dnsserv_configure_listener(connection_t *conn)
tor_assert(conn->s >= 0);
tor_assert(conn->type == CONN_TYPE_AP_DNS_LISTENER);
- conn->dns_server_port = evdns_add_server_port(conn->s, 0,
- evdns_server_callback, NULL);
+ conn->dns_server_port =
+ tor_evdns_add_server_port(conn->s, 0, evdns_server_callback, NULL);
}
/** Free the evdns server port for <b>conn</b>, which must be an
diff --git a/src/or/dnsserv.h b/src/or/dnsserv.h
new file mode 100644
index 0000000000..5bf154ebb2
--- /dev/null
+++ b/src/or/dnsserv.h
@@ -0,0 +1,26 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file dnsserv.h
+ * \brief Header file for dnsserv.c.
+ **/
+
+#ifndef _TOR_DNSSERV_H
+#define _TOR_DNSSERV_H
+
+void dnsserv_configure_listener(connection_t *conn);
+void dnsserv_close_listener(connection_t *conn);
+void dnsserv_resolved(edge_connection_t *conn,
+ int answer_type,
+ size_t answer_len,
+ const char *answer,
+ int ttl);
+void dnsserv_reject_request(edge_connection_t *conn);
+int dnsserv_launch_request(const char *name, int is_reverse);
+
+#endif
+
diff --git a/src/or/eventdns.c b/src/or/eventdns.c
index a889e803ed..b929303fd5 100644
--- a/src/or/eventdns.c
+++ b/src/or/eventdns.c
@@ -31,6 +31,7 @@
*/
#include "eventdns_tor.h"
+#include "../common/util.h"
#include <sys/types.h>
/* #define NDEBUG */
@@ -89,6 +90,7 @@
#include <stdarg.h>
#include "eventdns.h"
+
#ifdef WIN32
#include <windows.h>
#include <winsock2.h>
@@ -173,8 +175,6 @@ struct evdns_request {
/* these objects are kept in a circular list */
struct evdns_request *next, *prev;
- u16 timeout_event_deleted; /**< Debugging: where was timeout_event
- * deleted? 0 for "it's added." */
struct event timeout_event;
u16 trans_id; /* the transaction id */
@@ -214,8 +214,6 @@ struct nameserver {
struct event event;
/* these objects are kept in a circular list */
struct nameserver *next, *prev;
- u16 timeout_event_deleted; /**< Debugging: where was timeout_event
- * deleted? 0 for "it's added." */
struct event timeout_event; /* used to keep the timeout for */
/* when we next probe this server. */
/* Valid if state == 0 */
@@ -474,51 +472,10 @@ sockaddr_eq(const struct sockaddr *sa1, const struct sockaddr *sa2,
return 1;
}
-/* for debugging bug 929. XXXX022 */
-static int
-_add_timeout_event(u16 *lineno, struct event *ev, struct timeval *to)
-{
- *lineno = 0;
- return evtimer_add(ev, to);
-}
-#define add_timeout_event(s, to) \
- (_add_timeout_event(&(s)->timeout_event_deleted, &(s)->timeout_event, (to)))
-
-/* for debugging bug 929. XXXX022 */
-static int
-_del_timeout_event(u16 *lineno, struct event *ev, int line)
-{
- if (*lineno) {
- log(EVDNS_LOG_DEBUG,
- "Duplicate timeout event_del from line %d: first call "
- "was at %d.", line, (int)*lineno);
- return 0;
- } else {
- *lineno = (u16)line;
- return event_del(ev);
- }
-}
-#define del_timeout_event(s) \
- (_del_timeout_event(&(s)->timeout_event_deleted, &(s)->timeout_event, \
- __LINE__))
-/* For debugging bug 929/957. XXXX022 */
-static int
-_del_timeout_event_if_set(u16 *lineno, struct event *ev, int line)
-{
- if (*lineno == 0) {
- log(EVDNS_LOG_DEBUG,
- "Event that I thought was non-added as of line %d "
- "was actually added on line %d",
- line, (int)*lineno);
- *lineno = line;
- return event_del(ev);
- }
- return 0;
-}
-#define del_timeout_event_if_set(s) \
- _del_timeout_event_if_set(&(s)->timeout_event_deleted, \
- &(s)->timeout_event, \
- __LINE__)
+#define add_timeout_event(s, to) \
+ (event_add(&(s)->timeout_event, (to)))
+#define del_timeout_event(s) \
+ (event_del(&(s)->timeout_event))
/* This walks the list of inflight requests to find the */
/* one with a matching transaction id. Returns NULL on */
@@ -555,7 +512,7 @@ static void
nameserver_probe_failed(struct nameserver *const ns) {
const struct timeval * timeout;
del_timeout_event(ns);
- CLEAR(&ns->timeout_event);
+
if (ns->state == 1) {
/* This can happen if the nameserver acts in a way which makes us mark */
/* it as bad and then starts sending good replies. */
@@ -567,8 +524,6 @@ nameserver_probe_failed(struct nameserver *const ns) {
global_nameserver_timeouts_length - 1)];
ns->failed_times++;
- del_timeout_event_if_set(ns);
- evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
if (add_timeout_event(ns, (struct timeval *) timeout) < 0) {
log(EVDNS_LOG_WARN,
"Error from libevent when adding timer event for %s",
@@ -597,8 +552,6 @@ nameserver_failed(struct nameserver *const ns, const char *msg) {
ns->state = 0;
ns->failed_times = 1;
- del_timeout_event_if_set(ns);
- evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
if (add_timeout_event(ns, (struct timeval *) &global_nameserver_timeouts[0]) < 0) {
log(EVDNS_LOG_WARN,
"Error from libevent when adding timer event for %s",
@@ -634,7 +587,6 @@ nameserver_up(struct nameserver *const ns) {
log(EVDNS_LOG_WARN, "Nameserver %s is back up",
debug_ntop((struct sockaddr *)&ns->address));
del_timeout_event(ns);
- CLEAR(&ns->timeout_event);
ns->state = 1;
ns->failed_times = 0;
ns->timedout = 0;
@@ -666,7 +618,6 @@ request_finished(struct evdns_request *const req, struct evdns_request **head) {
log(EVDNS_LOG_DEBUG, "Removing timeout for request %lx",
(unsigned long) req);
del_timeout_event(req);
- CLEAR(&req->timeout_event);
search_request_finished(req);
global_requests_inflight--;
@@ -1342,8 +1293,8 @@ server_port_read(struct evdns_server_port *s) {
static void
server_port_flush(struct evdns_server_port *port)
{
- while (port->pending_replies) {
- struct server_request *req = port->pending_replies;
+ struct server_request *req = port->pending_replies;
+ while (req) {
ssize_t r = sendto(port->socket, req->response, req->response_len, 0,
(struct sockaddr*) &req->addr, (socklen_t)req->addrlen);
if (r < 0) {
@@ -1355,6 +1306,9 @@ server_port_flush(struct evdns_server_port *port)
if (server_request_free(req)) {
/* we released the last reference to req->port. */
return;
+ } else {
+ assert(port->pending_replies != req);
+ req = port->pending_replies;
}
}
@@ -2046,7 +2000,6 @@ evdns_request_timeout_callback(int fd, short events, void *arg) {
* request_finished; that one already deletes the timeout event.
* XXXX021 port this change to libevent. */
del_timeout_event(req);
- CLEAR(&req->timeout_event);
evdns_request_transmit(req);
}
}
@@ -2109,8 +2062,7 @@ evdns_request_transmit(struct evdns_request *req) {
/* transmitted; we need to check for timeout. */
log(EVDNS_LOG_DEBUG,
"Setting timeout for request %lx", (unsigned long) req);
- del_timeout_event_if_set(req);
- evtimer_set(&req->timeout_event, evdns_request_timeout_callback, req);
+
if (add_timeout_event(req, &global_timeout) < 0) {
log(EVDNS_LOG_WARN,
"Error from libevent when adding timer for request %lx",
@@ -2225,7 +2177,6 @@ evdns_clear_nameservers_and_suspend(void)
(void) event_del(&server->event);
CLEAR(&server->event);
del_timeout_event(server);
- CLEAR(&server->timeout_event);
if (server->socket >= 0)
CLOSE_SOCKET(server->socket);
CLEAR(server);
@@ -2243,7 +2194,6 @@ evdns_clear_nameservers_and_suspend(void)
req->ns = NULL;
/* ???? What to do about searches? */
del_timeout_event(req);
- CLEAR(&req->timeout_event);
req->trans_id = 0;
req->transmit_me = 0;
@@ -2292,6 +2242,21 @@ evdns_resume(void)
}
static int
+sockaddr_is_loopback(const struct sockaddr *addr)
+{
+ static const char LOOPBACK_S6[16] =
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1";
+ if (addr->sa_family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)addr;
+ return (ntohl(sin->sin_addr.s_addr) & 0xff000000) == 0x7f000000;
+ } else if (addr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
+ return !memcmp(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16);
+ }
+ return 0;
+}
+
+static int
_evdns_nameserver_add_impl(const struct sockaddr *address,
socklen_t addrlen) {
/* first check to see if we already have this nameserver */
@@ -2318,7 +2283,8 @@ _evdns_nameserver_add_impl(const struct sockaddr *address,
if (!ns) return -1;
memset(ns, 0, sizeof(struct nameserver));
- ns->timeout_event_deleted = __LINE__;
+
+ evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
ns->socket = socket(PF_INET, SOCK_DGRAM, 0);
if (ns->socket < 0) { err = 1; goto out1; }
@@ -2331,7 +2297,8 @@ _evdns_nameserver_add_impl(const struct sockaddr *address,
fcntl(ns->socket, F_SETFL, O_NONBLOCK);
#endif
- if (global_bind_addr_is_set) {
+ if (global_bind_addr_is_set &&
+ !sockaddr_is_loopback((struct sockaddr*)&global_bind_address)) {
if (bind(ns->socket, (struct sockaddr *)&global_bind_address,
global_bind_addrlen) < 0) {
log(EVDNS_LOG_DEBUG, "Couldn't bind to outgoing address.");
@@ -2553,7 +2520,8 @@ request_new(int type, const char *name, int flags,
}
memset(req, 0, sizeof(struct evdns_request));
- req->timeout_event_deleted = __LINE__;
+
+ evtimer_set(&req->timeout_event, evdns_request_timeout_callback, req);
if (global_randomize_case) {
unsigned i;
@@ -2941,14 +2909,6 @@ evdns_resolv_set_defaults(int flags) {
if (flags & DNS_OPTION_NAMESERVERS) evdns_nameserver_ip_add("127.0.0.1");
}
-#ifndef HAVE_STRTOK_R
-static char *
-strtok_r(char *s, const char *delim, char **state) {
- (void)state;
- return strtok(s, delim);
-}
-#endif
-
/* helper version of atoi which returns -1 on error */
static int
strtoint(const char *const str) {
@@ -3025,9 +2985,9 @@ static void
resolv_conf_parse_line(char *const start, int flags) {
char *strtok_state;
static const char *const delims = " \t";
-#define NEXT_TOKEN strtok_r(NULL, delims, &strtok_state)
+#define NEXT_TOKEN tor_strtok_r(NULL, delims, &strtok_state)
- char *const first_token = strtok_r(start, delims, &strtok_state);
+ char *const first_token = tor_strtok_r(start, delims, &strtok_state);
if (!first_token) return;
if (!strcmp(first_token, "nameserver") && (flags & DNS_OPTION_NAMESERVERS)) {
@@ -3171,14 +3131,13 @@ load_nameservers_with_getnetworkparams(void)
IP_ADDR_STRING *ns;
GetNetworkParams_fn_t fn;
- /* XXXX Possibly, we should hardcode the location of this DLL. */
- if (!(handle = LoadLibrary("iphlpapi.dll"))) {
+ if (!(handle = load_windows_system_library(TEXT("iphlpapi.dll")))) {
log(EVDNS_LOG_WARN, "Could not open iphlpapi.dll");
/* right now status = 0, doesn't that mean "good" - mikec */
status = -1;
goto done;
}
- if (!(fn = (GetNetworkParams_fn_t) GetProcAddress(handle, "GetNetworkParams"))) {
+ if (!(fn = (GetNetworkParams_fn_t) GetProcAddress(handle, TEXT("GetNetworkParams")))) {
log(EVDNS_LOG_WARN, "Could not get address of function.");
/* same as above */
status = -1;
@@ -3241,9 +3200,10 @@ load_nameservers_with_getnetworkparams(void)
}
static int
-config_nameserver_from_reg_key(HKEY key, const char *subkey)
+config_nameserver_from_reg_key(HKEY key, const TCHAR *subkey)
{
char *buf;
+ char ansibuf[MAX_PATH] = {0};
DWORD bufsz = 0, type = 0;
int status = 0;
@@ -3255,24 +3215,30 @@ config_nameserver_from_reg_key(HKEY key, const char *subkey)
if (RegQueryValueEx(key, subkey, 0, &type, (LPBYTE)buf, &bufsz)
== ERROR_SUCCESS && bufsz > 1) {
- status = evdns_nameserver_ip_add_line(buf);
+ wcstombs(ansibuf,(wchar_t*)buf,MAX_PATH);/*XXXX UNICODE */
+ status = evdns_nameserver_ip_add_line(ansibuf);
}
mm_free(buf);
return status;
}
-#define SERVICES_KEY "System\\CurrentControlSet\\Services\\"
-#define WIN_NS_9X_KEY SERVICES_KEY "VxD\\MSTCP"
-#define WIN_NS_NT_KEY SERVICES_KEY "Tcpip\\Parameters"
+#define SERVICES_KEY TEXT("System\\CurrentControlSet\\Services\\")
+#define WIN_NS_9X_KEY SERVICES_KEY TEXT("VxD\\MSTCP")
+#define WIN_NS_NT_KEY SERVICES_KEY TEXT("Tcpip\\Parameters")
static int
load_nameservers_from_registry(void)
{
int found = 0;
int r;
+ OSVERSIONINFO info;
+ memset(&info, 0, sizeof(info));
+ info.dwOSVersionInfoSize = sizeof (info);
+ GetVersionEx(&info);
+
#define TRY(k, name) \
- if (!found && config_nameserver_from_reg_key(k,name) == 0) { \
+ if (!found && config_nameserver_from_reg_key(k,TEXT(name)) == 0) { \
log(EVDNS_LOG_DEBUG,"Found nameservers in %s/%s",#k,name); \
found = 1; \
} else if (!found) { \
@@ -3280,7 +3246,7 @@ load_nameservers_from_registry(void)
#k,#name); \
}
- if (((int)GetVersion()) > 0) { /* NT */
+ if (info.dwMajorVersion >= 5) { /* NT */
HKEY nt_key = 0, interfaces_key = 0;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
@@ -3288,7 +3254,7 @@ load_nameservers_from_registry(void)
log(EVDNS_LOG_DEBUG,"Couldn't open nt key, %d",(int)GetLastError());
return -1;
}
- r = RegOpenKeyEx(nt_key, "Interfaces", 0,
+ r = RegOpenKeyEx(nt_key, TEXT("Interfaces"), 0,
KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS,
&interfaces_key);
if (r != ERROR_SUCCESS) {
@@ -3384,8 +3350,7 @@ evdns_shutdown(int fail_requests)
if (server->socket >= 0)
CLOSE_SOCKET(server->socket);
(void) event_del(&server->event);
- if (server->state == 0)
- del_timeout_event(server);
+ del_timeout_event(server);
CLEAR(server);
mm_free(server);
if (server_next == server_head)
diff --git a/src/or/geoip.c b/src/or/geoip.c
index eb8460e24e..ee8d72ee1d 100644
--- a/src/or/geoip.c
+++ b/src/or/geoip.c
@@ -3,15 +3,23 @@
/**
* \file geoip.c
- * \brief Functions related to maintaining an IP-to-country database and to
- * summarizing client connections by country.
+ * \brief Functions related to maintaining an IP-to-country database;
+ * to summarizing client connections by country to entry guards, bridges,
+ * and directory servers; and for statistics on answering network status
+ * requests.
*/
#define GEOIP_PRIVATE
#include "or.h"
#include "ht.h"
+#include "config.h"
+#include "control.h"
+#include "dnsserv.h"
+#include "geoip.h"
+#include "routerlist.h"
static void clear_geoip_db(void);
+static void init_geoip_countries(void);
/** An entry from the GeoIP file: maps an IP range to a country. */
typedef struct geoip_entry_t {
@@ -20,16 +28,11 @@ typedef struct geoip_entry_t {
intptr_t country; /**< An index into geoip_countries */
} geoip_entry_t;
-/** For how many periods should we remember per-country request history? */
-#define REQUEST_HIST_LEN 3
-/** How long are the periods for which we should remember request history? */
-#define REQUEST_HIST_PERIOD (8*60*60)
-
/** A per-country record for GeoIP request history. */
typedef struct geoip_country_t {
char countrycode[3];
- uint32_t n_v2_ns_requests[REQUEST_HIST_LEN];
- uint32_t n_v3_ns_requests[REQUEST_HIST_LEN];
+ uint32_t n_v2_ns_requests;
+ uint32_t n_v3_ns_requests;
} geoip_country_t;
/** A list of geoip_country_t */
@@ -42,7 +45,7 @@ static strmap_t *country_idxplus1_by_lc_code = NULL;
static smartlist_t *geoip_entries = NULL;
/** Return the index of the <b>country</b>'s entry in the GeoIP DB
- * if it is a valid 2-letter country code, otherwise return zero.
+ * if it is a valid 2-letter country code, otherwise return -1.
*/
country_t
geoip_get_country(const char *country)
@@ -101,11 +104,11 @@ geoip_parse_entry(const char *line)
{
unsigned int low, high;
char b[3];
- if (!geoip_countries) {
- geoip_countries = smartlist_create();
+ if (!geoip_countries)
+ init_geoip_countries();
+ if (!geoip_entries)
geoip_entries = smartlist_create();
- country_idxplus1_by_lc_code = strmap_new();
- }
+
while (TOR_ISSPACE(*line))
++line;
if (*line == '#')
@@ -142,6 +145,7 @@ _geoip_compare_entries(const void **_a, const void **_b)
static int
_geoip_compare_key_to_entry(const void *_key, const void **_member)
{
+ /* No alignment issue here, since _key really is a pointer to uint32_t */
const uint32_t addr = *(uint32_t *)_key;
const geoip_entry_t *entry = *_member;
if (addr < entry->ip_low)
@@ -160,6 +164,24 @@ should_record_bridge_info(or_options_t *options)
return options->BridgeRelay && options->BridgeRecordUsageByCountry;
}
+/** Set up a new list of geoip countries with no countries (yet) set in it,
+ * except for the unknown country.
+ */
+static void
+init_geoip_countries(void)
+{
+ geoip_country_t *geoip_unresolved;
+ geoip_countries = smartlist_create();
+ /* Add a geoip_country_t for requests that could not be resolved to a
+ * country as first element (index 0) to geoip_countries. */
+ geoip_unresolved = tor_malloc_zero(sizeof(geoip_country_t));
+ strlcpy(geoip_unresolved->countrycode, "??",
+ sizeof(geoip_unresolved->countrycode));
+ smartlist_add(geoip_countries, geoip_unresolved);
+ country_idxplus1_by_lc_code = strmap_new();
+ strmap_set_lc(country_idxplus1_by_lc_code, "??", (void*)(1));
+}
+
/** Clear the GeoIP database and reload it from the file
* <b>filename</b>. Return 0 on success, -1 on failure.
*
@@ -185,10 +207,8 @@ geoip_load_file(const char *filename, or_options_t *options)
filename, msg);
return -1;
}
- if (!geoip_countries) {
- geoip_countries = smartlist_create();
- country_idxplus1_by_lc_code = strmap_new();
- }
+ if (!geoip_countries)
+ init_geoip_countries();
if (geoip_entries) {
SMARTLIST_FOREACH(geoip_entries, geoip_entry_t *, e, tor_free(e));
smartlist_free(geoip_entries);
@@ -215,9 +235,10 @@ geoip_load_file(const char *filename, or_options_t *options)
}
/** Given an IP address in host order, return a number representing the
- * country to which that address belongs, or -1 for unknown. The return value
- * will always be less than geoip_get_n_countries(). To decode it,
- * call geoip_get_country_name().
+ * country to which that address belongs, -1 for "No geoip information
+ * available", or 0 for the 'unknown country'. The return value will always
+ * be less than geoip_get_n_countries(). To decode it, call
+ * geoip_get_country_name().
*/
int
geoip_get_country_by_ip(uint32_t ipaddr)
@@ -226,13 +247,15 @@ geoip_get_country_by_ip(uint32_t ipaddr)
if (!geoip_entries)
return -1;
ent = smartlist_bsearch(geoip_entries, &ipaddr, _geoip_compare_key_to_entry);
- return ent ? (int)ent->country : -1;
+ return ent ? (int)ent->country : 0;
}
/** Return the number of countries recognized by the GeoIP database. */
int
geoip_get_n_countries(void)
{
+ if (!geoip_countries)
+ init_geoip_countries();
return (int) smartlist_len(geoip_countries);
}
@@ -261,8 +284,8 @@ geoip_is_loaded(void)
typedef struct clientmap_entry_t {
HT_ENTRY(clientmap_entry_t) node;
uint32_t ipaddr;
- time_t last_seen; /* The last 2 bits of this value hold the client
- * operation. */
+ unsigned int last_seen_in_minutes:30;
+ unsigned int action:2;
} clientmap_entry_t;
#define ACTION_MASK 3
@@ -270,14 +293,6 @@ typedef struct clientmap_entry_t {
/** Map from client IP address to last time seen. */
static HT_HEAD(clientmap, clientmap_entry_t) client_history =
HT_INITIALIZER();
-/** Time at which we started tracking client IP history. */
-static time_t client_history_starts = 0;
-
-/** When did the current period of checking per-country request history
- * start? */
-static time_t current_request_period_starts = 0;
-/** How many older request periods are we remembering? */
-static int n_old_request_periods = 0;
/** Hashtable helper: compute a hash of a clientmap_entry_t. */
static INLINE unsigned
@@ -289,7 +304,7 @@ clientmap_entry_hash(const clientmap_entry_t *a)
static INLINE int
clientmap_entries_eq(const clientmap_entry_t *a, const clientmap_entry_t *b)
{
- return a->ipaddr == b->ipaddr;
+ return a->ipaddr == b->ipaddr && a->action == b->action;
}
HT_PROTOTYPE(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
@@ -297,8 +312,87 @@ HT_PROTOTYPE(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
HT_GENERATE(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
clientmap_entries_eq, 0.6, malloc, realloc, free);
+/** Clear history of connecting clients used by entry and bridge stats. */
+static void
+client_history_clear(void)
+{
+ clientmap_entry_t **ent, **next, *this;
+ for (ent = HT_START(clientmap, &client_history); ent != NULL;
+ ent = next) {
+ if ((*ent)->action == GEOIP_CLIENT_CONNECT) {
+ this = *ent;
+ next = HT_NEXT_RMV(clientmap, &client_history, ent);
+ tor_free(this);
+ } else {
+ next = HT_NEXT(clientmap, &client_history, ent);
+ }
+ }
+}
+
+/** How often do we update our estimate which share of v2 and v3 directory
+ * requests is sent to us? We could as well trigger updates of shares from
+ * network status updates, but that means adding a lot of calls into code
+ * that is independent from geoip stats (and keeping them up-to-date). We
+ * are perfectly fine with an approximation of 15-minute granularity. */
+#define REQUEST_SHARE_INTERVAL (15 * 60)
+
+/** When did we last determine which share of v2 and v3 directory requests
+ * is sent to us? */
+static time_t last_time_determined_shares = 0;
+
+/** Sum of products of v2 shares times the number of seconds for which we
+ * consider these shares as valid. */
+static double v2_share_times_seconds;
+
+/** Sum of products of v3 shares times the number of seconds for which we
+ * consider these shares as valid. */
+static double v3_share_times_seconds;
+
+/** Number of seconds we are determining v2 and v3 shares. */
+static int share_seconds;
+
+/** Try to determine which fraction of v2 and v3 directory requests aimed at
+ * caches will be sent to us at time <b>now</b> and store that value in
+ * order to take a mean value later on. */
+static void
+geoip_determine_shares(time_t now)
+{
+ double v2_share = 0.0, v3_share = 0.0;
+ if (router_get_my_share_of_directory_requests(&v2_share, &v3_share) < 0)
+ return;
+ if (last_time_determined_shares) {
+ v2_share_times_seconds += v2_share *
+ ((double) (now - last_time_determined_shares));
+ v3_share_times_seconds += v3_share *
+ ((double) (now - last_time_determined_shares));
+ share_seconds += (int)(now - last_time_determined_shares);
+ }
+ last_time_determined_shares = now;
+}
+
+/** Calculate which fraction of v2 and v3 directory requests aimed at caches
+ * have been sent to us since the last call of this function up to time
+ * <b>now</b>. Set *<b>v2_share_out</b> and *<b>v3_share_out</b> to the
+ * fractions of v2 and v3 protocol shares we expect to have seen. Reset
+ * counters afterwards. Return 0 on success, -1 on failure (e.g. when zero
+ * seconds have passed since the last call).*/
+static int
+geoip_get_mean_shares(time_t now, double *v2_share_out,
+ double *v3_share_out)
+{
+ geoip_determine_shares(now);
+ if (!share_seconds)
+ return -1;
+ *v2_share_out = v2_share_times_seconds / ((double) share_seconds);
+ *v3_share_out = v3_share_times_seconds / ((double) share_seconds);
+ v2_share_times_seconds = v3_share_times_seconds = 0.0;
+ share_seconds = 0;
+ return 0;
+}
+
/** Note that we've seen a client connect from the IP <b>addr</b> (host order)
- * at time <b>now</b>. Ignored by all but bridges. */
+ * at time <b>now</b>. Ignored by all but bridges and directories if
+ * configured accordingly. */
void
geoip_note_client_seen(geoip_client_action_t action,
uint32_t addr, time_t now)
@@ -306,72 +400,45 @@ geoip_note_client_seen(geoip_client_action_t action,
or_options_t *options = get_options();
clientmap_entry_t lookup, *ent;
if (action == GEOIP_CLIENT_CONNECT) {
- if (!(options->BridgeRelay && options->BridgeRecordUsageByCountry))
- return;
- /* Did we recently switch from bridge to relay or back? */
- if (client_history_starts > now)
+ /* Only remember statistics as entry guard or as bridge. */
+ if (!options->EntryStatistics &&
+ (!(options->BridgeRelay && options->BridgeRecordUsageByCountry)))
return;
} else {
-#ifndef ENABLE_GEOIP_STATS
- return;
-#else
if (options->BridgeRelay || options->BridgeAuthoritativeDir ||
- !options->DirRecordUsageByCountry)
+ !options->DirReqStatistics)
return;
-#endif
}
- /* Rotate the current request period. */
- while (current_request_period_starts + REQUEST_HIST_PERIOD < now) {
- if (!geoip_countries)
- geoip_countries = smartlist_create();
- if (!current_request_period_starts) {
- current_request_period_starts = now;
- break;
- }
- SMARTLIST_FOREACH(geoip_countries, geoip_country_t *, c, {
- memmove(&c->n_v2_ns_requests[0], &c->n_v2_ns_requests[1],
- sizeof(uint32_t)*(REQUEST_HIST_LEN-1));
- memmove(&c->n_v3_ns_requests[0], &c->n_v3_ns_requests[1],
- sizeof(uint32_t)*(REQUEST_HIST_LEN-1));
- c->n_v2_ns_requests[REQUEST_HIST_LEN-1] = 0;
- c->n_v3_ns_requests[REQUEST_HIST_LEN-1] = 0;
- });
- current_request_period_starts += REQUEST_HIST_PERIOD;
- if (n_old_request_periods < REQUEST_HIST_LEN-1)
- ++n_old_request_periods;
- }
-
- /* We use the low 3 bits of the time to encode the action. Since we're
- * potentially remembering tons of clients, we don't want to make
- * clientmap_entry_t larger than it has to be. */
- now = (now & ~ACTION_MASK) | (((int)action) & ACTION_MASK);
lookup.ipaddr = addr;
+ lookup.action = (int)action;
ent = HT_FIND(clientmap, &client_history, &lookup);
if (ent) {
- ent->last_seen = now;
+ ent->last_seen_in_minutes = now / 60;
} else {
ent = tor_malloc_zero(sizeof(clientmap_entry_t));
ent->ipaddr = addr;
- ent->last_seen = now;
+ ent->last_seen_in_minutes = now / 60;
+ ent->action = (int)action;
HT_INSERT(clientmap, &client_history, ent);
}
if (action == GEOIP_CLIENT_NETWORKSTATUS ||
action == GEOIP_CLIENT_NETWORKSTATUS_V2) {
int country_idx = geoip_get_country_by_ip(addr);
+ if (country_idx < 0)
+ country_idx = 0; /** unresolved requests are stored at index 0. */
if (country_idx >= 0 && country_idx < smartlist_len(geoip_countries)) {
geoip_country_t *country = smartlist_get(geoip_countries, country_idx);
if (action == GEOIP_CLIENT_NETWORKSTATUS)
- ++country->n_v3_ns_requests[REQUEST_HIST_LEN-1];
+ ++country->n_v3_ns_requests;
else
- ++country->n_v2_ns_requests[REQUEST_HIST_LEN-1];
+ ++country->n_v2_ns_requests;
}
- }
- if (!client_history_starts) {
- client_history_starts = now;
- current_request_period_starts = now;
+ /* Periodically determine share of requests that we should see */
+ if (last_time_determined_shares + REQUEST_SHARE_INTERVAL < now)
+ geoip_determine_shares(now);
}
}
@@ -380,8 +447,8 @@ geoip_note_client_seen(geoip_client_action_t action,
static int
_remove_old_client_helper(struct clientmap_entry_t *ent, void *_cutoff)
{
- time_t cutoff = *(time_t*)_cutoff;
- if (ent->last_seen < cutoff) {
+ time_t cutoff = *(time_t*)_cutoff / 60;
+ if (ent->last_seen_in_minutes < cutoff) {
tor_free(ent);
return 1;
} else {
@@ -389,18 +456,45 @@ _remove_old_client_helper(struct clientmap_entry_t *ent, void *_cutoff)
}
}
-/** Forget about all clients that haven't connected since <b>cutoff</b>.
- * If <b>cutoff</b> is in the future, clients won't be added to the history
- * until this time is reached. This is useful to prevent relays that switch
- * to bridges from reporting unbelievable numbers of clients. */
+/** Forget about all clients that haven't connected since <b>cutoff</b>. */
void
geoip_remove_old_clients(time_t cutoff)
{
clientmap_HT_FOREACH_FN(&client_history,
_remove_old_client_helper,
&cutoff);
- if (client_history_starts < cutoff)
- client_history_starts = cutoff;
+}
+
+/** How many responses are we giving to clients requesting v2 network
+ * statuses? */
+static uint32_t ns_v2_responses[GEOIP_NS_RESPONSE_NUM];
+
+/** How many responses are we giving to clients requesting v3 network
+ * statuses? */
+static uint32_t ns_v3_responses[GEOIP_NS_RESPONSE_NUM];
+
+/** Note that we've rejected a client's request for a v2 or v3 network
+ * status, encoded in <b>action</b> for reason <b>reason</b> at time
+ * <b>now</b>. */
+void
+geoip_note_ns_response(geoip_client_action_t action,
+ geoip_ns_response_t response)
+{
+ static int arrays_initialized = 0;
+ if (!get_options()->DirReqStatistics)
+ return;
+ if (!arrays_initialized) {
+ memset(ns_v2_responses, 0, sizeof(ns_v2_responses));
+ memset(ns_v3_responses, 0, sizeof(ns_v3_responses));
+ arrays_initialized = 1;
+ }
+ tor_assert(action == GEOIP_CLIENT_NETWORKSTATUS ||
+ action == GEOIP_CLIENT_NETWORKSTATUS_V2);
+ tor_assert(response < GEOIP_NS_RESPONSE_NUM);
+ if (action == GEOIP_CLIENT_NETWORKSTATUS)
+ ns_v3_responses[response]++;
+ else
+ ns_v2_responses[response]++;
}
/** Do not mention any country from which fewer than this number of IPs have
@@ -414,13 +508,6 @@ geoip_remove_old_clients(time_t cutoff)
* multiple of this value. */
#define IP_GRANULARITY 8
-/** Return the time at which we started recording geoip data. */
-time_t
-geoip_get_history_start(void)
-{
- return client_history_starts;
-}
-
/** Helper type: used to sort per-country totals by value. */
typedef struct c_hist_t {
char country[3]; /**< Two-letter country code. */
@@ -442,97 +529,319 @@ _c_hist_compare(const void **_a, const void **_b)
return strcmp(a->country, b->country);
}
-/** How long do we have to have observed per-country request history before we
- * are willing to talk about it? */
-#define GEOIP_MIN_OBSERVATION_TIME (12*60*60)
+/** When there are incomplete directory requests at the end of a 24-hour
+ * period, consider those requests running for longer than this timeout as
+ * failed, the others as still running. */
+#define DIRREQ_TIMEOUT (10*60)
-/** Return the lowest x such that x is at least <b>number</b>, and x modulo
- * <b>divisor</b> == 0. */
-static INLINE unsigned
-round_to_next_multiple_of(unsigned number, unsigned divisor)
+/** Entry in a map from either conn->global_identifier for direct requests
+ * or a unique circuit identifier for tunneled requests to request time,
+ * response size, and completion time of a network status request. Used to
+ * measure download times of requests to derive average client
+ * bandwidths. */
+typedef struct dirreq_map_entry_t {
+ HT_ENTRY(dirreq_map_entry_t) node;
+ /** Unique identifier for this network status request; this is either the
+ * conn->global_identifier of the dir conn (direct request) or a new
+ * locally unique identifier of a circuit (tunneled request). This ID is
+ * only unique among other direct or tunneled requests, respectively. */
+ uint64_t dirreq_id;
+ unsigned int state:3; /**< State of this directory request. */
+ unsigned int type:1; /**< Is this a direct or a tunneled request? */
+ unsigned int completed:1; /**< Is this request complete? */
+ unsigned int action:2; /**< Is this a v2 or v3 request? */
+ /** When did we receive the request and started sending the response? */
+ struct timeval request_time;
+ size_t response_size; /**< What is the size of the response in bytes? */
+ struct timeval completion_time; /**< When did the request succeed? */
+} dirreq_map_entry_t;
+
+/** Map of all directory requests asking for v2 or v3 network statuses in
+ * the current geoip-stats interval. Values are
+ * of type *<b>dirreq_map_entry_t</b>. */
+static HT_HEAD(dirreqmap, dirreq_map_entry_t) dirreq_map =
+ HT_INITIALIZER();
+
+static int
+dirreq_map_ent_eq(const dirreq_map_entry_t *a,
+ const dirreq_map_entry_t *b)
{
- number += divisor - 1;
- number -= number % divisor;
- return number;
+ return a->dirreq_id == b->dirreq_id && a->type == b->type;
}
-/** Return a newly allocated comma-separated string containing entries for all
- * the countries from which we've seen enough clients connect. The entry
- * format is cc=num where num is the number of IPs we've seen connecting from
- * that country, and cc is a lowercased country code. Returns NULL if we don't
- * want to export geoip data yet. */
-char *
-geoip_get_client_history(time_t now, geoip_client_action_t action)
+static unsigned
+dirreq_map_ent_hash(const dirreq_map_entry_t *entry)
+{
+ unsigned u = (unsigned) entry->dirreq_id;
+ u += entry->type << 20;
+ return u;
+}
+
+HT_PROTOTYPE(dirreqmap, dirreq_map_entry_t, node, dirreq_map_ent_hash,
+ dirreq_map_ent_eq);
+HT_GENERATE(dirreqmap, dirreq_map_entry_t, node, dirreq_map_ent_hash,
+ dirreq_map_ent_eq, 0.6, malloc, realloc, free);
+
+/** Helper: Put <b>entry</b> into map of directory requests using
+ * <b>type</b> and <b>dirreq_id</b> as key parts. If there is
+ * already an entry for that key, print out a BUG warning and return. */
+static void
+_dirreq_map_put(dirreq_map_entry_t *entry, dirreq_type_t type,
+ uint64_t dirreq_id)
+{
+ dirreq_map_entry_t *old_ent;
+ tor_assert(entry->type == type);
+ tor_assert(entry->dirreq_id == dirreq_id);
+
+ /* XXXX022 once we're sure the bug case never happens, we can switch
+ * to HT_INSERT */
+ old_ent = HT_REPLACE(dirreqmap, &dirreq_map, entry);
+ if (old_ent && old_ent != entry) {
+ log_warn(LD_BUG, "Error when putting directory request into local "
+ "map. There was already an entry for the same identifier.");
+ return;
+ }
+}
+
+/** Helper: Look up and return an entry in the map of directory requests
+ * using <b>type</b> and <b>dirreq_id</b> as key parts. If there
+ * is no such entry, return NULL. */
+static dirreq_map_entry_t *
+_dirreq_map_get(dirreq_type_t type, uint64_t dirreq_id)
+{
+ dirreq_map_entry_t lookup;
+ lookup.type = type;
+ lookup.dirreq_id = dirreq_id;
+ return HT_FIND(dirreqmap, &dirreq_map, &lookup);
+}
+
+/** Note that an either direct or tunneled (see <b>type</b>) directory
+ * request for a network status with unique ID <b>dirreq_id</b> of size
+ * <b>response_size</b> and action <b>action</b> (either v2 or v3) has
+ * started. */
+void
+geoip_start_dirreq(uint64_t dirreq_id, size_t response_size,
+ geoip_client_action_t action, dirreq_type_t type)
+{
+ dirreq_map_entry_t *ent;
+ if (!get_options()->DirReqStatistics)
+ return;
+ ent = tor_malloc_zero(sizeof(dirreq_map_entry_t));
+ ent->dirreq_id = dirreq_id;
+ tor_gettimeofday(&ent->request_time);
+ ent->response_size = response_size;
+ ent->action = action;
+ ent->type = type;
+ _dirreq_map_put(ent, type, dirreq_id);
+}
+
+/** Change the state of the either direct or tunneled (see <b>type</b>)
+ * directory request with <b>dirreq_id</b> to <b>new_state</b> and
+ * possibly mark it as completed. If no entry can be found for the given
+ * key parts (e.g., if this is a directory request that we are not
+ * measuring, or one that was started in the previous measurement period),
+ * or if the state cannot be advanced to <b>new_state</b>, do nothing. */
+void
+geoip_change_dirreq_state(uint64_t dirreq_id, dirreq_type_t type,
+ dirreq_state_t new_state)
+{
+ dirreq_map_entry_t *ent;
+ if (!get_options()->DirReqStatistics)
+ return;
+ ent = _dirreq_map_get(type, dirreq_id);
+ if (!ent)
+ return;
+ if (new_state == DIRREQ_IS_FOR_NETWORK_STATUS)
+ return;
+ if (new_state - 1 != ent->state)
+ return;
+ ent->state = new_state;
+ if ((type == DIRREQ_DIRECT &&
+ new_state == DIRREQ_FLUSHING_DIR_CONN_FINISHED) ||
+ (type == DIRREQ_TUNNELED &&
+ new_state == DIRREQ_OR_CONN_BUFFER_FLUSHED)) {
+ tor_gettimeofday(&ent->completion_time);
+ ent->completed = 1;
+ }
+}
+
+/** Return a newly allocated comma-separated string containing statistics
+ * on network status downloads. The string contains the number of completed
+ * requests, timeouts, and still running requests as well as the download
+ * times by deciles and quartiles. Return NULL if we have not observed
+ * requests for long enough. */
+static char *
+geoip_get_dirreq_history(geoip_client_action_t action,
+ dirreq_type_t type)
{
char *result = NULL;
- if (!geoip_is_loaded())
+ smartlist_t *dirreq_completed = NULL;
+ uint32_t complete = 0, timeouts = 0, running = 0;
+ int bufsize = 1024, written;
+ dirreq_map_entry_t **ptr, **next, *ent;
+ struct timeval now;
+
+ tor_gettimeofday(&now);
+ if (action != GEOIP_CLIENT_NETWORKSTATUS &&
+ action != GEOIP_CLIENT_NETWORKSTATUS_V2)
return NULL;
- if (client_history_starts < (now - GEOIP_MIN_OBSERVATION_TIME)) {
- char buf[32];
- smartlist_t *chunks = NULL;
- smartlist_t *entries = NULL;
- int n_countries = geoip_get_n_countries();
- int i;
- clientmap_entry_t **ent;
- unsigned *counts = tor_malloc_zero(sizeof(unsigned)*n_countries);
- unsigned total = 0;
- unsigned granularity = IP_GRANULARITY;
-#ifdef ENABLE_GEOIP_STATS
- if (get_options()->DirRecordUsageByCountry)
- granularity = get_options()->DirRecordUsageGranularity;
-#endif
- HT_FOREACH(ent, clientmap, &client_history) {
- int country;
- if (((*ent)->last_seen & ACTION_MASK) != (int)action)
- continue;
- country = geoip_get_country_by_ip((*ent)->ipaddr);
- if (country < 0)
- continue;
- tor_assert(0 <= country && country < n_countries);
- ++counts[country];
- ++total;
- }
- /* Don't record anything if we haven't seen enough IPs. */
- if (total < MIN_IPS_TO_NOTE_ANYTHING)
- goto done;
- /* Make a list of c_hist_t */
- entries = smartlist_create();
- for (i = 0; i < n_countries; ++i) {
- unsigned c = counts[i];
- const char *countrycode;
- c_hist_t *ent;
- /* Only report a country if it has a minimum number of IPs. */
- if (c >= MIN_IPS_TO_NOTE_COUNTRY) {
- c = round_to_next_multiple_of(c, granularity);
- countrycode = geoip_get_country_name(i);
- ent = tor_malloc(sizeof(c_hist_t));
- strlcpy(ent->country, countrycode, sizeof(ent->country));
- ent->total = c;
- smartlist_add(entries, ent);
+ dirreq_completed = smartlist_create();
+ for (ptr = HT_START(dirreqmap, &dirreq_map); ptr; ptr = next) {
+ ent = *ptr;
+ if (ent->action != action || ent->type != type) {
+ next = HT_NEXT(dirreqmap, &dirreq_map, ptr);
+ continue;
+ } else {
+ if (ent->completed) {
+ smartlist_add(dirreq_completed, ent);
+ complete++;
+ next = HT_NEXT_RMV(dirreqmap, &dirreq_map, ptr);
+ } else {
+ if (tv_mdiff(&ent->request_time, &now) / 1000 > DIRREQ_TIMEOUT)
+ timeouts++;
+ else
+ running++;
+ next = HT_NEXT_RMV(dirreqmap, &dirreq_map, ptr);
+ tor_free(ent);
}
}
- /* Sort entries. Note that we must do this _AFTER_ rounding, or else
- * the sort order could leak info. */
- smartlist_sort(entries, _c_hist_compare);
-
- /* Build the result. */
- chunks = smartlist_create();
- SMARTLIST_FOREACH(entries, c_hist_t *, ch, {
- tor_snprintf(buf, sizeof(buf), "%s=%u", ch->country, ch->total);
- smartlist_add(chunks, tor_strdup(buf));
- });
- result = smartlist_join_strings(chunks, ",", 0, NULL);
- done:
- tor_free(counts);
- if (chunks) {
- SMARTLIST_FOREACH(chunks, char *, c, tor_free(c));
- smartlist_free(chunks);
- }
- if (entries) {
- SMARTLIST_FOREACH(entries, c_hist_t *, c, tor_free(c));
- smartlist_free(entries);
+ }
+#define DIR_REQ_GRANULARITY 4
+ complete = round_uint32_to_next_multiple_of(complete,
+ DIR_REQ_GRANULARITY);
+ timeouts = round_uint32_to_next_multiple_of(timeouts,
+ DIR_REQ_GRANULARITY);
+ running = round_uint32_to_next_multiple_of(running,
+ DIR_REQ_GRANULARITY);
+ result = tor_malloc_zero(bufsize);
+ written = tor_snprintf(result, bufsize, "complete=%u,timeout=%u,"
+ "running=%u", complete, timeouts, running);
+ if (written < 0) {
+ tor_free(result);
+ goto done;
+ }
+
+#define MIN_DIR_REQ_RESPONSES 16
+ if (complete >= MIN_DIR_REQ_RESPONSES) {
+ uint32_t *dltimes;
+ /* We may have rounded 'completed' up. Here we want to use the
+ * real value. */
+ complete = smartlist_len(dirreq_completed);
+ dltimes = tor_malloc_zero(sizeof(uint32_t) * complete);
+ SMARTLIST_FOREACH_BEGIN(dirreq_completed, dirreq_map_entry_t *, ent) {
+ uint32_t bytes_per_second;
+ uint32_t time_diff = (uint32_t) tv_mdiff(&ent->request_time,
+ &ent->completion_time);
+ if (time_diff == 0)
+ time_diff = 1; /* Avoid DIV/0; "instant" answers are impossible
+ * by law of nature or something, but a milisecond
+ * is a bit greater than "instantly" */
+ bytes_per_second = (uint32_t)(1000 * ent->response_size / time_diff);
+ dltimes[ent_sl_idx] = bytes_per_second;
+ } SMARTLIST_FOREACH_END(ent);
+ median_uint32(dltimes, complete); /* sorts as a side effect. */
+ written = tor_snprintf(result + written, bufsize - written,
+ ",min=%u,d1=%u,d2=%u,q1=%u,d3=%u,d4=%u,md=%u,"
+ "d6=%u,d7=%u,q3=%u,d8=%u,d9=%u,max=%u",
+ dltimes[0],
+ dltimes[1*complete/10-1],
+ dltimes[2*complete/10-1],
+ dltimes[1*complete/4-1],
+ dltimes[3*complete/10-1],
+ dltimes[4*complete/10-1],
+ dltimes[5*complete/10-1],
+ dltimes[6*complete/10-1],
+ dltimes[7*complete/10-1],
+ dltimes[3*complete/4-1],
+ dltimes[8*complete/10-1],
+ dltimes[9*complete/10-1],
+ dltimes[complete-1]);
+ if (written<0)
+ tor_free(result);
+ tor_free(dltimes);
+ }
+ done:
+ SMARTLIST_FOREACH(dirreq_completed, dirreq_map_entry_t *, ent,
+ tor_free(ent));
+ smartlist_free(dirreq_completed);
+ return result;
+}
+
+/** Return a newly allocated comma-separated string containing entries for
+ * all the countries from which we've seen enough clients connect as a
+ * bridge, directory server, or entry guard. The entry format is cc=num
+ * where num is the number of IPs we've seen connecting from that country,
+ * and cc is a lowercased country code. Returns NULL if we don't want
+ * to export geoip data yet. */
+char *
+geoip_get_client_history(geoip_client_action_t action)
+{
+ char *result = NULL;
+ unsigned granularity = IP_GRANULARITY;
+ smartlist_t *chunks = NULL;
+ smartlist_t *entries = NULL;
+ int n_countries = geoip_get_n_countries();
+ int i;
+ clientmap_entry_t **ent;
+ unsigned *counts = NULL;
+ unsigned total = 0;
+
+ if (!geoip_is_loaded())
+ return NULL;
+
+ counts = tor_malloc_zero(sizeof(unsigned)*n_countries);
+ HT_FOREACH(ent, clientmap, &client_history) {
+ int country;
+ if ((*ent)->action != (int)action)
+ continue;
+ country = geoip_get_country_by_ip((*ent)->ipaddr);
+ if (country < 0)
+ country = 0; /** unresolved requests are stored at index 0. */
+ tor_assert(0 <= country && country < n_countries);
+ ++counts[country];
+ ++total;
+ }
+ /* Don't record anything if we haven't seen enough IPs. */
+ if (total < MIN_IPS_TO_NOTE_ANYTHING)
+ goto done;
+ /* Make a list of c_hist_t */
+ entries = smartlist_create();
+ for (i = 0; i < n_countries; ++i) {
+ unsigned c = counts[i];
+ const char *countrycode;
+ c_hist_t *ent;
+ /* Only report a country if it has a minimum number of IPs. */
+ if (c >= MIN_IPS_TO_NOTE_COUNTRY) {
+ c = round_to_next_multiple_of(c, granularity);
+ countrycode = geoip_get_country_name(i);
+ ent = tor_malloc(sizeof(c_hist_t));
+ strlcpy(ent->country, countrycode, sizeof(ent->country));
+ ent->total = c;
+ smartlist_add(entries, ent);
}
}
+ /* Sort entries. Note that we must do this _AFTER_ rounding, or else
+ * the sort order could leak info. */
+ smartlist_sort(entries, _c_hist_compare);
+
+ /* Build the result. */
+ chunks = smartlist_create();
+ SMARTLIST_FOREACH(entries, c_hist_t *, ch, {
+ char *buf=NULL;
+ tor_asprintf(&buf, "%s=%u", ch->country, ch->total);
+ smartlist_add(chunks, buf);
+ });
+ result = smartlist_join_strings(chunks, ",", 0, NULL);
+ done:
+ tor_free(counts);
+ if (chunks) {
+ SMARTLIST_FOREACH(chunks, char *, c, tor_free(c));
+ smartlist_free(chunks);
+ }
+ if (entries) {
+ SMARTLIST_FOREACH(entries, c_hist_t *, c, tor_free(c));
+ smartlist_free(entries);
+ }
return result;
}
@@ -540,18 +849,12 @@ geoip_get_client_history(time_t now, geoip_client_action_t action)
* for <b>action</b> in a format suitable for an extra-info document, or NULL
* on failure. */
char *
-geoip_get_request_history(time_t now, geoip_client_action_t action)
+geoip_get_request_history(geoip_client_action_t action)
{
smartlist_t *entries, *strings;
char *result;
unsigned granularity = IP_GRANULARITY;
-#ifdef ENABLE_GEOIP_STATS
- if (get_options()->DirRecordUsageByCountry)
- granularity = get_options()->DirRecordUsageGranularity;
-#endif
- if (client_history_starts >= (now - GEOIP_MIN_OBSERVATION_TIME))
- return NULL;
if (action != GEOIP_CLIENT_NETWORKSTATUS &&
action != GEOIP_CLIENT_NETWORKSTATUS_V2)
return NULL;
@@ -560,13 +863,10 @@ geoip_get_request_history(time_t now, geoip_client_action_t action)
entries = smartlist_create();
SMARTLIST_FOREACH(geoip_countries, geoip_country_t *, c, {
- uint32_t *n = (action == GEOIP_CLIENT_NETWORKSTATUS)
- ? c->n_v3_ns_requests : c->n_v2_ns_requests;
uint32_t tot = 0;
- int i;
c_hist_t *ent;
- for (i=0; i < REQUEST_HIST_LEN; ++i)
- tot += n[i];
+ tot = (action == GEOIP_CLIENT_NETWORKSTATUS) ?
+ c->n_v3_ns_requests : c->n_v2_ns_requests;
if (!tot)
continue;
ent = tor_malloc_zero(sizeof(c_hist_t));
@@ -578,9 +878,9 @@ geoip_get_request_history(time_t now, geoip_client_action_t action)
strings = smartlist_create();
SMARTLIST_FOREACH(entries, c_hist_t *, ent, {
- char buf[32];
- tor_snprintf(buf, sizeof(buf), "%s=%u", ent->country, ent->total);
- smartlist_add(strings, tor_strdup(buf));
+ char *buf = NULL;
+ tor_asprintf(&buf, "%s=%u", ent->country, ent->total);
+ smartlist_add(strings, buf);
});
result = smartlist_join_strings(strings, ",", 0, NULL);
SMARTLIST_FOREACH(strings, char *, cp, tor_free(cp));
@@ -590,69 +890,434 @@ geoip_get_request_history(time_t now, geoip_client_action_t action)
return result;
}
-/** Store all our geoip statistics into $DATADIR/geoip-stats. */
+/** Start time of directory request stats or 0 if we're not collecting
+ * directory request statistics. */
+static time_t start_of_dirreq_stats_interval;
+
+/** Initialize directory request stats. */
void
-dump_geoip_stats(void)
+geoip_dirreq_stats_init(time_t now)
{
-#ifdef ENABLE_GEOIP_STATS
- time_t now = time(NULL);
- time_t request_start;
- char *filename = get_datadir_fname("geoip-stats");
+ start_of_dirreq_stats_interval = now;
+}
+
+/** Stop collecting directory request stats in a way that we can re-start
+ * doing so in geoip_dirreq_stats_init(). */
+void
+geoip_dirreq_stats_term(void)
+{
+ SMARTLIST_FOREACH(geoip_countries, geoip_country_t *, c, {
+ c->n_v2_ns_requests = c->n_v3_ns_requests = 0;
+ });
+ {
+ clientmap_entry_t **ent, **next, *this;
+ for (ent = HT_START(clientmap, &client_history); ent != NULL;
+ ent = next) {
+ if ((*ent)->action == GEOIP_CLIENT_NETWORKSTATUS ||
+ (*ent)->action == GEOIP_CLIENT_NETWORKSTATUS_V2) {
+ this = *ent;
+ next = HT_NEXT_RMV(clientmap, &client_history, ent);
+ tor_free(this);
+ } else {
+ next = HT_NEXT(clientmap, &client_history, ent);
+ }
+ }
+ }
+ v2_share_times_seconds = v3_share_times_seconds = 0.0;
+ last_time_determined_shares = 0;
+ share_seconds = 0;
+ memset(ns_v2_responses, 0, sizeof(ns_v2_responses));
+ memset(ns_v3_responses, 0, sizeof(ns_v3_responses));
+ {
+ dirreq_map_entry_t **ent, **next, *this;
+ for (ent = HT_START(dirreqmap, &dirreq_map); ent != NULL; ent = next) {
+ this = *ent;
+ next = HT_NEXT_RMV(dirreqmap, &dirreq_map, ent);
+ tor_free(this);
+ }
+ }
+ start_of_dirreq_stats_interval = 0;
+}
+
+/** Write dirreq statistics to $DATADIR/stats/dirreq-stats and return when
+ * we would next want to write. */
+time_t
+geoip_dirreq_stats_write(time_t now)
+{
+ char *statsdir = NULL, *filename = NULL;
char *data_v2 = NULL, *data_v3 = NULL;
- char since[ISO_TIME_LEN+1], written[ISO_TIME_LEN+1];
+ char written[ISO_TIME_LEN+1];
open_file_t *open_file = NULL;
double v2_share = 0.0, v3_share = 0.0;
FILE *out;
+ int i;
+
+ if (!start_of_dirreq_stats_interval)
+ return 0; /* Not initialized. */
+ if (start_of_dirreq_stats_interval + WRITE_STATS_INTERVAL > now)
+ goto done; /* Not ready to write. */
+
+ /* Discard all items in the client history that are too old. */
+ geoip_remove_old_clients(start_of_dirreq_stats_interval);
- data_v2 = geoip_get_client_history(now, GEOIP_CLIENT_NETWORKSTATUS_V2);
- data_v3 = geoip_get_client_history(now, GEOIP_CLIENT_NETWORKSTATUS);
- format_iso_time(since, geoip_get_history_start());
+ statsdir = get_datadir_fname("stats");
+ if (check_private_dir(statsdir, CPD_CREATE) < 0)
+ goto done;
+ filename = get_datadir_fname2("stats", "dirreq-stats");
+ data_v2 = geoip_get_client_history(GEOIP_CLIENT_NETWORKSTATUS_V2);
+ data_v3 = geoip_get_client_history(GEOIP_CLIENT_NETWORKSTATUS);
format_iso_time(written, now);
- out = start_writing_to_stdio_file(filename, OPEN_FLAGS_REPLACE,
+ out = start_writing_to_stdio_file(filename, OPEN_FLAGS_APPEND,
0600, &open_file);
if (!out)
goto done;
- if (fprintf(out, "written %s\nstarted-at %s\nns-ips %s\nns-v2-ips %s\n",
- written, since,
+ if (fprintf(out, "dirreq-stats-end %s (%d s)\ndirreq-v3-ips %s\n"
+ "dirreq-v2-ips %s\n", written,
+ (unsigned) (now - start_of_dirreq_stats_interval),
data_v3 ? data_v3 : "", data_v2 ? data_v2 : "") < 0)
goto done;
tor_free(data_v2);
tor_free(data_v3);
- request_start = current_request_period_starts -
- (n_old_request_periods * REQUEST_HIST_PERIOD);
- format_iso_time(since, request_start);
- data_v2 = geoip_get_request_history(now, GEOIP_CLIENT_NETWORKSTATUS_V2);
- data_v3 = geoip_get_request_history(now, GEOIP_CLIENT_NETWORKSTATUS);
- if (fprintf(out, "requests-start %s\nn-ns-reqs %s\nn-v2-ns-reqs %s\n",
- since,
+ data_v2 = geoip_get_request_history(GEOIP_CLIENT_NETWORKSTATUS_V2);
+ data_v3 = geoip_get_request_history(GEOIP_CLIENT_NETWORKSTATUS);
+ if (fprintf(out, "dirreq-v3-reqs %s\ndirreq-v2-reqs %s\n",
data_v3 ? data_v3 : "", data_v2 ? data_v2 : "") < 0)
goto done;
- if (!router_get_my_share_of_directory_requests(&v2_share, &v3_share)) {
- if (fprintf(out, "v2-ns-share %0.2lf%%\n", v2_share*100) < 0)
+ tor_free(data_v2);
+ tor_free(data_v3);
+ SMARTLIST_FOREACH(geoip_countries, geoip_country_t *, c, {
+ c->n_v2_ns_requests = c->n_v3_ns_requests = 0;
+ });
+#define RESPONSE_GRANULARITY 8
+ for (i = 0; i < GEOIP_NS_RESPONSE_NUM; i++) {
+ ns_v2_responses[i] = round_uint32_to_next_multiple_of(
+ ns_v2_responses[i], RESPONSE_GRANULARITY);
+ ns_v3_responses[i] = round_uint32_to_next_multiple_of(
+ ns_v3_responses[i], RESPONSE_GRANULARITY);
+ }
+#undef RESPONSE_GRANULARITY
+ if (fprintf(out, "dirreq-v3-resp ok=%u,not-enough-sigs=%u,unavailable=%u,"
+ "not-found=%u,not-modified=%u,busy=%u\n",
+ ns_v3_responses[GEOIP_SUCCESS],
+ ns_v3_responses[GEOIP_REJECT_NOT_ENOUGH_SIGS],
+ ns_v3_responses[GEOIP_REJECT_UNAVAILABLE],
+ ns_v3_responses[GEOIP_REJECT_NOT_FOUND],
+ ns_v3_responses[GEOIP_REJECT_NOT_MODIFIED],
+ ns_v3_responses[GEOIP_REJECT_BUSY]) < 0)
+ goto done;
+ if (fprintf(out, "dirreq-v2-resp ok=%u,unavailable=%u,"
+ "not-found=%u,not-modified=%u,busy=%u\n",
+ ns_v2_responses[GEOIP_SUCCESS],
+ ns_v2_responses[GEOIP_REJECT_UNAVAILABLE],
+ ns_v2_responses[GEOIP_REJECT_NOT_FOUND],
+ ns_v2_responses[GEOIP_REJECT_NOT_MODIFIED],
+ ns_v2_responses[GEOIP_REJECT_BUSY]) < 0)
+ goto done;
+ memset(ns_v2_responses, 0, sizeof(ns_v2_responses));
+ memset(ns_v3_responses, 0, sizeof(ns_v3_responses));
+ if (!geoip_get_mean_shares(now, &v2_share, &v3_share)) {
+ if (fprintf(out, "dirreq-v2-share %0.2lf%%\n", v2_share*100) < 0)
goto done;
- if (fprintf(out, "v3-ns-share %0.2lf%%\n", v3_share*100) < 0)
+ if (fprintf(out, "dirreq-v3-share %0.2lf%%\n", v3_share*100) < 0)
goto done;
}
+ data_v2 = geoip_get_dirreq_history(GEOIP_CLIENT_NETWORKSTATUS_V2,
+ DIRREQ_DIRECT);
+ data_v3 = geoip_get_dirreq_history(GEOIP_CLIENT_NETWORKSTATUS,
+ DIRREQ_DIRECT);
+ if (fprintf(out, "dirreq-v3-direct-dl %s\ndirreq-v2-direct-dl %s\n",
+ data_v3 ? data_v3 : "", data_v2 ? data_v2 : "") < 0)
+ goto done;
+ tor_free(data_v2);
+ tor_free(data_v3);
+ data_v2 = geoip_get_dirreq_history(GEOIP_CLIENT_NETWORKSTATUS_V2,
+ DIRREQ_TUNNELED);
+ data_v3 = geoip_get_dirreq_history(GEOIP_CLIENT_NETWORKSTATUS,
+ DIRREQ_TUNNELED);
+ if (fprintf(out, "dirreq-v3-tunneled-dl %s\ndirreq-v2-tunneled-dl %s\n",
+ data_v3 ? data_v3 : "", data_v2 ? data_v2 : "") < 0)
+ goto done;
+
finish_writing_to_file(open_file);
open_file = NULL;
+
+ start_of_dirreq_stats_interval = now;
+
done:
if (open_file)
abort_writing_to_file(open_file);
tor_free(filename);
+ tor_free(statsdir);
tor_free(data_v2);
tor_free(data_v3);
-#endif
+ return start_of_dirreq_stats_interval + WRITE_STATS_INTERVAL;
+}
+
+/** Start time of bridge stats or 0 if we're not collecting bridge
+ * statistics. */
+static time_t start_of_bridge_stats_interval;
+
+/** Initialize bridge stats. */
+void
+geoip_bridge_stats_init(time_t now)
+{
+ start_of_bridge_stats_interval = now;
+}
+
+/** Stop collecting bridge stats in a way that we can re-start doing so in
+ * geoip_bridge_stats_init(). */
+void
+geoip_bridge_stats_term(void)
+{
+ client_history_clear();
+ start_of_bridge_stats_interval = 0;
+}
+
+/** Parse the bridge statistics as they are written to extra-info
+ * descriptors for being returned to controller clients. Return the
+ * controller string if successful, or NULL otherwise. */
+static char *
+parse_bridge_stats_controller(const char *stats_str, time_t now)
+{
+ char stats_end_str[ISO_TIME_LEN+1], stats_start_str[ISO_TIME_LEN+1],
+ *controller_str, *eos, *eol, *summary;
+
+ const char *BRIDGE_STATS_END = "bridge-stats-end ";
+ const char *BRIDGE_IPS = "bridge-ips ";
+ const char *BRIDGE_IPS_EMPTY_LINE = "bridge-ips\n";
+ const char *tmp;
+ time_t stats_end_time;
+ int seconds;
+ tor_assert(stats_str);
+
+ /* Parse timestamp and number of seconds from
+ "bridge-stats-end YYYY-MM-DD HH:MM:SS (N s)" */
+ tmp = find_str_at_start_of_line(stats_str, BRIDGE_STATS_END);
+ if (!tmp)
+ return NULL;
+ tmp += strlen(BRIDGE_STATS_END);
+
+ if (strlen(tmp) < ISO_TIME_LEN + 6)
+ return NULL;
+ strlcpy(stats_end_str, tmp, sizeof(stats_end_str));
+ if (parse_iso_time(stats_end_str, &stats_end_time) < 0)
+ return NULL;
+ if (stats_end_time < now - (25*60*60) ||
+ stats_end_time > now + (1*60*60))
+ return NULL;
+ seconds = (int)strtol(tmp + ISO_TIME_LEN + 2, &eos, 10);
+ if (!eos || seconds < 23*60*60)
+ return NULL;
+ format_iso_time(stats_start_str, stats_end_time - seconds);
+
+ /* Parse: "bridge-ips CC=N,CC=N,..." */
+ tmp = find_str_at_start_of_line(stats_str, BRIDGE_IPS);
+ if (tmp) {
+ tmp += strlen(BRIDGE_IPS);
+ tmp = eat_whitespace_no_nl(tmp);
+ eol = strchr(tmp, '\n');
+ if (eol)
+ summary = tor_strndup(tmp, eol-tmp);
+ else
+ summary = tor_strdup(tmp);
+ } else {
+ /* Look if there is an empty "bridge-ips" line */
+ tmp = find_str_at_start_of_line(stats_str, BRIDGE_IPS_EMPTY_LINE);
+ if (!tmp)
+ return NULL;
+ summary = tor_strdup("");
+ }
+
+ tor_asprintf(&controller_str,
+ "TimeStarted=\"%s\" CountrySummary=%s",
+ stats_start_str, summary);
+ tor_free(summary);
+ return controller_str;
+}
+
+/** Most recent bridge statistics formatted to be written to extra-info
+ * descriptors. */
+static char *bridge_stats_extrainfo = NULL;
+
+/** Most recent bridge statistics formatted to be returned to controller
+ * clients. */
+static char *bridge_stats_controller = NULL;
+
+/** Write bridge statistics to $DATADIR/stats/bridge-stats and return
+ * when we should next try to write statistics. */
+time_t
+geoip_bridge_stats_write(time_t now)
+{
+ char *statsdir = NULL, *filename = NULL, *data = NULL,
+ written[ISO_TIME_LEN+1], *out = NULL, *controller_str;
+ size_t len;
+
+ /* Check if 24 hours have passed since starting measurements. */
+ if (now < start_of_bridge_stats_interval + WRITE_STATS_INTERVAL)
+ return start_of_bridge_stats_interval + WRITE_STATS_INTERVAL;
+
+ /* Discard all items in the client history that are too old. */
+ geoip_remove_old_clients(start_of_bridge_stats_interval);
+
+ statsdir = get_datadir_fname("stats");
+ if (check_private_dir(statsdir, CPD_CREATE) < 0)
+ goto done;
+ filename = get_datadir_fname2("stats", "bridge-stats");
+ data = geoip_get_client_history(GEOIP_CLIENT_CONNECT);
+ format_iso_time(written, now);
+ len = strlen("bridge-stats-end (999999 s)\nbridge-ips \n") +
+ ISO_TIME_LEN + (data ? strlen(data) : 0) + 42;
+ out = tor_malloc(len);
+ if (tor_snprintf(out, len, "bridge-stats-end %s (%u s)\nbridge-ips %s\n",
+ written, (unsigned) (now - start_of_bridge_stats_interval),
+ data ? data : "") < 0)
+ goto done;
+ write_str_to_file(filename, out, 0);
+ controller_str = parse_bridge_stats_controller(out, now);
+ if (!controller_str)
+ goto done;
+ start_of_bridge_stats_interval = now;
+ tor_free(bridge_stats_extrainfo);
+ tor_free(bridge_stats_controller);
+ bridge_stats_extrainfo = out;
+ out = NULL;
+ bridge_stats_controller = controller_str;
+ control_event_clients_seen(controller_str);
+ done:
+ tor_free(filename);
+ tor_free(statsdir);
+ tor_free(data);
+ tor_free(out);
+ return start_of_bridge_stats_interval +
+ WRITE_STATS_INTERVAL;
+}
+
+/** Try to load the most recent bridge statistics from disk, unless we
+ * have finished a measurement interval lately. */
+static void
+load_bridge_stats(time_t now)
+{
+ char *statsdir, *fname=NULL, *contents, *controller_str;
+ if (bridge_stats_extrainfo)
+ return;
+ statsdir = get_datadir_fname("stats");
+ if (check_private_dir(statsdir, CPD_CREATE) < 0)
+ goto done;
+ fname = get_datadir_fname2("stats", "bridge-stats");
+ contents = read_file_to_str(fname, RFTS_IGNORE_MISSING, NULL);
+ if (contents) {
+ controller_str = parse_bridge_stats_controller(contents, now);
+ if (controller_str) {
+ bridge_stats_extrainfo = contents;
+ bridge_stats_controller = controller_str;
+ } else {
+ tor_free(contents);
+ }
+ }
+ done:
+ tor_free(fname);
+ tor_free(statsdir);
+}
+
+/** Return most recent bridge statistics for inclusion in extra-info
+ * descriptors, or NULL if we don't have recent bridge statistics. */
+const char *
+geoip_get_bridge_stats_extrainfo(time_t now)
+{
+ load_bridge_stats(now);
+ return bridge_stats_extrainfo;
+}
+
+/** Return most recent bridge statistics to be returned to controller
+ * clients, or NULL if we don't have recent bridge statistics. */
+const char *
+geoip_get_bridge_stats_controller(time_t now)
+{
+ load_bridge_stats(now);
+ return bridge_stats_controller;
+}
+
+/** Start time of entry stats or 0 if we're not collecting entry
+ * statistics. */
+static time_t start_of_entry_stats_interval;
+
+/** Initialize entry stats. */
+void
+geoip_entry_stats_init(time_t now)
+{
+ start_of_entry_stats_interval = now;
+}
+
+/** Stop collecting entry stats in a way that we can re-start doing so in
+ * geoip_entry_stats_init(). */
+void
+geoip_entry_stats_term(void)
+{
+ client_history_clear();
+ start_of_entry_stats_interval = 0;
+}
+
+/** Write entry statistics to $DATADIR/stats/entry-stats and return time
+ * when we would next want to write. */
+time_t
+geoip_entry_stats_write(time_t now)
+{
+ char *statsdir = NULL, *filename = NULL;
+ char *data = NULL;
+ char written[ISO_TIME_LEN+1];
+ open_file_t *open_file = NULL;
+ FILE *out;
+
+ if (!start_of_entry_stats_interval)
+ return 0; /* Not initialized. */
+ if (start_of_entry_stats_interval + WRITE_STATS_INTERVAL > now)
+ goto done; /* Not ready to write. */
+
+ /* Discard all items in the client history that are too old. */
+ geoip_remove_old_clients(start_of_entry_stats_interval);
+
+ statsdir = get_datadir_fname("stats");
+ if (check_private_dir(statsdir, CPD_CREATE) < 0)
+ goto done;
+ filename = get_datadir_fname2("stats", "entry-stats");
+ data = geoip_get_client_history(GEOIP_CLIENT_CONNECT);
+ format_iso_time(written, now);
+ out = start_writing_to_stdio_file(filename, OPEN_FLAGS_APPEND,
+ 0600, &open_file);
+ if (!out)
+ goto done;
+ if (fprintf(out, "entry-stats-end %s (%u s)\nentry-ips %s\n",
+ written, (unsigned) (now - start_of_entry_stats_interval),
+ data ? data : "") < 0)
+ goto done;
+
+ start_of_entry_stats_interval = now;
+
+ finish_writing_to_file(open_file);
+ open_file = NULL;
+ done:
+ if (open_file)
+ abort_writing_to_file(open_file);
+ tor_free(filename);
+ tor_free(statsdir);
+ tor_free(data);
+ return start_of_entry_stats_interval + WRITE_STATS_INTERVAL;
}
/** Helper used to implement GETINFO ip-to-country/... controller command. */
int
getinfo_helper_geoip(control_connection_t *control_conn,
- const char *question, char **answer)
+ const char *question, char **answer,
+ const char **errmsg)
{
(void)control_conn;
- if (geoip_is_loaded() && !strcmpstart(question, "ip-to-country/")) {
+ if (!geoip_is_loaded()) {
+ *errmsg = "GeoIP data not loaded";
+ return -1;
+ }
+ if (!strcmpstart(question, "ip-to-country/")) {
int c;
uint32_t ip;
struct in_addr in;
@@ -674,8 +1339,8 @@ clear_geoip_db(void)
SMARTLIST_FOREACH(geoip_countries, geoip_country_t *, c, tor_free(c));
smartlist_free(geoip_countries);
}
- if (country_idxplus1_by_lc_code)
- strmap_free(country_idxplus1_by_lc_code, NULL);
+
+ strmap_free(country_idxplus1_by_lc_code, NULL);
if (geoip_entries) {
SMARTLIST_FOREACH(geoip_entries, geoip_entry_t *, ent, tor_free(ent));
smartlist_free(geoip_entries);
@@ -689,13 +1354,24 @@ clear_geoip_db(void)
void
geoip_free_all(void)
{
- clientmap_entry_t **ent, **next, *this;
- for (ent = HT_START(clientmap, &client_history); ent != NULL; ent = next) {
- this = *ent;
- next = HT_NEXT_RMV(clientmap, &client_history, ent);
- tor_free(this);
+ {
+ clientmap_entry_t **ent, **next, *this;
+ for (ent = HT_START(clientmap, &client_history); ent != NULL; ent = next) {
+ this = *ent;
+ next = HT_NEXT_RMV(clientmap, &client_history, ent);
+ tor_free(this);
+ }
+ HT_CLEAR(clientmap, &client_history);
+ }
+ {
+ dirreq_map_entry_t **ent, **next, *this;
+ for (ent = HT_START(dirreqmap, &dirreq_map); ent != NULL; ent = next) {
+ this = *ent;
+ next = HT_NEXT_RMV(dirreqmap, &dirreq_map, ent);
+ tor_free(this);
+ }
+ HT_CLEAR(dirreqmap, &dirreq_map);
}
- HT_CLEAR(clientmap, &client_history);
clear_geoip_db();
}
diff --git a/src/or/geoip.h b/src/or/geoip.h
new file mode 100644
index 0000000000..68e01deecc
--- /dev/null
+++ b/src/or/geoip.h
@@ -0,0 +1,57 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file geoip.h
+ * \brief Header file for geoip.c.
+ **/
+
+#ifndef _TOR_GEOIP_H
+#define _TOR_GEOIP_H
+
+#ifdef GEOIP_PRIVATE
+int geoip_parse_entry(const char *line);
+#endif
+int should_record_bridge_info(or_options_t *options);
+int geoip_load_file(const char *filename, or_options_t *options);
+int geoip_get_country_by_ip(uint32_t ipaddr);
+int geoip_get_n_countries(void);
+const char *geoip_get_country_name(country_t num);
+int geoip_is_loaded(void);
+country_t geoip_get_country(const char *countrycode);
+
+void geoip_note_client_seen(geoip_client_action_t action,
+ uint32_t addr, time_t now);
+void geoip_remove_old_clients(time_t cutoff);
+
+void geoip_note_ns_response(geoip_client_action_t action,
+ geoip_ns_response_t response);
+char *geoip_get_client_history(geoip_client_action_t action);
+char *geoip_get_request_history(geoip_client_action_t action);
+int getinfo_helper_geoip(control_connection_t *control_conn,
+ const char *question, char **answer,
+ const char **errmsg);
+void geoip_free_all(void);
+
+void geoip_start_dirreq(uint64_t dirreq_id, size_t response_size,
+ geoip_client_action_t action, dirreq_type_t type);
+void geoip_change_dirreq_state(uint64_t dirreq_id, dirreq_type_t type,
+ dirreq_state_t new_state);
+
+void geoip_dirreq_stats_init(time_t now);
+time_t geoip_dirreq_stats_write(time_t now);
+void geoip_dirreq_stats_term(void);
+void geoip_entry_stats_init(time_t now);
+time_t geoip_entry_stats_write(time_t now);
+void geoip_entry_stats_term(void);
+void geoip_bridge_stats_init(time_t now);
+time_t geoip_bridge_stats_write(time_t now);
+void geoip_bridge_stats_term(void);
+const char *geoip_get_bridge_stats_extrainfo(time_t);
+const char *geoip_get_bridge_stats_controller(time_t);
+
+#endif
+
diff --git a/src/or/hibernate.c b/src/or/hibernate.c
index 5ebe5b1c5a..929c1994c3 100644
--- a/src/or/hibernate.c
+++ b/src/or/hibernate.c
@@ -22,6 +22,12 @@ hibernating, phase 2:
*/
#include "or.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_edge.h"
+#include "hibernate.h"
+#include "main.h"
+#include "router.h"
/** Possible values of hibernate_state */
typedef enum {
@@ -89,6 +95,13 @@ static uint64_t n_bytes_read_in_interval = 0;
static uint64_t n_bytes_written_in_interval = 0;
/** How many seconds have we been running this interval? */
static uint32_t n_seconds_active_in_interval = 0;
+/** How many seconds were we active in this interval before we hit our soft
+ * limit? */
+static int n_seconds_to_hit_soft_limit = 0;
+/** When in this interval was the soft limit hit. */
+static time_t soft_limit_hit_at = 0;
+/** How many bytes had we read/written when we hit the soft limit? */
+static uint64_t n_bytes_at_soft_limit = 0;
/** When did this accounting interval start? */
static time_t interval_start_time = 0;
/** When will this accounting interval end? */
@@ -182,6 +195,9 @@ accounting_parse_options(or_options_t *options, int validate_only)
case UNIT_DAY:
d = 0;
break;
+ /* Coverity dislikes unreachable default cases; some compilers warn on
+ * switch statements missing a case. Tell Coverity not to worry. */
+ /* coverity[dead_error_begin] */
default:
tor_assert(0);
}
@@ -332,29 +348,57 @@ start_of_accounting_period_after(time_t now)
return edge_of_accounting_period_containing(now, 1);
}
+/** Return the length of the accounting period containing the time
+ * <b>now</b>. */
+static long
+length_of_accounting_period_containing(time_t now)
+{
+ return edge_of_accounting_period_containing(now, 1) -
+ edge_of_accounting_period_containing(now, 0);
+}
+
/** Initialize the accounting subsystem. */
void
configure_accounting(time_t now)
{
+ time_t s_now;
/* Try to remember our recorded usage. */
if (!interval_start_time)
read_bandwidth_usage(); /* If we fail, we'll leave values at zero, and
* reset below.*/
- if (!interval_start_time ||
- start_of_accounting_period_after(interval_start_time) <= now) {
- /* We didn't have recorded usage, or we don't have recorded usage
- * for this interval. Start a new interval. */
+
+ s_now = start_of_accounting_period_containing(now);
+
+ if (!interval_start_time) {
+ /* We didn't have recorded usage; Start a new interval. */
log_info(LD_ACCT, "Starting new accounting interval.");
reset_accounting(now);
- } else if (interval_start_time ==
- start_of_accounting_period_containing(interval_start_time)) {
+ } else if (s_now == interval_start_time) {
log_info(LD_ACCT, "Continuing accounting interval.");
/* We are in the interval we thought we were in. Do nothing.*/
interval_end_time = start_of_accounting_period_after(interval_start_time);
} else {
- log_warn(LD_ACCT,
- "Mismatched accounting interval; starting a fresh one.");
- reset_accounting(now);
+ long duration = length_of_accounting_period_containing(now);
+ double delta = ((double)(s_now - interval_start_time)) / duration;
+ if (-0.50 <= delta && delta <= 0.50) {
+ /* The start of the period is now a little later or earlier than we
+ * remembered. That's fine; we might lose some bytes we could otherwise
+ * have written, but better to err on the side of obeying people's
+ * accounting settings. */
+ log_info(LD_ACCT, "Accounting interval moved by %.02f%%; "
+ "that's fine.", delta*100);
+ interval_end_time = start_of_accounting_period_after(now);
+ } else if (delta >= 0.99) {
+ /* This is the regular time-moved-forward case; don't be too noisy
+ * about it or people will complain */
+ log_info(LD_ACCT, "Accounting interval elapsed; starting a new one");
+ reset_accounting(now);
+ } else {
+ log_warn(LD_ACCT,
+ "Mismatched accounting interval: moved by %.02f%%. "
+ "Starting a fresh one.", delta*100);
+ reset_accounting(now);
+ }
}
accounting_set_wakeup_time();
}
@@ -365,23 +409,42 @@ configure_accounting(time_t now)
static void
update_expected_bandwidth(void)
{
- uint64_t used, expected;
- uint64_t max_configured = (get_options()->BandwidthRate * 60);
-
- if (n_seconds_active_in_interval < 1800) {
+ uint64_t expected;
+ or_options_t *options= get_options();
+ uint64_t max_configured = (options->RelayBandwidthRate > 0 ?
+ options->RelayBandwidthRate :
+ options->BandwidthRate) * 60;
+
+#define MIN_TIME_FOR_MEASUREMENT (1800)
+
+ if (soft_limit_hit_at > interval_start_time && n_bytes_at_soft_limit &&
+ (soft_limit_hit_at - interval_start_time) > MIN_TIME_FOR_MEASUREMENT) {
+ /* If we hit our soft limit last time, only count the bytes up to that
+ * time. This is a better predictor of our actual bandwidth than
+ * considering the entirety of the last interval, since we likely started
+ * using bytes very slowly once we hit our soft limit. */
+ expected = n_bytes_at_soft_limit /
+ (soft_limit_hit_at - interval_start_time);
+ expected /= 60;
+ } else if (n_seconds_active_in_interval >= MIN_TIME_FOR_MEASUREMENT) {
+ /* Otherwise, we either measured enough time in the last interval but
+ * never hit our soft limit, or we're using a state file from a Tor that
+ * doesn't know to store soft-limit info. Just take rate at which
+ * we were reading/writing in the last interval as our expected rate.
+ */
+ uint64_t used = MAX(n_bytes_written_in_interval,
+ n_bytes_read_in_interval);
+ expected = used / (n_seconds_active_in_interval / 60);
+ } else {
/* If we haven't gotten enough data last interval, set 'expected'
* to 0. This will set our wakeup to the start of the interval.
* Next interval, we'll choose our starting time based on how much
* we sent this interval.
*/
expected = 0;
- } else {
- used = n_bytes_written_in_interval < n_bytes_read_in_interval ?
- n_bytes_read_in_interval : n_bytes_written_in_interval;
- expected = used / (n_seconds_active_in_interval / 60);
- if (expected > max_configured)
- expected = max_configured;
}
+ if (expected > max_configured)
+ expected = max_configured;
expected_bandwidth_usage = expected;
}
@@ -399,6 +462,9 @@ reset_accounting(time_t now)
n_bytes_read_in_interval = 0;
n_bytes_written_in_interval = 0;
n_seconds_active_in_interval = 0;
+ n_bytes_at_soft_limit = 0;
+ soft_limit_hit_at = 0;
+ n_seconds_to_hit_soft_limit = 0;
}
/** Return true iff we should save our bandwidth usage to disk. */
@@ -449,35 +515,39 @@ accounting_run_housekeeping(time_t now)
static void
accounting_set_wakeup_time(void)
{
- char buf[ISO_TIME_LEN+1];
char digest[DIGEST_LEN];
crypto_digest_env_t *d_env;
int time_in_interval;
uint64_t time_to_exhaust_bw;
int time_to_consider;
- if (! identity_key_is_set()) {
+ if (! server_identity_key_is_set()) {
if (init_keys() < 0) {
log_err(LD_BUG, "Error initializing keys");
tor_assert(0);
}
}
- format_iso_time(buf, interval_start_time);
- crypto_pk_get_digest(get_identity_key(), digest);
+ if (server_identity_key_is_set()) {
+ char buf[ISO_TIME_LEN+1];
+ format_iso_time(buf, interval_start_time);
- d_env = crypto_new_digest_env();
- crypto_digest_add_bytes(d_env, buf, ISO_TIME_LEN);
- crypto_digest_add_bytes(d_env, digest, DIGEST_LEN);
- crypto_digest_get_digest(d_env, digest, DIGEST_LEN);
- crypto_free_digest_env(d_env);
+ crypto_pk_get_digest(get_server_identity_key(), digest);
+
+ d_env = crypto_new_digest_env();
+ crypto_digest_add_bytes(d_env, buf, ISO_TIME_LEN);
+ crypto_digest_add_bytes(d_env, digest, DIGEST_LEN);
+ crypto_digest_get_digest(d_env, digest, DIGEST_LEN);
+ crypto_free_digest_env(d_env);
+ } else {
+ crypto_rand(digest, DIGEST_LEN);
+ }
if (!expected_bandwidth_usage) {
char buf1[ISO_TIME_LEN+1];
char buf2[ISO_TIME_LEN+1];
format_local_iso_time(buf1, interval_start_time);
format_local_iso_time(buf2, interval_end_time);
- time_to_exhaust_bw = GUESS_TIME_TO_USE_BANDWIDTH;
interval_wakeup_time = interval_start_time;
log_notice(LD_ACCT,
@@ -492,8 +562,8 @@ accounting_set_wakeup_time(void)
time_to_exhaust_bw =
(get_options()->AccountingMax/expected_bandwidth_usage)*60;
- if (time_to_exhaust_bw > TIME_MAX) {
- time_to_exhaust_bw = TIME_MAX;
+ if (time_to_exhaust_bw > INT_MAX) {
+ time_to_exhaust_bw = INT_MAX;
time_to_consider = 0;
} else {
time_to_consider = time_in_interval - (int)time_to_exhaust_bw;
@@ -511,8 +581,6 @@ accounting_set_wakeup_time(void)
* to be chosen than the last half. */
interval_wakeup_time = interval_start_time +
(get_uint32(digest) % time_to_consider);
-
- format_iso_time(buf, interval_wakeup_time);
}
{
@@ -559,6 +627,10 @@ accounting_record_bandwidth_usage(time_t now, or_state_t *state)
state->AccountingSecondsActive = n_seconds_active_in_interval;
state->AccountingExpectedUsage = expected_bandwidth_usage;
+ state->AccountingSecondsToReachSoftLimit = n_seconds_to_hit_soft_limit;
+ state->AccountingSoftLimitHitAt = soft_limit_hit_at;
+ state->AccountingBytesAtSoftLimit = n_bytes_at_soft_limit;
+
or_state_mark_dirty(state,
now+(get_options()->AvoidDiskWrites ? 7200 : 60));
@@ -582,10 +654,6 @@ read_bandwidth_usage(void)
if (!state)
return -1;
- /* Okay; it looks like the state file is more up-to-date than the
- * bw_accounting file, or the bw_accounting file is nonexistent,
- * or the bw_accounting file is corrupt.
- */
log_info(LD_ACCT, "Reading bandwidth accounting data from state file");
n_bytes_read_in_interval = state->AccountingBytesReadInInterval;
n_bytes_written_in_interval = state->AccountingBytesWrittenInInterval;
@@ -593,6 +661,21 @@ read_bandwidth_usage(void)
interval_start_time = state->AccountingIntervalStart;
expected_bandwidth_usage = state->AccountingExpectedUsage;
+ /* Older versions of Tor (before 0.2.2.17-alpha or so) didn't generate these
+ * fields. If you switch back and forth, you might get an
+ * AccountingSoftLimitHitAt value from long before the most recent
+ * interval_start_time. If that's so, then ignore the softlimit-related
+ * values. */
+ if (state->AccountingSoftLimitHitAt > interval_start_time) {
+ soft_limit_hit_at = state->AccountingSoftLimitHitAt;
+ n_bytes_at_soft_limit = state->AccountingBytesAtSoftLimit;
+ n_seconds_to_hit_soft_limit = state->AccountingSecondsToReachSoftLimit;
+ } else {
+ soft_limit_hit_at = 0;
+ n_bytes_at_soft_limit = 0;
+ n_seconds_to_hit_soft_limit = 0;
+ }
+
{
char tbuf1[ISO_TIME_LEN+1];
char tbuf2[ISO_TIME_LEN+1];
@@ -632,8 +715,27 @@ hibernate_hard_limit_reached(void)
static int
hibernate_soft_limit_reached(void)
{
- uint64_t soft_limit = DBL_TO_U64(U64_TO_DBL(get_options()->AccountingMax)
- * .95);
+ const uint64_t acct_max = get_options()->AccountingMax;
+#define SOFT_LIM_PCT (.95)
+#define SOFT_LIM_BYTES (500*1024*1024)
+#define SOFT_LIM_MINUTES (3*60)
+ /* The 'soft limit' is a fair bit more complicated now than once it was.
+ * We want to stop accepting connections when ALL of the following are true:
+ * - We expect to use up the remaining bytes in under 3 hours
+ * - We have used up 95% of our bytes.
+ * - We have less than 500MB of bytes left.
+ */
+ uint64_t soft_limit = DBL_TO_U64(U64_TO_DBL(acct_max) * SOFT_LIM_PCT);
+ if (acct_max > SOFT_LIM_BYTES && acct_max - SOFT_LIM_BYTES > soft_limit) {
+ soft_limit = acct_max - SOFT_LIM_BYTES;
+ }
+ if (expected_bandwidth_usage) {
+ const uint64_t expected_usage =
+ expected_bandwidth_usage * SOFT_LIM_MINUTES;
+ if (acct_max > expected_usage && acct_max - expected_usage > soft_limit)
+ soft_limit = acct_max - expected_usage;
+ }
+
if (!soft_limit)
return 0;
return n_bytes_read_in_interval >= soft_limit
@@ -658,6 +760,14 @@ hibernate_begin(hibernate_state_t new_state, time_t now)
exit(0);
}
+ if (new_state == HIBERNATE_STATE_LOWBANDWIDTH &&
+ hibernate_state == HIBERNATE_STATE_LIVE) {
+ soft_limit_hit_at = now;
+ n_seconds_to_hit_soft_limit = n_seconds_active_in_interval;
+ n_bytes_at_soft_limit = MAX(n_bytes_read_in_interval,
+ n_bytes_written_in_interval);
+ }
+
/* close listeners. leave control listener(s). */
while ((conn = connection_get_by_type(CONN_TYPE_OR_LISTENER)) ||
(conn = connection_get_by_type(CONN_TYPE_AP_LISTENER)) ||
@@ -860,9 +970,11 @@ consider_hibernation(time_t now)
* NULL. */
int
getinfo_helper_accounting(control_connection_t *conn,
- const char *question, char **answer)
+ const char *question, char **answer,
+ const char **errmsg)
{
(void) conn;
+ (void) errmsg;
if (!strcmp(question, "accounting/enabled")) {
*answer = tor_strdup(accounting_is_enabled(get_options()) ? "1" : "0");
} else if (!strcmp(question, "accounting/hibernating")) {
diff --git a/src/or/hibernate.h b/src/or/hibernate.h
new file mode 100644
index 0000000000..687fadb669
--- /dev/null
+++ b/src/or/hibernate.h
@@ -0,0 +1,29 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file hibernate.h
+ * \brief Header file for hibernate.c.
+ **/
+
+#ifndef _TOR_HIBERNATE_H
+#define _TOR_HIBERNATE_H
+
+int accounting_parse_options(or_options_t *options, int validate_only);
+int accounting_is_enabled(or_options_t *options);
+void configure_accounting(time_t now);
+void accounting_run_housekeeping(time_t now);
+void accounting_add_bytes(size_t n_read, size_t n_written, int seconds);
+int accounting_record_bandwidth_usage(time_t now, or_state_t *state);
+void hibernate_begin_shutdown(void);
+int we_are_hibernating(void);
+void consider_hibernation(time_t now);
+int getinfo_helper_accounting(control_connection_t *conn,
+ const char *question, char **answer,
+ const char **errmsg);
+
+#endif
+
diff --git a/src/or/main.c b/src/or/main.c
index af2bf526d4..9bdbbc17a6 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -12,12 +12,50 @@
#define MAIN_PRIVATE
#include "or.h"
+#include "buffers.h"
+#include "circuitbuild.h"
+#include "circuitlist.h"
+#include "circuituse.h"
+#include "command.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_edge.h"
+#include "connection_or.h"
+#include "control.h"
+#include "cpuworker.h"
+#include "directory.h"
+#include "dirserv.h"
+#include "dirvote.h"
+#include "dns.h"
+#include "dnsserv.h"
+#include "geoip.h"
+#include "hibernate.h"
+#include "main.h"
+#include "microdesc.h"
+#include "networkstatus.h"
+#include "ntmain.h"
+#include "onion.h"
+#include "policies.h"
+#include "relay.h"
+#include "rendclient.h"
+#include "rendcommon.h"
+#include "rendservice.h"
+#include "rephist.h"
+#include "router.h"
+#include "routerlist.h"
+#include "routerparse.h"
#ifdef USE_DMALLOC
#include <dmalloc.h>
#include <openssl/crypto.h>
#endif
#include "memarea.h"
+#ifdef HAVE_EVENT2_EVENT_H
+#include <event2/event.h>
+#else
+#include <event.h>
+#endif
+
void evdns_shutdown(int);
/********* PROTOTYPES **********/
@@ -27,7 +65,7 @@ static void dumpstats(int severity); /* log stats */
static void conn_read_callback(int fd, short event, void *_conn);
static void conn_write_callback(int fd, short event, void *_conn);
static void signal_callback(int fd, short events, void *arg);
-static void second_elapsed_callback(int fd, short event, void *args);
+static void second_elapsed_callback(periodic_timer_t *timer, void *args);
static int conn_close_if_marked(int i);
static void connection_start_reading_from_linked_conn(connection_t *conn);
static int connection_should_read_from_linked_conn(connection_t *conn);
@@ -81,8 +119,12 @@ static smartlist_t *active_linked_connection_lst = NULL;
static int called_loop_once = 0;
/** We set this to 1 when we've opened a circuit, so we can print a log
- * entry to inform the user that Tor is working. */
-int has_completed_circuit=0;
+ * entry to inform the user that Tor is working. We set it to 0 when
+ * we think the fact that we once opened a circuit doesn't mean we can do so
+ * any longer (a big time jump happened, when we notice our directory is
+ * heinously out-of-date, etc.
+ */
+int can_complete_circuit=0;
/** How often do we check for router descriptors that we should download
* when we have too little directory info? */
@@ -127,12 +169,10 @@ connection_add(connection_t *conn)
smartlist_add(connection_array, conn);
if (conn->s >= 0 || conn->linked) {
- conn->read_event = tor_malloc_zero(sizeof(struct event));
- conn->write_event = tor_malloc_zero(sizeof(struct event));
- event_set(conn->read_event, conn->s, EV_READ|EV_PERSIST,
- conn_read_callback, conn);
- event_set(conn->write_event, conn->s, EV_WRITE|EV_PERSIST,
- conn_write_callback, conn);
+ conn->read_event = tor_event_new(tor_libevent_get_base(),
+ conn->s, EV_READ|EV_PERSIST, conn_read_callback, conn);
+ conn->write_event = tor_event_new(tor_libevent_get_base(),
+ conn->s, EV_WRITE|EV_PERSIST, conn_write_callback, conn);
}
log_debug(LD_NET,"new conn type %s, socket %d, address %s, n_conns %d.",
@@ -142,6 +182,25 @@ connection_add(connection_t *conn)
return 0;
}
+/** Tell libevent that we don't care about <b>conn</b> any more. */
+void
+connection_unregister_events(connection_t *conn)
+{
+ if (conn->read_event) {
+ if (event_del(conn->read_event))
+ log_warn(LD_BUG, "Error removing read event for %d", conn->s);
+ tor_free(conn->read_event);
+ }
+ if (conn->write_event) {
+ if (event_del(conn->write_event))
+ log_warn(LD_BUG, "Error removing write event for %d", conn->s);
+ tor_free(conn->write_event);
+ }
+ if (conn->dns_server_port) {
+ dnsserv_close_listener(conn);
+ }
+}
+
/** Remove the connection from the global list, and remove the
* corresponding poll entry. Calling this function will shift the last
* connection (if any) into the position occupied by conn.
@@ -246,17 +305,17 @@ get_connection_array(void)
}
/** Set the event mask on <b>conn</b> to <b>events</b>. (The event
- * mask is a bitmask whose bits are EV_READ and EV_WRITE.)
+ * mask is a bitmask whose bits are READ_EVENT and WRITE_EVENT)
*/
void
-connection_watch_events(connection_t *conn, short events)
+connection_watch_events(connection_t *conn, watchable_events_t events)
{
- if (events & EV_READ)
+ if (events & READ_EVENT)
connection_start_reading(conn);
else
connection_stop_reading(conn);
- if (events & EV_WRITE)
+ if (events & WRITE_EVENT)
connection_start_writing(conn);
else
connection_stop_writing(conn);
@@ -393,11 +452,11 @@ connection_start_reading_from_linked_conn(connection_t *conn)
smartlist_add(active_linked_connection_lst, conn);
if (!called_loop_once) {
/* This is the first event on the list; we won't be in LOOP_ONCE mode,
- * so we need to make sure that the event_loop() actually exits at the
- * end of its run through the current connections and
- * lets us activate read events for linked connections. */
+ * so we need to make sure that the event_base_loop() actually exits at
+ * the end of its run through the current connections and lets us
+ * activate read events for linked connections. */
struct timeval tv = { 0, 0 };
- event_loopexit(&tv);
+ tor_event_base_loopexit(tor_libevent_get_base(), &tv);
}
} else {
tor_assert(smartlist_isin(active_linked_connection_lst, conn));
@@ -540,7 +599,7 @@ conn_close_if_marked(int i)
log_info(LD_NET,
"Conn (addr %s, fd %d, type %s, state %d) marked, but wants "
"to flush %d bytes. (Marked at %s:%d)",
- escaped_safe_str(conn->address),
+ escaped_safe_str_client(conn->address),
conn->s, conn_type_to_string(conn->type), conn->state,
(int)conn->outbuf_flushlen,
conn->marked_for_close_file, conn->marked_for_close);
@@ -593,8 +652,8 @@ conn_close_if_marked(int i)
"something is wrong with theirs. "
"(fd %d, type %s, state %d, marked at %s:%d).",
(int)buf_datalen(conn->outbuf),
- escaped_safe_str(conn->address), conn->s,
- conn_type_to_string(conn->type), conn->state,
+ escaped_safe_str_client(conn->address),
+ conn->s, conn_type_to_string(conn->type), conn->state,
conn->marked_for_close_file,
conn->marked_for_close);
}
@@ -623,7 +682,7 @@ directory_all_unreachable(time_t now)
log_notice(LD_NET,
"Is your network connection down? "
"Failing connection to '%s:%d'.",
- safe_str(edge_conn->socks_request->address),
+ safe_str_client(edge_conn->socks_request->address),
edge_conn->socks_request->port);
connection_mark_unattached_ap(edge_conn,
END_STREAM_REASON_NET_UNREACHABLE);
@@ -651,7 +710,7 @@ directory_info_has_arrived(time_t now, int from_cache)
/* if we have enough dir info, then update our guard status with
* whatever we just learned. */
- entry_guards_compute_status();
+ entry_guards_compute_status(options, now);
/* Don't even bother trying to get extrainfo until the rest of our
* directory info is up-to-date */
if (options->DownloadExtraInfo)
@@ -659,7 +718,7 @@ directory_info_has_arrived(time_t now, int from_cache)
}
if (server_mode(options) && !we_are_hibernating() && !from_cache &&
- (has_completed_circuit || !any_predicted_circuits(now)))
+ (can_complete_circuit || !any_predicted_circuits(now)))
consider_testing_reachability(1, 1);
}
@@ -722,6 +781,7 @@ run_connection_housekeeping(int i, time_t now)
the connection or send a keepalive, depending. */
or_conn = TO_OR_CONN(conn);
+ tor_assert(conn->outbuf);
if (or_conn->is_bad_for_new_circs && !or_conn->n_circuits) {
/* It's bad for new circuits, and has no unmarked circuits on it:
@@ -778,7 +838,7 @@ run_connection_housekeeping(int i, time_t now)
}
}
-/** Honor a NEWNYM request: make future requests unlinkability to past
+/** Honor a NEWNYM request: make future requests unlinkable to past
* requests. */
static void
signewnym_impl(time_t now)
@@ -804,16 +864,18 @@ run_scheduled_events(time_t now)
static time_t time_to_try_getting_descriptors = 0;
static time_t time_to_reset_descriptor_failures = 0;
static time_t time_to_add_entropy = 0;
- static time_t time_to_write_hs_statistics = 0;
static time_t time_to_write_bridge_status_file = 0;
static time_t time_to_downrate_stability = 0;
static time_t time_to_save_stability = 0;
static time_t time_to_clean_caches = 0;
static time_t time_to_recheck_bandwidth = 0;
static time_t time_to_check_for_expired_networkstatus = 0;
- static time_t time_to_dump_geoip_stats = 0;
+ static time_t time_to_write_stats_files = 0;
+ static time_t time_to_write_bridge_stats = 0;
+ static int should_init_bridge_stats = 1;
static time_t time_to_retry_dns_init = 0;
or_options_t *options = get_options();
+ int is_server = server_mode(options);
int i;
int have_dir_info;
@@ -835,7 +897,7 @@ run_scheduled_events(time_t now)
* shut down and restart all cpuworkers, and update the directory if
* necessary.
*/
- if (server_mode(options) &&
+ if (is_server &&
get_onion_key_set_at()+MIN_ONION_KEY_LIFETIME < now) {
log_info(LD_GENERAL,"Rotating onion key.");
rotate_onion_key();
@@ -851,7 +913,7 @@ run_scheduled_events(time_t now)
update_router_descriptor_downloads(now);
update_extrainfo_downloads(now);
if (options->UseBridges)
- fetch_bridge_descriptors(now);
+ fetch_bridge_descriptors(options, now);
if (router_have_minimum_dir_info())
time_to_try_getting_descriptors = now + LAZY_DESCRIPTOR_RETRY_INTERVAL;
else
@@ -869,7 +931,10 @@ run_scheduled_events(time_t now)
last_rotated_x509_certificate = now;
if (last_rotated_x509_certificate+MAX_SSL_KEY_LIFETIME < now) {
log_info(LD_GENERAL,"Rotating tls context.");
- if (tor_tls_context_new(get_identity_key(), MAX_SSL_KEY_LIFETIME) < 0) {
+ if (tor_tls_context_init(public_server_mode(options),
+ get_tlsclient_identity_key(),
+ is_server ? get_server_identity_key() : NULL,
+ MAX_SSL_KEY_LIFETIME) < 0) {
log_warn(LD_BUG, "Error reinitializing TLS context");
/* XXX is it a bug here, that we just keep going? -RD */
}
@@ -897,7 +962,7 @@ run_scheduled_events(time_t now)
if (now % 10 == 0 && (authdir_mode_tests_reachability(options)) &&
!we_are_hibernating()) {
/* try to determine reachability of the other Tor relays */
- dirserv_test_reachability(now, 0);
+ dirserv_test_reachability(now);
}
/** 1d. Periodically, we discount older stability information so that new
@@ -939,11 +1004,56 @@ run_scheduled_events(time_t now)
time_to_check_for_expired_networkstatus = now + CHECK_EXPIRED_NS_INTERVAL;
}
- if (time_to_dump_geoip_stats < now) {
-#define DUMP_GEOIP_STATS_INTERVAL (60*60);
- if (time_to_dump_geoip_stats)
- dump_geoip_stats();
- time_to_dump_geoip_stats = now + DUMP_GEOIP_STATS_INTERVAL;
+ /* 1g. Check whether we should write statistics to disk.
+ */
+ if (time_to_write_stats_files < now) {
+#define CHECK_WRITE_STATS_INTERVAL (60*60)
+ time_t next_time_to_write_stats_files = (time_to_write_stats_files > 0 ?
+ time_to_write_stats_files : now) + CHECK_WRITE_STATS_INTERVAL;
+ if (options->CellStatistics) {
+ time_t next_write =
+ rep_hist_buffer_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->DirReqStatistics) {
+ time_t next_write = geoip_dirreq_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->EntryStatistics) {
+ time_t next_write = geoip_entry_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)
+ next_time_to_write_stats_files = next_write;
+ }
+ time_to_write_stats_files = next_time_to_write_stats_files;
+ }
+
+ /* 1h. Check whether we should write bridge statistics to disk.
+ */
+ if (should_record_bridge_info(options)) {
+ if (time_to_write_bridge_stats < now) {
+ if (should_init_bridge_stats) {
+ /* (Re-)initialize bridge statistics. */
+ geoip_bridge_stats_init(now);
+ time_to_write_bridge_stats = now + WRITE_STATS_INTERVAL;
+ should_init_bridge_stats = 0;
+ } else {
+ /* Possibly write bridge statistics to disk and ask when to write
+ * them next time. */
+ time_to_write_bridge_stats = geoip_bridge_stats_write(
+ time_to_write_bridge_stats);
+ }
+ }
+ } else if (!should_init_bridge_stats) {
+ /* Bridge mode was turned off. Ensure that stats are re-initialized
+ * next time bridge mode is turned on. */
+ should_init_bridge_stats = 1;
}
/* Remove old information from rephist and the rend cache. */
@@ -991,7 +1101,7 @@ run_scheduled_events(time_t now)
/* also, check religiously for reachability, if it's within the first
* 20 minutes of our uptime. */
if (server_mode(options) &&
- (has_completed_circuit || !any_predicted_circuits(now)) &&
+ (can_complete_circuit || !any_predicted_circuits(now)) &&
!we_are_hibernating()) {
if (stats_n_seconds_working < TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) {
consider_testing_reachability(1, dirport_reachability_count==0);
@@ -1067,7 +1177,7 @@ run_scheduled_events(time_t now)
circuit_expire_old_circuits_serverside(now);
/** 5. We do housekeeping for each connection... */
- connection_or_set_bad_connections();
+ connection_or_set_bad_connections(NULL, 0);
for (i=0;i<smartlist_len(connection_array);i++) {
run_connection_housekeeping(i, now);
}
@@ -1090,7 +1200,7 @@ run_scheduled_events(time_t now)
circuit_close_all_marked();
/** 7. And upload service descriptors if necessary. */
- if (has_completed_circuit && !we_are_hibernating()) {
+ if (can_complete_circuit && !we_are_hibernating()) {
rend_consider_services_upload(now);
rend_consider_descriptor_republication();
}
@@ -1107,7 +1217,7 @@ run_scheduled_events(time_t now)
/** 9. and if we're a server, check whether our DNS is telling stories to
* us. */
- if (server_mode(options) && time_to_check_for_correct_dns < now) {
+ if (is_server && time_to_check_for_correct_dns < now) {
if (!time_to_check_for_correct_dns) {
time_to_check_for_correct_dns = now + 60 + crypto_rand_int(120);
} else {
@@ -1117,12 +1227,6 @@ run_scheduled_events(time_t now)
}
}
- /** 10. write hidden service usage statistic to disk */
- if (options->HSAuthorityRecordStats && time_to_write_hs_statistics < now) {
- hs_usage_write_statistics_to_file(now);
-#define WRITE_HSUSAGE_INTERVAL (30*60)
- time_to_write_hs_statistics = now+WRITE_HSUSAGE_INTERVAL;
- }
/** 10b. write bridge networkstatus file to disk */
if (options->BridgeAuthoritativeDir &&
time_to_write_bridge_status_file < now) {
@@ -1132,39 +1236,30 @@ run_scheduled_events(time_t now)
}
}
-/** Libevent timer: used to invoke second_elapsed_callback() once per
- * second. */
-static struct event *timeout_event = NULL;
+/** Timer: used to invoke second_elapsed_callback() once per second. */
+static periodic_timer_t *second_timer = NULL;
/** Number of libevent errors in the last second: we die if we get too many. */
static int n_libevent_errors = 0;
/** Libevent callback: invoked once every second. */
static void
-second_elapsed_callback(int fd, short event, void *args)
+second_elapsed_callback(periodic_timer_t *timer, void *arg)
{
/* XXXX This could be sensibly refactored into multiple callbacks, and we
* could use Libevent's timers for this rather than checking the current
* time against a bunch of timeouts every second. */
- static struct timeval one_second;
static time_t current_second = 0;
time_t now;
size_t bytes_written;
size_t bytes_read;
int seconds_elapsed;
or_options_t *options = get_options();
- (void)fd;
- (void)event;
- (void)args;
- if (!timeout_event) {
- timeout_event = tor_malloc_zero(sizeof(struct event));
- evtimer_set(timeout_event, second_elapsed_callback, NULL);
- one_second.tv_sec = 1;
- one_second.tv_usec = 0;
- }
+ (void)timer;
+ (void)arg;
n_libevent_errors = 0;
- /* log_fn(LOG_NOTICE, "Tick."); */
+ /* log_notice(LD_GENERAL, "Tick."); */
now = time(NULL);
update_approx_time(now);
@@ -1187,7 +1282,7 @@ second_elapsed_callback(int fd, short event, void *args)
if (server_mode(options) &&
!we_are_hibernating() &&
seconds_elapsed > 0 &&
- has_completed_circuit &&
+ can_complete_circuit &&
stats_n_seconds_working / TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT !=
(stats_n_seconds_working+seconds_elapsed) /
TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) {
@@ -1229,18 +1324,6 @@ second_elapsed_callback(int fd, short event, void *args)
run_scheduled_events(now);
current_second = now; /* remember which second it is, for next time */
-
-#if 0
- if (current_second % 300 == 0) {
- rep_history_clean(current_second - options->RephistTrackTime);
- dumpmemusage(get_min_log_level()<LOG_INFO ?
- get_min_log_level() : LOG_INFO);
- }
-#endif
-
- if (evtimer_add(timeout_event, &one_second))
- log_err(LD_NET,
- "Error from libevent when setting one-second timeout event");
}
#ifndef MS_WINDOWS
@@ -1383,7 +1466,7 @@ do_main_loop(void)
/* load the private keys, if we're supposed to have them, and set up the
* TLS context. */
- if (! identity_key_is_set()) {
+ if (! client_identity_key_is_set()) {
if (init_keys() < 0) {
log_err(LD_BUG,"Error initializing keys; exiting");
return -1;
@@ -1401,8 +1484,10 @@ do_main_loop(void)
/* initialize the bootstrap status events to know we're starting up */
control_event_bootstrap(BOOTSTRAP_STATUS_STARTING, 0);
- if (trusted_dirs_reload_certs())
- return -1;
+ if (trusted_dirs_reload_certs()) {
+ log_warn(LD_DIR,
+ "Couldn't load all cached v3 certificates. Starting anyway.");
+ }
if (router_reload_v2_networkstatus()) {
return -1;
}
@@ -1419,18 +1504,23 @@ do_main_loop(void)
now = time(NULL);
directory_info_has_arrived(now, 1);
- if (authdir_mode_tests_reachability(get_options())) {
- /* the directory is already here, run startup things */
- dirserv_test_reachability(now, 1);
- }
-
if (server_mode(get_options())) {
/* launch cpuworkers. Need to do this *after* we've read the onion key. */
cpu_init();
}
/* set up once-a-second callback. */
- second_elapsed_callback(0,0,NULL);
+ if (! second_timer) {
+ struct timeval one_second;
+ one_second.tv_sec = 1;
+ one_second.tv_usec = 0;
+
+ second_timer = periodic_timer_new(tor_libevent_get_base(),
+ &one_second,
+ second_elapsed_callback,
+ NULL);
+ tor_assert(second_timer);
+ }
for (;;) {
if (nt_service_is_stopping())
@@ -1449,20 +1539,16 @@ do_main_loop(void)
/* poll until we have an event, or the second ends, or until we have
* some active linked connections to trigger events for. */
- loop_result = event_loop(called_loop_once ? EVLOOP_ONCE : 0);
+ loop_result = event_base_loop(tor_libevent_get_base(),
+ called_loop_once ? EVLOOP_ONCE : 0);
/* let catch() handle things like ^c, and otherwise don't worry about it */
if (loop_result < 0) {
int e = tor_socket_errno(-1);
/* let the program survive things like ^z */
if (e != EINTR && !ERRNO_IS_EINPROGRESS(e)) {
-#ifdef HAVE_EVENT_GET_METHOD
log_err(LD_NET,"libevent call with %s failed: %s [%d]",
- event_get_method(), tor_socket_strerror(e), e);
-#else
- log_err(LD_NET,"libevent call failed: %s [%d]",
- tor_socket_strerror(e), e);
-#endif
+ tor_libevent_get_method(), tor_socket_strerror(e), e);
return -1;
#ifndef MS_WINDOWS
} else if (e == EINVAL) {
@@ -1605,6 +1691,7 @@ dumpmemusage(int severity)
U64_PRINTF_ARG(rephist_total_alloc), rephist_total_num);
dump_routerlist_mem_usage(severity);
dump_cell_pool_usage(severity);
+ dump_dns_mem_usage(severity);
buf_dump_freelist_sizes(severity);
tor_log_mallinfo(severity);
}
@@ -1631,7 +1718,8 @@ dumpstats(int severity)
if (!connection_is_listener(conn)) {
log(severity,LD_GENERAL,
"Conn %d is to %s:%d.", i,
- safe_str(conn->address), conn->port);
+ safe_str_client(conn->address),
+ conn->port);
log(severity,LD_GENERAL,
"Conn %d: %d bytes waiting on inbuf (len %d, last read %d secs ago)",
i,
@@ -1728,7 +1816,7 @@ handle_signals(int is_parent)
{
#ifndef MS_WINDOWS /* do signal stuff only on Unix */
int i;
- static int signals[] = {
+ static const int signals[] = {
SIGINT, /* do a controlled slow shutdown */
SIGTERM, /* to terminate now */
SIGPIPE, /* otherwise SIGPIPE kills us */
@@ -1740,12 +1828,13 @@ handle_signals(int is_parent)
#endif
SIGCHLD, /* handle dns/cpu workers that exit */
-1 };
- static struct event signal_events[16]; /* bigger than it has to be. */
+ static struct event *signal_events[16]; /* bigger than it has to be. */
if (is_parent) {
for (i = 0; signals[i] >= 0; ++i) {
- signal_set(&signal_events[i], signals[i], signal_callback,
- (void*)(uintptr_t)signals[i]);
- if (signal_add(&signal_events[i], NULL))
+ signal_events[i] = tor_evsignal_new(
+ tor_libevent_get_base(), signals[i], signal_callback,
+ (void*)(uintptr_t)signals[i]);
+ if (event_add(signal_events[i], NULL))
log_warn(LD_BUG, "Error from libevent when adding event for signal %d",
signals[i]);
}
@@ -1834,7 +1923,9 @@ tor_init(int argc, char *argv[])
"and you probably shouldn't.");
#endif
- if (crypto_global_init(get_options()->HardwareAccel)) {
+ if (crypto_global_init(get_options()->HardwareAccel,
+ get_options()->AccelName,
+ get_options()->AccelDir)) {
log_err(LD_BUG, "Unable to initialize OpenSSL. Exiting.");
return -1;
}
@@ -1928,7 +2019,6 @@ tor_free_all(int postfork)
rend_cache_free_all();
rend_service_authorization_free_all();
rep_hist_free_all();
- hs_usage_free_all();
dns_free_all();
clear_pending_onions();
circuit_free_all();
@@ -1936,6 +2026,7 @@ tor_free_all(int postfork)
connection_free_all();
buf_shrink_freelists(1);
memarea_clear_freelist();
+ microdesc_free_all();
if (!postfork) {
config_free_all();
router_free_all();
@@ -1946,13 +2037,11 @@ tor_free_all(int postfork)
tor_tls_free_all();
}
/* stuff in main.c */
- if (connection_array)
- smartlist_free(connection_array);
- if (closeable_connection_lst)
- smartlist_free(closeable_connection_lst);
- if (active_linked_connection_lst)
- smartlist_free(active_linked_connection_lst);
- tor_free(timeout_event);
+
+ smartlist_free(connection_array);
+ smartlist_free(closeable_connection_lst);
+ smartlist_free(active_linked_connection_lst);
+ periodic_timer_free(second_timer);
if (!postfork) {
release_lockfile();
}
@@ -2013,7 +2102,7 @@ do_list_fingerprint(void)
log_err(LD_BUG,"Error initializing keys; can't display fingerprint");
return -1;
}
- if (!(k = get_identity_key())) {
+ if (!(k = get_server_identity_key())) {
log_err(LD_GENERAL,"Error: missing identity key.");
return -1;
}
@@ -2043,6 +2132,31 @@ do_hash_password(void)
printf("16:%s\n",output);
}
+#if defined (WINCE)
+int
+find_flashcard_path(PWCHAR path, size_t size)
+{
+ WIN32_FIND_DATA d = {0};
+ HANDLE h = NULL;
+
+ if (!path)
+ return -1;
+
+ h = FindFirstFlashCard(&d);
+ if (h == INVALID_HANDLE_VALUE)
+ return -1;
+
+ if (wcslen(d.cFileName) == 0) {
+ FindClose(h);
+ return -1;
+ }
+
+ wcsncpy(path,d.cFileName,size);
+ FindClose(h);
+ return 0;
+}
+#endif
+
/** Main entry point for the Tor process. Called from main(). */
/* This function is distinct from main() only so we can link main.c into
* the unittest binary without conflicting with the unittests' main. */
@@ -2050,6 +2164,33 @@ int
tor_main(int argc, char *argv[])
{
int result = 0;
+#if defined (WINCE)
+ WCHAR path [MAX_PATH] = {0};
+ WCHAR fullpath [MAX_PATH] = {0};
+ PWCHAR p = NULL;
+ FILE* redir = NULL;
+ FILE* redirdbg = NULL;
+
+ // this is to facilitate debugging by opening
+ // a file on a folder shared by the wm emulator.
+ // if no flashcard (real or emulated) is present,
+ // log files will be written in the root folder
+ if (find_flashcard_path(path,MAX_PATH) == -1)
+ {
+ redir = _wfreopen( L"\\stdout.log", L"w", stdout );
+ redirdbg = _wfreopen( L"\\stderr.log", L"w", stderr );
+ } else {
+ swprintf(fullpath,L"\\%s\\tor",path);
+ CreateDirectory(fullpath,NULL);
+
+ swprintf(fullpath,L"\\%s\\tor\\stdout.log",path);
+ redir = _wfreopen( fullpath, L"w", stdout );
+
+ swprintf(fullpath,L"\\%s\\tor\\stderr.log",path);
+ redirdbg = _wfreopen( fullpath, L"w", stderr );
+ }
+#endif
+
update_approx_time(time(NULL));
tor_threads_init();
init_logging();
diff --git a/src/or/main.h b/src/or/main.h
new file mode 100644
index 0000000000..ef38dc9351
--- /dev/null
+++ b/src/or/main.h
@@ -0,0 +1,67 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file main.h
+ * \brief Header file for main.c.
+ **/
+
+#ifndef _TOR_MAIN_H
+#define _TOR_MAIN_H
+
+extern int can_complete_circuit;
+
+int connection_add(connection_t *conn);
+int connection_remove(connection_t *conn);
+void connection_unregister_events(connection_t *conn);
+int connection_in_array(connection_t *conn);
+void add_connection_to_closeable_list(connection_t *conn);
+int connection_is_on_closeable_list(connection_t *conn);
+
+smartlist_t *get_connection_array(void);
+
+typedef enum watchable_events {
+ READ_EVENT=0x02,
+ WRITE_EVENT=0x04
+} watchable_events_t;
+void connection_watch_events(connection_t *conn, watchable_events_t events);
+int connection_is_reading(connection_t *conn);
+void connection_stop_reading(connection_t *conn);
+void connection_start_reading(connection_t *conn);
+
+int connection_is_writing(connection_t *conn);
+void connection_stop_writing(connection_t *conn);
+void connection_start_writing(connection_t *conn);
+
+void connection_stop_reading_from_linked_conn(connection_t *conn);
+
+void directory_all_unreachable(time_t now);
+void directory_info_has_arrived(time_t now, int from_cache);
+
+void ip_address_changed(int at_interface);
+void dns_servers_relaunch_checks(void);
+
+void control_signal_act(int the_signal);
+void handle_signals(int is_parent);
+
+int try_locking(or_options_t *options, int err_if_locked);
+int have_lockfile(void);
+void release_lockfile(void);
+
+void tor_cleanup(void);
+void tor_free_all(int postfork);
+
+int tor_main(int argc, char *argv[]);
+
+#ifdef MAIN_PRIVATE
+int do_main_loop(void);
+int do_list_fingerprint(void);
+void do_hash_password(void);
+int tor_init(int argc, char **argv);
+#endif
+
+#endif
+
diff --git a/src/or/microdesc.c b/src/or/microdesc.c
new file mode 100644
index 0000000000..e8f3e7c59f
--- /dev/null
+++ b/src/or/microdesc.c
@@ -0,0 +1,414 @@
+/* Copyright (c) 2009-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "or.h"
+#include "config.h"
+#include "microdesc.h"
+#include "routerparse.h"
+
+/** A data structure to hold a bunch of cached microdescriptors. There are
+ * two active files in the cache: a "cache file" that we mmap, and a "journal
+ * file" that we append to. Periodically, we rebuild the cache file to hold
+ * only the microdescriptors that we want to keep */
+struct microdesc_cache_t {
+ /** Map from sha256-digest to microdesc_t for every microdesc_t in the
+ * cache. */
+ HT_HEAD(microdesc_map, microdesc_t) map;
+
+ /** Name of the cache file. */
+ char *cache_fname;
+ /** Name of the journal file. */
+ char *journal_fname;
+ /** Mmap'd contents of the cache file, or NULL if there is none. */
+ tor_mmap_t *cache_content;
+ /** Number of bytes used in the journal file. */
+ size_t journal_len;
+
+ /** Total bytes of microdescriptor bodies we have added to this cache */
+ uint64_t total_len_seen;
+ /** Total number of microdescriptors we have added to this cache */
+ unsigned n_seen;
+};
+
+/** Helper: computes a hash of <b>md</b> to place it in a hash table. */
+static INLINE unsigned int
+_microdesc_hash(microdesc_t *md)
+{
+ unsigned *d = (unsigned*)md->digest;
+#if SIZEOF_INT == 4
+ return d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[4] ^ d[5] ^ d[6] ^ d[7];
+#else
+ return d[0] ^ d[1] ^ d[2] ^ d[3];
+#endif
+}
+
+/** Helper: compares <b>a</b> and </b> for equality for hash-table purposes. */
+static INLINE int
+_microdesc_eq(microdesc_t *a, microdesc_t *b)
+{
+ return !memcmp(a->digest, b->digest, DIGEST256_LEN);
+}
+
+HT_PROTOTYPE(microdesc_map, microdesc_t, node,
+ _microdesc_hash, _microdesc_eq);
+HT_GENERATE(microdesc_map, microdesc_t, node,
+ _microdesc_hash, _microdesc_eq, 0.6,
+ malloc, realloc, free);
+
+/** Write the body of <b>md</b> into <b>f</b>, with appropriate annotations.
+ * On success, return the total number of bytes written, and set
+ * *<b>annotation_len_out</b> to the number of bytes written as
+ * annotations. */
+static ssize_t
+dump_microdescriptor(FILE *f, microdesc_t *md, size_t *annotation_len_out)
+{
+ ssize_t r = 0;
+ size_t written;
+ /* XXXX drops unkown annotations. */
+ if (md->last_listed) {
+ char buf[ISO_TIME_LEN+1];
+ char annotation[ISO_TIME_LEN+32];
+ format_iso_time(buf, md->last_listed);
+ tor_snprintf(annotation, sizeof(annotation), "@last-listed %s\n", buf);
+ fputs(annotation, f);
+ r += strlen(annotation);
+ *annotation_len_out = r;
+ } else {
+ *annotation_len_out = 0;
+ }
+
+ md->off = (off_t) ftell(f);
+ written = fwrite(md->body, 1, md->bodylen, f);
+ if (written != md->bodylen) {
+ log_warn(LD_DIR,
+ "Couldn't dump microdescriptor (wrote %lu out of %lu): %s",
+ (unsigned long)written, (unsigned long)md->bodylen,
+ strerror(ferror(f)));
+ return -1;
+ }
+ r += md->bodylen;
+ return r;
+}
+
+/** Holds a pointer to the current microdesc_cache_t object, or NULL if no
+ * such object has been allocated. */
+static microdesc_cache_t *the_microdesc_cache = NULL;
+
+/** Return a pointer to the microdescriptor cache, loading it if necessary. */
+microdesc_cache_t *
+get_microdesc_cache(void)
+{
+ if (PREDICT_UNLIKELY(the_microdesc_cache==NULL)) {
+ microdesc_cache_t *cache = tor_malloc_zero(sizeof(microdesc_cache_t));
+ HT_INIT(microdesc_map, &cache->map);
+ cache->cache_fname = get_datadir_fname("cached-microdescs");
+ cache->journal_fname = get_datadir_fname("cached-microdescs.new");
+ microdesc_cache_reload(cache);
+ the_microdesc_cache = cache;
+ }
+ return the_microdesc_cache;
+}
+
+/* There are three sources of microdescriptors:
+ 1) Generated by us while acting as a directory authority.
+ 2) Loaded from the cache on disk.
+ 3) Downloaded.
+*/
+
+/** Decode the microdescriptors from the string starting at <b>s</b> and
+ * ending at <b>eos</b>, and store them in <b>cache</b>. If <b>no-save</b>,
+ * mark them as non-writable to disk. If <b>where</b> is SAVED_IN_CACHE,
+ * leave their bodies as pointers to the mmap'd cache. If where is
+ * <b>SAVED_NOWHERE</b>, do not allow annotations. Return a list of the added
+ * microdescriptors. */
+smartlist_t *
+microdescs_add_to_cache(microdesc_cache_t *cache,
+ const char *s, const char *eos, saved_location_t where,
+ int no_save)
+{
+ /*XXXX need an argument that sets last_listed as appropriate. */
+
+ smartlist_t *descriptors, *added;
+ const int allow_annotations = (where != SAVED_NOWHERE);
+ const int copy_body = (where != SAVED_IN_CACHE);
+
+ descriptors = microdescs_parse_from_string(s, eos,
+ allow_annotations,
+ copy_body);
+
+ added = microdescs_add_list_to_cache(cache, descriptors, where, no_save);
+ smartlist_free(descriptors);
+ return added;
+}
+
+/* As microdescs_add_to_cache, but takes a list of micrdescriptors instead of
+ * a string to encode. Frees any members of <b>descriptors</b> that it does
+ * not add. */
+smartlist_t *
+microdescs_add_list_to_cache(microdesc_cache_t *cache,
+ smartlist_t *descriptors, saved_location_t where,
+ int no_save)
+{
+ smartlist_t *added;
+ open_file_t *open_file = NULL;
+ FILE *f = NULL;
+ // int n_added = 0;
+ ssize_t size = 0;
+
+ if (where == SAVED_NOWHERE && !no_save) {
+ f = start_writing_to_stdio_file(cache->journal_fname,
+ OPEN_FLAGS_APPEND|O_BINARY,
+ 0600, &open_file);
+ if (!f) {
+ log_warn(LD_DIR, "Couldn't append to journal in %s: %s",
+ cache->journal_fname, strerror(errno));
+ return NULL;
+ }
+ }
+
+ added = smartlist_create();
+ SMARTLIST_FOREACH_BEGIN(descriptors, microdesc_t *, md) {
+ microdesc_t *md2;
+ md2 = HT_FIND(microdesc_map, &cache->map, md);
+ if (md2) {
+ /* We already had this one. */
+ if (md2->last_listed < md->last_listed)
+ md2->last_listed = md->last_listed;
+ microdesc_free(md);
+ continue;
+ }
+
+ /* Okay, it's a new one. */
+ if (f) {
+ size_t annotation_len;
+ size = dump_microdescriptor(f, md, &annotation_len);
+ if (size < 0) {
+ /* XXX handle errors from dump_microdescriptor() */
+ /* log? return -1? die? coredump the universe? */
+ continue;
+ }
+ md->saved_location = SAVED_IN_JOURNAL;
+ cache->journal_len += size;
+ } else {
+ md->saved_location = where;
+ }
+
+ md->no_save = no_save;
+
+ HT_INSERT(microdesc_map, &cache->map, md);
+ smartlist_add(added, md);
+ ++cache->n_seen;
+ cache->total_len_seen += md->bodylen;
+ } SMARTLIST_FOREACH_END(md);
+
+ if (f)
+ finish_writing_to_file(open_file); /*XXX Check me.*/
+
+ {
+ size_t old_content_len =
+ cache->cache_content ? cache->cache_content->size : 0;
+ if (cache->journal_len > 16384 + old_content_len &&
+ cache->journal_len > old_content_len * 2) {
+ microdesc_cache_rebuild(cache);
+ }
+ }
+
+ return added;
+}
+
+/** Remove every microdescriptor in <b>cache</b>. */
+void
+microdesc_cache_clear(microdesc_cache_t *cache)
+{
+ microdesc_t **entry, **next;
+ for (entry = HT_START(microdesc_map, &cache->map); entry; entry = next) {
+ microdesc_t *md = *entry;
+ next = HT_NEXT_RMV(microdesc_map, &cache->map, entry);
+ microdesc_free(md);
+ }
+ HT_CLEAR(microdesc_map, &cache->map);
+ if (cache->cache_content) {
+ tor_munmap_file(cache->cache_content);
+ cache->cache_content = NULL;
+ }
+ cache->total_len_seen = 0;
+ cache->n_seen = 0;
+}
+
+/** Reload the contents of <b>cache</b> from disk. If it is empty, load it
+ * for the first time. Return 0 on success, -1 on failure. */
+int
+microdesc_cache_reload(microdesc_cache_t *cache)
+{
+ struct stat st;
+ char *journal_content;
+ smartlist_t *added;
+ tor_mmap_t *mm;
+ int total = 0;
+
+ microdesc_cache_clear(cache);
+
+ mm = cache->cache_content = tor_mmap_file(cache->cache_fname);
+ if (mm) {
+ added = microdescs_add_to_cache(cache, mm->data, mm->data+mm->size,
+ SAVED_IN_CACHE, 0);
+ if (added) {
+ total += smartlist_len(added);
+ smartlist_free(added);
+ }
+ }
+
+ journal_content = read_file_to_str(cache->journal_fname,
+ RFTS_IGNORE_MISSING, &st);
+ if (journal_content) {
+ added = microdescs_add_to_cache(cache, journal_content,
+ journal_content+st.st_size,
+ SAVED_IN_JOURNAL, 0);
+ if (added) {
+ total += smartlist_len(added);
+ smartlist_free(added);
+ }
+ tor_free(journal_content);
+ }
+ log_notice(LD_DIR, "Reloaded microdescriptor cache. Found %d descriptors.",
+ total);
+ return 0;
+}
+
+/** Regenerate the main cache file for <b>cache</b>, clear the journal file,
+ * and update every microdesc_t in the cache with pointers to its new
+ * location. */
+int
+microdesc_cache_rebuild(microdesc_cache_t *cache)
+{
+ open_file_t *open_file;
+ FILE *f;
+ microdesc_t **mdp;
+ smartlist_t *wrote;
+ ssize_t size;
+ off_t off = 0;
+ int orig_size, new_size;
+
+ log_info(LD_DIR, "Rebuilding the microdescriptor cache...");
+ orig_size = (int)(cache->cache_content ? cache->cache_content->size : 0);
+ orig_size += (int)cache->journal_len;
+
+ f = start_writing_to_stdio_file(cache->cache_fname,
+ OPEN_FLAGS_REPLACE|O_BINARY,
+ 0600, &open_file);
+ if (!f)
+ return -1;
+
+ wrote = smartlist_create();
+
+ HT_FOREACH(mdp, microdesc_map, &cache->map) {
+ microdesc_t *md = *mdp;
+ size_t annotation_len;
+ if (md->no_save)
+ continue;
+
+ size = dump_microdescriptor(f, md, &annotation_len);
+ if (size < 0) {
+ /* XXX handle errors from dump_microdescriptor() */
+ /* log? return -1? die? coredump the universe? */
+ continue;
+ }
+ md->off = off + annotation_len;
+ off += size;
+ if (md->saved_location != SAVED_IN_CACHE) {
+ tor_free(md->body);
+ md->saved_location = SAVED_IN_CACHE;
+ }
+ smartlist_add(wrote, md);
+ }
+
+ finish_writing_to_file(open_file); /*XXX Check me.*/
+
+ if (cache->cache_content)
+ tor_munmap_file(cache->cache_content);
+ cache->cache_content = tor_mmap_file(cache->cache_fname);
+
+ if (!cache->cache_content && smartlist_len(wrote)) {
+ log_err(LD_DIR, "Couldn't map file that we just wrote to %s!",
+ cache->cache_fname);
+ smartlist_free(wrote);
+ return -1;
+ }
+ SMARTLIST_FOREACH_BEGIN(wrote, microdesc_t *, md) {
+ tor_assert(md->saved_location == SAVED_IN_CACHE);
+ md->body = (char*)cache->cache_content->data + md->off;
+ tor_assert(!memcmp(md->body, "onion-key", 9));
+ } SMARTLIST_FOREACH_END(md);
+
+ smartlist_free(wrote);
+
+ write_str_to_file(cache->journal_fname, "", 1);
+ cache->journal_len = 0;
+
+ new_size = (int)cache->cache_content->size;
+ log_info(LD_DIR, "Done rebuilding microdesc cache. "
+ "Saved %d bytes; %d still used.",
+ orig_size-new_size, new_size);
+
+ return 0;
+}
+
+/** Deallocate a single microdescriptor. Note: the microdescriptor MUST have
+ * previously been removed from the cache if it had ever been inserted. */
+void
+microdesc_free(microdesc_t *md)
+{
+ if (!md)
+ return;
+ /* Must be removed from hash table! */
+ if (md->onion_pkey)
+ crypto_free_pk_env(md->onion_pkey);
+ if (md->body && md->saved_location != SAVED_IN_CACHE)
+ tor_free(md->body);
+
+ if (md->family) {
+ SMARTLIST_FOREACH(md->family, char *, cp, tor_free(cp));
+ smartlist_free(md->family);
+ }
+ tor_free(md->exitsummary);
+
+ tor_free(md);
+}
+
+/** Free all storage held in the microdesc.c module. */
+void
+microdesc_free_all(void)
+{
+ if (the_microdesc_cache) {
+ microdesc_cache_clear(the_microdesc_cache);
+ tor_free(the_microdesc_cache->cache_fname);
+ tor_free(the_microdesc_cache->journal_fname);
+ tor_free(the_microdesc_cache);
+ }
+}
+
+/** If there is a microdescriptor in <b>cache</b> whose sha256 digest is
+ * <b>d</b>, return it. Otherwise return NULL. */
+microdesc_t *
+microdesc_cache_lookup_by_digest256(microdesc_cache_t *cache, const char *d)
+{
+ microdesc_t *md, search;
+ if (!cache)
+ cache = get_microdesc_cache();
+ memcpy(search.digest, d, DIGEST256_LEN);
+ md = HT_FIND(microdesc_map, &cache->map, &search);
+ return md;
+}
+
+/** Return the mean size of decriptors added to <b>cache</b> since it was last
+ * cleared. Used to estimate the size of large downloads. */
+size_t
+microdesc_average_size(microdesc_cache_t *cache)
+{
+ if (!cache)
+ cache = get_microdesc_cache();
+ if (!cache->n_seen)
+ return 512;
+ return (size_t)(cache->total_len_seen / cache->n_seen);
+}
+
diff --git a/src/or/microdesc.h b/src/or/microdesc.h
new file mode 100644
index 0000000000..2d1a60ad0a
--- /dev/null
+++ b/src/or/microdesc.h
@@ -0,0 +1,37 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file microdesc.h
+ * \brief Header file for microdesc.c.
+ **/
+
+#ifndef _TOR_MICRODESC_H
+#define _TOR_MICRODESC_H
+
+microdesc_cache_t *get_microdesc_cache(void);
+
+smartlist_t *microdescs_add_to_cache(microdesc_cache_t *cache,
+ const char *s, const char *eos, saved_location_t where,
+ int no_save);
+smartlist_t *microdescs_add_list_to_cache(microdesc_cache_t *cache,
+ smartlist_t *descriptors, saved_location_t where,
+ int no_save);
+
+int microdesc_cache_rebuild(microdesc_cache_t *cache);
+int microdesc_cache_reload(microdesc_cache_t *cache);
+void microdesc_cache_clear(microdesc_cache_t *cache);
+
+microdesc_t *microdesc_cache_lookup_by_digest256(microdesc_cache_t *cache,
+ const char *d);
+
+size_t microdesc_average_size(microdesc_cache_t *cache);
+
+void microdesc_free(microdesc_t *md);
+void microdesc_free_all(void);
+
+#endif
+
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 4721420bbd..d645ee2b40 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -11,6 +11,20 @@
*/
#include "or.h"
+#include "circuitbuild.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_or.h"
+#include "control.h"
+#include "directory.h"
+#include "dirserv.h"
+#include "dirvote.h"
+#include "main.h"
+#include "networkstatus.h"
+#include "relay.h"
+#include "router.h"
+#include "routerlist.h"
+#include "routerparse.h"
/* For tracking v2 networkstatus documents. Only caches do this now. */
@@ -35,16 +49,22 @@ static networkstatus_t *current_consensus = NULL;
/** A v3 consensus networkstatus that we've received, but which we don't
* have enough certificates to be happy about. */
-static networkstatus_t *consensus_waiting_for_certs = NULL;
-/** The encoded version of consensus_waiting_for_certs. */
-static char *consensus_waiting_for_certs_body = NULL;
-/** When did we set the current value of consensus_waiting_for_certs? If this
- * is too recent, we shouldn't try to fetch a new consensus for a little while,
- * to give ourselves time to get certificates for this one. */
-static time_t consensus_waiting_for_certs_set_at = 0;
-/** Set to 1 if we've been holding on to consensus_waiting_for_certs so long
- * that we should treat it as maybe being bad. */
-static int consensus_waiting_for_certs_dl_failed = 0;
+typedef struct consensus_waiting_for_certs_t {
+ /** The consensus itself. */
+ networkstatus_t *consensus;
+ /** The encoded version of the consensus, nul-terminated. */
+ char *body;
+ /** When did we set the current value of consensus_waiting_for_certs? If
+ * this is too recent, we shouldn't try to fetch a new consensus for a
+ * little while, to give ourselves time to get certificates for this one. */
+ time_t set_at;
+ /** Set to 1 if we've been holding on to it for so long we should maybe
+ * treat it as being bad. */
+ int dl_failed;
+} consensus_waiting_for_certs_t;
+
+static consensus_waiting_for_certs_t
+ consensus_waiting_for_certs[N_CONSENSUS_FLAVORS];
/** The last time we tried to download a networkstatus, or 0 for "never". We
* use this to rate-limit download attempts for directory caches (including
@@ -56,7 +76,7 @@ static time_t last_networkstatus_download_attempted = 0;
* before the current consensus becomes invalid. */
static time_t time_to_download_next_consensus = 0;
/** Download status for the current consensus networkstatus. */
-static download_status_t consensus_dl_status = { 0, 0, DL_SCHED_CONSENSUS };
+static download_status_t consensus_dl_status[N_CONSENSUS_FLAVORS];
/** True iff we have logged a warning about this OR's version being older than
* listed by the authorities. */
@@ -89,6 +109,7 @@ networkstatus_reset_warnings(void)
void
networkstatus_reset_download_failures(void)
{
+ int i;
const smartlist_t *networkstatus_v2_list = networkstatus_get_v2_list();
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
SMARTLIST_FOREACH(ns->entries, routerstatus_t *, rs,
@@ -97,7 +118,8 @@ networkstatus_reset_download_failures(void)
rs->need_to_mirror = 1;
}));;
- download_status_reset(&consensus_dl_status);
+ for (i=0; i < N_CONSENSUS_FLAVORS; ++i)
+ download_status_reset(&consensus_dl_status[i]);
if (v2_download_status_map) {
digestmap_iter_t *iter;
digestmap_t *map = v2_download_status_map;
@@ -170,7 +192,7 @@ router_reload_v2_networkstatus(void)
return 0;
}
-/** Read the cached v3 consensus networkstatus from the disk. */
+/** Read every cached v3 consensus networkstatus from the disk. */
int
router_reload_consensus_networkstatus(void)
{
@@ -179,31 +201,46 @@ router_reload_consensus_networkstatus(void)
struct stat st;
or_options_t *options = get_options();
const unsigned int flags = NSSET_FROM_CACHE | NSSET_DONT_DOWNLOAD_CERTS;
+ int flav;
/* FFFF Suppress warnings if cached consensus is bad? */
+ for (flav = 0; flav < N_CONSENSUS_FLAVORS; ++flav) {
+ char buf[128];
+ const char *flavor = networkstatus_get_flavor_name(flav);
+ if (flav == FLAV_NS) {
+ filename = get_datadir_fname("cached-consensus");
+ } else {
+ tor_snprintf(buf, sizeof(buf), "cached-%s-consensus", flavor);
+ filename = get_datadir_fname(buf);
+ }
+ s = read_file_to_str(filename, RFTS_IGNORE_MISSING, NULL);
+ if (s) {
+ if (networkstatus_set_current_consensus(s, flavor, flags) < -1) {
+ log_warn(LD_FS, "Couldn't load consensus %s networkstatus from \"%s\"",
+ flavor, filename);
+ }
+ tor_free(s);
+ }
+ tor_free(filename);
- filename = get_datadir_fname("cached-consensus");
- s = read_file_to_str(filename, RFTS_IGNORE_MISSING, NULL);
- if (s) {
- if (networkstatus_set_current_consensus(s, flags) < -1) {
- log_warn(LD_FS, "Couldn't load consensus networkstatus from \"%s\"",
- filename);
+ if (flav == FLAV_NS) {
+ filename = get_datadir_fname("unverified-consensus");
+ } else {
+ tor_snprintf(buf, sizeof(buf), "unverified-%s-consensus", flavor);
+ filename = get_datadir_fname(buf);
}
- tor_free(s);
- }
- tor_free(filename);
- filename = get_datadir_fname("unverified-consensus");
- s = read_file_to_str(filename, RFTS_IGNORE_MISSING, NULL);
- if (s) {
- if (networkstatus_set_current_consensus(s,
+ s = read_file_to_str(filename, RFTS_IGNORE_MISSING, NULL);
+ if (s) {
+ if (networkstatus_set_current_consensus(s, flavor,
flags|NSSET_WAS_WAITING_FOR_CERTS)) {
- log_info(LD_FS, "Couldn't load consensus networkstatus from \"%s\"",
- filename);
+ log_info(LD_FS, "Couldn't load consensus %s networkstatus from \"%s\"",
+ flavor, filename);
}
- tor_free(s);
+ tor_free(s);
+ }
+ tor_free(filename);
}
- tor_free(filename);
if (!current_consensus ||
(stat(options->FallbackNetworkstatusFile, &st)==0 &&
@@ -211,7 +248,7 @@ router_reload_consensus_networkstatus(void)
s = read_file_to_str(options->FallbackNetworkstatusFile,
RFTS_IGNORE_MISSING, NULL);
if (s) {
- if (networkstatus_set_current_consensus(s,
+ if (networkstatus_set_current_consensus(s, "ns",
flags|NSSET_ACCEPT_OBSOLETE)) {
log_info(LD_FS, "Couldn't load consensus networkstatus from \"%s\"",
options->FallbackNetworkstatusFile);
@@ -242,8 +279,16 @@ router_reload_consensus_networkstatus(void)
static void
vote_routerstatus_free(vote_routerstatus_t *rs)
{
+ vote_microdesc_hash_t *h, *next;
+ if (!rs)
+ return;
tor_free(rs->version);
tor_free(rs->status.exitsummary);
+ for (h = rs->microdesc; h; h = next) {
+ tor_free(h->microdesc_hash_line);
+ next = h->next;
+ tor_free(h);
+ }
tor_free(rs);
}
@@ -251,6 +296,8 @@ vote_routerstatus_free(vote_routerstatus_t *rs)
void
routerstatus_free(routerstatus_t *rs)
{
+ if (!rs)
+ return;
tor_free(rs->exitsummary);
tor_free(rs);
}
@@ -259,6 +306,8 @@ routerstatus_free(routerstatus_t *rs)
void
networkstatus_v2_free(networkstatus_v2_t *ns)
{
+ if (!ns)
+ return;
tor_free(ns->source_address);
tor_free(ns->contact);
if (ns->signing_key)
@@ -273,7 +322,25 @@ networkstatus_v2_free(networkstatus_v2_t *ns)
tor_free(ns);
}
-/** Clear all storage held in <b>ns</b>. */
+/** Free all storage held in <b>sig</b> */
+void
+document_signature_free(document_signature_t *sig)
+{
+ tor_free(sig->signature);
+ tor_free(sig);
+}
+
+/** Return a newly allocated copy of <b>sig</b> */
+document_signature_t *
+document_signature_dup(const document_signature_t *sig)
+{
+ document_signature_t *r = tor_memdup(sig, sizeof(document_signature_t));
+ if (r->signature)
+ r->signature = tor_memdup(sig->signature, sig->signature_len);
+ return r;
+}
+
+/** Free all storage held in <b>ns</b>. */
void
networkstatus_vote_free(networkstatus_t *ns)
{
@@ -286,6 +353,10 @@ networkstatus_vote_free(networkstatus_t *ns)
SMARTLIST_FOREACH(ns->known_flags, char *, c, tor_free(c));
smartlist_free(ns->known_flags);
}
+ if (ns->weight_params) {
+ SMARTLIST_FOREACH(ns->weight_params, char *, c, tor_free(c));
+ smartlist_free(ns->weight_params);
+ }
if (ns->net_params) {
SMARTLIST_FOREACH(ns->net_params, char *, c, tor_free(c));
smartlist_free(ns->net_params);
@@ -295,18 +366,20 @@ networkstatus_vote_free(networkstatus_t *ns)
smartlist_free(ns->supported_methods);
}
if (ns->voters) {
- SMARTLIST_FOREACH(ns->voters, networkstatus_voter_info_t *, voter,
- {
+ SMARTLIST_FOREACH_BEGIN(ns->voters, networkstatus_voter_info_t *, voter) {
tor_free(voter->nickname);
tor_free(voter->address);
tor_free(voter->contact);
- tor_free(voter->signature);
+ if (voter->sigs) {
+ SMARTLIST_FOREACH(voter->sigs, document_signature_t *, sig,
+ document_signature_free(sig));
+ smartlist_free(voter->sigs);
+ }
tor_free(voter);
- });
+ } SMARTLIST_FOREACH_END(voter);
smartlist_free(ns->voters);
}
- if (ns->cert)
- authority_cert_free(ns->cert);
+ authority_cert_free(ns->cert);
if (ns->routerstatus_list) {
if (ns->type == NS_TYPE_VOTE || ns->type == NS_TYPE_OPINION) {
@@ -319,8 +392,8 @@ networkstatus_vote_free(networkstatus_t *ns)
smartlist_free(ns->routerstatus_list);
}
- if (ns->desc_digest_map)
- digestmap_free(ns->desc_digest_map, NULL);
+
+ digestmap_free(ns->desc_digest_map, NULL);
memset(ns, 11, sizeof(*ns));
tor_free(ns);
@@ -341,34 +414,38 @@ networkstatus_get_voter_by_id(networkstatus_t *vote,
return NULL;
}
-/** Check whether the signature on <b>voter</b> is correctly signed by
- * the signing key of <b>cert</b>. Return -1 if <b>cert</b> doesn't match the
+/** Check whether the signature <b>sig</b> is correctly signed with the
+ * signing key in <b>cert</b>. Return -1 if <b>cert</b> doesn't match the
* signing key; otherwise set the good_signature or bad_signature flag on
* <b>voter</b>, and return 0. */
-/* (private; exposed for testing.) */
int
-networkstatus_check_voter_signature(networkstatus_t *consensus,
- networkstatus_voter_info_t *voter,
- authority_cert_t *cert)
+networkstatus_check_document_signature(const networkstatus_t *consensus,
+ document_signature_t *sig,
+ const authority_cert_t *cert)
{
- char d[DIGEST_LEN];
+ char key_digest[DIGEST_LEN];
+ const int dlen = sig->alg == DIGEST_SHA1 ? DIGEST_LEN : DIGEST256_LEN;
char *signed_digest;
size_t signed_digest_len;
- if (crypto_pk_get_digest(cert->signing_key, d)<0)
+
+ if (crypto_pk_get_digest(cert->signing_key, key_digest)<0)
return -1;
- if (memcmp(voter->signing_key_digest, d, DIGEST_LEN))
+ if (memcmp(sig->signing_key_digest, key_digest, DIGEST_LEN) ||
+ memcmp(sig->identity_digest, cert->cache_info.identity_digest,
+ DIGEST_LEN))
return -1;
+
signed_digest_len = crypto_pk_keysize(cert->signing_key);
signed_digest = tor_malloc(signed_digest_len);
if (crypto_pk_public_checksig(cert->signing_key,
signed_digest,
- voter->signature,
- voter->signature_len) != DIGEST_LEN ||
- memcmp(signed_digest, consensus->networkstatus_digest, DIGEST_LEN)) {
+ sig->signature,
+ sig->signature_len) < dlen ||
+ memcmp(signed_digest, consensus->digests.d[sig->alg], dlen)) {
log_warn(LD_DIR, "Got a bad signature on a networkstatus vote");
- voter->bad_signature = 1;
+ sig->bad_signature = 1;
} else {
- voter->good_signature = 1;
+ sig->good_signature = 1;
}
tor_free(signed_digest);
return 0;
@@ -387,7 +464,7 @@ networkstatus_check_consensus_signature(networkstatus_t *consensus,
int warn)
{
int n_good = 0;
- int n_missing_key = 0;
+ int n_missing_key = 0, n_dl_failed_key = 0;
int n_bad = 0;
int n_unknown = 0;
int n_no_signature = 0;
@@ -401,37 +478,62 @@ networkstatus_check_consensus_signature(networkstatus_t *consensus,
tor_assert(consensus->type == NS_TYPE_CONSENSUS);
- SMARTLIST_FOREACH(consensus->voters, networkstatus_voter_info_t *, voter,
- {
- if (!voter->good_signature && !voter->bad_signature && voter->signature) {
- /* we can try to check the signature. */
- int is_v3_auth = trusteddirserver_get_by_v3_auth_digest(
- voter->identity_digest) != NULL;
- authority_cert_t *cert =
- authority_cert_get_by_digests(voter->identity_digest,
- voter->signing_key_digest);
- if (!is_v3_auth) {
- smartlist_add(unrecognized, voter);
- ++n_unknown;
- continue;
- } else if (!cert || cert->expires < now) {
- smartlist_add(need_certs_from, voter);
- ++n_missing_key;
- continue;
- }
- if (networkstatus_check_voter_signature(consensus, voter, cert) < 0) {
- smartlist_add(need_certs_from, voter);
- ++n_missing_key;
- continue;
+ SMARTLIST_FOREACH_BEGIN(consensus->voters, networkstatus_voter_info_t *,
+ voter) {
+ int good_here = 0;
+ int bad_here = 0;
+ int unknown_here = 0;
+ int missing_key_here = 0, dl_failed_key_here = 0;
+ SMARTLIST_FOREACH_BEGIN(voter->sigs, document_signature_t *, sig) {
+ if (!sig->good_signature && !sig->bad_signature &&
+ sig->signature) {
+ /* we can try to check the signature. */
+ int is_v3_auth = trusteddirserver_get_by_v3_auth_digest(
+ sig->identity_digest) != NULL;
+ authority_cert_t *cert =
+ authority_cert_get_by_digests(sig->identity_digest,
+ sig->signing_key_digest);
+ tor_assert(!memcmp(sig->identity_digest, voter->identity_digest,
+ DIGEST_LEN));
+
+ if (!is_v3_auth) {
+ smartlist_add(unrecognized, voter);
+ ++unknown_here;
+ continue;
+ } else if (!cert || cert->expires < now) {
+ smartlist_add(need_certs_from, voter);
+ ++missing_key_here;
+ if (authority_cert_dl_looks_uncertain(sig->identity_digest))
+ ++dl_failed_key_here;
+ continue;
+ }
+ if (networkstatus_check_document_signature(consensus, sig, cert) < 0) {
+ smartlist_add(need_certs_from, voter);
+ ++missing_key_here;
+ if (authority_cert_dl_looks_uncertain(sig->identity_digest))
+ ++dl_failed_key_here;
+ continue;
+ }
}
- }
- if (voter->good_signature)
+ if (sig->good_signature)
+ ++good_here;
+ else if (sig->bad_signature)
+ ++bad_here;
+ } SMARTLIST_FOREACH_END(sig);
+ if (good_here)
++n_good;
- else if (voter->bad_signature)
+ else if (bad_here)
++n_bad;
- else
+ else if (missing_key_here) {
+ ++n_missing_key;
+ if (dl_failed_key_here)
+ ++n_dl_failed_key;
+ } else if (unknown_here) {
+ ++n_unknown;
+ } else {
++n_no_signature;
- });
+ }
+ } SMARTLIST_FOREACH_END(voter);
/* Now see whether we're missing any voters entirely. */
SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
@@ -442,39 +544,71 @@ networkstatus_check_consensus_signature(networkstatus_t *consensus,
smartlist_add(missing_authorities, ds);
});
- if (warn > 1 || (warn >= 0 && n_good < n_required))
+ if (warn > 1 || (warn >= 0 &&
+ (n_good + n_missing_key - n_dl_failed_key < n_required))) {
severity = LOG_WARN;
- else
+ } else {
severity = LOG_INFO;
+ }
if (warn >= 0) {
SMARTLIST_FOREACH(unrecognized, networkstatus_voter_info_t *, voter,
{
- log_info(LD_DIR, "Consensus includes unrecognized authority '%s' "
- "at %s:%d (contact %s; identity %s)",
+ log(severity, LD_DIR, "Consensus includes unrecognized authority "
+ "'%s' at %s:%d (contact %s; identity %s)",
voter->nickname, voter->address, (int)voter->dir_port,
voter->contact?voter->contact:"n/a",
hex_str(voter->identity_digest, DIGEST_LEN));
});
SMARTLIST_FOREACH(need_certs_from, networkstatus_voter_info_t *, voter,
{
- log_info(LD_DIR, "Looks like we need to download a new certificate "
- "from authority '%s' at %s:%d (contact %s; identity %s)",
+ log(severity, LD_DIR, "Looks like we need to download a new "
+ "certificate from authority '%s' at %s:%d (contact %s; "
+ "identity %s)",
voter->nickname, voter->address, (int)voter->dir_port,
voter->contact?voter->contact:"n/a",
hex_str(voter->identity_digest, DIGEST_LEN));
});
SMARTLIST_FOREACH(missing_authorities, trusted_dir_server_t *, ds,
{
- log_info(LD_DIR, "Consensus does not include configured "
+ log(severity, LD_DIR, "Consensus does not include configured "
"authority '%s' at %s:%d (identity %s)",
ds->nickname, ds->address, (int)ds->dir_port,
hex_str(ds->v3_identity_digest, DIGEST_LEN));
});
- log(severity, LD_DIR,
- "%d unknown, %d missing key, %d good, %d bad, %d no signature, "
- "%d required", n_unknown, n_missing_key, n_good, n_bad,
- n_no_signature, n_required);
+ {
+ smartlist_t *sl = smartlist_create();
+ char *cp;
+ tor_asprintf(&cp, "A consensus needs %d good signatures from recognized "
+ "authorities for us to accept it. This one has %d.",
+ n_required, n_good);
+ smartlist_add(sl,cp);
+ if (n_no_signature) {
+ tor_asprintf(&cp, "%d of the authorities we know didn't sign it.",
+ n_no_signature);
+ smartlist_add(sl,cp);
+ }
+ if (n_unknown) {
+ tor_asprintf(&cp, "It has %d signatures from authorities we don't "
+ "recognize.", n_unknown);
+ smartlist_add(sl,cp);
+ }
+ if (n_bad) {
+ tor_asprintf(&cp, "%d of the signatures on it didn't verify "
+ "correctly.", n_bad);
+ smartlist_add(sl,cp);
+ }
+ if (n_missing_key) {
+ tor_asprintf(&cp, "We were unable to check %d of the signatures, "
+ "because we were missing the keys.", n_missing_key);
+ smartlist_add(sl,cp);
+ }
+ cp = smartlist_join_strings(sl, " ", 0, NULL);
+ log(severity, LD_DIR, "%s", cp);
+ tor_free(cp);
+ SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
+ smartlist_free(sl);
+ }
}
smartlist_free(unrecognized);
@@ -784,8 +918,8 @@ networkstatus_v2_list_clean(time_t now)
/** Helper for bsearching a list of routerstatus_t pointers: compare a
* digest in the key to the identity digest of a routerstatus_t. */
-static int
-_compare_digest_to_routerstatus_entry(const void *_key, const void **_member)
+int
+compare_digest_to_routerstatus_entry(const void *_key, const void **_member)
{
const char *key = _key;
const routerstatus_t *rs = *_member;
@@ -798,7 +932,7 @@ routerstatus_t *
networkstatus_v2_find_entry(networkstatus_v2_t *ns, const char *digest)
{
return smartlist_bsearch(ns->entries, digest,
- _compare_digest_to_routerstatus_entry);
+ compare_digest_to_routerstatus_entry);
}
/** Return the entry in <b>ns</b> for the identity digest <b>digest</b>, or
@@ -807,7 +941,7 @@ routerstatus_t *
networkstatus_vote_find_entry(networkstatus_t *ns, const char *digest)
{
return smartlist_bsearch(ns->routerstatus_list, digest,
- _compare_digest_to_routerstatus_entry);
+ compare_digest_to_routerstatus_entry);
}
/*XXXX make this static once functions are moved into this file. */
@@ -819,7 +953,7 @@ networkstatus_vote_find_entry_idx(networkstatus_t *ns,
const char *digest, int *found_out)
{
return smartlist_bsearch_idx(ns->routerstatus_list, digest,
- _compare_digest_to_routerstatus_entry,
+ compare_digest_to_routerstatus_entry,
found_out);
}
@@ -872,7 +1006,7 @@ router_get_consensus_status_by_id(const char *digest)
if (!current_consensus)
return NULL;
return smartlist_bsearch(current_consensus->routerstatus_list, digest,
- _compare_digest_to_routerstatus_entry);
+ compare_digest_to_routerstatus_entry);
}
/** Given a nickname (possibly verbose, possibly a hexadecimal digest), return
@@ -1076,28 +1210,30 @@ update_v2_networkstatus_cache_downloads(time_t now)
static void
update_consensus_networkstatus_downloads(time_t now)
{
- or_options_t *options = get_options();
+ int i;
if (!networkstatus_get_live_consensus(now))
time_to_download_next_consensus = now; /* No live consensus? Get one now!*/
if (time_to_download_next_consensus > now)
return; /* Wait until the current consensus is older. */
- if (authdir_mode_v3(options))
- return; /* Authorities never fetch a consensus */
- if (!download_status_is_ready(&consensus_dl_status, now,
+ /* XXXXNM Microdescs: may need to download more types. */
+ if (!download_status_is_ready(&consensus_dl_status[FLAV_NS], now,
CONSENSUS_NETWORKSTATUS_MAX_DL_TRIES))
return; /* We failed downloading a consensus too recently. */
if (connection_get_by_type_purpose(CONN_TYPE_DIR,
DIR_PURPOSE_FETCH_CONSENSUS))
return; /* There's an in-progress download.*/
- if (consensus_waiting_for_certs) {
- /* XXXX make sure this doesn't delay sane downloads. */
- if (consensus_waiting_for_certs_set_at + DELAY_WHILE_FETCHING_CERTS > now)
- return; /* We're still getting certs for this one. */
- else {
- if (!consensus_waiting_for_certs_dl_failed) {
- download_status_failed(&consensus_dl_status, 0);
- consensus_waiting_for_certs_dl_failed=1;
+ for (i=0; i < N_CONSENSUS_FLAVORS; ++i) {
+ consensus_waiting_for_certs_t *waiting = &consensus_waiting_for_certs[i];
+ if (waiting->consensus) {
+ /* XXXX make sure this doesn't delay sane downloads. */
+ if (waiting->set_at + DELAY_WHILE_FETCHING_CERTS > now)
+ return; /* We're still getting certs for this one. */
+ else {
+ if (!waiting->dl_failed) {
+ download_status_failed(&consensus_dl_status[FLAV_NS], 0);
+ waiting->dl_failed=1;
+ }
}
}
}
@@ -1113,7 +1249,8 @@ update_consensus_networkstatus_downloads(time_t now)
void
networkstatus_consensus_download_failed(int status_code)
{
- download_status_failed(&consensus_dl_status, status_code);
+ /* XXXXNM Microdescs: may need to handle more types. */
+ download_status_failed(&consensus_dl_status[FLAV_NS], status_code);
/* Retry immediately, if appropriate. */
update_consensus_networkstatus_downloads(time(NULL));
}
@@ -1147,8 +1284,15 @@ update_consensus_networkstatus_fetch_time(time_t now)
/* We want to cache the next one at some point after this one
* is no longer fresh... */
start = c->fresh_until + min_sec_before_caching;
- /* But only in the first half-interval after that. */
- dl_interval = interval/2;
+ /* Some clients may need the consensus sooner than others. */
+ if (options->FetchDirInfoExtraEarly || authdir_mode_v3(options)) {
+ dl_interval = 60;
+ if (min_sec_before_caching + dl_interval > interval)
+ dl_interval = interval/2;
+ } else {
+ /* But only in the first half-interval after that. */
+ dl_interval = interval/2;
+ }
} else {
/* We're an ordinary client or a bridge. Give all the caches enough
* time to download the consensus. */
@@ -1167,7 +1311,7 @@ update_consensus_networkstatus_fetch_time(time_t now)
}
if (dl_interval < 1)
dl_interval = 1;
- /* We must not try to replace c while it's still the most valid: */
+ /* 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: */
tor_assert(start+dl_interval < c->valid_until);
@@ -1188,7 +1332,6 @@ update_consensus_networkstatus_fetch_time(time_t now)
time_to_download_next_consensus = now;
log_info(LD_DIR, "No live consensus; we should fetch one immediately.");
}
-
}
/** Return 1 if there's a reason we shouldn't try any directory
@@ -1223,10 +1366,14 @@ update_networkstatus_downloads(time_t now)
void
update_certificate_downloads(time_t now)
{
- if (consensus_waiting_for_certs)
- authority_certs_fetch_missing(consensus_waiting_for_certs, now);
- else
- authority_certs_fetch_missing(current_consensus, now);
+ int i;
+ for (i = 0; i < N_CONSENSUS_FLAVORS; ++i) {
+ if (consensus_waiting_for_certs[i].consensus)
+ authority_certs_fetch_missing(consensus_waiting_for_certs[i].consensus,
+ now);
+ }
+
+ authority_certs_fetch_missing(current_consensus, now);
}
/** Return 1 if we have a consensus but we don't have enough certificates
@@ -1234,7 +1381,8 @@ update_certificate_downloads(time_t now)
int
consensus_is_waiting_for_certs(void)
{
- return consensus_waiting_for_certs ? 1 : 0;
+ return consensus_waiting_for_certs[USABLE_CONSENSUS_FLAVOR].consensus
+ ? 1 : 0;
}
/** Return the network status with a given identity digest. */
@@ -1403,16 +1551,31 @@ networkstatus_copy_old_consensus_info(networkstatus_t *new_c,
* user, and -2 for more serious problems.
*/
int
-networkstatus_set_current_consensus(const char *consensus, unsigned flags)
+networkstatus_set_current_consensus(const char *consensus,
+ const char *flavor,
+ unsigned flags)
{
- networkstatus_t *c;
+ networkstatus_t *c=NULL;
int r, result = -1;
time_t now = time(NULL);
+ or_options_t *options = get_options();
char *unverified_fname = NULL, *consensus_fname = NULL;
+ int flav = networkstatus_parse_flavor_name(flavor);
const unsigned from_cache = flags & NSSET_FROM_CACHE;
const unsigned was_waiting_for_certs = flags & NSSET_WAS_WAITING_FOR_CERTS;
const unsigned dl_certs = !(flags & NSSET_DONT_DOWNLOAD_CERTS);
const unsigned accept_obsolete = flags & NSSET_ACCEPT_OBSOLETE;
+ const unsigned require_flavor = flags & NSSET_REQUIRE_FLAVOR;
+ const digests_t *current_digests = NULL;
+ consensus_waiting_for_certs_t *waiting = NULL;
+ time_t current_valid_after = 0;
+ int free_consensus = 1; /* Free 'c' at the end of the function */
+
+ if (flav < 0) {
+ /* XXXX we don't handle unrecognized flavors yet. */
+ log_warn(LD_BUG, "Unrecognized consensus flavor %s", flavor);
+ return -2;
+ }
/* Make sure it's parseable. */
c = networkstatus_parse_vote_from_string(consensus, NULL, NS_TYPE_CONSENSUS);
@@ -1422,33 +1585,69 @@ networkstatus_set_current_consensus(const char *consensus, unsigned flags)
goto done;
}
+ if ((int)c->flavor != flav) {
+ /* This wasn't the flavor we thought we were getting. */
+ if (require_flavor) {
+ log_warn(LD_DIR, "Got consensus with unexpected flavor %s (wanted %s)",
+ networkstatus_get_flavor_name(c->flavor), flavor);
+ goto done;
+ }
+ flav = c->flavor;
+ flavor = networkstatus_get_flavor_name(flav);
+ }
+
+ if (flav != USABLE_CONSENSUS_FLAVOR &&
+ !directory_caches_dir_info(options)) {
+ /* This consensus is totally boring to us: we won't use it, and we won't
+ * serve it. Drop it. */
+ goto done;
+ }
+
if (from_cache && !accept_obsolete &&
c->valid_until < now-OLD_ROUTER_DESC_MAX_AGE) {
/* XXX022 when we try to make fallbackconsensus work again, we should
* consider taking this out. Until then, believing obsolete consensuses
* is causing more harm than good. See also bug 887. */
- log_info(LD_DIR, "Loaded an obsolete consensus. Discarding.");
+ log_info(LD_DIR, "Loaded an expired consensus. Discarding.");
goto done;
}
- if (current_consensus &&
- !memcmp(c->networkstatus_digest, current_consensus->networkstatus_digest,
- DIGEST_LEN)) {
+ if (!strcmp(flavor, "ns")) {
+ consensus_fname = get_datadir_fname("cached-consensus");
+ unverified_fname = get_datadir_fname("unverified-consensus");
+ if (current_consensus) {
+ current_digests = &current_consensus->digests;
+ current_valid_after = current_consensus->valid_after;
+ }
+ } else {
+ cached_dir_t *cur;
+ char buf[128];
+ tor_snprintf(buf, sizeof(buf), "cached-%s-consensus", flavor);
+ consensus_fname = get_datadir_fname(buf);
+ tor_snprintf(buf, sizeof(buf), "unverified-%s-consensus", flavor);
+ unverified_fname = get_datadir_fname(buf);
+ cur = dirserv_get_consensus(flavor);
+ if (cur) {
+ current_digests = &cur->digests;
+ current_valid_after = cur->published;
+ }
+ }
+
+ if (current_digests &&
+ !memcmp(&c->digests, current_digests, sizeof(c->digests))) {
/* We already have this one. That's a failure. */
- log_info(LD_DIR, "Got a consensus we already have");
+ log_info(LD_DIR, "Got a %s consensus we already have", flavor);
goto done;
}
- if (current_consensus && c->valid_after <= current_consensus->valid_after) {
+ if (current_valid_after && c->valid_after <= current_valid_after) {
/* We have a newer one. There's no point in accepting this one,
* even if it's great. */
- log_info(LD_DIR, "Got a consensus at least as old as the one we have");
+ log_info(LD_DIR, "Got a %s consensus at least as old as the one we have",
+ flavor);
goto done;
}
- consensus_fname = get_datadir_fname("cached-consensus");
- unverified_fname = get_datadir_fname("unverified-consensus");
-
/* Make sure it's signed enough. */
if ((r=networkstatus_check_consensus_signature(c, 1))<0) {
if (r == -1) {
@@ -1457,16 +1656,16 @@ networkstatus_set_current_consensus(const char *consensus, unsigned flags)
log_info(LD_DIR,
"Not enough certificates to check networkstatus consensus");
}
- if (!current_consensus ||
- c->valid_after > current_consensus->valid_after) {
- if (consensus_waiting_for_certs)
- networkstatus_vote_free(consensus_waiting_for_certs);
- tor_free(consensus_waiting_for_certs_body);
- consensus_waiting_for_certs = c;
- c = NULL; /* Prevent free. */
- consensus_waiting_for_certs_body = tor_strdup(consensus);
- consensus_waiting_for_certs_set_at = now;
- consensus_waiting_for_certs_dl_failed = 0;
+ if (!current_valid_after ||
+ c->valid_after > current_valid_after) {
+ waiting = &consensus_waiting_for_certs[flav];
+ networkstatus_vote_free(waiting->consensus);
+ tor_free(waiting->body);
+ waiting->consensus = c;
+ free_consensus = 0;
+ waiting->body = tor_strdup(consensus);
+ waiting->set_at = now;
+ waiting->dl_failed = 0;
if (!from_cache) {
write_str_to_file(unverified_fname, consensus, 0);
}
@@ -1495,56 +1694,75 @@ networkstatus_set_current_consensus(const char *consensus, unsigned flags)
}
}
- if (!from_cache)
+ if (!from_cache && flav == USABLE_CONSENSUS_FLAVOR)
control_event_client_status(LOG_NOTICE, "CONSENSUS_ARRIVED");
/* Are we missing any certificates at all? */
if (r != 1 && dl_certs)
authority_certs_fetch_missing(c, now);
- notify_control_networkstatus_changed(current_consensus, c);
+ if (flav == USABLE_CONSENSUS_FLAVOR) {
+ notify_control_networkstatus_changed(current_consensus, c);
- if (current_consensus) {
- networkstatus_copy_old_consensus_info(c, current_consensus);
- networkstatus_vote_free(current_consensus);
+ if (current_consensus) {
+ networkstatus_copy_old_consensus_info(c, current_consensus);
+ networkstatus_vote_free(current_consensus);
+ /* Defensive programming : we should set current_consensus very soon,
+ * but we're about to call some stuff in the meantime, and leaving this
+ * dangling pointer around has proven to be trouble. */
+ current_consensus = NULL;
+ }
}
- if (consensus_waiting_for_certs &&
- consensus_waiting_for_certs->valid_after <= c->valid_after) {
- networkstatus_vote_free(consensus_waiting_for_certs);
- consensus_waiting_for_certs = NULL;
- if (consensus != consensus_waiting_for_certs_body)
- tor_free(consensus_waiting_for_certs_body);
+ waiting = &consensus_waiting_for_certs[flav];
+ if (waiting->consensus &&
+ waiting->consensus->valid_after <= c->valid_after) {
+ networkstatus_vote_free(waiting->consensus);
+ waiting->consensus = NULL;
+ if (consensus != waiting->body)
+ tor_free(waiting->body);
else
- consensus_waiting_for_certs_body = NULL;
- consensus_waiting_for_certs_set_at = 0;
- consensus_waiting_for_certs_dl_failed = 0;
+ waiting->body = NULL;
+ waiting->set_at = 0;
+ waiting->dl_failed = 0;
unlink(unverified_fname);
}
/* Reset the failure count only if this consensus is actually valid. */
if (c->valid_after <= now && now <= c->valid_until) {
- download_status_reset(&consensus_dl_status);
+ download_status_reset(&consensus_dl_status[flav]);
} else {
if (!from_cache)
- download_status_failed(&consensus_dl_status, 0);
+ download_status_failed(&consensus_dl_status[flav], 0);
}
- current_consensus = c;
- c = NULL; /* Prevent free. */
+ if (flav == USABLE_CONSENSUS_FLAVOR) {
+ current_consensus = c;
+ free_consensus = 0; /* Prevent free. */
+
+ /* XXXXNM Microdescs: needs a non-ns variant. */
+ update_consensus_networkstatus_fetch_time(now);
+ dirvote_recalculate_timing(options, now);
+ routerstatus_list_update_named_server_map();
+ cell_ewma_set_scale_factor(options, current_consensus);
+
+ /* XXX022 where is the right place to put this call? */
+ connection_or_update_token_buckets(get_connection_array(), options);
- update_consensus_networkstatus_fetch_time(now);
- dirvote_recalculate_timing(get_options(), now);
- routerstatus_list_update_named_server_map();
+ circuit_build_times_new_consensus_params(&circ_times, current_consensus);
+ }
+
+ if (directory_caches_dir_info(options)) {
+ dirserv_set_cached_consensus_networkstatus(consensus,
+ flavor,
+ &c->digests,
+ c->valid_after);
+ }
if (!from_cache) {
write_str_to_file(consensus_fname, consensus, 0);
}
- if (directory_caches_dir_info(get_options()))
- dirserv_set_cached_networkstatus_v3(consensus,
- current_consensus->valid_after);
-
if (ftime_definitely_before(now, current_consensus->valid_after)) {
char tbuf[ISO_TIME_LEN+1];
char dbuf[64];
@@ -1563,7 +1781,7 @@ networkstatus_set_current_consensus(const char *consensus, unsigned flags)
result = 0;
done:
- if (c)
+ if (free_consensus)
networkstatus_vote_free(c);
tor_free(consensus_fname);
tor_free(unverified_fname);
@@ -1575,13 +1793,17 @@ networkstatus_set_current_consensus(const char *consensus, unsigned flags)
void
networkstatus_note_certs_arrived(void)
{
- if (consensus_waiting_for_certs) {
- if (networkstatus_check_consensus_signature(
- consensus_waiting_for_certs, 0)>=0) {
+ int i;
+ for (i=0; i<N_CONSENSUS_FLAVORS; ++i) {
+ consensus_waiting_for_certs_t *waiting = &consensus_waiting_for_certs[i];
+ if (!waiting->consensus)
+ continue;
+ if (networkstatus_check_consensus_signature(waiting->consensus, 0)>=0) {
if (!networkstatus_set_current_consensus(
- consensus_waiting_for_certs_body,
+ waiting->body,
+ networkstatus_get_flavor_name(i),
NSSET_WAS_WAITING_FOR_CERTS)) {
- tor_free(consensus_waiting_for_certs_body);
+ tor_free(waiting->body);
}
}
}
@@ -1667,10 +1889,8 @@ download_status_map_update_from_v2_networkstatus(void)
v2_download_status_map = digestmap_new();
dl_status = digestmap_new();
- SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
- {
- SMARTLIST_FOREACH(ns->entries, routerstatus_t *, rs,
- {
+ SMARTLIST_FOREACH_BEGIN(networkstatus_v2_list, networkstatus_v2_t *, ns) {
+ SMARTLIST_FOREACH_BEGIN(ns->entries, routerstatus_t *, rs) {
const char *d = rs->descriptor_digest;
download_status_t *s;
if (digestmap_get(dl_status, d))
@@ -1679,8 +1899,8 @@ download_status_map_update_from_v2_networkstatus(void)
s = tor_malloc_zero(sizeof(download_status_t));
}
digestmap_set(dl_status, d, s);
- });
- });
+ } SMARTLIST_FOREACH_END(rs);
+ } SMARTLIST_FOREACH_END(ns);
digestmap_free(v2_download_status_map, _tor_free);
v2_download_status_map = dl_status;
networkstatus_v2_list_has_changed = 0;
@@ -1694,11 +1914,9 @@ routerstatus_list_update_named_server_map(void)
if (!current_consensus)
return;
- if (named_server_map)
- strmap_free(named_server_map, _tor_free);
+ strmap_free(named_server_map, _tor_free);
named_server_map = strmap_new();
- if (unnamed_server_map)
- strmap_free(unnamed_server_map, NULL);
+ strmap_free(unnamed_server_map, NULL);
unnamed_server_map = strmap_new();
SMARTLIST_FOREACH(current_consensus->routerstatus_list, routerstatus_t *, rs,
{
@@ -1773,6 +1991,15 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
router->is_bad_directory = rs->is_bad_directory;
router->is_bad_exit = rs->is_bad_exit;
router->is_hs_dir = rs->is_hs_dir;
+ } else {
+ /* If we _are_ an authority, we should check whether this router
+ * is one that will cause us to need a reachability test. */
+ routerinfo_t *old_router =
+ router_get_by_digest(router->cache_info.identity_digest);
+ if (old_router != router) {
+ router->needs_retest_if_added =
+ dirserv_should_launch_reachability_test(router, old_router);
+ }
}
if (router->is_running && ds) {
download_status_reset(&ds->v2_ns_dl_status);
@@ -1835,7 +2062,7 @@ char *
networkstatus_getinfo_helper_single(routerstatus_t *rs)
{
char buf[RS_ENTRY_LEN+1];
- routerstatus_format_entry(buf, sizeof(buf), rs, NULL, 0, 1);
+ routerstatus_format_entry(buf, sizeof(buf), rs, NULL, NS_CONTROL_PORT);
return tor_strdup(buf);
}
@@ -1872,7 +2099,7 @@ networkstatus_getinfo_by_purpose(const char *purpose_string, time_t now)
if (bridge_auth && ri->purpose == ROUTER_PURPOSE_BRIDGE)
dirserv_set_router_is_running(ri, now);
/* then generate and write out status lines for each of them */
- set_routerstatus_from_routerinfo(&rs, ri, now, 0, 0, 0, 0);
+ set_routerstatus_from_routerinfo(&rs, ri, now, 0, 0, 0);
smartlist_add(statuses, networkstatus_getinfo_helper_single(&rs));
});
@@ -1897,6 +2124,25 @@ networkstatus_dump_bridge_status_to_file(time_t now)
tor_free(status);
}
+int32_t
+get_net_param_from_list(smartlist_t *net_params, const char *param_name,
+ int default_val)
+{
+ size_t name_len = strlen(param_name);
+
+ SMARTLIST_FOREACH_BEGIN(net_params, const char *, p) {
+ if (!strcmpstart(p, param_name) && p[name_len] == '=') {
+ int ok=0;
+ long v = tor_parse_long(p+name_len+1, 10, INT32_MIN,
+ INT32_MAX, &ok, NULL);
+ if (ok)
+ return (int32_t) v;
+ }
+ } SMARTLIST_FOREACH_END(p);
+
+ return default_val;
+}
+
/** Return the value of a integer parameter from the networkstatus <b>ns</b>
* whose name is <b>param_name</b>. If <b>ns</b> is NULL, try loading the
* latest consensus ourselves. Return <b>default_val</b> if no latest
@@ -1905,27 +2151,59 @@ int32_t
networkstatus_get_param(networkstatus_t *ns, const char *param_name,
int32_t default_val)
{
- size_t name_len;
-
if (!ns) /* if they pass in null, go find it ourselves */
ns = networkstatus_get_latest_consensus();
if (!ns || !ns->net_params)
return default_val;
- name_len = strlen(param_name);
+ return get_net_param_from_list(ns->net_params, param_name, default_val);
+}
- SMARTLIST_FOREACH_BEGIN(ns->net_params, const char *, p) {
- if (!strcmpstart(p, param_name) && p[name_len] == '=') {
- int ok=0;
- long v = tor_parse_long(p+name_len+1, 10, INT32_MIN, INT32_MAX, &ok,
- NULL);
- if (ok)
- return (int32_t) v;
- }
- } SMARTLIST_FOREACH_END(p);
+/** Return the value of a integer bw weight parameter from the networkstatus
+ * <b>ns</b> whose name is <b>weight_name</b>. If <b>ns</b> is NULL, try
+ * loading the latest consensus ourselves. Return <b>default_val</b> if no
+ * latest consensus, or if it has no parameter called <b>param_name</b>. */
+int32_t
+networkstatus_get_bw_weight(networkstatus_t *ns, const char *weight_name,
+ int32_t default_val)
+{
+ if (!ns) /* if they pass in null, go find it ourselves */
+ ns = networkstatus_get_latest_consensus();
- return default_val;
+ if (!ns || !ns->weight_params)
+ return default_val;
+
+ return get_net_param_from_list(ns->weight_params, weight_name, default_val);
+}
+
+/** Return the name of the consensus flavor <b>flav</b> as used to identify
+ * the flavor in directory documents. */
+const char *
+networkstatus_get_flavor_name(consensus_flavor_t flav)
+{
+ switch (flav) {
+ case FLAV_NS:
+ return "ns";
+ case FLAV_MICRODESC:
+ return "microdesc";
+ default:
+ tor_fragile_assert();
+ return "??";
+ }
+}
+
+/** Return the consensus_flavor_t value for the flavor called <b>flavname</b>,
+ * or -1 if the flavor is not recognized. */
+int
+networkstatus_parse_flavor_name(const char *flavname)
+{
+ if (!strcmp(flavname, "ns"))
+ return FLAV_NS;
+ else if (!strcmp(flavname, "microdesc"))
+ return FLAV_MICRODESC;
+ else
+ return -1;
}
/** If <b>question</b> is a string beginning with "ns/" in a format the
@@ -1934,7 +2212,8 @@ networkstatus_get_param(networkstatus_t *ns, const char *param_name,
* ORs. Return 0 on success, -1 on unrecognized question format. */
int
getinfo_helper_networkstatus(control_connection_t *conn,
- const char *question, char **answer)
+ const char *question, char **answer,
+ const char **errmsg)
{
routerstatus_t *status;
(void) conn;
@@ -1958,8 +2237,10 @@ getinfo_helper_networkstatus(control_connection_t *conn,
} else if (!strcmpstart(question, "ns/id/")) {
char d[DIGEST_LEN];
- if (base16_decode(d, DIGEST_LEN, question+6, strlen(question+6)))
+ if (base16_decode(d, DIGEST_LEN, question+6, strlen(question+6))) {
+ *errmsg = "Data not decodeable as hex";
return -1;
+ }
status = router_get_consensus_status_by_id(d);
} else if (!strcmpstart(question, "ns/name/")) {
status = router_get_consensus_status_by_nickname(question+8, 0);
@@ -1967,7 +2248,7 @@ getinfo_helper_networkstatus(control_connection_t *conn,
*answer = networkstatus_getinfo_by_purpose(question+11, time(NULL));
return *answer ? 0 : -1;
} else {
- return -1;
+ return 0;
}
if (status)
@@ -1979,30 +2260,29 @@ getinfo_helper_networkstatus(control_connection_t *conn,
void
networkstatus_free_all(void)
{
+ int i;
if (networkstatus_v2_list) {
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
networkstatus_v2_free(ns));
smartlist_free(networkstatus_v2_list);
networkstatus_v2_list = NULL;
}
- if (v2_download_status_map) {
- digestmap_free(v2_download_status_map, _tor_free);
- v2_download_status_map = NULL;
- }
- if (current_consensus) {
- networkstatus_vote_free(current_consensus);
- current_consensus = NULL;
- }
- if (consensus_waiting_for_certs) {
- networkstatus_vote_free(consensus_waiting_for_certs);
- consensus_waiting_for_certs = NULL;
- }
- tor_free(consensus_waiting_for_certs_body);
- if (named_server_map) {
- strmap_free(named_server_map, _tor_free);
- }
- if (unnamed_server_map) {
- strmap_free(unnamed_server_map, NULL);
+
+ digestmap_free(v2_download_status_map, _tor_free);
+ v2_download_status_map = NULL;
+ networkstatus_vote_free(current_consensus);
+ current_consensus = NULL;
+
+ for (i=0; i < N_CONSENSUS_FLAVORS; ++i) {
+ consensus_waiting_for_certs_t *waiting = &consensus_waiting_for_certs[i];
+ if (waiting->consensus) {
+ networkstatus_vote_free(waiting->consensus);
+ waiting->consensus = NULL;
+ }
+ tor_free(waiting->body);
}
+
+ strmap_free(named_server_map, _tor_free);
+ strmap_free(unnamed_server_map, NULL);
}
diff --git a/src/or/networkstatus.h b/src/or/networkstatus.h
new file mode 100644
index 0000000000..32b71a9ceb
--- /dev/null
+++ b/src/or/networkstatus.h
@@ -0,0 +1,100 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file networkstatus.h
+ * \brief Header file for networkstatus.c.
+ **/
+
+#ifndef _TOR_NETWORKSTATUS_H
+#define _TOR_NETWORKSTATUS_H
+
+/** How old do we allow a v2 network-status to get before removing it
+ * completely? */
+#define MAX_NETWORKSTATUS_AGE (10*24*60*60)
+
+void networkstatus_reset_warnings(void);
+void networkstatus_reset_download_failures(void);
+int router_reload_v2_networkstatus(void);
+int router_reload_consensus_networkstatus(void);
+void routerstatus_free(routerstatus_t *rs);
+void networkstatus_v2_free(networkstatus_v2_t *ns);
+void networkstatus_vote_free(networkstatus_t *ns);
+networkstatus_voter_info_t *networkstatus_get_voter_by_id(
+ networkstatus_t *vote,
+ const char *identity);
+int networkstatus_check_consensus_signature(networkstatus_t *consensus,
+ int warn);
+int networkstatus_check_document_signature(const networkstatus_t *consensus,
+ document_signature_t *sig,
+ const authority_cert_t *cert);
+char *networkstatus_get_cache_filename(const char *identity_digest);
+int router_set_networkstatus_v2(const char *s, time_t arrived_at,
+ v2_networkstatus_source_t source,
+ smartlist_t *requested_fingerprints);
+void networkstatus_v2_list_clean(time_t now);
+int compare_digest_to_routerstatus_entry(const void *_key,
+ const void **_member);
+routerstatus_t *networkstatus_v2_find_entry(networkstatus_v2_t *ns,
+ const char *digest);
+routerstatus_t *networkstatus_vote_find_entry(networkstatus_t *ns,
+ const char *digest);
+int networkstatus_vote_find_entry_idx(networkstatus_t *ns,
+ const char *digest, int *found_out);
+const smartlist_t *networkstatus_get_v2_list(void);
+download_status_t *router_get_dl_status_by_descriptor_digest(const char *d);
+routerstatus_t *router_get_consensus_status_by_id(const char *digest);
+routerstatus_t *router_get_consensus_status_by_descriptor_digest(
+ const char *digest);
+routerstatus_t *router_get_consensus_status_by_nickname(const char *nickname,
+ int warn_if_unnamed);
+const char *networkstatus_get_router_digest_by_nickname(const char *nickname);
+int networkstatus_nickname_is_unnamed(const char *nickname);
+void networkstatus_consensus_download_failed(int status_code);
+void update_consensus_networkstatus_fetch_time(time_t now);
+int should_delay_dir_fetches(or_options_t *options);
+void update_networkstatus_downloads(time_t now);
+void update_certificate_downloads(time_t now);
+int consensus_is_waiting_for_certs(void);
+networkstatus_v2_t *networkstatus_v2_get_by_digest(const char *digest);
+networkstatus_t *networkstatus_get_latest_consensus(void);
+networkstatus_t *networkstatus_get_live_consensus(time_t now);
+networkstatus_t *networkstatus_get_reasonably_live_consensus(time_t now);
+#define NSSET_FROM_CACHE 1
+#define NSSET_WAS_WAITING_FOR_CERTS 2
+#define NSSET_DONT_DOWNLOAD_CERTS 4
+#define NSSET_ACCEPT_OBSOLETE 8
+#define NSSET_REQUIRE_FLAVOR 16
+int networkstatus_set_current_consensus(const char *consensus,
+ const char *flavor,
+ unsigned flags);
+void networkstatus_note_certs_arrived(void);
+void routers_update_all_from_networkstatus(time_t now, int dir_version);
+void routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
+ int reset_failures);
+void signed_descs_update_status_from_consensus_networkstatus(
+ smartlist_t *descs);
+
+char *networkstatus_getinfo_helper_single(routerstatus_t *rs);
+char *networkstatus_getinfo_by_purpose(const char *purpose_string, time_t now);
+void networkstatus_dump_bridge_status_to_file(time_t now);
+int32_t get_net_param_from_list(smartlist_t *net_params, const char *name,
+ int default_val);
+int32_t networkstatus_get_param(networkstatus_t *ns, const char *param_name,
+ int32_t default_val);
+int getinfo_helper_networkstatus(control_connection_t *conn,
+ const char *question, char **answer,
+ const char **errmsg);
+int32_t networkstatus_get_bw_weight(networkstatus_t *ns, const char *weight,
+ int32_t default_val);
+const char *networkstatus_get_flavor_name(consensus_flavor_t flav);
+int networkstatus_parse_flavor_name(const char *flavname);
+void document_signature_free(document_signature_t *sig);
+document_signature_t *document_signature_dup(const document_signature_t *sig);
+void networkstatus_free_all(void);
+
+#endif
+
diff --git a/src/or/ntmain.c b/src/or/ntmain.c
index ad6698e722..46e7afb78b 100644
--- a/src/or/ntmain.c
+++ b/src/or/ntmain.c
@@ -5,13 +5,22 @@
#define MAIN_PRIVATE
#include "or.h"
-
-#include <tchar.h>
-#define GENSRV_SERVICENAME TEXT("tor")
-#define GENSRV_DISPLAYNAME TEXT("Tor Win32 Service")
+#include "config.h"
+#include "main.h"
+#include "ntmain.h"
+
+#ifdef HAVE_EVENT2_EVENT_H
+#include <event2/event.h>
+#else
+#include <event.h>
+#endif
+
+#include <windows.h>
+#define GENSRV_SERVICENAME "tor"
+#define GENSRV_DISPLAYNAME "Tor Win32 Service"
#define GENSRV_DESCRIPTION \
- TEXT("Provides an anonymous Internet communication system")
-#define GENSRV_USERACCT TEXT("NT AUTHORITY\\LocalService")
+ "Provides an anonymous Internet communication system"
+#define GENSRV_USERACCT "NT AUTHORITY\\LocalService"
// Cheating: using the pre-defined error codes, tricks Windows into displaying
// a semi-related human-readable error message if startup fails as
@@ -27,7 +36,6 @@ static SERVICE_STATUS_HANDLE hStatus;
* to the NT service functions. */
static char **backup_argv;
static int backup_argc;
-static char* nt_strerror(uint32_t errnum);
static void nt_service_control(DWORD request);
static void nt_service_body(int argc, char **argv);
@@ -61,30 +69,30 @@ struct service_fns {
SC_HANDLE (WINAPI *CreateServiceA_fn)(
SC_HANDLE hSCManager,
- LPCTSTR lpServiceName,
- LPCTSTR lpDisplayName,
+ LPCSTR lpServiceName,
+ LPCSTR lpDisplayName,
DWORD dwDesiredAccess,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
- LPCTSTR lpBinaryPathName,
- LPCTSTR lpLoadOrderGroup,
+ LPCSTR lpBinaryPathName,
+ LPCSTR lpLoadOrderGroup,
LPDWORD lpdwTagId,
- LPCTSTR lpDependencies,
- LPCTSTR lpServiceStartName,
- LPCTSTR lpPassword);
+ LPCSTR lpDependencies,
+ LPCSTR lpServiceStartName,
+ LPCSTR lpPassword);
BOOL (WINAPI *DeleteService_fn)(
SC_HANDLE hService);
SC_HANDLE (WINAPI *OpenSCManagerA_fn)(
- LPCTSTR lpMachineName,
- LPCTSTR lpDatabaseName,
+ LPCSTR lpMachineName,
+ LPCSTR lpDatabaseName,
DWORD dwDesiredAccess);
SC_HANDLE (WINAPI *OpenServiceA_fn)(
SC_HANDLE hSCManager,
- LPCTSTR lpServiceName,
+ LPCSTR lpServiceName,
DWORD dwDesiredAccess);
BOOL (WINAPI *QueryServiceStatus_fn)(
@@ -92,23 +100,23 @@ struct service_fns {
LPSERVICE_STATUS lpServiceStatus);
SERVICE_STATUS_HANDLE (WINAPI *RegisterServiceCtrlHandlerA_fn)(
- LPCTSTR lpServiceName,
+ LPCSTR lpServiceName,
LPHANDLER_FUNCTION lpHandlerProc);
BOOL (WINAPI *SetServiceStatus_fn)(SERVICE_STATUS_HANDLE,
LPSERVICE_STATUS);
BOOL (WINAPI *StartServiceCtrlDispatcherA_fn)(
- const SERVICE_TABLE_ENTRY* lpServiceTable);
+ const SERVICE_TABLE_ENTRYA* lpServiceTable);
BOOL (WINAPI *StartServiceA_fn)(
SC_HANDLE hService,
DWORD dwNumServiceArgs,
- LPCTSTR* lpServiceArgVectors);
+ LPCSTR* lpServiceArgVectors);
BOOL (WINAPI *LookupAccountNameA_fn)(
- LPCTSTR lpSystemName,
- LPCTSTR lpAccountName,
+ LPCSTR lpSystemName,
+ LPCSTR lpAccountName,
PSID Sid,
LPDWORD cbSid,
LPTSTR ReferencedDomainName,
@@ -130,8 +138,7 @@ nt_service_loadlibrary(void)
if (service_fns.loaded)
return;
- /* XXXX Possibly, we should hardcode the location of this DLL. */
- if (!(library = LoadLibrary("advapi32.dll"))) {
+ if (!(library = load_windows_system_library(TEXT("advapi32.dll")))) {
log_err(LD_GENERAL, "Couldn't open advapi32.dll. Are you trying to use "
"NT services on Windows 98? That doesn't work.");
goto err;
@@ -218,7 +225,7 @@ nt_service_control(DWORD request)
log_notice(LD_GENERAL,
"Got stop/shutdown request; shutting down cleanly.");
service_status.dwCurrentState = SERVICE_STOP_PENDING;
- event_loopexit(&exit_now);
+ event_base_loopexit(tor_libevent_get_base(), &exit_now);
return;
}
service_fns.SetServiceStatus_fn(hStatus, &service_status);
@@ -275,20 +282,20 @@ nt_service_body(int argc, char **argv)
static void
nt_service_main(void)
{
- SERVICE_TABLE_ENTRY table[2];
+ SERVICE_TABLE_ENTRYA table[2];
DWORD result = 0;
char *errmsg;
nt_service_loadlibrary();
table[0].lpServiceName = (char*)GENSRV_SERVICENAME;
- table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)nt_service_body;
+ table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTIONA)nt_service_body;
table[1].lpServiceName = NULL;
table[1].lpServiceProc = NULL;
if (!service_fns.StartServiceCtrlDispatcherA_fn(table)) {
result = GetLastError();
- errmsg = nt_strerror(result);
+ errmsg = format_win32_error(result);
printf("Service error %d : %s\n", (int) result, errmsg);
- LocalFree(errmsg);
+ tor_free(errmsg);
if (result == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) {
if (tor_init(backup_argc, backup_argv) < 0)
return;
@@ -323,9 +330,9 @@ nt_service_open_scm(void)
nt_service_loadlibrary();
if ((hSCManager = service_fns.OpenSCManagerA_fn(
NULL, NULL, SC_MANAGER_CREATE_SERVICE)) == NULL) {
- errmsg = nt_strerror(GetLastError());
+ errmsg = format_win32_error(GetLastError());
printf("OpenSCManager() failed : %s\n", errmsg);
- LocalFree(errmsg);
+ tor_free(errmsg);
}
return hSCManager;
}
@@ -340,9 +347,9 @@ nt_service_open(SC_HANDLE hSCManager)
nt_service_loadlibrary();
if ((hService = service_fns.OpenServiceA_fn(hSCManager, GENSRV_SERVICENAME,
SERVICE_ALL_ACCESS)) == NULL) {
- errmsg = nt_strerror(GetLastError());
+ errmsg = format_win32_error(GetLastError());
printf("OpenService() failed : %s\n", errmsg);
- LocalFree(errmsg);
+ tor_free(errmsg);
}
return hService;
}
@@ -374,14 +381,14 @@ nt_service_start(SC_HANDLE hService)
printf("Service started successfully\n");
return 0;
} else {
- errmsg = nt_strerror(service_status.dwWin32ExitCode);
+ errmsg = format_win32_error(service_status.dwWin32ExitCode);
printf("Service failed to start : %s\n", errmsg);
- LocalFree(errmsg);
+ tor_free(errmsg);
}
} else {
- errmsg = nt_strerror(GetLastError());
+ errmsg = format_win32_error(GetLastError());
printf("StartService() failed : %s\n", errmsg);
- LocalFree(errmsg);
+ tor_free(errmsg);
}
return -1;
}
@@ -418,14 +425,14 @@ nt_service_stop(SC_HANDLE hService)
} else if (wait_time == MAX_SERVICE_WAIT_TIME) {
printf("Service did not stop within %d seconds.\n", wait_time);
} else {
- errmsg = nt_strerror(GetLastError());
+ errmsg = format_win32_error(GetLastError());
printf("QueryServiceStatus() failed : %s\n",errmsg);
- LocalFree(errmsg);
+ tor_free(errmsg);
}
} else {
- errmsg = nt_strerror(GetLastError());
+ errmsg = format_win32_error(GetLastError());
printf("ControlService() failed : %s\n", errmsg);
- LocalFree(errmsg);
+ tor_free(errmsg);
}
return -1;
}
@@ -439,6 +446,7 @@ static char *
nt_service_command_line(int *using_default_torrc)
{
TCHAR tor_exe[MAX_PATH+1];
+ char tor_exe_ascii[MAX_PATH+1];
char *command, *options=NULL;
smartlist_t *sl;
int i, cmdlen;
@@ -464,18 +472,25 @@ nt_service_command_line(int *using_default_torrc)
options = smartlist_join_strings(sl,"\" \"",0,NULL);
smartlist_free(sl);
+#ifdef UNICODE
+ wcstombs(tor_exe_ascii, tor_exe, sizeof(tor_exe_ascii));
+#else
+ strlcpy(tor_exe_ascii, tor_exe, sizeof(tor_exe_ascii));
+#endif
+
/* Allocate a string for the NT service command line */
- cmdlen = strlen(tor_exe) + (options?strlen(options):0) + 32;
+ cmdlen = strlen(tor_exe_ascii) + (options?strlen(options):0) + 32;
command = tor_malloc(cmdlen);
/* Format the service command */
if (options) {
if (tor_snprintf(command, cmdlen, "\"%s\" --nt-service \"%s\"",
- tor_exe, options)<0) {
+ tor_exe_ascii, options)<0) {
tor_free(command); /* sets command to NULL. */
}
} else { /* ! options */
- if (tor_snprintf(command, cmdlen, "\"%s\" --nt-service", tor_exe)<0) {
+ if (tor_snprintf(command, cmdlen, "\"%s\" --nt-service",
+ tor_exe_ascii)<0) {
tor_free(command); /* sets command to NULL. */
}
}
@@ -500,7 +515,7 @@ nt_service_install(int argc, char **argv)
SC_HANDLE hSCManager = NULL;
SC_HANDLE hService = NULL;
- SERVICE_DESCRIPTION sdBuff;
+ SERVICE_DESCRIPTIONA sdBuff;
char *command;
char *errmsg;
const char *user_acct = GENSRV_USERACCT;
@@ -590,10 +605,10 @@ nt_service_install(int argc, char **argv)
SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,
command, NULL, NULL, NULL,
user_acct, password)) == NULL) {
- errmsg = nt_strerror(GetLastError());
+ errmsg = format_win32_error(GetLastError());
printf("CreateService() failed : %s\n", errmsg);
service_fns.CloseServiceHandle_fn(hSCManager);
- LocalFree(errmsg);
+ tor_free(errmsg);
tor_free(command);
return -1;
}
@@ -634,9 +649,9 @@ nt_service_remove(void)
nt_service_stop(hService);
if (service_fns.DeleteService_fn(hService) == FALSE) {
- errmsg = nt_strerror(GetLastError());
+ errmsg = format_win32_error(GetLastError());
printf("DeleteService() failed : %s\n", errmsg);
- LocalFree(errmsg);
+ tor_free(errmsg);
service_fns.CloseServiceHandle_fn(hService);
service_fns.CloseServiceHandle_fn(hSCManager);
return -1;
@@ -693,20 +708,6 @@ nt_service_cmd_stop(void)
return stop;
}
-/** Given a Win32 error code, this attempts to make Windows
- * return a human-readable error message. The char* returned
- * is allocated by Windows, but should be freed with LocalFree()
- * when finished with it. */
-static char*
-nt_strerror(uint32_t errnum)
-{
- char *msgbuf;
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPSTR)&msgbuf, 0, NULL);
- return msgbuf;
-}
-
int
nt_service_parse_options(int argc, char **argv, int *should_exit)
{
diff --git a/src/or/ntmain.h b/src/or/ntmain.h
new file mode 100644
index 0000000000..2cfa653c3d
--- /dev/null
+++ b/src/or/ntmain.h
@@ -0,0 +1,30 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file ntmain.h
+ * \brief Header file for ntmain.c.
+ **/
+
+#ifndef _TOR_NTMAIN_H
+#define _TOR_NTMAIN_H
+
+#ifdef MS_WINDOWS
+#if !defined (WINCE)
+#define NT_SERVICE
+#endif
+#endif
+
+#ifdef NT_SERVICE
+int nt_service_parse_options(int argc, char **argv, int *should_exit);
+int nt_service_is_stopping(void);
+void nt_service_set_state(DWORD state);
+#else
+#define nt_service_is_stopping() 0
+#endif
+
+#endif
+
diff --git a/src/or/onion.c b/src/or/onion.c
index 42e02c690c..4d14f9095b 100644
--- a/src/or/onion.c
+++ b/src/or/onion.c
@@ -11,6 +11,10 @@
**/
#include "or.h"
+#include "circuitlist.h"
+#include "config.h"
+#include "onion.h"
+#include "rephist.h"
/** Type for a linked list of circuits that are waiting for a free CPU worker
* to process a waiting onion handshake. */
@@ -58,11 +62,18 @@ onion_pending_add(or_circuit_t *circ, char *onionskin)
tor_assert(!ol_tail->next);
if (ol_length >= get_options()->MaxOnionsPending) {
- log_warn(LD_GENERAL,
- "Your computer is too slow to handle this many circuit "
- "creation requests! Please consider using the "
- "MaxAdvertisedBandwidth config option or choosing a more "
- "restricted exit policy.");
+#define WARN_TOO_MANY_CIRC_CREATIONS_INTERVAL (60)
+ static ratelim_t last_warned =
+ RATELIM_INIT(WARN_TOO_MANY_CIRC_CREATIONS_INTERVAL);
+ char *m;
+ if ((m = rate_limit_log(&last_warned, approx_time()))) {
+ log_warn(LD_GENERAL,
+ "Your computer is too slow to handle this many circuit "
+ "creation requests! Please consider using the "
+ "MaxAdvertisedBandwidth config option or choosing a more "
+ "restricted exit policy.%s",m);
+ tor_free(m);
+ }
tor_free(tmp);
return -1;
}
@@ -253,8 +264,9 @@ onion_skin_server_handshake(const char *onion_skin, /*ONIONSKIN_CHALLENGE_LEN*/
key_material_len = DIGEST_LEN+key_out_len;
key_material = tor_malloc(key_material_len);
- len = crypto_dh_compute_secret(dh, challenge, DH_KEY_LEN,
- key_material, key_material_len);
+ len = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, dh, challenge,
+ DH_KEY_LEN, key_material,
+ key_material_len);
if (len < 0) {
log_info(LD_GENERAL, "crypto_dh_compute_secret failed.");
goto err;
@@ -304,8 +316,9 @@ onion_skin_client_handshake(crypto_dh_env_t *handshake_state,
key_material_len = DIGEST_LEN + key_out_len;
key_material = tor_malloc(key_material_len);
- len = crypto_dh_compute_secret(handshake_state, handshake_reply, DH_KEY_LEN,
- key_material, key_material_len);
+ len = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, handshake_state,
+ handshake_reply, DH_KEY_LEN, key_material,
+ key_material_len);
if (len < 0)
goto err;
diff --git a/src/or/onion.h b/src/or/onion.h
new file mode 100644
index 0000000000..e097dcdbb3
--- /dev/null
+++ b/src/or/onion.h
@@ -0,0 +1,48 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file onion.h
+ * \brief Header file for onion.c.
+ **/
+
+#ifndef _TOR_ONION_H
+#define _TOR_ONION_H
+
+int onion_pending_add(or_circuit_t *circ, char *onionskin);
+or_circuit_t *onion_next_task(char **onionskin_out);
+void onion_pending_remove(or_circuit_t *circ);
+
+int onion_skin_create(crypto_pk_env_t *router_key,
+ crypto_dh_env_t **handshake_state_out,
+ char *onion_skin_out);
+
+int onion_skin_server_handshake(const char *onion_skin,
+ crypto_pk_env_t *private_key,
+ crypto_pk_env_t *prev_private_key,
+ char *handshake_reply_out,
+ char *key_out,
+ size_t key_out_len);
+
+int onion_skin_client_handshake(crypto_dh_env_t *handshake_state,
+ const char *handshake_reply,
+ char *key_out,
+ size_t key_out_len);
+
+int fast_server_handshake(const uint8_t *key_in,
+ uint8_t *handshake_reply_out,
+ uint8_t *key_out,
+ size_t key_out_len);
+
+int fast_client_handshake(const uint8_t *handshake_state,
+ const uint8_t *handshake_reply_out,
+ uint8_t *key_out,
+ size_t key_out_len);
+
+void clear_pending_onions(void);
+
+#endif
+
diff --git a/src/or/or.h b/src/or/or.h
index 2a251187fa..07b73ec9b7 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -20,9 +20,6 @@
#ifndef INSTRUMENT_DOWNLOADS
#define INSTRUMENT_DOWNLOADS 1
#endif
-#ifndef ENABLE_GEOIP_STATS
-#define ENABLE_GEOIP_STATS 1
-#endif
#endif
#ifdef MS_WINDOWS
@@ -62,6 +59,9 @@
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
@@ -83,16 +83,13 @@
#define snprintf _snprintf
#endif
-#include "crypto.h"
#include "tortls.h"
-#include "log.h"
-#include "compat.h"
+#include "../common/torlog.h"
#include "container.h"
-#include "util.h"
#include "torgzip.h"
#include "address.h"
-
-#include <event.h>
+#include "compat_libevent.h"
+#include "ht.h"
/* These signals are defined to help control_signal_act work.
*/
@@ -161,7 +158,7 @@
#define MAX_DNS_TTL (3*60*60)
/** How small can a TTL be before we stop believing it? Provides rudimentary
* pinning. */
-#define MIN_DNS_TTL (60)
+#define MIN_DNS_TTL 60
/** How often do we rotate onion keys? */
#define MIN_ONION_KEY_LIFETIME (7*24*60*60)
@@ -221,6 +218,21 @@ typedef enum {
/* !!!! If _CONN_TYPE_MAX is ever over 15, we must grow the type field in
* connection_t. */
+/* Proxy client types */
+#define PROXY_NONE 0
+#define PROXY_CONNECT 1
+#define PROXY_SOCKS4 2
+#define PROXY_SOCKS5 3
+
+/* Proxy client handshake states */
+#define PROXY_HTTPS_WANT_CONNECT_OK 1
+#define PROXY_SOCKS4_WANT_CONNECT_OK 2
+#define PROXY_SOCKS5_WANT_AUTH_METHOD_NONE 3
+#define PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929 4
+#define PROXY_SOCKS5_WANT_AUTH_RFC1929_OK 5
+#define PROXY_SOCKS5_WANT_CONNECT_OK 6
+#define PROXY_CONNECTED 7
+
/** True iff <b>x</b> is an edge connection. */
#define CONN_IS_EDGE(x) \
((x)->type == CONN_TYPE_EXIT || (x)->type == CONN_TYPE_AP)
@@ -241,26 +253,24 @@ typedef enum {
#define _OR_CONN_STATE_MIN 1
/** State for a connection to an OR: waiting for connect() to finish. */
#define OR_CONN_STATE_CONNECTING 1
-/** State for a connection to an OR: waiting for proxy command to flush. */
-#define OR_CONN_STATE_PROXY_FLUSHING 2
-/** State for a connection to an OR: waiting for proxy response. */
-#define OR_CONN_STATE_PROXY_READING 3
+/** State for a connection to an OR: waiting for proxy handshake to complete */
+#define OR_CONN_STATE_PROXY_HANDSHAKING 2
/** State for a connection to an OR or client: SSL is handshaking, not done
* yet. */
-#define OR_CONN_STATE_TLS_HANDSHAKING 4
+#define OR_CONN_STATE_TLS_HANDSHAKING 3
/** State for a connection to an OR: We're doing a second SSL handshake for
* renegotiation purposes. */
-#define OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING 5
+#define OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING 4
/** State for a connection at an OR: We're waiting for the client to
* renegotiate. */
-#define OR_CONN_STATE_TLS_SERVER_RENEGOTIATING 6
+#define OR_CONN_STATE_TLS_SERVER_RENEGOTIATING 5
/** State for a connection to an OR: We're done with our SSL handshake, but we
* haven't yet negotiated link protocol versions and sent a netinfo cell.
*/
-#define OR_CONN_STATE_OR_HANDSHAKING 7
+#define OR_CONN_STATE_OR_HANDSHAKING 6
/** State for a connection to an OR: Ready to send/receive cells. */
-#define OR_CONN_STATE_OPEN 8
-#define _OR_CONN_STATE_MAX 8
+#define OR_CONN_STATE_OPEN 7
+#define _OR_CONN_STATE_MAX 7
#define _EXIT_CONN_STATE_MIN 1
/** State for an exit connection: waiting for response from DNS farm. */
@@ -457,23 +467,23 @@ typedef enum {
#define CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED 11
/** Client-side circuit purpose: at Alice, rendezvous established. */
#define CIRCUIT_PURPOSE_C_REND_JOINED 12
-
-#define _CIRCUIT_PURPOSE_C_MAX 12
-
+/** This circuit is used for build time measurement only */
+#define CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT 13
+#define _CIRCUIT_PURPOSE_C_MAX 13
/** Hidden-service-side circuit purpose: at Bob, waiting for introductions. */
-#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO 13
+#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO 14
/** Hidden-service-side circuit purpose: at Bob, successfully established
* intro. */
-#define CIRCUIT_PURPOSE_S_INTRO 14
+#define CIRCUIT_PURPOSE_S_INTRO 15
/** Hidden-service-side circuit purpose: at Bob, connecting to rend point. */
-#define CIRCUIT_PURPOSE_S_CONNECT_REND 15
+#define CIRCUIT_PURPOSE_S_CONNECT_REND 16
/** Hidden-service-side circuit purpose: at Bob, rendezvous established. */
-#define CIRCUIT_PURPOSE_S_REND_JOINED 16
+#define CIRCUIT_PURPOSE_S_REND_JOINED 17
/** A testing circuit; not meant to be used for actual traffic. */
-#define CIRCUIT_PURPOSE_TESTING 17
+#define CIRCUIT_PURPOSE_TESTING 18
/** A controller made this circuit and Tor should not use it. */
-#define CIRCUIT_PURPOSE_CONTROLLER 18
-#define _CIRCUIT_PURPOSE_MAX 18
+#define CIRCUIT_PURPOSE_CONTROLLER 19
+#define _CIRCUIT_PURPOSE_MAX 19
/** A catch-all for unrecognized purposes. Currently we don't expect
* to make or see any circuits with this purpose. */
#define CIRCUIT_PURPOSE_UNKNOWN 255
@@ -483,7 +493,7 @@ typedef enum {
#define CIRCUIT_PURPOSE_IS_ORIGIN(p) ((p)>_CIRCUIT_PURPOSE_OR_MAX)
/** True iff the circuit purpose <b>p</b> is for a circuit that originated
* here to serve as a client. (Hidden services don't count here.) */
-#define CIRCUIT_PURPOSE_IS_CLIENT(p) \
+#define CIRCUIT_PURPOSE_IS_CLIENT(p) \
((p)> _CIRCUIT_PURPOSE_OR_MAX && \
(p)<=_CIRCUIT_PURPOSE_C_MAX)
/** True iff the circuit_t <b>c</b> is actually an origin_circuit_t. */
@@ -604,6 +614,10 @@ typedef enum {
/* Negative reasons are internal: we never send them in a DESTROY or TRUNCATE
* call; they only go to the controller for tracking */
+/** Our post-timeout circuit time measurement period expired.
+ * We must give up now */
+#define END_CIRC_REASON_MEASUREMENT_EXPIRED -3
+
/** We couldn't build a path for this circuit. */
#define END_CIRC_REASON_NOPATH -2
/** Catch-all "other" reason for closing origin circuits. */
@@ -641,10 +655,6 @@ typedef enum {
/** Length of a binary-encoded rendezvous service ID. */
#define REND_SERVICE_ID_LEN 10
-/** How long after we receive a hidden service descriptor do we consider
- * it fresh? */
-#define NUM_SECONDS_BEFORE_HS_REFETCH (60*15)
-
/** Time period for which a v2 descriptor will be valid. */
#define REND_TIME_PERIOD_V2_DESC_VALIDITY (24*60*60)
@@ -739,12 +749,6 @@ typedef struct rend_data_t {
/** Rendezvous cookie used by both, client and service. */
char rend_cookie[REND_COOKIE_LEN];
-
- /** Rendezvous descriptor version that is used by a service. Used to
- * distinguish introduction and rendezvous points belonging to the same
- * rendezvous service ID, but different descriptor versions.
- */
- uint8_t rend_desc_version;
} rend_data_t;
/** Time interval for tracking possible replays of INTRODUCE2 cells.
@@ -851,12 +855,28 @@ typedef struct packed_cell_t {
char body[CELL_NETWORK_SIZE]; /**< Cell as packed for network. */
} packed_cell_t;
+/** Number of cells added to a circuit queue including their insertion
+ * time on 10 millisecond detail; used for buffer statistics. */
+typedef struct insertion_time_elem_t {
+ struct insertion_time_elem_t *next; /**< Next element in queue. */
+ uint32_t insertion_time; /**< When were cells inserted (in 10 ms steps
+ * starting at 0:00 of the current day)? */
+ unsigned counter; /**< How many cells were inserted? */
+} insertion_time_elem_t;
+
+/** Queue of insertion times. */
+typedef struct insertion_time_queue_t {
+ struct insertion_time_elem_t *first; /**< First element in queue. */
+ struct insertion_time_elem_t *last; /**< Last element in queue. */
+} insertion_time_queue_t;
+
/** A queue of cells on a circuit, waiting to be added to the
* or_connection_t's outbuf. */
typedef struct cell_queue_t {
packed_cell_t *head; /**< The first cell, or NULL if the queue is empty. */
packed_cell_t *tail; /**< The last cell, or NULL if the queue is empty. */
int n; /**< The number of cells in the queue. */
+ insertion_time_queue_t *insertion_times; /**< Insertion times of cells. */
} cell_queue_t;
/** Beginning of a RELAY cell payload. */
@@ -912,7 +932,7 @@ typedef struct connection_t {
* again once the bandwidth throttler allows it? */
unsigned int write_blocked_on_bw:1; /**< Boolean: should we start writing
* again once the bandwidth throttler allows
- * reads? */
+ * writes? */
unsigned int hold_open_until_flushed:1; /**< Despite this connection's being
* marked for close, do we flush it
* before closing it? */
@@ -937,8 +957,11 @@ typedef struct connection_t {
* connection. */
unsigned int linked_conn_is_closed:1;
- int s; /**< Our socket; -1 if this connection is closed, or has no
- * socket. */
+ /** CONNECT/SOCKS proxy client handshake state (for outgoing connections). */
+ unsigned int proxy_state:4;
+
+ /** Our socket; -1 if this connection is closed, or has no socket. */
+ evutil_socket_t s;
int conn_array_index; /**< Index into the global connection array. */
struct event *read_event; /**< Libevent event structure. */
struct event *write_event; /**< Libevent event structure. */
@@ -980,6 +1003,8 @@ typedef struct connection_t {
* to the evdns_server_port is uses to listen to and answer connections. */
struct evdns_server_port *dns_server_port;
+ /** Unique ID for measuring tunneled network status requests. */
+ uint64_t dirreq_id;
} connection_t;
/** Stores flags and information related to the portion of a v2 Tor OR
@@ -1026,7 +1051,10 @@ typedef struct or_connection_t {
* NETINFO cell listed the address we're connected to as recognized. */
unsigned int is_canonical:1;
/** True iff this connection shouldn't get any new circs attached to it,
- * because the connection is too old, or because there's a better one, etc.
+ * because the connection is too old, or because there's a better one.
+ * More generally, this flag is used to note an unhealthy connection;
+ * for example, if a bad connection fails we shouldn't assume that the
+ * router itself has a problem.
*/
unsigned int is_bad_for_new_circs:1;
uint8_t link_proto; /**< What protocol version are we using? 0 for
@@ -1041,12 +1069,13 @@ typedef struct or_connection_t {
time_t timestamp_last_added_nonpadding; /** When did we last add a
* non-padding cell to the outbuf? */
- /* bandwidth* and read_bucket only used by ORs in OPEN state: */
+ /* bandwidth* and *_bucket only used by ORs in OPEN state: */
int bandwidthrate; /**< Bytes/s added to the bucket. (OPEN ORs only.) */
int bandwidthburst; /**< Max bucket size for this conn. (OPEN ORs only.) */
int read_bucket; /**< When this hits 0, stop receiving. Every second we
* add 'bandwidthrate' to this, capping it at
* bandwidthburst. (OPEN ORs only) */
+ int write_bucket; /**< When this hits 0, stop writing. Like read_bucket. */
int n_circuits; /**< How many circuits use this connection as p_conn or
* n_conn ? */
@@ -1054,6 +1083,17 @@ typedef struct or_connection_t {
* free up on this connection's outbuf. Every time we pull cells from a
* circuit, we advance this pointer to the next circuit in the ring. */
struct circuit_t *active_circuits;
+ /** Priority queue of cell_ewma_t for circuits with queued cells waiting for
+ * room to free up on this connection's outbuf. Kept in heap order
+ * according to EWMA.
+ *
+ * This is redundant with active_circuits; if we ever decide only to use the
+ * cell_ewma algorithm for choosing circuits, we can remove active_circuits.
+ */
+ smartlist_t *active_circuit_pqueue;
+ /** The tick on which the cell_ewma_ts in active_circuit_pqueue last had
+ * their ewma values rescaled. */
+ unsigned active_circuit_pqueue_last_recalibrated;
struct or_connection_t *next_with_same_id; /**< Next connection with same
* identity digest as this one. */
} or_connection_t;
@@ -1150,7 +1190,8 @@ typedef struct dir_connection_t {
enum {
DIR_SPOOL_NONE=0, DIR_SPOOL_SERVER_BY_DIGEST, DIR_SPOOL_SERVER_BY_FP,
DIR_SPOOL_EXTRA_BY_DIGEST, DIR_SPOOL_EXTRA_BY_FP,
- DIR_SPOOL_CACHED_DIR, DIR_SPOOL_NETWORKSTATUS
+ DIR_SPOOL_CACHED_DIR, DIR_SPOOL_NETWORKSTATUS,
+ DIR_SPOOL_MICRODESC, /* NOTE: if we add another entry, add another bit. */
} dir_spool_src : 3;
/** If we're fetching descriptors, what router purpose shall we assign
* to them? */
@@ -1178,12 +1219,6 @@ typedef struct control_connection_t {
uint32_t event_mask; /**< Bitfield: which events does this controller
* care about? */
- unsigned int use_long_names:1; /**< True if we should use long nicknames
- * on this (v1) connection. Only settable
- * via v1 controllers. */
- /** For control connections only. If set, we send extended info with control
- * events as appropriate. */
- unsigned int use_extended_events:1;
/** True if we have sent a protocolinfo reply on this connection. */
unsigned int have_sent_protocolinfo:1;
@@ -1267,6 +1302,7 @@ typedef struct cached_dir_t {
size_t dir_len; /**< Length of <b>dir</b> (not counting its NUL). */
size_t dir_z_len; /**< Length of <b>dir_z</b>. */
time_t published; /**< When was this object published. */
+ digests_t digests; /**< Digests of this object (networkstatus only) */
int refcnt; /**< Reference count for this cached_dir_t. */
} cached_dir_t;
@@ -1427,6 +1463,9 @@ typedef struct {
* directory according to the authorities. */
unsigned int policy_is_reject_star:1; /**< True iff the exit policy for this
* router rejects everything. */
+ /** True if, after we have added this router, we should re-launch
+ * tests for it. */
+ unsigned int needs_retest_if_added:1;
/** Tor can use this router for general positions in circuits. */
#define ROUTER_PURPOSE_GENERAL 0
@@ -1516,6 +1555,9 @@ typedef struct routerstatus_t {
unsigned int has_bandwidth:1; /**< The vote/consensus had bw info */
unsigned int has_exitsummary:1; /**< The vote/consensus had exit summaries */
+ unsigned int has_measured_bw:1; /**< The vote/consensus had a measured bw */
+
+ uint32_t measured_bw; /**< Measured bandwidth (capacity) of the router */
uint32_t bandwidth; /**< Bandwidth (capacity) of the router as reported in
* the vote/consensus, in kilobytes/sec. */
@@ -1540,6 +1582,52 @@ typedef struct routerstatus_t {
} routerstatus_t;
+/** A microdescriptor is the smallest amount of information needed to build a
+ * circuit through a router. They are generated by the directory authorities,
+ * using information from the uploaded routerinfo documents. They are not
+ * self-signed, but are rather authenticated by having their hash in a signed
+ * networkstatus document. */
+typedef struct microdesc_t {
+ /** Hashtable node, used to look up the microdesc by its digest. */
+ HT_ENTRY(microdesc_t) node;
+
+ /* Cache information */
+
+ /** When was this microdescriptor last listed in a consensus document?
+ * Once a microdesc has been unlisted long enough, we can drop it.
+ */
+ time_t last_listed;
+ /** Where is this microdescriptor currently stored? */
+ saved_location_t saved_location : 3;
+ /** If true, do not attempt to cache this microdescriptor on disk. */
+ unsigned int no_save : 1;
+ /** If saved_location == SAVED_IN_CACHE, this field holds the offset of the
+ * microdescriptor in the cache. */
+ off_t off;
+
+ /* The string containing the microdesc. */
+
+ /** A pointer to the encoded body of the microdescriptor. If the
+ * saved_location is SAVED_IN_CACHE, then the body is a pointer into an
+ * mmap'd region. Otherwise, it is a malloc'd string. The string might not
+ * be NUL-terminated; take the length from <b>bodylen</b>. */
+ char *body;
+ /** The length of the microdescriptor in <b>body</b>. */
+ size_t bodylen;
+ /** A SHA256-digest of the microdescriptor. */
+ char digest[DIGEST256_LEN];
+
+ /* Fields in the microdescriptor. */
+
+ /** As routerinfo_t.onion_pkey */
+ crypto_pk_env_t *onion_pkey;
+ /** As routerinfo_t.family */
+ smartlist_t *family;
+ /** Encoded exit policy summary */
+ char *exitsummary; /**< exit policy summary -
+ * XXX this probably should not stay a string. */
+} microdesc_t;
+
/** How many times will we try to download a router's descriptor before giving
* up? */
#define MAX_ROUTERDESC_DOWNLOAD_FAILURES 8
@@ -1582,6 +1670,11 @@ typedef struct networkstatus_v2_t {
* sorted by identity_digest. */
} networkstatus_v2_t;
+typedef struct vote_microdesc_hash_t {
+ struct vote_microdesc_hash_t *next;
+ char *microdesc_hash_line;
+} vote_microdesc_hash_t;
+
/** The claim about a single router, made in a vote. */
typedef struct vote_routerstatus_t {
routerstatus_t status; /**< Underlying 'status' object for this router.
@@ -1590,31 +1683,45 @@ typedef struct vote_routerstatus_t {
* networkstatus_t.known_flags. */
char *version; /**< The version that the authority says this router is
* running. */
+ vote_microdesc_hash_t *microdesc;
} vote_routerstatus_t;
+/** A signature of some document by an authority. */
+typedef struct document_signature_t {
+ /** Declared SHA-1 digest of this voter's identity key */
+ char identity_digest[DIGEST_LEN];
+ /** Declared SHA-1 digest of signing key used by this voter. */
+ char signing_key_digest[DIGEST_LEN];
+ /** Algorithm used to compute the digest of the document. */
+ digest_algorithm_t alg;
+ /** Signature of the signed thing. */
+ char *signature;
+ /** Length of <b>signature</b> */
+ int signature_len;
+ unsigned int bad_signature : 1; /**< Set to true if we've tried to verify
+ * the sig, and we know it's bad. */
+ unsigned int good_signature : 1; /**< Set to true if we've verified the sig
+ * as good. */
+} document_signature_t;
+
/** Information about a single voter in a vote or a consensus. */
typedef struct networkstatus_voter_info_t {
+ /** Declared SHA-1 digest of this voter's identity key */
+ char identity_digest[DIGEST_LEN];
char *nickname; /**< Nickname of this voter */
- char identity_digest[DIGEST_LEN]; /**< Digest of this voter's identity key */
+ /** Digest of this voter's "legacy" identity key, if any. In vote only; for
+ * consensuses, we treat legacy keys as additional signers. */
+ char legacy_id_digest[DIGEST_LEN];
char *address; /**< Address of this voter, in string format. */
uint32_t addr; /**< Address of this voter, in IPv4, in host order. */
uint16_t dir_port; /**< Directory port of this voter */
uint16_t or_port; /**< OR port of this voter */
char *contact; /**< Contact information for this voter. */
char vote_digest[DIGEST_LEN]; /**< Digest of this voter's vote, as signed. */
- /** Digest of this voter's "legacy" identity key, if any. In vote only; for
- * consensuses, we treat legacy keys as additional signers. */
- char legacy_id_digest[DIGEST_LEN];
/* Nothing from here on is signed. */
- char signing_key_digest[DIGEST_LEN]; /**< Declared digest of signing key
- * used by this voter. */
- char *signature; /**< Signature from this voter. */
- int signature_len; /**< Length of <b>signature</b> */
- unsigned int bad_signature : 1; /**< Set to true if we've tried to verify
- * the sig, and we know it's bad. */
- unsigned int good_signature : 1; /**< Set to true if we've verified the sig
- * as good. */
+ /** The signature of the document and the signature's status. */
+ smartlist_t *sigs;
} networkstatus_voter_info_t;
/** Enumerates the possible seriousness values of a networkstatus document. */
@@ -1624,10 +1731,25 @@ typedef enum {
NS_TYPE_OPINION,
} networkstatus_type_t;
+/** Enumerates recognized flavors of a consensus networkstatus document. All
+ * flavors of a consensus are generated from the same set of votes, but they
+ * present different types information to different versions of Tor. */
+typedef enum {
+ FLAV_NS = 0,
+ FLAV_MICRODESC = 1,
+} consensus_flavor_t;
+
+/** Which consensus flavor do we actually want to use to build circuits? */
+#define USABLE_CONSENSUS_FLAVOR FLAV_NS
+
+/** How many different consensus flavors are there? */
+#define N_CONSENSUS_FLAVORS ((int)(FLAV_MICRODESC)+1)
+
/** A common structure to hold a v3 network status vote, or a v3 network
* status consensus. */
typedef struct networkstatus_t {
- networkstatus_type_t type; /**< Vote, consensus, or opinion? */
+ networkstatus_type_t type : 8; /**< Vote, consensus, or opinion? */
+ consensus_flavor_t flavor : 8; /**< If a consensus, what kind? */
time_t published; /**< Vote only: Time when vote was written. */
time_t valid_after; /**< Time after which this vote or consensus applies. */
time_t fresh_until; /**< Time before which this is the most recent vote or
@@ -1659,6 +1781,10 @@ typedef struct networkstatus_t {
* consensus, sorted by key. */
smartlist_t *net_params;
+ /** List of key=value strings for the bw weight parameters in the
+ * consensus. */
+ smartlist_t *weight_params;
+
/** List of networkstatus_voter_info_t. For a vote, only one element
* is included. For a consensus, one element is included for every voter
* whose vote contributed to the consensus. */
@@ -1666,8 +1792,8 @@ typedef struct networkstatus_t {
struct authority_cert_t *cert; /**< Vote only: the voter's certificate. */
- /** Digest of this document, as signed. */
- char networkstatus_digest[DIGEST_LEN];
+ /** Digests of this document, as signed. */
+ digests_t digests;
/** List of router statuses, sorted by identity digest. For a vote,
* the elements are vote_routerstatus_t; for a consensus, the elements
@@ -1679,14 +1805,15 @@ typedef struct networkstatus_t {
digestmap_t *desc_digest_map;
} networkstatus_t;
-/** A set of signatures for a networkstatus consensus. All fields are as for
- * networkstatus_t. */
+/** A set of signatures for a networkstatus consensus. Unless otherwise
+ * noted, all fields are as for networkstatus_t. */
typedef struct ns_detached_signatures_t {
time_t valid_after;
time_t fresh_until;
time_t valid_until;
- char networkstatus_digest[DIGEST_LEN];
- smartlist_t *signatures; /* list of networkstatus_voter_info_t */
+ strmap_t *digests; /**< Map from flavor name to digestset_t */
+ strmap_t *signatures; /**< Map from flavor name to list of
+ * document_signature_t */
} ns_detached_signatures_t;
/** Allowable types of desc_store_t. */
@@ -1891,6 +2018,29 @@ typedef struct {
time_t expiry_time;
} cpath_build_state_t;
+/**
+ * The cell_ewma_t structure keeps track of how many cells a circuit has
+ * transferred recently. It keeps an EWMA (exponentially weighted moving
+ * average) of the number of cells flushed from the circuit queue onto a
+ * connection in connection_or_flush_from_first_active_circuit().
+ */
+typedef struct {
+ /** The last 'tick' at which we recalibrated cell_count.
+ *
+ * A cell sent at exactly the start of this tick has weight 1.0. Cells sent
+ * since the start of this tick have weight greater than 1.0; ones sent
+ * earlier have less weight. */
+ unsigned last_adjusted_tick;
+ /** The EWMA of the cell count. */
+ double cell_count;
+ /** True iff this is the cell count for a circuit's previous
+ * connection. */
+ unsigned int is_for_p_conn : 1;
+ /** The position of the circuit within the OR connection's priority
+ * queue. */
+ int heap_index;
+} cell_ewma_t;
+
#define ORIGIN_CIRCUIT_MAGIC 0x35315243u
#define OR_CIRCUIT_MAGIC 0x98ABC04Fu
@@ -1960,6 +2110,7 @@ typedef struct circuit_t {
time_t timestamp_created; /**< When was this circuit created? */
time_t timestamp_dirty; /**< When the circuit was first used, or 0 if the
* circuit is clean. */
+ struct timeval highres_created; /**< When exactly was the circuit created? */
uint16_t marked_for_close; /**< Should we close this circuit at the end of
* the main loop? (If true, holds the line number
@@ -1976,6 +2127,14 @@ typedef struct circuit_t {
* linked to an OR connection. */
struct circuit_t *prev_active_on_n_conn;
struct circuit_t *next; /**< Next circuit in linked list of all circuits. */
+
+ /** Unique ID for measuring tunneled network status requests. */
+ uint64_t dirreq_id;
+
+ /** The EWMA count for the number of cells flushed from the
+ * n_conn_cells queue. Used to determine which circuit to flush from next.
+ */
+ cell_ewma_t n_cell_ewma;
} circuit_t;
/** Largest number of relay_early cells that we can send on a given
@@ -2008,6 +2167,13 @@ typedef struct origin_circuit_t {
* to the specification? */
unsigned int remaining_relay_early_cells : 4;
+ /** Set if this circuit is insanely old and we already informed the user */
+ unsigned int is_ancient : 1;
+
+ /** Set if this circuit has already been opened. Used to detect
+ * cannibalized circuits. */
+ unsigned int has_opened : 1;
+
/** What commands were sent over this circuit that decremented the
* RELAY_EARLY counter? This is for debugging task 878. */
uint8_t relay_early_commands[MAX_RELAY_EARLY_CELLS_PER_CIRCUIT];
@@ -2098,6 +2264,19 @@ typedef struct or_circuit_t {
/** True iff this circuit was made with a CREATE_FAST cell. */
unsigned int is_first_hop : 1;
+
+ /** Number of cells that were removed from circuit queue; reset every
+ * time when writing buffer stats to disk. */
+ uint32_t processed_cells;
+
+ /** Total time in milliseconds that cells spent in both app-ward and
+ * exit-ward queues of this circuit; reset every time when writing
+ * buffer stats to disk. */
+ uint64_t total_cell_waiting_time;
+
+ /** The EWMA count for the number of cells flushed from the
+ * p_conn_cells queue. */
+ cell_ewma_t p_cell_ewma;
} or_circuit_t;
/** Convert a circuit subtype to a circuit_t.*/
@@ -2169,13 +2348,13 @@ typedef struct {
routerset_t *EntryNodes;/**< Structure containing nicknames, digests,
* country codes and IP address patterns of ORs to
* consider as entry points. */
- int StrictExitNodes; /**< Boolean: When none of our ExitNodes are up, do we
- * stop building circuits? */
- int StrictEntryNodes; /**< Boolean: When none of our EntryNodes are up, do we
- * stop building circuits? */
+ int StrictNodes; /**< Boolean: When none of our EntryNodes or ExitNodes
+ * are up, or we need to access a node in ExcludeNodes,
+ * do we just fail instead? */
routerset_t *ExcludeNodes;/**< Structure containing nicknames, digests,
* country codes and IP address patterns of ORs
- * not to use in circuits. */
+ * not to use in circuits. But see StrictNodes
+ * above. */
routerset_t *ExcludeExitNodes;/**< Structure containing nicknames, digests,
* country codes and IP address patterns of
* ORs not to consider as exits. */
@@ -2183,6 +2362,9 @@ typedef struct {
/** Union of ExcludeNodes and ExcludeExitNodes */
struct routerset_t *_ExcludeExitNodesUnion;
+ int DisableAllSwap; /**< Boolean: Attempt to call mlockall() on our
+ * process for all current and future memory. */
+
/** List of "entry", "middle", "exit", "introduction", "rendezvous". */
smartlist_t *AllowInvalidNodes;
/** Bitmask; derived from AllowInvalidNodes. */
@@ -2197,7 +2379,7 @@ typedef struct {
* connections. */
config_line_t *TransListenAddress;
/** Addresses to bind for listening for transparent natd connections */
- config_line_t *NatdListenAddress;
+ config_line_t *NATDListenAddress;
/** Addresses to bind for listening for SOCKS connections. */
config_line_t *DNSListenAddress;
/** Addresses to bind for listening for OR connections. */
@@ -2221,7 +2403,7 @@ typedef struct {
int SocksPort; /**< Port to listen on for SOCKS connections. */
/** Port to listen on for transparent pf/netfilter connections. */
int TransPort;
- int NatdPort; /**< Port to listen on for transparent natd connections. */
+ int NATDPort; /**< Port to listen on for transparent natd connections. */
int ControlPort; /**< Port to listen on for control connections. */
config_line_t *ControlSocket; /**< List of Unix Domain Sockets to listen on
* for control connections. */
@@ -2237,8 +2419,6 @@ typedef struct {
* for version 3 directories? */
int HSAuthoritativeDir; /**< Boolean: does this an authoritative directory
* handle hidden service requests? */
- int HSAuthorityRecordStats; /**< Boolean: does this HS authoritative
- * directory record statistics? */
int NamingAuthoritativeDir; /**< Boolean: is this an authoritative directory
* that's willing to bind names? */
int VersioningAuthoritativeDir; /**< Boolean: is this an authoritative
@@ -2267,8 +2447,6 @@ typedef struct {
int AvoidDiskWrites; /**< Boolean: should we never cache things to disk?
* Not used yet. */
int ClientOnly; /**< Boolean: should we never evolve into a server role? */
- /** Boolean: should we never publish a descriptor? Deprecated. */
- int NoPublish;
/** To what authority types do we publish our descriptor? Choices are
* "v1", "v2", "v3", "bridge", or "". */
smartlist_t *PublishServerDescriptor;
@@ -2299,6 +2477,14 @@ typedef struct {
int ConstrainedSockets; /**< Shrink xmit and recv socket buffers. */
uint64_t ConstrainedSockSize; /**< Size of constrained buffers. */
+ /** Whether we should drop exit streams from Tors that we don't know are
+ * relays. One of "0" (never refuse), "1" (always refuse), or "auto" (do
+ * what the consensus says, defaulting to 'refuse' if the consensus says
+ * nothing). */
+ char *RefuseUnknownExits;
+ /** Parsed version of RefuseUnknownExits. -1 for auto. */
+ int RefuseUnknownExits_;
+
/** Application ports that require all nodes in circ to have sufficient
* uptime. */
smartlist_t *LongLivedPorts;
@@ -2328,10 +2514,18 @@ typedef struct {
* connections alive? */
int SocksTimeout; /**< How long do we let a socks connection wait
* unattached before we fail it? */
- int CircuitBuildTimeout; /**< Cull non-open circuits that were born
- * at least this many seconds ago. */
+ int LearnCircuitBuildTimeout; /**< If non-zero, we attempt to learn a value
+ * for CircuitBuildTimeout based on timeout
+ * history */
+ int CircuitBuildTimeout; /**< Cull non-open circuits that were born at
+ * least this many seconds ago. Used until
+ * adaptive algorithm learns a new value. */
int CircuitIdleTimeout; /**< Cull open clean circuits that were born
* at least this many seconds ago. */
+ int CircuitStreamTimeout; /**< If non-zero, detach streams from circuits
+ * and try a new circuit if the stream has been
+ * waiting for this many seconds. If zero, use
+ * our default internal timeout schedule. */
int MaxOnionsPending; /**< How many circuit CREATE requests do we allow
* to wait simultaneously before we start dropping
* them? */
@@ -2349,24 +2543,36 @@ typedef struct {
* willing to use for all relayed conns? */
uint64_t RelayBandwidthBurst; /**< How much bandwidth, at maximum, will we
* use in a second for all relayed conns? */
- int NumCpus; /**< How many CPUs should we try to use? */
- int RunTesting; /**< If true, create testing circuits to measure how well the
- * other ORs are running. */
+ uint64_t PerConnBWRate; /**< Long-term bw on a single TLS conn, if set. */
+ uint64_t PerConnBWBurst; /**< Allowed burst on a single TLS conn, if set. */
+ int NumCPUs; /**< How many CPUs should we try to use? */
+//int RunTesting; /**< If true, create testing circuits to measure how well the
+// * other ORs are running. */
config_line_t *RendConfigLines; /**< List of configuration lines
* for rendezvous services. */
config_line_t *HidServAuth; /**< List of configuration lines for client-side
* authorizations for hidden services */
char *ContactInfo; /**< Contact info to be published in the directory. */
- char *HttpProxy; /**< hostname[:port] to use as http proxy, if any. */
- uint32_t HttpProxyAddr; /**< Parsed IPv4 addr for http proxy, if any. */
- uint16_t HttpProxyPort; /**< Parsed port for http proxy, if any. */
- char *HttpProxyAuthenticator; /**< username:password string, if any. */
+ char *HTTPProxy; /**< hostname[:port] to use as http proxy, if any. */
+ tor_addr_t HTTPProxyAddr; /**< Parsed IPv4 addr for http proxy, if any. */
+ uint16_t HTTPProxyPort; /**< Parsed port for http proxy, if any. */
+ char *HTTPProxyAuthenticator; /**< username:password string, if any. */
+
+ char *HTTPSProxy; /**< hostname[:port] to use as https proxy, if any. */
+ tor_addr_t HTTPSProxyAddr; /**< Parsed addr for https proxy, if any. */
+ uint16_t HTTPSProxyPort; /**< Parsed port for https proxy, if any. */
+ char *HTTPSProxyAuthenticator; /**< username:password string, if any. */
- char *HttpsProxy; /**< hostname[:port] to use as https proxy, if any. */
- uint32_t HttpsProxyAddr; /**< Parsed IPv4 addr for https proxy, if any. */
- uint16_t HttpsProxyPort; /**< Parsed port for https proxy, if any. */
- char *HttpsProxyAuthenticator; /**< username:password string, if any. */
+ char *Socks4Proxy; /**< hostname:port to use as a SOCKS4 proxy, if any. */
+ tor_addr_t Socks4ProxyAddr; /**< Derived from Socks4Proxy. */
+ uint16_t Socks4ProxyPort; /**< Derived from Socks4Proxy. */
+
+ char *Socks5Proxy; /**< hostname:port to use as a SOCKS5 proxy, if any. */
+ tor_addr_t Socks5ProxyAddr; /**< Derived from Sock5Proxy. */
+ uint16_t Socks5ProxyPort; /**< Derived from Socks5Proxy. */
+ char *Socks5ProxyUsername; /**< Username for SOCKS5 authentication, if any */
+ char *Socks5ProxyPassword; /**< Password for SOCKS5 authentication, if any */
/** List of configuration lines for replacement directory authorities.
* If you just want to replace one class of authority at a time,
@@ -2429,8 +2635,13 @@ typedef struct {
* or not (1)? */
int ShutdownWaitLength; /**< When we get a SIGINT and we're a server, how
* long do we wait before exiting? */
- int SafeLogging; /**< Boolean: are we allowed to log sensitive strings
- * such as addresses (0), or do we scrub them first (1)? */
+ char *SafeLogging; /**< Contains "relay", "1", "0" (meaning no scrubbing). */
+
+ /* Derived from SafeLogging */
+ enum {
+ SAFELOG_SCRUB_ALL, SAFELOG_SCRUB_RELAY, SAFELOG_SCRUB_NONE
+ } _SafeLogging;
+
int SafeSocks; /**< Boolean: should we outright refuse application
* connections that use socks4 or socks5-with-local-dns? */
#define LOG_PROTOCOL_WARN (get_options()->ProtocolWarnings ? \
@@ -2441,6 +2652,8 @@ typedef struct {
* log whether it was DNS-leaking or not? */
int HardwareAccel; /**< Boolean: Should we enable OpenSSL hardware
* acceleration where available? */
+ char *AccelName; /**< Optional hardware acceleration engine name. */
+ char *AccelDir; /**< Optional hardware acceleration engine search dir. */
int UseEntryGuards; /**< Boolean: Do we try to enter from a smallish number
* of fixed nodes? */
int NumEntryGuards; /**< How many entry guards do we try to establish? */
@@ -2451,6 +2664,9 @@ typedef struct {
* means directly from the authorities) no matter our other config? */
int FetchDirInfoEarly;
+ /** Should we fetch our dir info at the start of the consensus period? */
+ int FetchDirInfoExtraEarly;
+
char *VirtualAddrNetwork; /**< Address and mask to hand out for virtual
* MAPADDRESS requests. */
int ServerDNSSearchDomains; /**< Boolean: If set, we don't force exit
@@ -2499,6 +2715,33 @@ typedef struct {
* exit allows it, we use it. */
int AllowSingleHopCircuits;
+ /** If true, we convert "www.google.com.foo.exit" addresses on the
+ * socks/trans/natd ports into "www.google.com" addresses that
+ * exit from the node "foo". Disabled by default since attacking
+ * websites and exit relays can use it to manipulate your path
+ * selection. */
+ int AllowDotExit;
+
+ /** If true, we will warn if a user gives us only an IP address
+ * instead of a hostname. */
+ int WarnUnsafeSocks;
+
+ /** If true, the user wants us to collect statistics on clients
+ * requesting network statuses from us as directory. */
+ int DirReqStatistics;
+
+ /** If true, the user wants us to collect statistics on port usage. */
+ int ExitPortStatistics;
+
+ /** If true, the user wants us to collect cell statistics. */
+ int CellStatistics;
+
+ /** If true, the user wants us to collect statistics as entry node. */
+ int EntryStatistics;
+
+ /** If true, include statistics file contents in extra-info documents. */
+ int ExtraInfoStatistics;
+
/** If true, do not believe anybody who tells us that a domain resolves
* to an internal address, or that an internal address has a PTR mapping.
* Helps avoid some cross-site attacks. */
@@ -2517,6 +2760,13 @@ typedef struct {
* migration purposes? */
int V3AuthUseLegacyKey;
+ /** Location of bandwidth measurement file */
+ char *V3BandwidthsFile;
+
+ /** Authority only: key=value pairs that we add to our networkstatus
+ * consensus vote on the 'params' line. */
+ char *ConsensusParams;
+
/** The length of time that we think an initial consensus should be fresh.
* Only altered on testing networks. */
int TestingV3AuthInitialVotingInterval;
@@ -2553,19 +2803,6 @@ typedef struct {
* the bridge authority guess which countries have blocked access to us. */
int BridgeRecordUsageByCountry;
-#ifdef ENABLE_GEOIP_STATS
- /** If true, and Tor is built with GEOIP_STATS support, and we're a
- * directory, record how many directory requests we get from each country. */
- int DirRecordUsageByCountry;
- /** Round all GeoIP results to the next multiple of this value, to avoid
- * leaking information. */
- int DirRecordUsageGranularity;
- /** Time interval: purge geoip stats after this long. */
- int DirRecordUsageRetainIPs;
- /** Time interval: Flush geoip data to disk this often. */
- int DirRecordUsageSaveInterval;
-#endif
-
/** Optionally, a file with GeoIP data. */
char *GeoIPFile;
@@ -2573,6 +2810,21 @@ typedef struct {
* to make this false. */
int ReloadTorrcOnSIGHUP;
+ /* The main parameter for picking circuits within a connection.
+ *
+ * If this value is positive, when picking a cell to relay on a connection,
+ * we always relay from the circuit whose weighted cell count is lowest.
+ * Cells are weighted exponentially such that if one cell is sent
+ * 'CircuitPriorityHalflife' seconds before another, it counts for half as
+ * much.
+ *
+ * If this value is zero, we're disabling the cell-EWMA algorithm.
+ *
+ * If this value is negative, we're using the default approach
+ * according to either Tor or a parameter set in the consensus.
+ */
+ double CircuitPriorityHalflife;
+
} or_options_t;
/** Persistent state for an onion router, as saved to disk. */
@@ -2591,6 +2843,9 @@ typedef struct {
uint64_t AccountingBytesReadInInterval;
uint64_t AccountingBytesWrittenInInterval;
int AccountingSecondsActive;
+ int AccountingSecondsToReachSoftLimit;
+ time_t AccountingSoftLimitHitAt;
+ uint64_t AccountingBytesAtSoftLimit;
uint64_t AccountingExpectedUsage;
/** A list of Entry Guard-related configuration lines. */
@@ -2608,6 +2863,17 @@ typedef struct {
time_t BWHistoryWriteEnds;
int BWHistoryWriteInterval;
smartlist_t *BWHistoryWriteValues;
+ time_t BWHistoryDirReadEnds;
+ int BWHistoryDirReadInterval;
+ smartlist_t *BWHistoryDirReadValues;
+ time_t BWHistoryDirWriteEnds;
+ int BWHistoryDirWriteInterval;
+ smartlist_t *BWHistoryDirWriteValues;
+
+ /** Build time histogram */
+ config_line_t * BuildtimeHistogram;
+ unsigned int TotalBuildTimes;
+ unsigned int CircuitBuildAbandonedCount;
/** What version of Tor wrote this state file? */
char *TorVersion;
@@ -2669,209 +2935,120 @@ struct socks_request_t {
/* all the function prototypes go here */
-/********************************* buffers.c ***************************/
-
-buf_t *buf_new(void);
-buf_t *buf_new_with_capacity(size_t size);
-void buf_free(buf_t *buf);
-void buf_clear(buf_t *buf);
-void buf_shrink(buf_t *buf);
-void buf_shrink_freelists(int free_all);
-void buf_dump_freelist_sizes(int severity);
-
-size_t buf_datalen(const buf_t *buf);
-size_t buf_allocation(const buf_t *buf);
-size_t buf_slack(const buf_t *buf);
-const char *_buf_peek_raw_buffer(const buf_t *buf);
-
-int read_to_buf(int s, size_t at_most, buf_t *buf, int *reached_eof,
- int *socket_error);
-int read_to_buf_tls(tor_tls_t *tls, size_t at_most, buf_t *buf);
-
-int flush_buf(int s, buf_t *buf, size_t sz, size_t *buf_flushlen);
-int flush_buf_tls(tor_tls_t *tls, buf_t *buf, size_t sz, size_t *buf_flushlen);
-
-int write_to_buf(const char *string, size_t string_len, buf_t *buf);
-int write_to_buf_zlib(buf_t *buf, tor_zlib_state_t *state,
- const char *data, size_t data_len, int done);
-int move_buf_to_buf(buf_t *buf_out, buf_t *buf_in, size_t *buf_flushlen);
-int fetch_from_buf(char *string, size_t string_len, buf_t *buf);
-int fetch_var_cell_from_buf(buf_t *buf, var_cell_t **out, int linkproto);
-int fetch_from_buf_http(buf_t *buf,
- char **headers_out, size_t max_headerlen,
- char **body_out, size_t *body_used, size_t max_bodylen,
- int force_complete);
-int fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
- int log_sockstype, int safe_socks);
-int fetch_from_buf_line(buf_t *buf, char *data_out, size_t *data_len);
-
-int peek_buf_has_control0_command(buf_t *buf);
-
-void assert_buf_ok(buf_t *buf);
-
-#ifdef BUFFERS_PRIVATE
-int buf_find_string_offset(const buf_t *buf, const char *s, size_t n);
-#endif
-
/********************************* circuitbuild.c **********************/
-char *circuit_list_path(origin_circuit_t *circ, int verbose);
-char *circuit_list_path_for_controller(origin_circuit_t *circ);
-void circuit_log_path(int severity, unsigned int domain,
- origin_circuit_t *circ);
-void circuit_rep_hist_note_result(origin_circuit_t *circ);
-origin_circuit_t *origin_circuit_init(uint8_t purpose, int flags);
-origin_circuit_t *circuit_establish_circuit(uint8_t purpose,
- extend_info_t *exit,
- int flags);
-int circuit_handle_first_hop(origin_circuit_t *circ);
-void circuit_n_conn_done(or_connection_t *or_conn, int status);
-int inform_testing_reachability(void);
-int circuit_send_next_onion_skin(origin_circuit_t *circ);
-void circuit_note_clock_jumped(int seconds_elapsed);
-int circuit_extend(cell_t *cell, circuit_t *circ);
-int circuit_init_cpath_crypto(crypt_path_t *cpath, const char *key_data,
- int reverse);
-int circuit_finish_handshake(origin_circuit_t *circ, uint8_t cell_type,
- const uint8_t *reply);
-int circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer);
-int onionskin_answer(or_circuit_t *circ, uint8_t cell_type,
- const char *payload, const char *keys);
-int circuit_all_predicted_ports_handled(time_t now, int *need_uptime,
- int *need_capacity);
-
-int circuit_append_new_exit(origin_circuit_t *circ, extend_info_t *info);
-int circuit_extend_to_new_exit(origin_circuit_t *circ, extend_info_t *info);
-void onion_append_to_cpath(crypt_path_t **head_ptr, crypt_path_t *new_hop);
-extend_info_t *extend_info_alloc(const char *nickname, const char *digest,
- crypto_pk_env_t *onion_key,
- const tor_addr_t *addr, uint16_t port);
-extend_info_t *extend_info_from_router(routerinfo_t *r);
-extend_info_t *extend_info_dup(extend_info_t *info);
-void extend_info_free(extend_info_t *info);
-routerinfo_t *build_state_get_exit_router(cpath_build_state_t *state);
-const char *build_state_get_exit_nickname(cpath_build_state_t *state);
-
-void entry_guards_compute_status(void);
-int entry_guard_register_connect_status(const char *digest, int succeeded,
- int mark_relay_status, time_t now);
-void entry_nodes_should_be_added(void);
-int entry_list_can_grow(or_options_t *options);
-routerinfo_t *choose_random_entry(cpath_build_state_t *state);
-int entry_guards_parse_state(or_state_t *state, int set, char **msg);
-void entry_guards_update_state(or_state_t *state);
-int getinfo_helper_entry_guards(control_connection_t *conn,
- const char *question, char **answer);
-
-void clear_bridge_list(void);
-int routerinfo_is_a_configured_bridge(routerinfo_t *ri);
-void bridge_add_from_config(const tor_addr_t *addr, uint16_t port,
- char *digest);
-void retry_bridge_descriptor_fetch_directly(const char *digest);
-void fetch_bridge_descriptors(time_t now);
-void learned_bridge_descriptor(routerinfo_t *ri, int from_cache);
-int any_bridge_descriptors_known(void);
-int any_pending_bridge_descriptor_fetches(void);
-int bridges_known_but_down(void);
-void bridges_retry_all(void);
-
-void entry_guards_free_all(void);
-
-/********************************* circuitlist.c ***********************/
-
-circuit_t * _circuit_get_global_list(void);
-const char *circuit_state_to_string(int state);
-const char *circuit_purpose_to_controller_string(uint8_t purpose);
-void circuit_dump_by_conn(connection_t *conn, int severity);
-void circuit_set_p_circid_orconn(or_circuit_t *circ, circid_t id,
- or_connection_t *conn);
-void circuit_set_n_circid_orconn(circuit_t *circ, circid_t id,
- or_connection_t *conn);
-void circuit_set_state(circuit_t *circ, uint8_t state);
-void circuit_close_all_marked(void);
-int32_t circuit_initial_package_window(void);
-origin_circuit_t *origin_circuit_new(void);
-or_circuit_t *or_circuit_new(circid_t p_circ_id, or_connection_t *p_conn);
-circuit_t *circuit_get_by_circid_orconn(circid_t circ_id,
- or_connection_t *conn);
-int circuit_id_in_use_on_orconn(circid_t circ_id, or_connection_t *conn);
-circuit_t *circuit_get_by_edge_conn(edge_connection_t *conn);
-void circuit_unlink_all_from_or_conn(or_connection_t *conn, int reason);
-origin_circuit_t *circuit_get_by_global_id(uint32_t id);
-origin_circuit_t *circuit_get_by_rend_query_and_purpose(const char *rend_query,
- uint8_t purpose);
-origin_circuit_t *circuit_get_next_by_pk_and_purpose(origin_circuit_t *start,
- const char *digest, uint8_t purpose);
-or_circuit_t *circuit_get_rendezvous(const char *cookie);
-or_circuit_t *circuit_get_intro_point(const char *digest);
-origin_circuit_t *circuit_find_to_cannibalize(uint8_t purpose,
- extend_info_t *info, int flags);
-void circuit_mark_all_unused_circs(void);
-void circuit_expire_all_dirty_circs(void);
-void _circuit_mark_for_close(circuit_t *circ, int reason,
- int line, const char *file);
-int circuit_get_cpath_len(origin_circuit_t *circ);
-crypt_path_t *circuit_get_cpath_hop(origin_circuit_t *circ, int hopnum);
-void circuit_get_all_pending_on_or_conn(smartlist_t *out,
- or_connection_t *or_conn);
-int circuit_count_pending_on_or_conn(or_connection_t *or_conn);
-
-#define circuit_mark_for_close(c, reason) \
- _circuit_mark_for_close((c), (reason), __LINE__, _SHORT_FILE_)
-
-void assert_cpath_layer_ok(const crypt_path_t *cp);
-void assert_circuit_ok(const circuit_t *c);
-void circuit_free_all(void);
-
-/********************************* circuituse.c ************************/
-
-void circuit_expire_building(time_t now);
-void circuit_remove_handled_ports(smartlist_t *needed_ports);
-int circuit_stream_is_being_handled(edge_connection_t *conn, uint16_t port,
- int min);
-int circuit_conforms_to_options(const origin_circuit_t *circ,
- const or_options_t *options);
-void circuit_build_needed_circs(time_t now);
-void circuit_detach_stream(circuit_t *circ, edge_connection_t *conn);
-
-void circuit_expire_old_circuits_serverside(time_t now);
-
-void reset_bandwidth_test(void);
-int circuit_enough_testing_circs(void);
-
-void circuit_has_opened(origin_circuit_t *circ);
-void circuit_build_failed(origin_circuit_t *circ);
-
-/** Flag to set when a circuit should have only a single hop. */
-#define CIRCLAUNCH_ONEHOP_TUNNEL (1<<0)
-/** Flag to set when a circuit needs to be built of high-uptime nodes */
-#define CIRCLAUNCH_NEED_UPTIME (1<<1)
-/** Flag to set when a circuit needs to be built of high-capacity nodes */
-#define CIRCLAUNCH_NEED_CAPACITY (1<<2)
-/** Flag to set when the last hop of a circuit doesn't need to be an
- * exit node. */
-#define CIRCLAUNCH_IS_INTERNAL (1<<3)
-origin_circuit_t *circuit_launch_by_extend_info(uint8_t purpose,
- extend_info_t *info,
- int flags);
-origin_circuit_t *circuit_launch_by_router(uint8_t purpose,
- routerinfo_t *exit, int flags);
-void circuit_reset_failure_count(int timeout);
-int connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn,
- origin_circuit_t *circ,
- crypt_path_t *cpath);
-int connection_ap_handshake_attach_circuit(edge_connection_t *conn);
-
-/********************************* command.c ***************************/
-
-void command_process_cell(cell_t *cell, or_connection_t *conn);
-void command_process_var_cell(var_cell_t *cell, or_connection_t *conn);
-
-extern uint64_t stats_n_padding_cells_processed;
-extern uint64_t stats_n_create_cells_processed;
-extern uint64_t stats_n_created_cells_processed;
-extern uint64_t stats_n_relay_cells_processed;
-extern uint64_t stats_n_destroy_cells_processed;
+/** How many hops does a general-purpose circuit have by default? */
+#define DEFAULT_ROUTE_LEN 3
+
+/* Circuit Build Timeout "public" structures. */
+
+/** Total size of the circuit timeout history to accumulate.
+ * 1000 is approx 2.5 days worth of continual-use circuits. */
+#define CBT_NCIRCUITS_TO_OBSERVE 1000
+
+/** Width of the histogram bins in milliseconds */
+#define CBT_BIN_WIDTH ((build_time_t)50)
+
+/** Number of modes to use in the weighted-avg computation of Xm */
+#define CBT_DEFAULT_NUM_XM_MODES 3
+
+/** A build_time_t is milliseconds */
+typedef uint32_t build_time_t;
+
+/**
+ * CBT_BUILD_ABANDONED is our flag value to represent a force-closed
+ * circuit (Aka a 'right-censored' pareto value).
+ */
+#define CBT_BUILD_ABANDONED ((build_time_t)(INT32_MAX-1))
+#define CBT_BUILD_TIME_MAX ((build_time_t)(INT32_MAX))
+
+/** Save state every 10 circuits */
+#define CBT_SAVE_STATE_EVERY 10
+
+/* Circuit build times consensus parameters */
+
+/**
+ * How long to wait before actually closing circuits that take too long to
+ * build in terms of CDF quantile.
+ */
+#define CBT_DEFAULT_CLOSE_QUANTILE 95
+
+/**
+ * How many circuits count as recent when considering if the
+ * connection has gone gimpy or changed.
+ */
+#define CBT_DEFAULT_RECENT_CIRCUITS 20
+
+/**
+ * Maximum count of timeouts that finish the first hop in the past
+ * RECENT_CIRCUITS before calculating a new timeout.
+ *
+ * This tells us whether to abandon timeout history and set
+ * the timeout back to whatever circuit_build_times_get_initial_timeout()
+ * gives us.
+ */
+#define CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT (CBT_DEFAULT_RECENT_CIRCUITS*9/10)
+
+/** Minimum circuits before estimating a timeout */
+#define CBT_DEFAULT_MIN_CIRCUITS_TO_OBSERVE 100
+
+/** Cutoff percentile on the CDF for our timeout estimation. */
+#define CBT_DEFAULT_QUANTILE_CUTOFF 80
+double circuit_build_times_quantile_cutoff(void);
+
+/** How often in seconds should we build a test circuit */
+#define CBT_DEFAULT_TEST_FREQUENCY 60
+
+/** Lowest allowable value for CircuitBuildTimeout in milliseconds */
+#define CBT_DEFAULT_TIMEOUT_MIN_VALUE (1500)
+
+/** Initial circuit build timeout in milliseconds */
+#define CBT_DEFAULT_TIMEOUT_INITIAL_VALUE (60*1000)
+int32_t circuit_build_times_initial_timeout(void);
+
+#if CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT < 1
+#error "RECENT_CIRCUITS is set too low."
+#endif
+
+/** Information about the state of our local network connection */
+typedef struct {
+ /** The timestamp we last completed a TLS handshake or received a cell */
+ time_t network_last_live;
+ /** If the network is not live, how many timeouts has this caused? */
+ int nonlive_timeouts;
+ /** Circular array of circuits that have made it to the first hop. Slot is
+ * 1 if circuit timed out, 0 if circuit succeeded */
+ int8_t *timeouts_after_firsthop;
+ /** Number of elements allocated for the above array */
+ int num_recent_circs;
+ /** Index into circular array. */
+ int after_firsthop_idx;
+} network_liveness_t;
+
+/** Structure for circuit build times history */
+typedef struct {
+ /** The circular array of recorded build times in milliseconds */
+ build_time_t circuit_build_times[CBT_NCIRCUITS_TO_OBSERVE];
+ /** Current index in the circuit_build_times circular array */
+ int build_times_idx;
+ /** Total number of build times accumulated. Max CBT_NCIRCUITS_TO_OBSERVE */
+ int total_build_times;
+ /** Information about the state of our local network connection */
+ network_liveness_t liveness;
+ /** Last time we built a circuit. Used to decide to build new test circs */
+ time_t last_circ_at;
+ /** "Minimum" value of our pareto distribution (actually mode) */
+ build_time_t Xm;
+ /** alpha exponent for pareto dist. */
+ double alpha;
+ /** Have we computed a timeout? */
+ int have_computed_timeout;
+ /** The exact value for that timeout in milliseconds. Stored as a double
+ * to maintain precision from calculations to and from quantile value. */
+ double timeout_ms;
+ /** How long we wait before actually closing the circuit. */
+ double close_ms;
+} circuit_build_times_t;
/********************************* config.c ***************************/
@@ -2884,203 +3061,8 @@ typedef enum setopt_err_t {
SETOPT_ERR_SETTING = -4,
} setopt_err_t;
-const char *get_dirportfrontpage(void);
-or_options_t *get_options(void);
-int set_options(or_options_t *new_val, char **msg);
-void config_free_all(void);
-const char *safe_str(const char *address);
-const char *escaped_safe_str(const char *address);
-const char *get_version(void);
-
-int config_get_lines(const char *string, config_line_t **result);
-void config_free_lines(config_line_t *front);
-setopt_err_t options_trial_assign(config_line_t *list, int use_defaults,
- int clear_first, char **msg);
-int resolve_my_address(int warn_severity, or_options_t *options,
- uint32_t *addr, char **hostname_out);
-int is_local_addr(const tor_addr_t *addr) ATTR_PURE;
-void options_init(or_options_t *options);
-int options_init_from_torrc(int argc, char **argv);
-setopt_err_t options_init_from_string(const char *cf,
- int command, const char *command_arg, char **msg);
-int option_is_recognized(const char *key);
-const char *option_get_canonical_name(const char *key);
-config_line_t *option_get_assignment(or_options_t *options,
- const char *key);
-int options_save_current(void);
-const char *get_torrc_fname(void);
-char *options_get_datadir_fname2_suffix(or_options_t *options,
- const char *sub1, const char *sub2,
- const char *suffix);
-#define get_datadir_fname2_suffix(sub1, sub2, suffix) \
- options_get_datadir_fname2_suffix(get_options(), (sub1), (sub2), (suffix))
-/** Return a newly allocated string containing datadir/sub1. See
- * get_datadir_fname2_suffix. */
-#define get_datadir_fname(sub1) get_datadir_fname2_suffix((sub1), NULL, NULL)
-/** Return a newly allocated string containing datadir/sub1/sub2. See
- * get_datadir_fname2_suffix. */
-#define get_datadir_fname2(sub1,sub2) \
- get_datadir_fname2_suffix((sub1), (sub2), NULL)
-/** Return a newly allocated string containing datadir/sub1suffix. See
- * get_datadir_fname2_suffix. */
-#define get_datadir_fname_suffix(sub1, suffix) \
- get_datadir_fname2_suffix((sub1), NULL, (suffix))
-
-or_state_t *get_or_state(void);
-int or_state_save(time_t now);
-
-int options_need_geoip_info(or_options_t *options, const char **reason_out);
-int getinfo_helper_config(control_connection_t *conn,
- const char *question, char **answer);
-
-uint32_t get_effective_bwrate(or_options_t *options);
-uint32_t get_effective_bwburst(or_options_t *options);
-
-#ifdef CONFIG_PRIVATE
-/* Used only by config.c and test.c */
-or_options_t *options_new(void);
-#endif
-
-/********************************* connection.c ***************************/
-
-const char *conn_type_to_string(int type);
-const char *conn_state_to_string(int type, int state);
-
-dir_connection_t *dir_connection_new(int socket_family);
-or_connection_t *or_connection_new(int socket_family);
-edge_connection_t *edge_connection_new(int type, int socket_family);
-control_connection_t *control_connection_new(int socket_family);
-connection_t *connection_new(int type, int socket_family);
-
-void connection_link_connections(connection_t *conn_a, connection_t *conn_b);
-void connection_unregister_events(connection_t *conn);
-void connection_free(connection_t *conn);
-void connection_free_all(void);
-void connection_about_to_close_connection(connection_t *conn);
-void connection_close_immediate(connection_t *conn);
-void _connection_mark_for_close(connection_t *conn,int line, const char *file);
-
-#define connection_mark_for_close(c) \
- _connection_mark_for_close((c), __LINE__, _SHORT_FILE_)
-
-void connection_expire_held_open(void);
-
-int connection_connect(connection_t *conn, const char *address,
- const tor_addr_t *addr,
- uint16_t port, int *socket_error);
-int retry_all_listeners(smartlist_t *replaced_conns,
- smartlist_t *new_conns);
-
-ssize_t connection_bucket_write_limit(connection_t *conn, time_t now);
-int global_write_bucket_low(connection_t *conn, size_t attempt, int priority);
-void connection_bucket_init(void);
-void connection_bucket_refill(int seconds_elapsed, time_t now);
-
-int connection_handle_read(connection_t *conn);
-
-int connection_fetch_from_buf(char *string, size_t len, connection_t *conn);
-
-int connection_wants_to_flush(connection_t *conn);
-int connection_outbuf_too_full(connection_t *conn);
-int connection_handle_write(connection_t *conn, int force);
-void _connection_write_to_buf_impl(const char *string, size_t len,
- connection_t *conn, int zlib);
-static void connection_write_to_buf(const char *string, size_t len,
- connection_t *conn);
-static void connection_write_to_buf_zlib(const char *string, size_t len,
- dir_connection_t *conn, int done);
-static INLINE void
-connection_write_to_buf(const char *string, size_t len, connection_t *conn)
-{
- _connection_write_to_buf_impl(string, len, conn, 0);
-}
-static INLINE void
-connection_write_to_buf_zlib(const char *string, size_t len,
- dir_connection_t *conn, int done)
-{
- _connection_write_to_buf_impl(string, len, TO_CONN(conn), done ? -1 : 1);
-}
-
-connection_t *connection_get_by_global_id(uint64_t id);
-
-connection_t *connection_get_by_type(int type);
-connection_t *connection_get_by_type_purpose(int type, int purpose);
-connection_t *connection_get_by_type_addr_port_purpose(int type,
- const tor_addr_t *addr,
- uint16_t port, int purpose);
-connection_t *connection_get_by_type_state(int type, int state);
-connection_t *connection_get_by_type_state_rendquery(int type, int state,
- const char *rendquery,
- int rendversion);
-
-#define connection_speaks_cells(conn) ((conn)->type == CONN_TYPE_OR)
-int connection_is_listener(connection_t *conn);
-int connection_state_is_open(connection_t *conn);
-int connection_state_is_connecting(connection_t *conn);
-
-char *alloc_http_authenticator(const char *authenticator);
-
-void assert_connection_ok(connection_t *conn, time_t now);
-int connection_or_nonopen_was_started_here(or_connection_t *conn);
-void connection_dump_buffer_mem_stats(int severity);
-void remove_file_if_very_old(const char *fname, time_t now);
-
/********************************* connection_edge.c *************************/
-#define connection_mark_unattached_ap(conn, endreason) \
- _connection_mark_unattached_ap((conn), (endreason), __LINE__, _SHORT_FILE_)
-
-void _connection_mark_unattached_ap(edge_connection_t *conn, int endreason,
- int line, const char *file);
-int connection_edge_reached_eof(edge_connection_t *conn);
-int connection_edge_process_inbuf(edge_connection_t *conn,
- int package_partial);
-int connection_edge_destroy(circid_t circ_id, edge_connection_t *conn);
-int connection_edge_end(edge_connection_t *conn, uint8_t reason);
-int connection_edge_end_errno(edge_connection_t *conn);
-int connection_edge_finished_flushing(edge_connection_t *conn);
-int connection_edge_finished_connecting(edge_connection_t *conn);
-
-int connection_ap_handshake_send_begin(edge_connection_t *ap_conn);
-int connection_ap_handshake_send_resolve(edge_connection_t *ap_conn);
-
-edge_connection_t *connection_ap_make_link(char *address, uint16_t port,
- const char *digest,
- int use_begindir, int want_onehop);
-void connection_ap_handshake_socks_reply(edge_connection_t *conn, char *reply,
- size_t replylen,
- int endreason);
-void connection_ap_handshake_socks_resolved(edge_connection_t *conn,
- int answer_type,
- size_t answer_len,
- const uint8_t *answer,
- int ttl,
- time_t expires);
-
-int connection_exit_begin_conn(cell_t *cell, circuit_t *circ);
-int connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ);
-void connection_exit_connect(edge_connection_t *conn);
-int connection_edge_is_rendezvous_stream(edge_connection_t *conn);
-int connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit);
-void connection_ap_expire_beginning(void);
-void connection_ap_attach_pending(void);
-void connection_ap_fail_onehop(const char *failed_digest,
- cpath_build_state_t *build_state);
-void circuit_discard_optional_exit_enclaves(extend_info_t *info);
-int connection_ap_detach_retriable(edge_connection_t *conn,
- origin_circuit_t *circ,
- int reason);
-int connection_ap_process_transparent(edge_connection_t *conn);
-
-int address_is_invalid_destination(const char *address, int client);
-
-void addressmap_init(void);
-void addressmap_clean(time_t now);
-void addressmap_clear_configured(void);
-void addressmap_clear_transient(void);
-void addressmap_free_all(void);
-int addressmap_rewrite(char *address, size_t maxlen, time_t *expires_out);
-int addressmap_have_mapping(const char *address, int update_timeout);
/** Enumerates possible origins of a client-side address mapping. */
typedef enum {
/** We're remapping this address because the controller told us to. */
@@ -3095,75 +3077,6 @@ typedef enum {
* Tor server that told us what its value was. */
ADDRMAPSRC_DNS,
} addressmap_entry_source_t;
-void addressmap_register(const char *address, char *new_address,
- time_t expires, addressmap_entry_source_t source);
-int parse_virtual_addr_network(const char *val, int validate_only,
- char **msg);
-int client_dns_incr_failures(const char *address);
-void client_dns_clear_failures(const char *address);
-void client_dns_set_addressmap(const char *address, uint32_t val,
- const char *exitname, int ttl);
-const char *addressmap_register_virtual_address(int type, char *new_address);
-void addressmap_get_mappings(smartlist_t *sl, time_t min_expires,
- time_t max_expires, int want_expiry);
-int connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
- origin_circuit_t *circ,
- crypt_path_t *cpath);
-int hostname_is_noconnect_address(const char *address);
-
-/** Possible return values for parse_extended_hostname. */
-typedef enum hostname_type_t {
- NORMAL_HOSTNAME, ONION_HOSTNAME, EXIT_HOSTNAME, BAD_HOSTNAME
-} hostname_type_t;
-hostname_type_t parse_extended_hostname(char *address);
-
-#if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
-int get_pf_socket(void);
-#endif
-
-/********************************* connection_or.c ***************************/
-
-void connection_or_remove_from_identity_map(or_connection_t *conn);
-void connection_or_clear_identity_map(void);
-or_connection_t *connection_or_get_for_extend(const char *digest,
- const tor_addr_t *target_addr,
- const char **msg_out,
- int *launch_out);
-void connection_or_set_bad_connections(void);
-
-int connection_or_reached_eof(or_connection_t *conn);
-int connection_or_process_inbuf(or_connection_t *conn);
-int connection_or_flushed_some(or_connection_t *conn);
-int connection_or_finished_flushing(or_connection_t *conn);
-int connection_or_finished_connecting(or_connection_t *conn);
-
-void connection_or_connect_failed(or_connection_t *conn,
- int reason, const char *msg);
-or_connection_t *connection_or_connect(const tor_addr_t *addr, uint16_t port,
- const char *id_digest);
-
-int connection_tls_start_handshake(or_connection_t *conn, int receiving);
-int connection_tls_continue_handshake(or_connection_t *conn);
-
-void or_handshake_state_free(or_handshake_state_t *state);
-int connection_or_set_state_open(or_connection_t *conn);
-void connection_or_write_cell_to_buf(const cell_t *cell,
- or_connection_t *conn);
-void connection_or_write_var_cell_to_buf(const var_cell_t *cell,
- or_connection_t *conn);
-int connection_or_send_destroy(circid_t circ_id, or_connection_t *conn,
- int reason);
-int connection_or_send_netinfo(or_connection_t *conn);
-int connection_or_send_cert(or_connection_t *conn);
-int connection_or_send_link_auth(or_connection_t *conn);
-int connection_or_compute_link_auth_hmac(or_connection_t *conn,
- char *hmac_out);
-int is_or_protocol_version_known(uint16_t version);
-
-void cell_pack(packed_cell_t *dest, const cell_t *src);
-void var_cell_pack_header(const var_cell_t *cell, char *hdr_out);
-var_cell_t *var_cell_new(uint16_t payload_len);
-void var_cell_free(var_cell_t *cell);
/********************************* control.c ***************************/
@@ -3201,8 +3114,14 @@ typedef enum or_conn_status_event_t {
OR_CONN_EVENT_NEW = 4,
} or_conn_status_event_t;
-void control_update_global_event_mask(void);
-void control_adjust_event_log_severity(void);
+/** Used to indicate the type of a buildtime event */
+typedef enum buildtimeout_set_event_t {
+ BUILDTIMEOUT_SET_EVENT_COMPUTED = 0,
+ BUILDTIMEOUT_SET_EVENT_RESET = 1,
+ BUILDTIMEOUT_SET_EVENT_SUSPENDED = 2,
+ BUILDTIMEOUT_SET_EVENT_DISCARD = 3,
+ BUILDTIMEOUT_SET_EVENT_RESUME = 4
+} buildtimeout_set_event_t;
/** Execute the statement <b>stmt</b>, which may log events concerning the
* connection <b>conn</b>. To prevent infinite loops, disable log messages
@@ -3220,58 +3139,6 @@ void control_adjust_event_log_severity(void);
enable_control_logging(); \
STMT_END
-/** Log information about the connection <b>conn</b>, protecting it as with
- * CONN_LOG_PROTECT. Example:
- *
- * LOG_FN_CONN(conn, (LOG_DEBUG, "Socket %d wants to write", conn->s));
- **/
-#define LOG_FN_CONN(conn, args) \
- CONN_LOG_PROTECT(conn, log_fn args)
-
-int connection_control_finished_flushing(control_connection_t *conn);
-int connection_control_reached_eof(control_connection_t *conn);
-int connection_control_process_inbuf(control_connection_t *conn);
-
-#define EVENT_AUTHDIR_NEWDESCS 0x000D
-#define EVENT_NS 0x000F
-int control_event_is_interesting(int event);
-
-int control_event_circuit_status(origin_circuit_t *circ,
- circuit_status_event_t e, int reason);
-int control_event_stream_status(edge_connection_t *conn,
- stream_status_event_t e,
- int reason);
-int control_event_or_conn_status(or_connection_t *conn,
- or_conn_status_event_t e, int reason);
-int control_event_bandwidth_used(uint32_t n_read, uint32_t n_written);
-int control_event_stream_bandwidth(edge_connection_t *edge_conn);
-int control_event_stream_bandwidth_used(void);
-void control_event_logmsg(int severity, unsigned int domain, const char *msg);
-int control_event_descriptors_changed(smartlist_t *routers);
-int control_event_address_mapped(const char *from, const char *to,
- time_t expires, const char *error);
-int control_event_or_authdir_new_descriptor(const char *action,
- const char *desc,
- size_t desclen,
- const char *msg);
-int control_event_my_descriptor_changed(void);
-int control_event_networkstatus_changed(smartlist_t *statuses);
-int control_event_newconsensus(const networkstatus_t *consensus);
-int control_event_networkstatus_changed_single(routerstatus_t *rs);
-int control_event_general_status(int severity, const char *format, ...)
- CHECK_PRINTF(2,3);
-int control_event_client_status(int severity, const char *format, ...)
- CHECK_PRINTF(2,3);
-int control_event_server_status(int severity, const char *format, ...)
- CHECK_PRINTF(2,3);
-int control_event_guard(const char *nickname, const char *digest,
- const char *status);
-
-int init_cookie_authentication(int enabled);
-smartlist_t *decode_hashed_passwords(config_line_t *passwords);
-void disable_control_logging(void);
-void enable_control_logging(void);
-
/** Enum describing various stages of bootstrapping, for use with controller
* bootstrap status events. The values range from 0 to 100. */
typedef enum {
@@ -3292,252 +3159,30 @@ typedef enum {
BOOTSTRAP_STATUS_DONE=100
} bootstrap_status_t;
-void control_event_bootstrap(bootstrap_status_t status, int progress);
-void control_event_bootstrap_problem(const char *warn, int reason);
-
-void control_event_clients_seen(const char *timestarted,
- const char *countries);
-
-#ifdef CONTROL_PRIVATE
-/* Used only by control.c and test.c */
-size_t write_escaped_data(const char *data, size_t len, char **out);
-size_t read_escaped_data(const char *data, size_t len, char **out);
-#endif
-
-/********************************* cpuworker.c *****************************/
-
-void cpu_init(void);
-void cpuworkers_rotate(void);
-int connection_cpu_finished_flushing(connection_t *conn);
-int connection_cpu_reached_eof(connection_t *conn);
-int connection_cpu_process_inbuf(connection_t *conn);
-int assign_onionskin_to_cpuworker(connection_t *cpuworker,
- or_circuit_t *circ,
- char *onionskin);
-
/********************************* directory.c ***************************/
-int directories_have_accepted_server_descriptor(void);
-char *authority_type_to_string(authority_type_t auth);
-void directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
- authority_type_t type, const char *payload,
- size_t payload_len, size_t extrainfo_len);
-void directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
- const char *resource,
- int pds_flags);
-void directory_get_from_all_authorities(uint8_t dir_purpose,
- uint8_t router_purpose,
- const char *resource);
-void directory_initiate_command_routerstatus(routerstatus_t *status,
- uint8_t dir_purpose,
- uint8_t router_purpose,
- int anonymized_connection,
- const char *resource,
- const char *payload,
- size_t payload_len,
- time_t if_modified_since);
-void directory_initiate_command_routerstatus_rend(routerstatus_t *status,
- uint8_t dir_purpose,
- uint8_t router_purpose,
- int anonymized_connection,
- const char *resource,
- const char *payload,
- size_t payload_len,
- time_t if_modified_since,
- const rend_data_t *rend_query);
-
-int parse_http_response(const char *headers, int *code, time_t *date,
- compress_method_t *compression, char **response);
-
-int connection_dir_is_encrypted(dir_connection_t *conn);
-int connection_dir_reached_eof(dir_connection_t *conn);
-int connection_dir_process_inbuf(dir_connection_t *conn);
-int connection_dir_finished_flushing(dir_connection_t *conn);
-int connection_dir_finished_connecting(dir_connection_t *conn);
-void connection_dir_request_failed(dir_connection_t *conn);
-void directory_initiate_command(const char *address, const tor_addr_t *addr,
- uint16_t or_port, uint16_t dir_port,
- int supports_conditional_consensus,
- int supports_begindir, const char *digest,
- uint8_t dir_purpose, uint8_t router_purpose,
- int anonymized_connection,
- const char *resource,
- const char *payload, size_t payload_len,
- time_t if_modified_since);
-
-int dir_split_resource_into_fingerprints(const char *resource,
- smartlist_t *fp_out, int *compresseed_out,
- int decode_hex, int sort_uniq);
/** A pair of digests created by dir_split_resource_info_fingerprint_pairs() */
typedef struct {
char first[DIGEST_LEN];
char second[DIGEST_LEN];
} fp_pair_t;
-int dir_split_resource_into_fingerprint_pairs(const char *res,
- smartlist_t *pairs_out);
-char *directory_dump_request_log(void);
-void note_request(const char *key, size_t bytes);
-int router_supports_extrainfo(const char *identity_digest, int is_authority);
-
-time_t download_status_increment_failure(download_status_t *dls,
- int status_code, const char *item,
- int server, time_t now);
-/** Increment the failure count of the download_status_t <b>dls</b>, with
- * the optional status code <b>sc</b>. */
-#define download_status_failed(dls, sc) \
- download_status_increment_failure((dls), (sc), NULL, \
- get_options()->DirPort, time(NULL))
-
-void download_status_reset(download_status_t *dls);
-static int download_status_is_ready(download_status_t *dls, time_t now,
- int max_failures);
-/** Return true iff, as of <b>now</b>, the resource tracked by <b>dls</b> is
- * ready to get its download reattempted. */
-static INLINE int
-download_status_is_ready(download_status_t *dls, time_t now,
- int max_failures)
-{
- return (dls->n_download_failures <= max_failures
- && dls->next_attempt_at <= now);
-}
-
-static void download_status_mark_impossible(download_status_t *dl);
-/** Mark <b>dl</b> as never downloadable. */
-static INLINE void
-download_status_mark_impossible(download_status_t *dl)
-{
- dl->n_download_failures = IMPOSSIBLE_TO_DOWNLOAD;
-}
/********************************* dirserv.c ***************************/
-/** Maximum length of an exit policy summary. */
-#define MAX_EXITPOLICY_SUMMARY_LEN (1000)
-
-/** Maximum allowable length of a version line in a networkstatus. */
-#define MAX_V_LINE_LEN 128
-/** Length of "r Authority BadDirectory BadExit Exit Fast Guard HSDir Named
- * Running Stable Unnamed V2Dir Valid\n". */
-#define MAX_FLAG_LINE_LEN 96
-/** Length of "w" line for weighting. Currently at most
- * "w Bandwidth=<uint32t>\n" */
-#define MAX_WEIGHT_LINE_LEN (13+10)
-/** Maximum length of an exit policy summary line. */
-#define MAX_POLICY_LINE_LEN (3+MAX_EXITPOLICY_SUMMARY_LEN)
-/** Amount of space to allocate for each entry: r, s, and v lines. */
-#define RS_ENTRY_LEN \
- ( /* first line */ \
- MAX_NICKNAME_LEN+BASE64_DIGEST_LEN*2+ISO_TIME_LEN+INET_NTOA_BUF_LEN+ \
- 5*2 /* ports */ + 10 /* punctuation */ + \
- /* second line */ \
- MAX_FLAG_LINE_LEN + \
- /* weight line */ \
- MAX_WEIGHT_LINE_LEN + \
- /* p line. */ \
- MAX_POLICY_LINE_LEN + \
- /* v line. */ \
- MAX_V_LINE_LEN \
- )
-#define UNNAMED_ROUTER_NICKNAME "Unnamed"
-
-int connection_dirserv_flushed_some(dir_connection_t *conn);
-
-int dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk);
-int dirserv_load_fingerprint_file(void);
-void dirserv_free_fingerprint_list(void);
-const char *dirserv_get_nickname_by_digest(const char *digest);
-enum was_router_added_t dirserv_add_multiple_descriptors(
- const char *desc, uint8_t purpose,
- const char *source,
- const char **msg);
-enum was_router_added_t dirserv_add_descriptor(routerinfo_t *ri,
- const char **msg,
- const char *source);
-int getinfo_helper_dirserv_unregistered(control_connection_t *conn,
- const char *question, char **answer);
-void dirserv_free_descriptors(void);
-void dirserv_set_router_is_running(routerinfo_t *router, time_t now);
-int list_server_status_v1(smartlist_t *routers, char **router_status_out,
- int for_controller);
-int dirserv_dump_directory_to_string(char **dir_out,
- crypto_pk_env_t *private_key);
-
-int directory_fetches_from_authorities(or_options_t *options);
-int directory_fetches_dir_info_early(or_options_t *options);
-int directory_fetches_dir_info_later(or_options_t *options);
-int directory_caches_v2_dir_info(or_options_t *options);
-#define directory_caches_v1_dir_info(o) directory_caches_v2_dir_info(o)
-int directory_caches_dir_info(or_options_t *options);
-int directory_permits_begindir_requests(or_options_t *options);
-int directory_permits_controller_requests(or_options_t *options);
-int directory_too_idle_to_fetch_descriptors(or_options_t *options, time_t now);
-
-void directory_set_dirty(void);
-cached_dir_t *dirserv_get_directory(void);
-cached_dir_t *dirserv_get_runningrouters(void);
-cached_dir_t *dirserv_get_consensus(void);
-void dirserv_set_cached_directory(const char *directory, time_t when,
- int is_running_routers);
-void dirserv_set_cached_networkstatus_v2(const char *directory,
- const char *identity,
- time_t published);
-void dirserv_set_cached_networkstatus_v3(const char *consensus,
- time_t published);
-void dirserv_clear_old_networkstatuses(time_t cutoff);
-void dirserv_clear_old_v1_info(time_t now);
-void dirserv_get_networkstatus_v2(smartlist_t *result, const char *key);
-void dirserv_get_networkstatus_v2_fingerprints(smartlist_t *result,
- const char *key);
-int dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
- const char **msg,
- int for_unencrypted_conn,
- int is_extrainfo);
-int dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
- const char **msg);
-void dirserv_orconn_tls_done(const char *address,
- uint16_t or_port,
- const char *digest_rcvd,
- int as_advertised);
-void dirserv_test_reachability(time_t now, int try_all);
-int authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
- int complain);
-int dirserv_would_reject_router(routerstatus_t *rs);
-int dirserv_remove_old_statuses(smartlist_t *fps, time_t cutoff);
-int dirserv_have_any_serverdesc(smartlist_t *fps, int spool_src);
-size_t dirserv_estimate_data_size(smartlist_t *fps, int is_serverdescs,
- int compressed);
-int routerstatus_format_entry(char *buf, size_t buf_len,
- routerstatus_t *rs, const char *platform,
- int first_line_only, int v2_format);
-void dirserv_free_all(void);
-void cached_dir_decref(cached_dir_t *d);
-cached_dir_t *new_cached_dir(char *s, time_t published);
+typedef enum {
+ NS_V2, NS_V3_CONSENSUS, NS_V3_VOTE, NS_CONTROL_PORT,
+ NS_V3_CONSENSUS_MICRODESC
+} routerstatus_format_type_t;
-/********************************* dirvote.c ************************/
+#ifdef DIRSERV_PRIVATE
+typedef struct measured_bw_line_t {
+ char node_id[DIGEST_LEN];
+ char node_hex[MAX_HEX_NICKNAME_LEN+1];
+ long int bw;
+} measured_bw_line_t;
+
+#endif
-/** Lowest allowable value for VoteSeconds. */
-#define MIN_VOTE_SECONDS 20
-/** Lowest allowable value for DistSeconds. */
-#define MIN_DIST_SECONDS 20
-/** Smallest allowable voting interval. */
-#define MIN_VOTE_INTERVAL 300
-
-void dirvote_free_all(void);
-
-/* vote manipulation */
-char *networkstatus_compute_consensus(smartlist_t *votes,
- int total_authorities,
- crypto_pk_env_t *identity_key,
- crypto_pk_env_t *signing_key,
- const char *legacy_identity_key_digest,
- crypto_pk_env_t *legacy_signing_key);
-int networkstatus_add_detached_signatures(networkstatus_t *target,
- ns_detached_signatures_t *sigs,
- const char **msg_out);
-char *networkstatus_get_detached_signatures(networkstatus_t *consensus);
-void ns_detached_signatures_free(ns_detached_signatures_t *s);
-
-/* cert manipulation */
-authority_cert_t *authority_cert_dup(authority_cert_t *cert);
+/********************************* dirvote.c ************************/
/** Describes the schedule by which votes should be generated. */
typedef struct vote_timing_t {
@@ -3546,173 +3191,85 @@ typedef struct vote_timing_t {
int vote_delay;
int dist_delay;
} vote_timing_t;
-/* vote scheduling */
-void dirvote_get_preferred_voting_intervals(vote_timing_t *timing_out);
-time_t dirvote_get_start_of_next_interval(time_t now, int interval);
-void dirvote_recalculate_timing(or_options_t *options, time_t now);
-void dirvote_act(or_options_t *options, time_t now);
-
-/* invoked on timers and by outside triggers. */
-struct pending_vote_t * dirvote_add_vote(const char *vote_body,
- const char **msg_out,
- int *status_out);
-int dirvote_add_signatures(const char *detached_signatures_body,
- const char *source,
- const char **msg_out);
-
-/* Item access */
-const char *dirvote_get_pending_consensus(void);
-const char *dirvote_get_pending_detached_signatures(void);
-#define DGV_BY_ID 1
-#define DGV_INCLUDE_PENDING 2
-#define DGV_INCLUDE_PREVIOUS 4
-const cached_dir_t *dirvote_get_vote(const char *fp, int flags);
-void set_routerstatus_from_routerinfo(routerstatus_t *rs,
- routerinfo_t *ri, time_t now,
- int naming, int exits_can_be_guards,
- int listbadexits, int listbaddirs);
-void router_clear_status_flags(routerinfo_t *ri);
-networkstatus_t *
-dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
- authority_cert_t *cert);
-
-#ifdef DIRVOTE_PRIVATE
-char *format_networkstatus_vote(crypto_pk_env_t *private_key,
- networkstatus_t *v3_ns);
-char *dirvote_compute_params(smartlist_t *votes);
-#endif
-
-/********************************* dns.c ***************************/
-
-int dns_init(void);
-int has_dns_init_failed(void);
-void dns_free_all(void);
-uint32_t dns_clip_ttl(uint32_t ttl);
-int dns_reset(void);
-void connection_dns_remove(edge_connection_t *conn);
-void assert_connection_edge_not_dns_pending(edge_connection_t *conn);
-void assert_all_pending_dns_resolves_ok(void);
-void dns_cancel_pending_resolve(const char *question);
-int dns_resolve(edge_connection_t *exitconn);
-void dns_launch_correctness_checks(void);
-int dns_seems_to_be_broken(void);
-void dns_reset_correctness_checks(void);
-
-/********************************* dnsserv.c ************************/
-
-void dnsserv_configure_listener(connection_t *conn);
-void dnsserv_close_listener(connection_t *conn);
-void dnsserv_resolved(edge_connection_t *conn,
- int answer_type,
- size_t answer_len,
- const char *answer,
- int ttl);
-void dnsserv_reject_request(edge_connection_t *conn);
-int dnsserv_launch_request(const char *name, int is_reverse);
/********************************* geoip.c **************************/
-#ifdef GEOIP_PRIVATE
-int geoip_parse_entry(const char *line);
-#endif
-int should_record_bridge_info(or_options_t *options);
-int geoip_load_file(const char *filename, or_options_t *options);
-int geoip_get_country_by_ip(uint32_t ipaddr);
-int geoip_get_n_countries(void);
-const char *geoip_get_country_name(country_t num);
-int geoip_is_loaded(void);
-country_t geoip_get_country(const char *countrycode);
+/** Round all GeoIP results to the next multiple of this value, to avoid
+ * leaking information. */
+#define DIR_RECORD_USAGE_GRANULARITY 8
+/** Time interval: Flush geoip data to disk this often. */
+#define DIR_ENTRY_RECORD_USAGE_RETAIN_IPS (24*60*60)
+/** How long do we have to have observed per-country request history before
+ * we are willing to talk about it? */
+#define DIR_RECORD_USAGE_MIN_OBSERVATION_TIME (12*60*60)
+
/** Indicates an action that we might be noting geoip statistics on.
* Note that if we're noticing CONNECT, we're a bridge, and if we're noticing
* the others, we're not.
*/
typedef enum {
- /** We've noticed a connection as a bridge relay. */
+ /** We've noticed a connection as a bridge relay or entry guard. */
GEOIP_CLIENT_CONNECT = 0,
/** We've served a networkstatus consensus as a directory server. */
GEOIP_CLIENT_NETWORKSTATUS = 1,
/** We've served a v2 networkstatus consensus as a directory server. */
GEOIP_CLIENT_NETWORKSTATUS_V2 = 2,
} geoip_client_action_t;
-void geoip_note_client_seen(geoip_client_action_t action,
- uint32_t addr, time_t now);
-void geoip_remove_old_clients(time_t cutoff);
-time_t geoip_get_history_start(void);
-char *geoip_get_client_history(time_t now, geoip_client_action_t action);
-char *geoip_get_request_history(time_t now, geoip_client_action_t action);
-int getinfo_helper_geoip(control_connection_t *control_conn,
- const char *question, char **answer);
-void geoip_free_all(void);
-void dump_geoip_stats(void);
-
-/********************************* hibernate.c **********************/
-
-int accounting_parse_options(or_options_t *options, int validate_only);
-int accounting_is_enabled(or_options_t *options);
-void configure_accounting(time_t now);
-void accounting_run_housekeeping(time_t now);
-void accounting_add_bytes(size_t n_read, size_t n_written, int seconds);
-int accounting_record_bandwidth_usage(time_t now, or_state_t *state);
-void hibernate_begin_shutdown(void);
-int we_are_hibernating(void);
-void consider_hibernation(time_t now);
-int getinfo_helper_accounting(control_connection_t *conn,
- const char *question, char **answer);
-void accounting_set_bandwidth_usage_from_state(or_state_t *state);
-
-/********************************* main.c ***************************/
-
-extern int has_completed_circuit;
-
-int connection_add(connection_t *conn);
-int connection_remove(connection_t *conn);
-int connection_in_array(connection_t *conn);
-void add_connection_to_closeable_list(connection_t *conn);
-int connection_is_on_closeable_list(connection_t *conn);
-
-smartlist_t *get_connection_array(void);
-
-void connection_watch_events(connection_t *conn, short events);
-int connection_is_reading(connection_t *conn);
-void connection_stop_reading(connection_t *conn);
-void connection_start_reading(connection_t *conn);
-
-int connection_is_writing(connection_t *conn);
-void connection_stop_writing(connection_t *conn);
-void connection_start_writing(connection_t *conn);
-
-void connection_stop_reading_from_linked_conn(connection_t *conn);
-
-void directory_all_unreachable(time_t now);
-void directory_info_has_arrived(time_t now, int from_cache);
-
-void ip_address_changed(int at_interface);
-void dns_servers_relaunch_checks(void);
-
-void control_signal_act(int the_signal);
-void handle_signals(int is_parent);
-
-int try_locking(or_options_t *options, int err_if_locked);
-int have_lockfile(void);
-void release_lockfile(void);
-
-void tor_cleanup(void);
-void tor_free_all(int postfork);
-
-int tor_main(int argc, char *argv[]);
-
-#ifdef MAIN_PRIVATE
-int do_main_loop(void);
-int do_list_fingerprint(void);
-void do_hash_password(void);
-int tor_init(int argc, char **argv);
-#endif
+/** Indicates either a positive reply or a reason for rejectng a network
+ * status request that will be included in geoip statistics. */
+typedef enum {
+ /** Request is answered successfully. */
+ GEOIP_SUCCESS = 0,
+ /** V3 network status is not signed by a sufficient number of requested
+ * authorities. */
+ GEOIP_REJECT_NOT_ENOUGH_SIGS = 1,
+ /** Requested network status object is unavailable. */
+ GEOIP_REJECT_UNAVAILABLE = 2,
+ /** Requested network status not found. */
+ GEOIP_REJECT_NOT_FOUND = 3,
+ /** Network status has not been modified since If-Modified-Since time. */
+ GEOIP_REJECT_NOT_MODIFIED = 4,
+ /** Directory is busy. */
+ GEOIP_REJECT_BUSY = 5,
+} geoip_ns_response_t;
+#define GEOIP_NS_RESPONSE_NUM 6
+
+/** Directory requests that we are measuring can be either direct or
+ * tunneled. */
+typedef enum {
+ DIRREQ_DIRECT = 0,
+ DIRREQ_TUNNELED = 1,
+} dirreq_type_t;
-/********************************* networkstatus.c *********************/
+/** Possible states for either direct or tunneled directory requests that
+ * are relevant for determining network status download times. */
+typedef enum {
+ /** Found that the client requests a network status; applies to both
+ * direct and tunneled requests; initial state of a request that we are
+ * measuring. */
+ DIRREQ_IS_FOR_NETWORK_STATUS = 0,
+ /** Finished writing a network status to the directory connection;
+ * applies to both direct and tunneled requests; completes a direct
+ * request. */
+ DIRREQ_FLUSHING_DIR_CONN_FINISHED = 1,
+ /** END cell sent to circuit that initiated a tunneled request. */
+ DIRREQ_END_CELL_SENT = 2,
+ /** Flushed last cell from queue of the circuit that initiated a
+ * tunneled request to the outbuf of the OR connection. */
+ DIRREQ_CIRC_QUEUE_FLUSHED = 3,
+ /** Flushed last byte from buffer of the OR connection belonging to the
+ * circuit that initiated a tunneled request; completes a tunneled
+ * request. */
+ DIRREQ_OR_CONN_BUFFER_FLUSHED = 4
+} dirreq_state_t;
+
+#define WRITE_STATS_INTERVAL (24*60*60)
+
+/********************************* microdesc.c *************************/
+
+typedef struct microdesc_cache_t microdesc_cache_t;
-/** How old do we allow a v2 network-status to get before removing it
- * completely? */
-#define MAX_NETWORKSTATUS_AGE (10*24*60*60)
+/********************************* networkstatus.c *********************/
/** Location where we found a v2 networkstatus. */
typedef enum {
@@ -3733,127 +3290,8 @@ typedef enum version_status_t {
VS_UNKNOWN, /**< We have no idea. */
} version_status_t;
-void networkstatus_reset_warnings(void);
-void networkstatus_reset_download_failures(void);
-int router_reload_v2_networkstatus(void);
-int router_reload_consensus_networkstatus(void);
-void routerstatus_free(routerstatus_t *rs);
-void networkstatus_v2_free(networkstatus_v2_t *ns);
-void networkstatus_vote_free(networkstatus_t *ns);
-networkstatus_voter_info_t *networkstatus_get_voter_by_id(
- networkstatus_t *vote,
- const char *identity);
-int networkstatus_check_consensus_signature(networkstatus_t *consensus,
- int warn);
-int networkstatus_check_voter_signature(networkstatus_t *consensus,
- networkstatus_voter_info_t *voter,
- authority_cert_t *cert);
-char *networkstatus_get_cache_filename(const char *identity_digest);
-int router_set_networkstatus_v2(const char *s, time_t arrived_at,
- v2_networkstatus_source_t source,
- smartlist_t *requested_fingerprints);
-void networkstatus_v2_list_clean(time_t now);
-routerstatus_t *networkstatus_v2_find_entry(networkstatus_v2_t *ns,
- const char *digest);
-routerstatus_t *networkstatus_vote_find_entry(networkstatus_t *ns,
- const char *digest);
-int networkstatus_vote_find_entry_idx(networkstatus_t *ns,
- const char *digest, int *found_out);
-const smartlist_t *networkstatus_get_v2_list(void);
-download_status_t *router_get_dl_status_by_descriptor_digest(const char *d);
-routerstatus_t *router_get_consensus_status_by_id(const char *digest);
-routerstatus_t *router_get_consensus_status_by_descriptor_digest(
- const char *digest);
-routerstatus_t *router_get_consensus_status_by_nickname(const char *nickname,
- int warn_if_unnamed);
-const char *networkstatus_get_router_digest_by_nickname(const char *nickname);
-int networkstatus_nickname_is_unnamed(const char *nickname);
-void networkstatus_consensus_download_failed(int status_code);
-void update_consensus_networkstatus_fetch_time(time_t now);
-int should_delay_dir_fetches(or_options_t *options);
-void update_networkstatus_downloads(time_t now);
-void update_certificate_downloads(time_t now);
-int consensus_is_waiting_for_certs(void);
-networkstatus_v2_t *networkstatus_v2_get_by_digest(const char *digest);
-networkstatus_t *networkstatus_get_latest_consensus(void);
-networkstatus_t *networkstatus_get_live_consensus(time_t now);
-networkstatus_t *networkstatus_get_reasonably_live_consensus(time_t now);
-#define NSSET_FROM_CACHE 1
-#define NSSET_WAS_WAITING_FOR_CERTS 2
-#define NSSET_DONT_DOWNLOAD_CERTS 4
-#define NSSET_ACCEPT_OBSOLETE 8
-int networkstatus_set_current_consensus(const char *consensus, unsigned flags);
-void networkstatus_note_certs_arrived(void);
-void routers_update_all_from_networkstatus(time_t now, int dir_version);
-void routerstatus_list_update_from_consensus_networkstatus(time_t now);
-void routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
- int reset_failures);
-void signed_descs_update_status_from_consensus_networkstatus(
- smartlist_t *descs);
-
-char *networkstatus_getinfo_helper_single(routerstatus_t *rs);
-char *networkstatus_getinfo_by_purpose(const char *purpose_string, time_t now);
-void networkstatus_dump_bridge_status_to_file(time_t now);
-int32_t networkstatus_get_param(networkstatus_t *ns, const char *param_name,
- int32_t default_val);
-int getinfo_helper_networkstatus(control_connection_t *conn,
- const char *question, char **answer);
-void networkstatus_free_all(void);
-
-/********************************* ntmain.c ***************************/
-#ifdef MS_WINDOWS
-#define NT_SERVICE
-#endif
-
-#ifdef NT_SERVICE
-int nt_service_parse_options(int argc, char **argv, int *should_exit);
-int nt_service_is_stopping(void);
-void nt_service_set_state(DWORD state);
-#else
-#define nt_service_is_stopping() (0)
-#endif
-
-/********************************* onion.c ***************************/
-
-int onion_pending_add(or_circuit_t *circ, char *onionskin);
-or_circuit_t *onion_next_task(char **onionskin_out);
-void onion_pending_remove(or_circuit_t *circ);
-
-int onion_skin_create(crypto_pk_env_t *router_key,
- crypto_dh_env_t **handshake_state_out,
- char *onion_skin_out);
-
-int onion_skin_server_handshake(const char *onion_skin,
- crypto_pk_env_t *private_key,
- crypto_pk_env_t *prev_private_key,
- char *handshake_reply_out,
- char *key_out,
- size_t key_out_len);
-
-int onion_skin_client_handshake(crypto_dh_env_t *handshake_state,
- const char *handshake_reply,
- char *key_out,
- size_t key_out_len);
-
-int fast_server_handshake(const uint8_t *key_in,
- uint8_t *handshake_reply_out,
- uint8_t *key_out,
- size_t key_out_len);
-
-int fast_client_handshake(const uint8_t *handshake_state,
- const uint8_t *handshake_reply_out,
- uint8_t *key_out,
- size_t key_out_len);
-
-void clear_pending_onions(void);
-
/********************************* policies.c ************************/
-/* (length of "accept 255.255.255.255/255.255.255.255:65535-65535\n" plus a
- * NUL.)
- */
-#define POLICY_BUF_LEN 52
-
/** Outcome of applying an address policy to an address. */
typedef enum {
/** The address was accepted */
@@ -3868,146 +3306,8 @@ typedef enum {
ADDR_POLICY_PROBABLY_REJECTED=2
} addr_policy_result_t;
-int firewall_is_fascist_or(void);
-int fascist_firewall_allows_address_or(const tor_addr_t *addr, uint16_t port);
-int fascist_firewall_allows_or(routerinfo_t *ri);
-int fascist_firewall_allows_address_dir(const tor_addr_t *addr, uint16_t port);
-int dir_policy_permits_address(const tor_addr_t *addr);
-int socks_policy_permits_address(const tor_addr_t *addr);
-int authdir_policy_permits_address(uint32_t addr, uint16_t port);
-int authdir_policy_valid_address(uint32_t addr, uint16_t port);
-int authdir_policy_baddir_address(uint32_t addr, uint16_t port);
-int authdir_policy_badexit_address(uint32_t addr, uint16_t port);
-
-int validate_addr_policies(or_options_t *options, char **msg);
-void policy_expand_private(smartlist_t **policy);
-int policies_parse_from_options(or_options_t *options);
-
-addr_policy_t *addr_policy_get_canonical_entry(addr_policy_t *ent);
-int cmp_addr_policies(smartlist_t *a, smartlist_t *b);
-addr_policy_result_t compare_tor_addr_to_addr_policy(const tor_addr_t *addr,
- uint16_t port, const smartlist_t *policy);
-addr_policy_result_t compare_addr_to_addr_policy(uint32_t addr,
- uint16_t port, const smartlist_t *policy);
-int policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
- int rejectprivate, const char *local_address);
-void policies_set_router_exitpolicy_to_reject_all(routerinfo_t *exitrouter);
-int exit_policy_is_general_exit(smartlist_t *policy);
-int policy_is_reject_star(const smartlist_t *policy);
-int getinfo_helper_policies(control_connection_t *conn,
- const char *question, char **answer);
-int policy_write_item(char *buf, size_t buflen, addr_policy_t *item,
- int format_for_desc);
-
-void addr_policy_list_free(smartlist_t *p);
-void addr_policy_free(addr_policy_t *p);
-void policies_free_all(void);
-
-char *policy_summarize(smartlist_t *policy);
-
-/********************************* reasons.c ***************************/
-
-const char *stream_end_reason_to_control_string(int reason);
-const char *stream_end_reason_to_string(int reason);
-socks5_reply_status_t stream_end_reason_to_socks5_response(int reason);
-uint8_t errno_to_stream_end_reason(int e);
-
-const char *orconn_end_reason_to_control_string(int r);
-int tls_error_to_orconn_end_reason(int e);
-int errno_to_orconn_end_reason(int e);
-
-const char *circuit_end_reason_to_control_string(int reason);
-
-/********************************* relay.c ***************************/
-
-extern uint64_t stats_n_relay_cells_relayed;
-extern uint64_t stats_n_relay_cells_delivered;
-
-int circuit_receive_relay_cell(cell_t *cell, circuit_t *circ,
- cell_direction_t cell_direction);
-
-void relay_header_pack(uint8_t *dest, const relay_header_t *src);
-void relay_header_unpack(relay_header_t *dest, const uint8_t *src);
-int relay_send_command_from_edge(streamid_t stream_id, circuit_t *circ,
- uint8_t relay_command, const char *payload,
- size_t payload_len, crypt_path_t *cpath_layer);
-int connection_edge_send_command(edge_connection_t *fromconn,
- uint8_t relay_command, const char *payload,
- size_t payload_len);
-int connection_edge_package_raw_inbuf(edge_connection_t *conn,
- int package_partial);
-void connection_edge_consider_sending_sendme(edge_connection_t *conn);
-
-extern uint64_t stats_n_data_cells_packaged;
-extern uint64_t stats_n_data_bytes_packaged;
-extern uint64_t stats_n_data_cells_received;
-extern uint64_t stats_n_data_bytes_received;
-
-void init_cell_pool(void);
-void free_cell_pool(void);
-void clean_cell_pool(void);
-void dump_cell_pool_usage(int severity);
-
-void cell_queue_clear(cell_queue_t *queue);
-void cell_queue_append(cell_queue_t *queue, packed_cell_t *cell);
-void cell_queue_append_packed_copy(cell_queue_t *queue, const cell_t *cell);
-
-void append_cell_to_circuit_queue(circuit_t *circ, or_connection_t *orconn,
- cell_t *cell, cell_direction_t direction);
-void connection_or_unlink_all_active_circs(or_connection_t *conn);
-int connection_or_flush_from_first_active_circuit(or_connection_t *conn,
- int max, time_t now);
-void assert_active_circuits_ok(or_connection_t *orconn);
-void make_circuit_inactive_on_conn(circuit_t *circ, or_connection_t *conn);
-void make_circuit_active_on_conn(circuit_t *circ, or_connection_t *conn);
-
-int append_address_to_payload(uint8_t *payload_out, const tor_addr_t *addr);
-const uint8_t *decode_address_from_payload(tor_addr_t *addr_out,
- const uint8_t *payload,
- int payload_len);
-
/********************************* rephist.c ***************************/
-void rep_hist_init(void);
-void rep_hist_note_connect_failed(const char* nickname, time_t when);
-void rep_hist_note_connect_succeeded(const char* nickname, time_t when);
-void rep_hist_note_disconnect(const char* nickname, time_t when);
-void rep_hist_note_connection_died(const char* nickname, time_t when);
-void rep_hist_note_extend_succeeded(const char *from_name,
- const char *to_name);
-void rep_hist_note_extend_failed(const char *from_name, const char *to_name);
-void rep_hist_dump_stats(time_t now, int severity);
-void rep_hist_note_bytes_read(size_t num_bytes, time_t when);
-void rep_hist_note_bytes_written(size_t num_bytes, time_t when);
-int rep_hist_bandwidth_assess(void);
-char *rep_hist_get_bandwidth_lines(int for_extrainfo);
-void rep_hist_update_state(or_state_t *state);
-int rep_hist_load_state(or_state_t *state, char **err);
-void rep_history_clean(time_t before);
-
-void rep_hist_note_router_reachable(const char *id, time_t when);
-void rep_hist_note_router_unreachable(const char *id, time_t when);
-int rep_hist_record_mtbf_data(time_t now, int missing_means_down);
-int rep_hist_load_mtbf_data(time_t now);
-
-time_t rep_hist_downrate_old_runs(time_t now);
-double rep_hist_get_stability(const char *id, time_t when);
-double rep_hist_get_weighted_fractional_uptime(const char *id, time_t when);
-long rep_hist_get_weighted_time_known(const char *id, time_t when);
-int rep_hist_have_measured_enough_stability(void);
-const char *rep_hist_get_router_stability_doc(time_t now);
-
-void rep_hist_note_used_port(time_t now, uint16_t port);
-smartlist_t *rep_hist_get_predicted_ports(time_t now);
-void rep_hist_note_used_resolve(time_t now);
-void rep_hist_note_used_internal(time_t now, int need_uptime,
- int need_capacity);
-int rep_hist_get_predicted_internal(time_t now, int *need_uptime,
- int *need_capacity);
-
-int any_predicted_circuits(time_t now);
-int rep_hist_circbuilding_dormant(time_t now);
-
/** Possible public/private key operations in Tor: used to keep track of where
* we're spending our time. */
typedef enum {
@@ -4017,48 +3317,6 @@ typedef enum {
TLS_HANDSHAKE_C, TLS_HANDSHAKE_S,
REND_CLIENT, REND_MID, REND_SERVER,
} pk_op_t;
-void note_crypto_pk_op(pk_op_t operation);
-void dump_pk_ops(int severity);
-
-void rep_hist_free_all(void);
-
-/* for hidden service usage statistics */
-void hs_usage_note_publish_total(const char *service_id, time_t now);
-void hs_usage_note_publish_novel(const char *service_id, time_t now);
-void hs_usage_note_fetch_total(const char *service_id, time_t now);
-void hs_usage_note_fetch_successful(const char *service_id, time_t now);
-void hs_usage_write_statistics_to_file(time_t now);
-void hs_usage_free_all(void);
-
-/********************************* rendclient.c ***************************/
-
-void rend_client_introcirc_has_opened(origin_circuit_t *circ);
-void rend_client_rendcirc_has_opened(origin_circuit_t *circ);
-int rend_client_introduction_acked(origin_circuit_t *circ,
- const uint8_t *request,
- size_t request_len);
-void rend_client_refetch_renddesc(const char *query);
-void rend_client_refetch_v2_renddesc(const rend_data_t *rend_query);
-int rend_client_remove_intro_point(extend_info_t *failed_intro,
- const rend_data_t *rend_query);
-int rend_client_rendezvous_acked(origin_circuit_t *circ,
- const uint8_t *request,
- size_t request_len);
-int rend_client_receive_rendezvous(origin_circuit_t *circ,
- const uint8_t *request,
- size_t request_len);
-void rend_client_desc_trynow(const char *query, int rend_version);
-
-extend_info_t *rend_client_get_random_intro(const rend_data_t *rend_query);
-
-int rend_client_send_introduction(origin_circuit_t *introcirc,
- origin_circuit_t *rendcirc);
-int rend_parse_service_authorization(or_options_t *options,
- int validate_only);
-rend_service_authorization_t *rend_client_lookup_service_authorization(
- const char *onion_address);
-void rend_service_authorization_free_all(void);
-rend_data_t *rend_data_dup(const rend_data_t *request);
/********************************* rendcommon.c ***************************/
@@ -4101,31 +3359,6 @@ typedef struct rend_service_descriptor_t {
smartlist_t *successful_uploads;
} rend_service_descriptor_t;
-/** Free all storage associated with <b>data</b> */
-static INLINE void
-rend_data_free(rend_data_t *data)
-{
- tor_free(data);
-}
-
-int rend_cmp_service_ids(const char *one, const char *two);
-
-void rend_process_relay_cell(circuit_t *circ, const crypt_path_t *layer_hint,
- int command, size_t length,
- const uint8_t *payload);
-
-void rend_service_descriptor_free(rend_service_descriptor_t *desc);
-int rend_encode_service_descriptor(rend_service_descriptor_t *desc,
- crypto_pk_env_t *key,
- char **str_out,
- size_t *len_out);
-rend_service_descriptor_t *rend_parse_service_descriptor(const char *str,
- size_t len);
-int rend_get_service_id(crypto_pk_env_t *pk, char *out);
-void rend_encoded_v2_service_descriptor_free(
- rend_encoded_v2_service_descriptor_t *desc);
-void rend_intro_point_free(rend_intro_point_t *intro);
-
/** A cached rendezvous descriptor. */
typedef struct rend_cache_entry_t {
size_t len; /**< Length of <b>desc</b> */
@@ -4134,150 +3367,6 @@ typedef struct rend_cache_entry_t {
rend_service_descriptor_t *parsed; /**< Parsed value of 'desc' */
} rend_cache_entry_t;
-void rend_cache_init(void);
-void rend_cache_clean(void);
-void rend_cache_clean_v2_descs_as_dir(void);
-void rend_cache_free_all(void);
-int rend_valid_service_id(const char *query);
-int rend_cache_lookup_desc(const char *query, int version, const char **desc,
- size_t *desc_len);
-int rend_cache_lookup_entry(const char *query, int version,
- rend_cache_entry_t **entry_out);
-int rend_cache_lookup_v2_desc_as_dir(const char *query, const char **desc);
-int rend_cache_store(const char *desc, size_t desc_len, int published);
-int rend_cache_store_v2_desc_as_client(const char *desc,
- const rend_data_t *rend_query);
-int rend_cache_store_v2_desc_as_dir(const char *desc);
-int rend_cache_size(void);
-int rend_encode_v2_descriptors(smartlist_t *descs_out,
- rend_service_descriptor_t *desc, time_t now,
- uint8_t period, rend_auth_type_t auth_type,
- crypto_pk_env_t *client_key,
- smartlist_t *client_cookies);
-int rend_compute_v2_desc_id(char *desc_id_out, const char *service_id,
- const char *descriptor_cookie,
- time_t now, uint8_t replica);
-int rend_id_is_in_interval(const char *a, const char *b, const char *c);
-void rend_get_descriptor_id_bytes(char *descriptor_id_out,
- const char *service_id,
- const char *secret_id_part);
-
-/********************************* rendservice.c ***************************/
-
-int num_rend_services(void);
-int rend_config_services(or_options_t *options, int validate_only);
-int rend_service_load_keys(void);
-void rend_services_init(void);
-void rend_services_introduce(void);
-void rend_consider_services_upload(time_t now);
-void rend_hsdir_routers_changed(void);
-void rend_consider_descriptor_republication(void);
-
-void rend_service_intro_has_opened(origin_circuit_t *circuit);
-int rend_service_intro_established(origin_circuit_t *circuit,
- const uint8_t *request,
- size_t request_len);
-void rend_service_rendezvous_has_opened(origin_circuit_t *circuit);
-int rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
- size_t request_len);
-void rend_service_relaunch_rendezvous(origin_circuit_t *oldcirc);
-int rend_service_set_connection_addr_port(edge_connection_t *conn,
- origin_circuit_t *circ);
-void rend_service_dump_stats(int severity);
-void rend_service_free_all(void);
-
-/********************************* rendmid.c *******************************/
-int rend_mid_establish_intro(or_circuit_t *circ, const uint8_t *request,
- size_t request_len);
-int rend_mid_introduce(or_circuit_t *circ, const uint8_t *request,
- size_t request_len);
-int rend_mid_establish_rendezvous(or_circuit_t *circ, const uint8_t *request,
- size_t request_len);
-int rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request,
- size_t request_len);
-
-/********************************* router.c ***************************/
-
-crypto_pk_env_t *get_onion_key(void);
-time_t get_onion_key_set_at(void);
-void set_identity_key(crypto_pk_env_t *k);
-crypto_pk_env_t *get_identity_key(void);
-int identity_key_is_set(void);
-authority_cert_t *get_my_v3_authority_cert(void);
-crypto_pk_env_t *get_my_v3_authority_signing_key(void);
-authority_cert_t *get_my_v3_legacy_cert(void);
-crypto_pk_env_t *get_my_v3_legacy_signing_key(void);
-void dup_onion_keys(crypto_pk_env_t **key, crypto_pk_env_t **last);
-void rotate_onion_key(void);
-crypto_pk_env_t *init_key_from_file(const char *fname, int generate,
- int severity);
-void v3_authority_check_key_expiry(void);
-
-int init_keys(void);
-
-int check_whether_orport_reachable(void);
-int check_whether_dirport_reachable(void);
-void consider_testing_reachability(int test_or, int test_dir);
-void router_orport_found_reachable(void);
-void router_dirport_found_reachable(void);
-void router_perform_bandwidth_test(int num_circs, time_t now);
-
-int authdir_mode(or_options_t *options);
-int authdir_mode_v1(or_options_t *options);
-int authdir_mode_v2(or_options_t *options);
-int authdir_mode_v3(or_options_t *options);
-int authdir_mode_any_main(or_options_t *options);
-int authdir_mode_any_nonhidserv(or_options_t *options);
-int authdir_mode_handles_descs(or_options_t *options, int purpose);
-int authdir_mode_publishes_statuses(or_options_t *options);
-int authdir_mode_tests_reachability(or_options_t *options);
-int authdir_mode_bridge(or_options_t *options);
-
-int server_mode(or_options_t *options);
-int advertised_server_mode(void);
-int proxy_mode(or_options_t *options);
-void consider_publishable_server(int force);
-
-void router_upload_dir_desc_to_dirservers(int force);
-void mark_my_descriptor_dirty_if_older_than(time_t when);
-void mark_my_descriptor_dirty(void);
-void check_descriptor_bandwidth_changed(time_t now);
-void check_descriptor_ipaddress_changed(time_t now);
-void router_new_address_suggestion(const char *suggestion,
- const dir_connection_t *d_conn);
-int router_compare_to_my_exit_policy(edge_connection_t *conn);
-routerinfo_t *router_get_my_routerinfo(void);
-extrainfo_t *router_get_my_extrainfo(void);
-const char *router_get_my_descriptor(void);
-int router_digest_is_me(const char *digest);
-int router_extrainfo_digest_is_me(const char *digest);
-int router_is_me(routerinfo_t *router);
-int router_fingerprint_is_me(const char *fp);
-int router_pick_published_address(or_options_t *options, uint32_t *addr);
-int router_rebuild_descriptor(int force);
-int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
- crypto_pk_env_t *ident_key);
-int extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo,
- crypto_pk_env_t *ident_key);
-char *extrainfo_get_client_geoip_summary(time_t);
-int is_legal_nickname(const char *s);
-int is_legal_nickname_or_hexdigest(const char *s);
-int is_legal_hexdigest(const char *s);
-void router_get_verbose_nickname(char *buf, const routerinfo_t *router);
-void routerstatus_get_verbose_nickname(char *buf,
- const routerstatus_t *router);
-void router_reset_warnings(void);
-void router_reset_reachability(void);
-void router_free_all(void);
-
-const char *router_purpose_to_string(uint8_t p);
-uint8_t router_purpose_from_string(const char *s);
-
-#ifdef ROUTER_PRIVATE
-/* Used only by router.c and test.c */
-void get_platform_str(char *platform, size_t len);
-#endif
-
/********************************* routerlist.c ***************************/
/** Represents information about a single trusted directory server. */
@@ -4317,21 +3406,6 @@ typedef struct trusted_dir_server_t {
#define ROUTER_MAX_DECLARED_BANDWIDTH INT32_MAX
-int get_n_authorities(authority_type_t type);
-int trusted_dirs_reload_certs(void);
-int trusted_dirs_load_certs_from_string(const char *contents, int from_store,
- int flush);
-void trusted_dirs_flush_certs_to_disk(void);
-authority_cert_t *authority_cert_get_newest_by_id(const char *id_digest);
-authority_cert_t *authority_cert_get_by_sk_digest(const char *sk_digest);
-authority_cert_t *authority_cert_get_by_digests(const char *id_digest,
- const char *sk_digest);
-void authority_cert_get_all(smartlist_t *certs_out);
-void authority_cert_dl_failed(const char *id_digest, int status);
-void authority_certs_fetch_missing(networkstatus_t *status, time_t now);
-int router_reload_router_list(void);
-smartlist_t *router_get_trusted_dir_servers(void);
-
/* Flags for pick_directory_server and pick_trusteddirserver. */
/** Flag to indicate that we should not automatically be willing to use
* ourself to answer a directory request.
@@ -4361,34 +3435,13 @@ smartlist_t *router_get_trusted_dir_servers(void);
*/
#define PDS_NO_EXISTING_SERVERDESC_FETCH (1<<3)
#define _PDS_PREFER_TUNNELED_DIR_CONNS (1<<16)
-routerstatus_t *router_pick_directory_server(authority_type_t type, int flags);
-trusted_dir_server_t *router_get_trusteddirserver_by_digest(const char *d);
-trusted_dir_server_t *trusteddirserver_get_by_v3_auth_digest(const char *d);
-routerstatus_t *router_pick_trusteddirserver(authority_type_t type, int flags);
-int router_get_my_share_of_directory_requests(double *v2_share_out,
- double *v3_share_out);
-void router_reset_status_download_failures(void);
-void routerlist_add_family(smartlist_t *sl, routerinfo_t *router);
-int routers_in_same_family(routerinfo_t *r1, routerinfo_t *r2);
-void add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
- int must_be_running);
-int router_nickname_is_in_list(routerinfo_t *router, const char *list);
-routerinfo_t *routerlist_find_my_routerinfo(void);
-routerinfo_t *router_find_exact_exit_enclave(const char *address,
- uint16_t port);
-int router_is_unreliable(routerinfo_t *router, int need_uptime,
- int need_capacity, int need_guard);
-uint32_t router_get_advertised_bandwidth(routerinfo_t *router);
-uint32_t router_get_advertised_bandwidth_capped(routerinfo_t *router);
/** Possible ways to weight routers when choosing one randomly. See
* routerlist_sl_choose_by_bandwidth() for more information.*/
-typedef enum {
- NO_WEIGHTING, WEIGHT_FOR_EXIT, WEIGHT_FOR_GUARD
+typedef enum bandwidth_weight_rule_t {
+ NO_WEIGHTING, WEIGHT_FOR_EXIT, WEIGHT_FOR_MID, WEIGHT_FOR_GUARD,
+ WEIGHT_FOR_DIR
} bandwidth_weight_rule_t;
-routerinfo_t *routerlist_sl_choose_by_bandwidth(smartlist_t *sl,
- bandwidth_weight_rule_t rule);
-routerstatus_t *routerstatus_sl_choose_by_bandwidth(smartlist_t *sl);
/** Flags to be passed to control router_choose_random_node() to indicate what
* kind of nodes to pick according to what algorithm. */
@@ -4398,44 +3451,9 @@ typedef enum {
CRN_NEED_GUARD = 1<<2,
CRN_ALLOW_INVALID = 1<<3,
/* XXXX not used, apparently. */
- CRN_STRICT_PREFERRED = 1<<4,
- /* XXXX not used, apparently. */
CRN_WEIGHT_AS_EXIT = 1<<5
} router_crn_flags_t;
-routerinfo_t *router_choose_random_node(const char *preferred,
- smartlist_t *excludedsmartlist,
- struct routerset_t *excludedset,
- router_crn_flags_t flags);
-
-routerinfo_t *router_get_by_nickname(const char *nickname,
- int warn_if_unnamed);
-int router_digest_version_as_new_as(const char *digest, const char *cutoff);
-int router_digest_is_trusted_dir_type(const char *digest,
- authority_type_t type);
-#define router_digest_is_trusted_dir(d) \
- router_digest_is_trusted_dir_type((d), NO_AUTHORITY)
-
-int router_addr_is_trusted_dir(uint32_t addr);
-int hexdigest_to_digest(const char *hexdigest, char *digest);
-routerinfo_t *router_get_by_hexdigest(const char *hexdigest);
-routerinfo_t *router_get_by_digest(const char *digest);
-signed_descriptor_t *router_get_by_descriptor_digest(const char *digest);
-signed_descriptor_t *router_get_by_extrainfo_digest(const char *digest);
-signed_descriptor_t *extrainfo_get_by_descriptor_digest(const char *digest);
-const char *signed_descriptor_get_body(signed_descriptor_t *desc);
-const char *signed_descriptor_get_annotations(signed_descriptor_t *desc);
-routerlist_t *router_get_routerlist(void);
-void routerinfo_free(routerinfo_t *router);
-void extrainfo_free(extrainfo_t *extrainfo);
-void routerlist_free(routerlist_t *rl);
-void dump_routerlist_mem_usage(int severity);
-void routerlist_remove(routerlist_t *rl, routerinfo_t *ri, int make_old,
- time_t now);
-void routerlist_free_all(void);
-void routerlist_reset_warnings(void);
-void router_set_status(const char *digest, int up);
-
/** Return value for router_add_to_routerlist() and dirserv_add_descriptor() */
typedef enum was_router_added_t {
ROUTER_ADDED_SUCCESSFULLY = 1,
@@ -4447,109 +3465,6 @@ typedef enum was_router_added_t {
ROUTER_AUTHDIR_REJECTS = -5,
} was_router_added_t;
-static int WRA_WAS_ADDED(was_router_added_t s);
-static int WRA_WAS_OUTDATED(was_router_added_t s);
-static int WRA_WAS_REJECTED(was_router_added_t s);
-/** Return true iff the descriptor was added. It might still be necessary to
- * check whether the descriptor generator should be notified.
- */
-static INLINE int
-WRA_WAS_ADDED(was_router_added_t s) {
- return s == ROUTER_ADDED_SUCCESSFULLY || s == ROUTER_ADDED_NOTIFY_GENERATOR;
-}
-/** Return true iff the descriptor was not added because it was either:
- * - not in the consensus
- * - neither in the consensus nor in any networkstatus document
- * - it was outdated.
- */
-static INLINE int WRA_WAS_OUTDATED(was_router_added_t s)
-{
- return (s == ROUTER_WAS_NOT_NEW ||
- s == ROUTER_NOT_IN_CONSENSUS ||
- s == ROUTER_NOT_IN_CONSENSUS_OR_NETWORKSTATUS);
-}
-/** Return true iff the descriptor rejected because it was malformed. */
-static INLINE int WRA_WAS_REJECTED(was_router_added_t s)
-{
- return (s == ROUTER_AUTHDIR_REJECTS);
-}
-was_router_added_t router_add_to_routerlist(routerinfo_t *router,
- const char **msg,
- int from_cache,
- int from_fetch);
-was_router_added_t router_add_extrainfo_to_routerlist(
- extrainfo_t *ei, const char **msg,
- int from_cache, int from_fetch);
-void routerlist_remove_old_routers(void);
-int router_load_single_router(const char *s, uint8_t purpose, int cache,
- const char **msg);
-int router_load_routers_from_string(const char *s, const char *eos,
- saved_location_t saved_location,
- smartlist_t *requested_fingerprints,
- int descriptor_digests,
- const char *prepend_annotations);
-void router_load_extrainfo_from_string(const char *s, const char *eos,
- saved_location_t saved_location,
- smartlist_t *requested_fingerprints,
- int descriptor_digests);
-void routerlist_retry_directory_downloads(time_t now);
-int router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port,
- int need_uptime);
-int router_exit_policy_rejects_all(routerinfo_t *router);
-trusted_dir_server_t *add_trusted_dir_server(const char *nickname,
- const char *address,
- uint16_t dir_port, uint16_t or_port,
- const char *digest, const char *v3_auth_digest,
- authority_type_t type);
-void authority_cert_free(authority_cert_t *cert);
-void clear_trusted_dir_servers(void);
-int any_trusted_dir_is_v1_authority(void);
-void update_router_descriptor_downloads(time_t now);
-void update_extrainfo_downloads(time_t now);
-int router_have_minimum_dir_info(void);
-void router_dir_info_changed(void);
-const char *get_dir_info_status_string(void);
-int count_loading_descriptors_progress(void);
-void router_reset_descriptor_download_failures(void);
-int router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2);
-int routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei,
- signed_descriptor_t *sd,
- const char **msg);
-void routerlist_assert_ok(routerlist_t *rl);
-const char *esc_router_info(routerinfo_t *router);
-void routers_sort_by_identity(smartlist_t *routers);
-
-routerset_t *routerset_new(void);
-int routerset_parse(routerset_t *target, const char *s,
- const char *description);
-void routerset_union(routerset_t *target, const routerset_t *source);
-int routerset_is_list(const routerset_t *set);
-int routerset_needs_geoip(const routerset_t *set);
-int routerset_contains_router(const routerset_t *set, routerinfo_t *ri);
-int routerset_contains_routerstatus(const routerset_t *set,
- routerstatus_t *rs);
-int routerset_contains_extendinfo(const routerset_t *set,
- const extend_info_t *ei);
-void routerset_get_all_routers(smartlist_t *out, const routerset_t *routerset,
- int running_only);
-void routersets_get_disjunction(smartlist_t *target, const smartlist_t *source,
- const routerset_t *include,
- const routerset_t *exclude, int running_only);
-void routerset_subtract_routers(smartlist_t *out,
- const routerset_t *routerset);
-char *routerset_to_string(const routerset_t *routerset);
-void routerset_refresh_countries(routerset_t *target);
-int routerset_equal(const routerset_t *old, const routerset_t *new);
-void routerset_free(routerset_t *routerset);
-void routerinfo_set_country(routerinfo_t *ri);
-void routerlist_refresh_countries(void);
-void refresh_all_country_info(void);
-
-int hid_serv_get_responsible_directories(smartlist_t *responsible_dirs,
- const char *id);
-int hid_serv_acting_as_directory(void);
-int hid_serv_responsible_for_desc_id(const char *id);
-
/********************************* routerparse.c ************************/
#define MAX_STATUS_TAG_LEN 32
@@ -4568,71 +3483,10 @@ typedef struct tor_version_t {
int patchlevel;
char status_tag[MAX_STATUS_TAG_LEN];
int svn_revision;
-} tor_version_t;
-int router_get_router_hash(const char *s, size_t s_len, char *digest);
-int router_get_dir_hash(const char *s, char *digest);
-int router_get_runningrouters_hash(const char *s, char *digest);
-int router_get_networkstatus_v2_hash(const char *s, char *digest);
-int router_get_networkstatus_v3_hash(const char *s, char *digest);
-int router_get_extrainfo_hash(const char *s, char *digest);
-int router_append_dirobj_signature(char *buf, size_t buf_len,
- const char *digest,
- crypto_pk_env_t *private_key);
-int router_parse_list_from_string(const char **s, const char *eos,
- smartlist_t *dest,
- saved_location_t saved_location,
- int is_extrainfo,
- int allow_annotations,
- const char *prepend_annotations);
-int router_parse_routerlist_from_directory(const char *s,
- routerlist_t **dest,
- crypto_pk_env_t *pkey,
- int check_version,
- int write_to_cache);
-int router_parse_runningrouters(const char *str);
-int router_parse_directory(const char *str);
-routerinfo_t *router_parse_entry_from_string(const char *s, const char *end,
- int cache_copy,
- int allow_annotations,
- const char *prepend_annotations);
-extrainfo_t *extrainfo_parse_entry_from_string(const char *s, const char *end,
- int cache_copy, struct digest_ri_map_t *routermap);
-addr_policy_t *router_parse_addr_policy_item_from_string(const char *s,
- int assume_action);
-version_status_t tor_version_is_obsolete(const char *myversion,
- const char *versionlist);
-int tor_version_parse(const char *s, tor_version_t *out);
-int tor_version_as_new_as(const char *platform, const char *cutoff);
-int tor_version_compare(tor_version_t *a, tor_version_t *b);
-void sort_version_list(smartlist_t *lst, int remove_duplicates);
-void assert_addr_policy_ok(smartlist_t *t);
-void dump_distinct_digest_count(int severity);
-
-networkstatus_v2_t *networkstatus_v2_parse_from_string(const char *s);
-networkstatus_t *networkstatus_parse_vote_from_string(const char *s,
- const char **eos_out,
- networkstatus_type_t ns_type);
-ns_detached_signatures_t *networkstatus_parse_detached_signatures(
- const char *s, const char *eos);
-
-authority_cert_t *authority_cert_parse_from_string(const char *s,
- const char **end_of_string);
-int rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
- char *desc_id_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);
-int rend_decrypt_introduction_points(char **ipos_decrypted,
- size_t *ipos_decrypted_size,
- const char *descriptor_cookie,
- const char *ipos_encrypted,
- size_t ipos_encrypted_size);
-int rend_parse_introduction_points(rend_service_descriptor_t *parsed,
- const char *intro_points_encoded,
- size_t intro_points_encoded_size);
-int rend_parse_client_keys(strmap_t *parsed_clients, const char *str);
+ int git_tag_len;
+ char git_tag[DIGEST_LEN];
+} tor_version_t;
#endif
diff --git a/src/or/policies.c b/src/or/policies.c
index 7299b7db3c..4fd0904152 100644
--- a/src/or/policies.c
+++ b/src/or/policies.c
@@ -9,6 +9,10 @@
**/
#include "or.h"
+#include "config.h"
+#include "dirserv.h"
+#include "policies.h"
+#include "routerparse.h"
#include "ht.h"
/** Policy that addresses for incoming SOCKS connections must match. */
@@ -344,7 +348,8 @@ validate_addr_policies(or_options_t *options, char **msg)
*msg = NULL;
if (policies_parse_exit_policy(options->ExitPolicy, &addr_policy,
- options->ExitPolicyRejectPrivate, NULL))
+ options->ExitPolicyRejectPrivate, NULL,
+ !options->BridgeRelay))
REJECT("Error in ExitPolicy entry.");
/* The rest of these calls *append* to addr_policy. So don't actually
@@ -375,14 +380,8 @@ validate_addr_policies(or_options_t *options, char **msg)
if (parse_addr_policy(options->ReachableDirAddresses, &addr_policy,
ADDR_POLICY_ACCEPT))
REJECT("Error in ReachableDirAddresses entry.");
- if (parse_addr_policy(options->AuthDirReject, &addr_policy,
- ADDR_POLICY_REJECT))
- REJECT("Error in AuthDirReject entry.");
- if (parse_addr_policy(options->AuthDirInvalid, &addr_policy,
- ADDR_POLICY_REJECT))
- REJECT("Error in AuthDirInvalid entry.");
-err:
+ err:
addr_policy_list_free(addr_policy);
return *msg ? -1 : 0;
#undef REJECT
@@ -829,14 +828,16 @@ exit_policy_remove_redundancies(smartlist_t *dest)
"reject *:6346-6429,reject *:6699,reject *:6881-6999,accept *:*"
/** Parse the exit policy <b>cfg</b> into the linked list *<b>dest</b>. If
- * cfg doesn't end in an absolute accept or reject, add the default exit
+ * cfg doesn't end in an absolute accept or reject and if
+ * <b>add_default_policy</b> is true, add the default exit
* policy afterwards. If <b>rejectprivate</b> is true, prepend
* "reject private:*" to the policy. Return -1 if we can't parse cfg,
* else return 0.
*/
int
policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
- int rejectprivate, const char *local_address)
+ int rejectprivate, const char *local_address,
+ int add_default_policy)
{
if (rejectprivate) {
append_exit_policy_string(dest, "reject private:*");
@@ -848,8 +849,10 @@ policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
}
if (parse_addr_policy(cfg, dest, -1))
return -1;
- append_exit_policy_string(dest, DEFAULT_EXIT_POLICY);
-
+ if (add_default_policy)
+ append_exit_policy_string(dest, DEFAULT_EXIT_POLICY);
+ else
+ append_exit_policy_string(dest, "reject *:*");
exit_policy_remove_redundancies(*dest);
return 0;
@@ -866,6 +869,49 @@ policies_set_router_exitpolicy_to_reject_all(routerinfo_t *r)
smartlist_add(r->exit_policy, item);
}
+/** Return 1 if there is at least one /8 subnet in <b>policy</b> that
+ * allows exiting to <b>port</b>. Otherwise, return 0. */
+static int
+exit_policy_is_general_exit_helper(smartlist_t *policy, int port)
+{
+ uint32_t mask, ip, i;
+ /* Is this /8 rejected (1), or undecided (0)? */
+ char subnet_status[256];
+
+ memset(subnet_status, 0, sizeof(subnet_status));
+ SMARTLIST_FOREACH(policy, addr_policy_t *, p, {
+ if (p->prt_min > port || p->prt_max < port)
+ continue; /* Doesn't cover our port. */
+ mask = 0;
+ tor_assert(p->maskbits <= 32);
+
+ if (p->maskbits)
+ mask = UINT32_MAX<<(32-p->maskbits);
+ ip = tor_addr_to_ipv4h(&p->addr);
+
+ /* Calculate the first and last subnet that this exit policy touches
+ * and set it as loop boundaries. */
+ for (i = ((mask & ip)>>24); i <= (~((mask & ip) ^ mask)>>24); ++i) {
+ tor_addr_t addr;
+ if (subnet_status[i] != 0)
+ continue; /* We already reject some part of this /8 */
+ tor_addr_from_ipv4h(&addr, i<<24);
+ if (tor_addr_is_internal(&addr, 0))
+ continue; /* Local or non-routable addresses */
+ if (p->policy_type == ADDR_POLICY_ACCEPT) {
+ if (p->maskbits > 8)
+ continue; /* Narrower than a /8. */
+ /* We found an allowed subnet of at least size /8. Done
+ * for this port! */
+ return 1;
+ } else if (p->policy_type == ADDR_POLICY_REJECT) {
+ subnet_status[i] = 1;
+ }
+ }
+ });
+ return 0;
+}
+
/** Return true iff <b>ri</b> is "useful as an exit node", meaning
* it allows exit to at least one /8 address space for at least
* two of ports 80, 443, and 6667. */
@@ -879,19 +925,7 @@ exit_policy_is_general_exit(smartlist_t *policy)
return 0;
for (i = 0; i < 3; ++i) {
- SMARTLIST_FOREACH(policy, addr_policy_t *, p, {
- if (p->prt_min > ports[i] || p->prt_max < ports[i])
- continue; /* Doesn't cover our port. */
- if (p->maskbits > 8)
- continue; /* Narrower than a /8. */
- if (tor_addr_is_loopback(&p->addr))
- continue; /* 127.x or ::1. */
- /* We have a match that is at least a /8. */
- if (p->policy_type == ADDR_POLICY_ACCEPT) {
- ++n_allowed;
- break; /* stop considering this port */
- }
- });
+ n_allowed += exit_policy_is_general_exit_helper(policy, ports[i]);
}
return n_allowed >= 2;
}
@@ -1238,7 +1272,7 @@ policy_summarize(smartlist_t *policy)
result = tor_malloc(final_size);
tor_snprintf(result, final_size, "%s %s", prefix, shorter_str);
-cleanup:
+ cleanup:
/* cleanup */
SMARTLIST_FOREACH(summary, policy_summary_item_t *, s, tor_free(s));
smartlist_free(summary);
@@ -1258,9 +1292,11 @@ cleanup:
* about "exit-policy/..." */
int
getinfo_helper_policies(control_connection_t *conn,
- const char *question, char **answer)
+ const char *question, char **answer,
+ const char **errmsg)
{
(void) conn;
+ (void) errmsg;
if (!strcmp(question, "exit-policy/default")) {
*answer = tor_strdup(DEFAULT_EXIT_POLICY);
}
@@ -1271,7 +1307,8 @@ getinfo_helper_policies(control_connection_t *conn,
void
addr_policy_list_free(smartlist_t *lst)
{
- if (!lst) return;
+ if (!lst)
+ return;
SMARTLIST_FOREACH(lst, addr_policy_t *, policy, addr_policy_free(policy));
smartlist_free(lst);
}
@@ -1280,19 +1317,20 @@ addr_policy_list_free(smartlist_t *lst)
void
addr_policy_free(addr_policy_t *p)
{
- if (p) {
- if (--p->refcnt <= 0) {
- if (p->is_canonical) {
- policy_map_ent_t search, *found;
- search.policy = p;
- found = HT_REMOVE(policy_map, &policy_root, &search);
- if (found) {
- tor_assert(p == found->policy);
- tor_free(found);
- }
+ if (!p)
+ return;
+
+ if (--p->refcnt <= 0) {
+ if (p->is_canonical) {
+ policy_map_ent_t search, *found;
+ search.policy = p;
+ found = HT_REMOVE(policy_map, &policy_root, &search);
+ if (found) {
+ tor_assert(p == found->policy);
+ tor_free(found);
}
- tor_free(p);
}
+ tor_free(p);
}
}
diff --git a/src/or/policies.h b/src/or/policies.h
new file mode 100644
index 0000000000..dd46f4de9c
--- /dev/null
+++ b/src/or/policies.h
@@ -0,0 +1,60 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file policies.h
+ * \brief Header file for policies.c.
+ **/
+
+#ifndef _TOR_POLICIES_H
+#define _TOR_POLICIES_H
+
+/* (length of "accept 255.255.255.255/255.255.255.255:65535-65535\n" plus a
+ * NUL.)
+ */
+#define POLICY_BUF_LEN 52
+
+int firewall_is_fascist_or(void);
+int fascist_firewall_allows_address_or(const tor_addr_t *addr, uint16_t port);
+int fascist_firewall_allows_or(routerinfo_t *ri);
+int fascist_firewall_allows_address_dir(const tor_addr_t *addr, uint16_t port);
+int dir_policy_permits_address(const tor_addr_t *addr);
+int socks_policy_permits_address(const tor_addr_t *addr);
+int authdir_policy_permits_address(uint32_t addr, uint16_t port);
+int authdir_policy_valid_address(uint32_t addr, uint16_t port);
+int authdir_policy_baddir_address(uint32_t addr, uint16_t port);
+int authdir_policy_badexit_address(uint32_t addr, uint16_t port);
+
+int validate_addr_policies(or_options_t *options, char **msg);
+void policy_expand_private(smartlist_t **policy);
+int policies_parse_from_options(or_options_t *options);
+
+addr_policy_t *addr_policy_get_canonical_entry(addr_policy_t *ent);
+int cmp_addr_policies(smartlist_t *a, smartlist_t *b);
+addr_policy_result_t compare_tor_addr_to_addr_policy(const tor_addr_t *addr,
+ uint16_t port, const smartlist_t *policy);
+addr_policy_result_t compare_addr_to_addr_policy(uint32_t addr,
+ uint16_t port, const smartlist_t *policy);
+int policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
+ int rejectprivate, const char *local_address,
+ int add_default_policy);
+void policies_set_router_exitpolicy_to_reject_all(routerinfo_t *exitrouter);
+int exit_policy_is_general_exit(smartlist_t *policy);
+int policy_is_reject_star(const smartlist_t *policy);
+int getinfo_helper_policies(control_connection_t *conn,
+ const char *question, char **answer,
+ const char **errmsg);
+int policy_write_item(char *buf, size_t buflen, addr_policy_t *item,
+ int format_for_desc);
+
+void addr_policy_list_free(smartlist_t *p);
+void addr_policy_free(addr_policy_t *p);
+void policies_free_all(void);
+
+char *policy_summarize(smartlist_t *policy);
+
+#endif
+
diff --git a/src/or/reasons.c b/src/or/reasons.c
index 97fe0f83a7..aa7972be5b 100644
--- a/src/or/reasons.c
+++ b/src/or/reasons.c
@@ -9,6 +9,8 @@
**/
#include "or.h"
+#include "config.h"
+#include "reasons.h"
/***************************** Edge (stream) reasons **********************/
@@ -332,9 +334,78 @@ circuit_end_reason_to_control_string(int reason)
return "NOPATH";
case END_CIRC_REASON_NOSUCHSERVICE:
return "NOSUCHSERVICE";
+ case END_CIRC_REASON_MEASUREMENT_EXPIRED:
+ return "MEASUREMENT_EXPIRED";
default:
log_warn(LD_BUG, "Unrecognized reason code %d", (int)reason);
return NULL;
}
}
+/** Return a string corresponding to a SOCKS4 reponse code. */
+const char *
+socks4_response_code_to_string(uint8_t code)
+{
+ switch (code) {
+ case 0x5a:
+ return "connection accepted";
+ case 0x5b:
+ return "server rejected connection";
+ case 0x5c:
+ return "server cannot connect to identd on this client";
+ case 0x5d:
+ return "user id does not match identd";
+ default:
+ return "invalid SOCKS 4 response code";
+ }
+}
+
+/** Return a string corresponding to a SOCKS5 reponse code. */
+const char *
+socks5_response_code_to_string(uint8_t code)
+{
+ switch (code) {
+ case 0x00:
+ return "connection accepted";
+ case 0x01:
+ return "general SOCKS server failure";
+ case 0x02:
+ return "connection not allowed by ruleset";
+ case 0x03:
+ return "Network unreachable";
+ case 0x04:
+ return "Host unreachable";
+ case 0x05:
+ return "Connection refused";
+ case 0x06:
+ return "TTL expired";
+ case 0x07:
+ return "Command not supported";
+ case 0x08:
+ return "Address type not supported";
+ default:
+ return "unknown reason";
+ }
+}
+
+/** Return a string corresponding to a bandwidht_weight_rule_t */
+const char *
+bandwidth_weight_rule_to_string(bandwidth_weight_rule_t rule)
+{
+ switch (rule)
+ {
+ case NO_WEIGHTING:
+ return "no weighting";
+ case WEIGHT_FOR_EXIT:
+ return "weight as exit";
+ case WEIGHT_FOR_MID:
+ return "weight as middle node";
+ case WEIGHT_FOR_GUARD:
+ return "weight as guard";
+ case WEIGHT_FOR_DIR:
+ return "weight as directory";
+ default:
+ return "unknown rule";
+ }
+}
+
diff --git a/src/or/reasons.h b/src/or/reasons.h
new file mode 100644
index 0000000000..b87d36a77a
--- /dev/null
+++ b/src/or/reasons.h
@@ -0,0 +1,31 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file reasons.h
+ * \brief Header file for reasons.c.
+ **/
+
+#ifndef _TOR_REASONS_H
+#define _TOR_REASONS_H
+
+const char *stream_end_reason_to_control_string(int reason);
+const char *stream_end_reason_to_string(int reason);
+socks5_reply_status_t stream_end_reason_to_socks5_response(int reason);
+uint8_t errno_to_stream_end_reason(int e);
+
+const char *orconn_end_reason_to_control_string(int r);
+int tls_error_to_orconn_end_reason(int e);
+int errno_to_orconn_end_reason(int e);
+
+const char *circuit_end_reason_to_control_string(int reason);
+const char *socks4_response_code_to_string(uint8_t code);
+const char *socks5_response_code_to_string(uint8_t code);
+
+const char *bandwidth_weight_rule_to_string(enum bandwidth_weight_rule_t rule);
+
+#endif
+
diff --git a/src/or/relay.c b/src/or/relay.c
index 02671473e6..c951cab560 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -10,8 +10,26 @@
* receiving from circuits, plus queuing on circuits.
**/
+#include <math.h>
#include "or.h"
+#include "buffers.h"
+#include "circuitbuild.h"
+#include "circuitlist.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_edge.h"
+#include "connection_or.h"
+#include "control.h"
+#include "geoip.h"
+#include "main.h"
#include "mempool.h"
+#include "networkstatus.h"
+#include "policies.h"
+#include "reasons.h"
+#include "relay.h"
+#include "rendcommon.h"
+#include "routerlist.h"
+#include "routerparse.h"
static int relay_crypt(circuit_t *circ, cell_t *cell,
cell_direction_t cell_direction,
@@ -20,20 +38,46 @@ static edge_connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell,
cell_direction_t cell_direction,
crypt_path_t *layer_hint);
-static int
-connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
- edge_connection_t *conn,
- crypt_path_t *layer_hint);
-static void
-circuit_consider_sending_sendme(circuit_t *circ, crypt_path_t *layer_hint);
+static int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
+ edge_connection_t *conn,
+ crypt_path_t *layer_hint);
+static void circuit_consider_sending_sendme(circuit_t *circ,
+ crypt_path_t *layer_hint);
+static void circuit_resume_edge_reading(circuit_t *circ,
+ crypt_path_t *layer_hint);
+static int circuit_resume_edge_reading_helper(edge_connection_t *conn,
+ circuit_t *circ,
+ crypt_path_t *layer_hint);
+static int circuit_consider_stop_edge_reading(circuit_t *circ,
+ crypt_path_t *layer_hint);
+static int circuit_queue_streams_are_blocked(circuit_t *circ);
+
+/** Cache the current hi-res time; the cache gets reset when libevent
+ * calls us. */
+
+static struct timeval cached_time_hires = {0, 0};
+
+/** Stop reading on edge connections when we have this many cells
+ * waiting on the appropriate queue. */
+#define CELL_QUEUE_HIGHWATER_SIZE 256
+/** Start reading from edge connections again when we get down to this many
+ * cells. */
+#define CELL_QUEUE_LOWWATER_SIZE 64
+
static void
-circuit_resume_edge_reading(circuit_t *circ, crypt_path_t *layer_hint);
-static int
-circuit_resume_edge_reading_helper(edge_connection_t *conn,
- circuit_t *circ,
- crypt_path_t *layer_hint);
-static int
-circuit_consider_stop_edge_reading(circuit_t *circ, crypt_path_t *layer_hint);
+tor_gettimeofday_cached(struct timeval *tv)
+{
+ if (cached_time_hires.tv_sec == 0) {
+ tor_gettimeofday(&cached_time_hires);
+ }
+ *tv = cached_time_hires;
+}
+
+void
+tor_gettimeofday_cache_clear(void)
+{
+ cached_time_hires.tv_sec = 0;
+}
/** Stats: how many relay cells have originated at this hop, or have
* been relayed onward (not recognized at this hop)?
@@ -230,7 +274,7 @@ circuit_receive_relay_cell(cell_t *cell, circuit_t *circ,
* we might kill the circ before we relay
* the cells. */
- append_cell_to_circuit_queue(circ, or_conn, cell, cell_direction);
+ append_cell_to_circuit_queue(circ, or_conn, cell, cell_direction, 0);
return 0;
}
@@ -327,7 +371,7 @@ relay_crypt(circuit_t *circ, cell_t *cell, cell_direction_t cell_direction,
static int
circuit_package_relay_cell(cell_t *cell, circuit_t *circ,
cell_direction_t cell_direction,
- crypt_path_t *layer_hint)
+ crypt_path_t *layer_hint, streamid_t on_stream)
{
or_connection_t *conn; /* where to send the cell */
@@ -371,7 +415,7 @@ circuit_package_relay_cell(cell_t *cell, circuit_t *circ,
}
++stats_n_relay_cells_relayed;
- append_cell_to_circuit_queue(circ, conn, cell, cell_direction);
+ append_cell_to_circuit_queue(circ, conn, cell, cell_direction, on_stream);
return 0;
}
@@ -496,7 +540,7 @@ relay_command_to_string(uint8_t command)
* return 0.
*/
int
-relay_send_command_from_edge(uint16_t stream_id, circuit_t *circ,
+relay_send_command_from_edge(streamid_t stream_id, circuit_t *circ,
uint8_t relay_command, const char *payload,
size_t payload_len, crypt_path_t *cpath_layer)
{
@@ -531,6 +575,12 @@ relay_send_command_from_edge(uint16_t stream_id, circuit_t *circ,
log_debug(LD_OR,"delivering %d cell %s.", relay_command,
cell_direction == CELL_DIRECTION_OUT ? "forward" : "backward");
+ /* If we are sending an END cell and this circuit is used for a tunneled
+ * directory request, advance its state. */
+ if (relay_command == RELAY_COMMAND_END && circ->dirreq_id)
+ geoip_change_dirreq_state(circ->dirreq_id, DIRREQ_TUNNELED,
+ DIRREQ_END_CELL_SENT);
+
if (cell_direction == CELL_DIRECTION_OUT && circ->n_conn) {
/* if we're using relaybandwidthrate, this conn wants priority */
circ->n_conn->client_used = approx_time();
@@ -540,17 +590,11 @@ relay_send_command_from_edge(uint16_t stream_id, circuit_t *circ,
origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
if (origin_circ->remaining_relay_early_cells > 0 &&
(relay_command == RELAY_COMMAND_EXTEND ||
- (cpath_layer != origin_circ->cpath &&
- !CIRCUIT_PURPOSE_IS_ESTABLISHED_REND(circ->purpose)))) {
- /* If we've got any relay_early cells left, and we're sending
- * an extend cell or (we're not talking to the first hop and we're
- * not talking to a rendezvous circuit), use one of them.
- * Don't worry about the conn protocol version:
+ cpath_layer != origin_circ->cpath)) {
+ /* If we've got any relay_early cells left and (we're sending
+ * an extend cell or we're not talking to the first hop), use
+ * one of them. Don't worry about the conn protocol version:
* append_cell_to_circuit_queue will fix it up. */
- /* XXX For now, clients don't use RELAY_EARLY cells when sending
- * relay cells on rendezvous circuits. See bug 1038. Eventually,
- * we can take this behavior away in favor of having clients avoid
- * rendezvous points running 0.2.1.3-alpha through 0.2.1.18. -RD */
cell.command = CELL_RELAY_EARLY;
--origin_circ->remaining_relay_early_cells;
log_debug(LD_OR, "Sending a RELAY_EARLY cell; %d remaining.",
@@ -578,8 +622,8 @@ relay_send_command_from_edge(uint16_t stream_id, circuit_t *circ,
}
}
- if (circuit_package_relay_cell(&cell, circ, cell_direction, cpath_layer)
- < 0) {
+ if (circuit_package_relay_cell(&cell, circ, cell_direction, cpath_layer,
+ stream_id) < 0) {
log_warn(LD_BUG,"circuit_package_relay_cell failed. Closing.");
circuit_mark_for_close(circ, END_CIRC_REASON_INTERNAL);
return -1;
@@ -901,7 +945,7 @@ connection_edge_process_relay_cell_not_open(
}
/* handle anything that might have queued */
- if (connection_edge_package_raw_inbuf(conn, 1) < 0) {
+ if (connection_edge_package_raw_inbuf(conn, 1, NULL) < 0) {
/* (We already sent an end cell if possible) */
connection_mark_for_close(TO_CONN(conn));
return 0;
@@ -999,7 +1043,8 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
relay_header_unpack(&rh, cell->payload);
// log_fn(LOG_DEBUG,"command %d stream %d", rh.command, rh.stream_id);
num_seen++;
- log_debug(domain, "Now seen %d relay cells here.", num_seen);
+ log_debug(domain, "Now seen %d relay cells here (command %d, stream %d).",
+ num_seen, rh.command, rh.stream_id);
if (rh.length > RELAY_PAYLOAD_SIZE) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
@@ -1038,6 +1083,16 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
"Begin cell for known stream. Dropping.");
return 0;
}
+ if (rh.command == RELAY_COMMAND_BEGIN_DIR) {
+ /* Assign this circuit and its app-ward OR connection a unique ID,
+ * so that we can measure download times. The local edge and dir
+ * connection will be assigned the same ID when they are created
+ * and linked. */
+ static uint64_t next_id = 0;
+ circ->dirreq_id = ++next_id;
+ TO_CONN(TO_OR_CIRCUIT(circ)->p_conn)->dirreq_id = circ->dirreq_id;
+ }
+
return connection_exit_begin_conn(cell, circ);
case RELAY_COMMAND_DATA:
++stats_n_data_cells_received;
@@ -1131,6 +1186,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
}
if (circ->n_conn) {
uint8_t trunc_reason = *(uint8_t*)(cell->payload + RELAY_HEADER_SIZE);
+ circuit_clear_cell_queue(circ, circ->n_conn);
connection_or_send_destroy(circ->n_circ_id, circ->n_conn,
trunc_reason);
circuit_set_n_circid_orconn(circ, 0, NULL);
@@ -1179,9 +1235,13 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
conn->package_window += STREAMWINDOW_INCREMENT;
log_debug(domain,"stream-level sendme, packagewindow now %d.",
conn->package_window);
+ if (circuit_queue_streams_are_blocked(circ)) {
+ /* Still waiting for queue to flush; don't touch conn */
+ return 0;
+ }
connection_start_reading(TO_CONN(conn));
/* handle whatever might still be on the inbuf */
- if (connection_edge_package_raw_inbuf(conn, 1) < 0) {
+ if (connection_edge_package_raw_inbuf(conn, 1, NULL) < 0) {
/* (We already sent an end cell if possible) */
connection_mark_for_close(TO_CONN(conn));
return 0;
@@ -1247,15 +1307,19 @@ uint64_t stats_n_data_cells_received = 0;
* ever received were completely full of data. */
uint64_t stats_n_data_bytes_received = 0;
-/** While conn->inbuf has an entire relay payload of bytes on it,
- * and the appropriate package windows aren't empty, grab a cell
- * and send it down the circuit.
+/** If <b>conn</b> has an entire relay payload of bytes on its inbuf (or
+ * <b>package_partial</b> is true), and the appropriate package windows aren't
+ * empty, grab a cell and send it down the circuit.
+ *
+ * If *<b>max_cells</b> is given, package no more than max_cells. Decrement
+ * *<b>max_cells</b> by the number of cells packaged.
*
* Return -1 (and send a RELAY_COMMAND_END cell if necessary) if conn should
* be marked for close, else return 0.
*/
int
-connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial)
+connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
+ int *max_cells)
{
size_t amount_to_process, length;
char payload[CELL_PAYLOAD_SIZE];
@@ -1271,7 +1335,10 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial)
return 0;
}
-repeat_connection_edge_package_raw_inbuf:
+ if (max_cells && *max_cells <= 0)
+ return 0;
+
+ repeat_connection_edge_package_raw_inbuf:
circ = circuit_get_by_edge_conn(conn);
if (!circ) {
@@ -1332,6 +1399,12 @@ repeat_connection_edge_package_raw_inbuf:
}
log_debug(domain,"conn->package_window is now %d",conn->package_window);
+ if (max_cells) {
+ *max_cells -= 1;
+ if (*max_cells <= 0)
+ return 0;
+ }
+
/* handle more if there's more, or return 0 if there isn't */
goto repeat_connection_edge_package_raw_inbuf;
}
@@ -1379,7 +1452,10 @@ connection_edge_consider_sending_sendme(edge_connection_t *conn)
static void
circuit_resume_edge_reading(circuit_t *circ, crypt_path_t *layer_hint)
{
-
+ if (circuit_queue_streams_are_blocked(circ)) {
+ log_debug(layer_hint?LD_APP:LD_EXIT,"Too big queue, no resuming");
+ return;
+ }
log_debug(layer_hint?LD_APP:LD_EXIT,"resuming");
if (CIRCUIT_IS_ORIGIN(circ))
@@ -1395,31 +1471,136 @@ circuit_resume_edge_reading(circuit_t *circ, crypt_path_t *layer_hint)
* of a linked list of edge streams that should each be considered.
*/
static int
-circuit_resume_edge_reading_helper(edge_connection_t *conn,
+circuit_resume_edge_reading_helper(edge_connection_t *first_conn,
circuit_t *circ,
crypt_path_t *layer_hint)
{
- for ( ; conn; conn=conn->next_stream) {
- if (conn->_base.marked_for_close)
+ edge_connection_t *conn;
+ int n_packaging_streams, n_streams_left;
+ int packaged_this_round;
+ int cells_on_queue;
+ int cells_per_conn;
+ edge_connection_t *chosen_stream = NULL;
+
+ /* How many cells do we have space for? It will be the minimum of
+ * the number needed to exhaust the package window, and the minimum
+ * needed to fill the cell queue. */
+ int max_to_package = circ->package_window;
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ cells_on_queue = circ->n_conn_cells.n;
+ } else {
+ or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
+ cells_on_queue = or_circ->p_conn_cells.n;
+ }
+ if (CELL_QUEUE_HIGHWATER_SIZE - cells_on_queue < max_to_package)
+ max_to_package = CELL_QUEUE_HIGHWATER_SIZE - cells_on_queue;
+
+ /* Once we used to start listening on the streams in the order they
+ * appeared in the linked list. That leads to starvation on the
+ * streams that appeared later on the list, since the first streams
+ * would always get to read first. Instead, we just pick a random
+ * stream on the list, and enable reading for streams starting at that
+ * point (and wrapping around as if the list were circular). It would
+ * probably be better to actually remember which streams we've
+ * serviced in the past, but this is simple and effective. */
+
+ /* Select a stream uniformly at random from the linked list. We
+ * don't need cryptographic randomness here. */
+ {
+ int num_streams = 0;
+ for (conn = first_conn; conn; conn = conn->next_stream) {
+ num_streams++;
+ if ((tor_weak_random() % num_streams)==0)
+ chosen_stream = conn;
+ /* Invariant: chosen_stream has been chosen uniformly at random from
+ * among the first num_streams streams on first_conn. */
+ }
+ }
+
+ /* Count how many non-marked streams there are that have anything on
+ * their inbuf, and enable reading on all of the connections. */
+ n_packaging_streams = 0;
+ /* Activate reading starting from the chosen stream */
+ for (conn=chosen_stream; conn; conn = conn->next_stream) {
+ /* Start reading for the streams starting from here */
+ if (conn->_base.marked_for_close || conn->package_window <= 0)
continue;
- if ((!layer_hint && conn->package_window > 0) ||
- (layer_hint && conn->package_window > 0 &&
- conn->cpath_layer == layer_hint)) {
+ if (!layer_hint || conn->cpath_layer == layer_hint) {
connection_start_reading(TO_CONN(conn));
+
+ if (buf_datalen(conn->_base.inbuf) > 0)
+ ++n_packaging_streams;
+ }
+ }
+ /* Go back and do the ones we skipped, circular-style */
+ for (conn = first_conn; conn != chosen_stream; conn = conn->next_stream) {
+ if (conn->_base.marked_for_close || conn->package_window <= 0)
+ continue;
+ if (!layer_hint || conn->cpath_layer == layer_hint) {
+ connection_start_reading(TO_CONN(conn));
+
+ if (buf_datalen(conn->_base.inbuf) > 0)
+ ++n_packaging_streams;
+ }
+ }
+
+ if (n_packaging_streams == 0) /* avoid divide-by-zero */
+ return 0;
+
+ again:
+
+ cells_per_conn = CEIL_DIV(max_to_package, n_packaging_streams);
+
+ packaged_this_round = 0;
+ n_streams_left = 0;
+
+ /* Iterate over all connections. Package up to cells_per_conn cells on
+ * each. Update packaged_this_round with the total number of cells
+ * packaged, and n_streams_left with the number that still have data to
+ * package.
+ */
+ for (conn=first_conn; conn; conn=conn->next_stream) {
+ if (conn->_base.marked_for_close || conn->package_window <= 0)
+ continue;
+ if (!layer_hint || conn->cpath_layer == layer_hint) {
+ int n = cells_per_conn, r;
/* handle whatever might still be on the inbuf */
- if (connection_edge_package_raw_inbuf(conn, 1)<0) {
- /* (We already sent an end cell if possible) */
+ r = connection_edge_package_raw_inbuf(conn, 1, &n);
+
+ /* Note how many we packaged */
+ packaged_this_round += (cells_per_conn-n);
+
+ if (r<0) {
+ /* Problem while packaging. (We already sent an end cell if
+ * possible) */
connection_mark_for_close(TO_CONN(conn));
continue;
}
+ /* If there's still data to read, we'll be coming back to this stream. */
+ if (buf_datalen(conn->_base.inbuf))
+ ++n_streams_left;
+
/* If the circuit won't accept any more data, return without looking
* at any more of the streams. Any connections that should be stopped
* have already been stopped by connection_edge_package_raw_inbuf. */
if (circuit_consider_stop_edge_reading(circ, layer_hint))
return -1;
+ /* XXXX should we also stop immediately if we fill up the cell queue?
+ * Probably. */
}
}
+
+ /* If we made progress, and we are willing to package more, and there are
+ * any streams left that want to package stuff... try again!
+ */
+ if (packaged_this_round && packaged_this_round < max_to_package &&
+ n_streams_left) {
+ max_to_package -= packaged_this_round;
+ n_packaging_streams = n_streams_left;
+ goto again;
+ }
+
return 0;
}
@@ -1488,13 +1669,6 @@ circuit_consider_sending_sendme(circuit_t *circ, crypt_path_t *layer_hint)
}
}
-/** Stop reading on edge connections when we have this many cells
- * waiting on the appropriate queue. */
-#define CELL_QUEUE_HIGHWATER_SIZE 256
-/** Start reading from edge connections again when we get down to this many
- * cells. */
-#define CELL_QUEUE_LOWWATER_SIZE 64
-
#ifdef ACTIVE_CIRCUITS_PARANOIA
#define assert_active_circuits_ok_paranoid(conn) \
assert_active_circuits_ok(conn)
@@ -1508,6 +1682,10 @@ static int total_cells_allocated = 0;
/** A memory pool to allocate packed_cell_t objects. */
static mp_pool_t *cell_pool = NULL;
+/** Memory pool to allocate insertion_time_elem_t objects used for cell
+ * statistics. */
+static mp_pool_t *it_pool = NULL;
+
/** Allocate structures to hold cells. */
void
init_cell_pool(void)
@@ -1516,7 +1694,8 @@ init_cell_pool(void)
cell_pool = mp_pool_new(sizeof(packed_cell_t), 128*1024);
}
-/** Free all storage used to hold cells. */
+/** Free all storage used to hold cells (and insertion times if we measure
+ * cell statistics). */
void
free_cell_pool(void)
{
@@ -1525,6 +1704,10 @@ free_cell_pool(void)
mp_pool_destroy(cell_pool);
cell_pool = NULL;
}
+ if (it_pool) {
+ mp_pool_destroy(it_pool);
+ it_pool = NULL;
+ }
}
/** Free excess storage in cell pool. */
@@ -1537,7 +1720,7 @@ clean_cell_pool(void)
/** Release storage held by <b>cell</b>. */
static INLINE void
-packed_cell_free(packed_cell_t *cell)
+packed_cell_free_unchecked(packed_cell_t *cell)
{
--total_cells_allocated;
mp_pool_release(cell);
@@ -1599,7 +1782,38 @@ cell_queue_append(cell_queue_t *queue, packed_cell_t *cell)
void
cell_queue_append_packed_copy(cell_queue_t *queue, const cell_t *cell)
{
- cell_queue_append(queue, packed_cell_copy(cell));
+ packed_cell_t *copy = packed_cell_copy(cell);
+ /* Remember the time when this cell was put in the queue. */
+ if (get_options()->CellStatistics) {
+ struct timeval now;
+ uint32_t added;
+ insertion_time_queue_t *it_queue = queue->insertion_times;
+ if (!it_pool)
+ it_pool = mp_pool_new(sizeof(insertion_time_elem_t), 1024);
+ tor_gettimeofday_cached(&now);
+#define SECONDS_IN_A_DAY 86400L
+ added = (uint32_t)(((now.tv_sec % SECONDS_IN_A_DAY) * 100L)
+ + ((uint32_t)now.tv_usec / (uint32_t)10000L));
+ if (!it_queue) {
+ it_queue = tor_malloc_zero(sizeof(insertion_time_queue_t));
+ queue->insertion_times = it_queue;
+ }
+ if (it_queue->last && it_queue->last->insertion_time == added) {
+ it_queue->last->counter++;
+ } else {
+ insertion_time_elem_t *elem = mp_pool_get(it_pool);
+ elem->next = NULL;
+ elem->insertion_time = added;
+ elem->counter = 1;
+ if (it_queue->last) {
+ it_queue->last->next = elem;
+ it_queue->last = elem;
+ } else {
+ it_queue->first = it_queue->last = elem;
+ }
+ }
+ }
+ cell_queue_append(queue, copy);
}
/** Remove and free every cell in <b>queue</b>. */
@@ -1610,11 +1824,19 @@ cell_queue_clear(cell_queue_t *queue)
cell = queue->head;
while (cell) {
next = cell->next;
- packed_cell_free(cell);
+ packed_cell_free_unchecked(cell);
cell = next;
}
queue->head = queue->tail = NULL;
queue->n = 0;
+ if (queue->insertion_times) {
+ while (queue->insertion_times->first) {
+ insertion_time_elem_t *elem = queue->insertion_times->first;
+ queue->insertion_times->first = elem->next;
+ mp_pool_release(elem);
+ }
+ tor_free(queue->insertion_times);
+ }
}
/** Extract and return the cell at the head of <b>queue</b>; return NULL if
@@ -1666,8 +1888,226 @@ prev_circ_on_conn_p(circuit_t *circ, or_connection_t *conn)
}
}
+/** Helper for sorting cell_ewma_t values in their priority queue. */
+static int
+compare_cell_ewma_counts(const void *p1, const void *p2)
+{
+ const cell_ewma_t *e1=p1, *e2=p2;
+ if (e1->cell_count < e2->cell_count)
+ return -1;
+ else if (e1->cell_count > e2->cell_count)
+ return 1;
+ else
+ return 0;
+}
+
+/** Given a cell_ewma_t, return a pointer to the circuit containing it. */
+static circuit_t *
+cell_ewma_to_circuit(cell_ewma_t *ewma)
+{
+ if (ewma->is_for_p_conn) {
+ /* This is an or_circuit_t's p_cell_ewma. */
+ or_circuit_t *orcirc = SUBTYPE_P(ewma, or_circuit_t, p_cell_ewma);
+ return TO_CIRCUIT(orcirc);
+ } else {
+ /* This is some circuit's n_cell_ewma. */
+ return SUBTYPE_P(ewma, circuit_t, n_cell_ewma);
+ }
+}
+
+/* ==== Functions for scaling cell_ewma_t ====
+
+ When choosing which cells to relay first, we favor circuits that have been
+ quiet recently. This gives better latency on connections that aren't
+ pushing lots of data, and makes the network feel more interactive.
+
+ Conceptually, we take an exponentially weighted mean average of the number
+ of cells a circuit has sent, and allow active circuits (those with cells to
+ relay) to send cells in reverse order of their exponentially-weighted mean
+ average (EWMA) cell count. [That is, a cell sent N seconds ago 'counts'
+ F^N times as much as a cell sent now, for 0<F<1.0, and we favor the
+ circuit that has sent the fewest cells]
+
+ If 'double' had infinite precision, we could do this simply by counting a
+ cell sent at startup as having weight 1.0, and a cell sent N seconds later
+ as having weight F^-N. This way, we would never need to re-scale
+ any already-sent cells.
+
+ To prevent double from overflowing, we could count a cell sent now as
+ having weight 1.0 and a cell sent N seconds ago as having weight F^N.
+ This, however, would mean we'd need to re-scale *ALL* old circuits every
+ time we wanted to send a cell.
+
+ So as a compromise, we divide time into 'ticks' (currently, 10-second
+ increments) and say that a cell sent at the start of a current tick is
+ worth 1.0, a cell sent N seconds before the start of the current tick is
+ worth F^N, and a cell sent N seconds after the start of the current tick is
+ worth F^-N. This way we don't overflow, and we don't need to constantly
+ rescale.
+ */
+
+/** How long does a tick last (seconds)? */
+#define EWMA_TICK_LEN 10
+
+/** The default per-tick scale factor, if it hasn't been overridden by a
+ * consensus or a configuration setting. zero means "disabled". */
+#define EWMA_DEFAULT_HALFLIFE 0.0
+
+/** Given a timeval <b>now</b>, compute the cell_ewma tick in which it occurs
+ * and the fraction of the tick that has elapsed between the start of the tick
+ * and <b>now</b>. Return the former and store the latter in
+ * *<b>remainder_out</b>.
+ *
+ * These tick values are not meant to be shared between Tor instances, or used
+ * for other purposes. */
+static unsigned
+cell_ewma_tick_from_timeval(const struct timeval *now,
+ double *remainder_out)
+{
+ unsigned res = (unsigned) (now->tv_sec / EWMA_TICK_LEN);
+ /* rem */
+ double rem = (now->tv_sec % EWMA_TICK_LEN) +
+ ((double)(now->tv_usec)) / 1.0e6;
+ *remainder_out = rem / EWMA_TICK_LEN;
+ return res;
+}
+
+/** Compute and return the current cell_ewma tick. */
+unsigned
+cell_ewma_get_tick(void)
+{
+ return ((unsigned)approx_time() / EWMA_TICK_LEN);
+}
+
+/** The per-tick scale factor to be used when computing cell-count EWMA
+ * values. (A cell sent N ticks before the start of the current tick
+ * has value ewma_scale_factor ** N.)
+ */
+static double ewma_scale_factor = 0.1;
+static int ewma_enabled = 0;
+
+#define EPSILON 0.00001
+#define LOG_ONEHALF -0.69314718055994529
+
+/** Adjust the global cell scale factor based on <b>options</b> */
+void
+cell_ewma_set_scale_factor(or_options_t *options, networkstatus_t *consensus)
+{
+ int32_t halflife_ms;
+ double halflife;
+ const char *source;
+ if (options && options->CircuitPriorityHalflife >= -EPSILON) {
+ halflife = options->CircuitPriorityHalflife;
+ source = "CircuitPriorityHalflife in configuration";
+ } else if (consensus &&
+ (halflife_ms = networkstatus_get_param(
+ consensus, "CircuitPriorityHalflifeMsec", -1)) >= 0) {
+ halflife = ((double)halflife_ms)/1000.0;
+ source = "CircuitPriorityHalflifeMsec in consensus";
+ } else {
+ halflife = EWMA_DEFAULT_HALFLIFE;
+ source = "Default value";
+ }
+
+ if (halflife <= EPSILON) {
+ /* The cell EWMA algorithm is disabled. */
+ ewma_scale_factor = 0.1;
+ ewma_enabled = 0;
+ log_info(LD_OR,
+ "Disabled cell_ewma algorithm because of value in %s",
+ source);
+ } else {
+ /* convert halflife into halflife-per-tick. */
+ halflife /= EWMA_TICK_LEN;
+ /* compute per-tick scale factor. */
+ ewma_scale_factor = exp( LOG_ONEHALF / halflife );
+ ewma_enabled = 1;
+ log_info(LD_OR,
+ "Enabled cell_ewma algorithm because of value in %s; "
+ "scale factor is %lf per %d seconds",
+ source, ewma_scale_factor, EWMA_TICK_LEN);
+ }
+}
+
+/** Return the multiplier necessary to convert the value of a cell sent in
+ * 'from_tick' to one sent in 'to_tick'. */
+static INLINE double
+get_scale_factor(unsigned from_tick, unsigned to_tick)
+{
+ /* This math can wrap around, but that's okay: unsigned overflow is
+ well-defined */
+ int diff = (int)(to_tick - from_tick);
+ return pow(ewma_scale_factor, diff);
+}
+
+/** Adjust the cell count of <b>ewma</b> so that it is scaled with respect to
+ * <b>cur_tick</b> */
+static void
+scale_single_cell_ewma(cell_ewma_t *ewma, unsigned cur_tick)
+{
+ double factor = get_scale_factor(ewma->last_adjusted_tick, cur_tick);
+ ewma->cell_count *= factor;
+ ewma->last_adjusted_tick = cur_tick;
+}
+
+/** Adjust the cell count of every active circuit on <b>conn</b> so
+ * that they are scaled with respect to <b>cur_tick</b> */
+static void
+scale_active_circuits(or_connection_t *conn, unsigned cur_tick)
+{
+
+ double factor = get_scale_factor(
+ conn->active_circuit_pqueue_last_recalibrated,
+ cur_tick);
+ /** Ordinarily it isn't okay to change the value of an element in a heap,
+ * but it's okay here, since we are preserving the order. */
+ SMARTLIST_FOREACH(conn->active_circuit_pqueue, cell_ewma_t *, e, {
+ tor_assert(e->last_adjusted_tick ==
+ conn->active_circuit_pqueue_last_recalibrated);
+ e->cell_count *= factor;
+ e->last_adjusted_tick = cur_tick;
+ });
+ conn->active_circuit_pqueue_last_recalibrated = cur_tick;
+}
+
+/** Rescale <b>ewma</b> to the same scale as <b>conn</b>, and add it to
+ * <b>conn</b>'s priority queue of active circuits */
+static void
+add_cell_ewma_to_conn(or_connection_t *conn, cell_ewma_t *ewma)
+{
+ tor_assert(ewma->heap_index == -1);
+ scale_single_cell_ewma(ewma,
+ conn->active_circuit_pqueue_last_recalibrated);
+
+ smartlist_pqueue_add(conn->active_circuit_pqueue,
+ compare_cell_ewma_counts,
+ STRUCT_OFFSET(cell_ewma_t, heap_index),
+ ewma);
+}
+
+/** Remove <b>ewma</b> from <b>conn</b>'s priority queue of active circuits */
+static void
+remove_cell_ewma_from_conn(or_connection_t *conn, cell_ewma_t *ewma)
+{
+ tor_assert(ewma->heap_index != -1);
+ smartlist_pqueue_remove(conn->active_circuit_pqueue,
+ compare_cell_ewma_counts,
+ STRUCT_OFFSET(cell_ewma_t, heap_index),
+ ewma);
+}
+
+/** Remove and return the first cell_ewma_t from conn's priority queue of
+ * active circuits. Requires that the priority queue is nonempty. */
+static cell_ewma_t *
+pop_first_cell_ewma_from_conn(or_connection_t *conn)
+{
+ return smartlist_pqueue_pop(conn->active_circuit_pqueue,
+ compare_cell_ewma_counts,
+ STRUCT_OFFSET(cell_ewma_t, heap_index));
+}
+
/** Add <b>circ</b> to the list of circuits with pending cells on
- * <b>conn</b>. No effect if <b>circ</b> is already unlinked. */
+ * <b>conn</b>. No effect if <b>circ</b> is already linked. */
void
make_circuit_active_on_conn(circuit_t *circ, or_connection_t *conn)
{
@@ -1679,6 +2119,8 @@ make_circuit_active_on_conn(circuit_t *circ, or_connection_t *conn)
return;
}
+ assert_active_circuits_ok_paranoid(conn);
+
if (! conn->active_circuits) {
conn->active_circuits = circ;
*prevp = *nextp = circ;
@@ -1690,10 +2132,19 @@ make_circuit_active_on_conn(circuit_t *circ, or_connection_t *conn)
*prev_circ_on_conn_p(head, conn) = circ;
*prevp = old_tail;
}
+
+ if (circ->n_conn == conn) {
+ add_cell_ewma_to_conn(conn, &circ->n_cell_ewma);
+ } else {
+ or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
+ tor_assert(conn == orcirc->p_conn);
+ add_cell_ewma_to_conn(conn, &orcirc->p_cell_ewma);
+ }
+
assert_active_circuits_ok_paranoid(conn);
}
-/** Remove <b>circ</b> to the list of circuits with pending cells on
+/** Remove <b>circ</b> from the list of circuits with pending cells on
* <b>conn</b>. No effect if <b>circ</b> is already unlinked. */
void
make_circuit_inactive_on_conn(circuit_t *circ, or_connection_t *conn)
@@ -1707,6 +2158,8 @@ make_circuit_inactive_on_conn(circuit_t *circ, or_connection_t *conn)
return;
}
+ assert_active_circuits_ok_paranoid(conn);
+
tor_assert(next && prev);
tor_assert(*prev_circ_on_conn_p(next, conn) == circ);
tor_assert(*next_circ_on_conn_p(prev, conn) == circ);
@@ -1720,6 +2173,15 @@ make_circuit_inactive_on_conn(circuit_t *circ, or_connection_t *conn)
conn->active_circuits = next;
}
*prevp = *nextp = NULL;
+
+ if (circ->n_conn == conn) {
+ remove_cell_ewma_from_conn(conn, &circ->n_cell_ewma);
+ } else {
+ or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
+ tor_assert(conn == orcirc->p_conn);
+ remove_cell_ewma_from_conn(conn, &orcirc->p_cell_ewma);
+ }
+
assert_active_circuits_ok_paranoid(conn);
}
@@ -1739,16 +2201,27 @@ connection_or_unlink_all_active_circs(or_connection_t *orconn)
cur = next;
} while (cur != head);
orconn->active_circuits = NULL;
+
+ SMARTLIST_FOREACH(orconn->active_circuit_pqueue, cell_ewma_t *, e,
+ e->heap_index = -1);
+ smartlist_clear(orconn->active_circuit_pqueue);
}
/** Block (if <b>block</b> is true) or unblock (if <b>block</b> is false)
* every edge connection that is using <b>circ</b> to write to <b>orconn</b>,
- * and start or stop reading as appropriate. */
-static void
+ * and start or stop reading as appropriate.
+ *
+ * If <b>stream_id</b> is nonzero, block only the edge connection whose
+ * stream_id matches it.
+ *
+ * Returns the number of streams whose status we changed.
+ */
+static int
set_streams_blocked_on_circ(circuit_t *circ, or_connection_t *orconn,
- int block)
+ int block, streamid_t stream_id)
{
edge_connection_t *edge = NULL;
+ int n = 0;
if (circ->n_conn == orconn) {
circ->streams_blocked_on_n_conn = block;
if (CIRCUIT_IS_ORIGIN(circ))
@@ -1761,7 +2234,13 @@ set_streams_blocked_on_circ(circuit_t *circ, or_connection_t *orconn,
for (; edge; edge = edge->next_stream) {
connection_t *conn = TO_CONN(edge);
- edge->edge_blocked_on_circ = block;
+ if (stream_id && edge->stream_id != stream_id)
+ continue;
+
+ if (edge->edge_blocked_on_circ != block) {
+ ++n;
+ edge->edge_blocked_on_circ = block;
+ }
if (!conn->read_event) {
/* This connection is a placeholder for something; probably a DNS
@@ -1778,10 +2257,12 @@ set_streams_blocked_on_circ(circuit_t *circ, or_connection_t *orconn,
connection_start_reading(conn);
}
}
+
+ return n;
}
/** Pull as many cells as possible (but no more than <b>max</b>) from the
- * queue of the first active circuit on <b>conn</b>, and write then to
+ * queue of the first active circuit on <b>conn</b>, and write them to
* <b>conn</b>-&gt;outbuf. Return the number of cells written. Advance
* the active circuit pointer to the next active circuit in the ring. */
int
@@ -1792,9 +2273,35 @@ connection_or_flush_from_first_active_circuit(or_connection_t *conn, int max,
cell_queue_t *queue;
circuit_t *circ;
int streams_blocked;
+
+ /* The current (hi-res) time */
+ struct timeval now_hires;
+
+ /* The EWMA cell counter for the circuit we're flushing. */
+ cell_ewma_t *cell_ewma = NULL;
+ double ewma_increment = -1;
+
circ = conn->active_circuits;
if (!circ) return 0;
assert_active_circuits_ok_paranoid(conn);
+
+ /* See if we're doing the ewma circuit selection algorithm. */
+ if (ewma_enabled) {
+ unsigned tick;
+ double fractional_tick;
+ tor_gettimeofday_cached(&now_hires);
+ tick = cell_ewma_tick_from_timeval(&now_hires, &fractional_tick);
+
+ if (tick != conn->active_circuit_pqueue_last_recalibrated) {
+ scale_active_circuits(conn, tick);
+ }
+
+ ewma_increment = pow(ewma_scale_factor, -fractional_tick);
+
+ cell_ewma = smartlist_get(conn->active_circuit_pqueue, 0);
+ circ = cell_ewma_to_circuit(cell_ewma);
+ }
+
if (circ->n_conn == conn) {
queue = &circ->n_conn_cells;
streams_blocked = circ->streams_blocked_on_n_conn;
@@ -1808,10 +2315,60 @@ connection_or_flush_from_first_active_circuit(or_connection_t *conn, int max,
packed_cell_t *cell = cell_queue_pop(queue);
tor_assert(*next_circ_on_conn_p(circ,conn));
+ /* Calculate the exact time that this cell has spent in the queue. */
+ if (get_options()->CellStatistics && !CIRCUIT_IS_ORIGIN(circ)) {
+ struct timeval now;
+ uint32_t flushed;
+ uint32_t cell_waiting_time;
+ insertion_time_queue_t *it_queue = queue->insertion_times;
+ tor_gettimeofday_cached(&now);
+ flushed = (uint32_t)((now.tv_sec % SECONDS_IN_A_DAY) * 100L +
+ (uint32_t)now.tv_usec / (uint32_t)10000L);
+ if (!it_queue || !it_queue->first) {
+ log_info(LD_GENERAL, "Cannot determine insertion time of cell. "
+ "Looks like the CellStatistics option was "
+ "recently enabled.");
+ } else {
+ or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
+ insertion_time_elem_t *elem = it_queue->first;
+ cell_waiting_time =
+ (uint32_t)((flushed * 10L + SECONDS_IN_A_DAY * 1000L -
+ elem->insertion_time * 10L) %
+ (SECONDS_IN_A_DAY * 1000L));
+#undef SECONDS_IN_A_DAY
+ elem->counter--;
+ if (elem->counter < 1) {
+ it_queue->first = elem->next;
+ if (elem == it_queue->last)
+ it_queue->last = NULL;
+ mp_pool_release(elem);
+ }
+ orcirc->total_cell_waiting_time += cell_waiting_time;
+ orcirc->processed_cells++;
+ }
+ }
+
+ /* If we just flushed our queue and this circuit is used for a
+ * tunneled directory request, possibly advance its state. */
+ if (queue->n == 0 && TO_CONN(conn)->dirreq_id)
+ geoip_change_dirreq_state(TO_CONN(conn)->dirreq_id,
+ DIRREQ_TUNNELED,
+ DIRREQ_CIRC_QUEUE_FLUSHED);
+
connection_write_to_buf(cell->body, CELL_NETWORK_SIZE, TO_CONN(conn));
- packed_cell_free(cell);
+ packed_cell_free_unchecked(cell);
++n_flushed;
+ if (cell_ewma) {
+ cell_ewma_t *tmp;
+ cell_ewma->cell_count += ewma_increment;
+ /* We pop and re-add the cell_ewma_t here, not above, since we need to
+ * re-add it immediately to keep the priority queue consistent with
+ * the linked-list implementation */
+ tmp = pop_first_cell_ewma_from_conn(conn);
+ tor_assert(tmp == cell_ewma);
+ add_cell_ewma_to_conn(conn, cell_ewma);
+ }
if (circ != conn->active_circuits) {
/* If this happens, the current circuit just got made inactive by
* a call in connection_write_to_buf(). That's nothing to worry about:
@@ -1829,9 +2386,9 @@ connection_or_flush_from_first_active_circuit(or_connection_t *conn, int max,
/* Is the cell queue low enough to unblock all the streams that are waiting
* to write to this circuit? */
if (streams_blocked && queue->n <= CELL_QUEUE_LOWWATER_SIZE)
- set_streams_blocked_on_circ(circ, conn, 0); /* unblock streams */
+ set_streams_blocked_on_circ(circ, conn, 0, 0); /* unblock streams */
- /* Did we just ran out of cells on this queue? */
+ /* Did we just run out of cells on this circuit's queue? */
if (queue->n == 0) {
log_debug(LD_GENERAL, "Made a circuit inactive.");
make_circuit_inactive_on_conn(circ, conn);
@@ -1846,10 +2403,14 @@ connection_or_flush_from_first_active_circuit(or_connection_t *conn, int max,
* transmitting in <b>direction</b>. */
void
append_cell_to_circuit_queue(circuit_t *circ, or_connection_t *orconn,
- cell_t *cell, cell_direction_t direction)
+ cell_t *cell, cell_direction_t direction,
+ streamid_t fromstream)
{
cell_queue_t *queue;
int streams_blocked;
+ if (circ->marked_for_close)
+ return;
+
if (direction == CELL_DIRECTION_OUT) {
queue = &circ->n_conn_cells;
streams_blocked = circ->streams_blocked_on_n_conn;
@@ -1868,7 +2429,12 @@ append_cell_to_circuit_queue(circuit_t *circ, or_connection_t *orconn,
/* If we have too many cells on the circuit, we should stop reading from
* the edge streams for a while. */
if (!streams_blocked && queue->n >= CELL_QUEUE_HIGHWATER_SIZE)
- set_streams_blocked_on_circ(circ, orconn, 1); /* block streams */
+ set_streams_blocked_on_circ(circ, orconn, 1, 0); /* block streams */
+
+ if (streams_blocked && fromstream) {
+ /* This edge connection is apparently not blocked; block it. */
+ set_streams_blocked_on_circ(circ, orconn, 1, fromstream);
+ }
if (queue->n == 1) {
/* This was the first cell added to the queue. We need to make this
@@ -1947,6 +2513,25 @@ decode_address_from_payload(tor_addr_t *addr_out, const uint8_t *payload,
return payload + 2 + payload[1];
}
+/** Remove all the cells queued on <b>circ</b> for <b>orconn</b>. */
+void
+circuit_clear_cell_queue(circuit_t *circ, or_connection_t *orconn)
+{
+ cell_queue_t *queue;
+ if (circ->n_conn == orconn) {
+ queue = &circ->n_conn_cells;
+ } else {
+ or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
+ tor_assert(orcirc->p_conn == orconn);
+ queue = &orcirc->p_conn_cells;
+ }
+
+ if (queue->n)
+ make_circuit_inactive_on_conn(circ,orconn);
+
+ cell_queue_clear(queue);
+}
+
/** Fail with an assert if the active circuits ring on <b>orconn</b> is
* corrupt. */
void
@@ -1954,16 +2539,44 @@ assert_active_circuits_ok(or_connection_t *orconn)
{
circuit_t *head = orconn->active_circuits;
circuit_t *cur = head;
+ int n = 0;
if (! head)
return;
do {
circuit_t *next = *next_circ_on_conn_p(cur, orconn);
circuit_t *prev = *prev_circ_on_conn_p(cur, orconn);
+ cell_ewma_t *ewma;
tor_assert(next);
tor_assert(prev);
tor_assert(*next_circ_on_conn_p(prev, orconn) == cur);
tor_assert(*prev_circ_on_conn_p(next, orconn) == cur);
+ if (orconn == cur->n_conn) {
+ ewma = &cur->n_cell_ewma;
+ tor_assert(!ewma->is_for_p_conn);
+ } else {
+ ewma = &TO_OR_CIRCUIT(cur)->p_cell_ewma;
+ tor_assert(ewma->is_for_p_conn);
+ }
+ tor_assert(ewma->heap_index != -1);
+ tor_assert(ewma == smartlist_get(orconn->active_circuit_pqueue,
+ ewma->heap_index));
+ n++;
cur = next;
} while (cur != head);
+
+ tor_assert(n == smartlist_len(orconn->active_circuit_pqueue));
+}
+
+/** Return 1 if we shouldn't restart reading on this circuit, even if
+ * we get a SENDME. Else return 0.
+*/
+static int
+circuit_queue_streams_are_blocked(circuit_t *circ)
+{
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ return circ->streams_blocked_on_n_conn;
+ } else {
+ return circ->streams_blocked_on_p_conn;
+ }
}
diff --git a/src/or/relay.h b/src/or/relay.h
new file mode 100644
index 0000000000..8ccf0e2b30
--- /dev/null
+++ b/src/or/relay.h
@@ -0,0 +1,68 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file relay.h
+ * \brief Header file for relay.c.
+ **/
+
+#ifndef _TOR_RELAY_H
+#define _TOR_RELAY_H
+
+extern uint64_t stats_n_relay_cells_relayed;
+extern uint64_t stats_n_relay_cells_delivered;
+
+int circuit_receive_relay_cell(cell_t *cell, circuit_t *circ,
+ cell_direction_t cell_direction);
+
+void relay_header_pack(uint8_t *dest, const relay_header_t *src);
+void relay_header_unpack(relay_header_t *dest, const uint8_t *src);
+int relay_send_command_from_edge(streamid_t stream_id, circuit_t *circ,
+ uint8_t relay_command, const char *payload,
+ size_t payload_len, crypt_path_t *cpath_layer);
+int connection_edge_send_command(edge_connection_t *fromconn,
+ uint8_t relay_command, const char *payload,
+ size_t payload_len);
+int connection_edge_package_raw_inbuf(edge_connection_t *conn,
+ int package_partial,
+ int *max_cells);
+void connection_edge_consider_sending_sendme(edge_connection_t *conn);
+
+extern uint64_t stats_n_data_cells_packaged;
+extern uint64_t stats_n_data_bytes_packaged;
+extern uint64_t stats_n_data_cells_received;
+extern uint64_t stats_n_data_bytes_received;
+
+void init_cell_pool(void);
+void free_cell_pool(void);
+void clean_cell_pool(void);
+void dump_cell_pool_usage(int severity);
+
+void cell_queue_clear(cell_queue_t *queue);
+void cell_queue_append(cell_queue_t *queue, packed_cell_t *cell);
+void cell_queue_append_packed_copy(cell_queue_t *queue, const cell_t *cell);
+
+void append_cell_to_circuit_queue(circuit_t *circ, or_connection_t *orconn,
+ cell_t *cell, cell_direction_t direction,
+ streamid_t fromstream);
+void connection_or_unlink_all_active_circs(or_connection_t *conn);
+int connection_or_flush_from_first_active_circuit(or_connection_t *conn,
+ int max, time_t now);
+void assert_active_circuits_ok(or_connection_t *orconn);
+void make_circuit_inactive_on_conn(circuit_t *circ, or_connection_t *conn);
+void make_circuit_active_on_conn(circuit_t *circ, or_connection_t *conn);
+
+int append_address_to_payload(uint8_t *payload_out, const tor_addr_t *addr);
+const uint8_t *decode_address_from_payload(tor_addr_t *addr_out,
+ const uint8_t *payload,
+ int payload_len);
+unsigned cell_ewma_get_tick(void);
+void cell_ewma_set_scale_factor(or_options_t *options,
+ networkstatus_t *consensus);
+void circuit_clear_cell_queue(circuit_t *circ, or_connection_t *orconn);
+
+#endif
+
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index feecf237c4..ab968078e8 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -8,6 +8,19 @@
**/
#include "or.h"
+#include "circuitbuild.h"
+#include "circuitlist.h"
+#include "circuituse.h"
+#include "config.h"
+#include "connection.h"
+#include "connection_edge.h"
+#include "directory.h"
+#include "main.h"
+#include "relay.h"
+#include "rendclient.h"
+#include "rendcommon.h"
+#include "rephist.h"
+#include "routerlist.h"
/** Called when we've established a circuit to an introduction point:
* send the introduction request. */
@@ -63,7 +76,7 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
rend_cache_entry_t *entry;
crypt_path_t *cpath;
off_t dh_offset;
- crypto_pk_env_t *intro_key; /* either Bob's public key or an intro key. */
+ crypto_pk_env_t *intro_key = NULL;
tor_assert(introcirc->_base.purpose == CIRCUIT_PURPOSE_C_INTRODUCING);
tor_assert(rendcirc->_base.purpose == CIRCUIT_PURPOSE_C_REND_READY);
@@ -76,48 +89,26 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
&entry) < 1) {
log_warn(LD_REND,
"query %s didn't have valid rend desc in cache. Failing.",
- escaped_safe_str(introcirc->rend_data->onion_address));
+ escaped_safe_str_client(introcirc->rend_data->onion_address));
goto err;
}
- /* first 20 bytes of payload are the hash of Bob's pk */
- if (entry->parsed->version == 0) { /* un-versioned descriptor */
- intro_key = entry->parsed->pk;
- } else { /* versioned descriptor */
- intro_key = NULL;
- SMARTLIST_FOREACH(entry->parsed->intro_nodes, rend_intro_point_t *,
- intro, {
- if (!memcmp(introcirc->build_state->chosen_exit->identity_digest,
- intro->extend_info->identity_digest, DIGEST_LEN)) {
- intro_key = intro->intro_key;
- break;
- }
- });
- if (!intro_key) {
- /** XXX This case probably means that the intro point vanished while
- * we were building a circuit to it. In the future, we should find
- * out how that happened and whether we should kill the circuits to
- * removed intro points immediately. See task 1073. */
- int num_intro_points = smartlist_len(entry->parsed->intro_nodes);
- if (rend_cache_lookup_entry(introcirc->rend_data->onion_address,
- 0, &entry) > 0) {
- log_info(LD_REND, "We have both a v0 and a v2 rend desc for this "
- "service. The v2 desc doesn't contain the introduction "
- "point (and key) to send an INTRODUCE1/2 cell to this "
- "introduction point. Assuming the introduction point "
- "is for v0 rend clients and using the service key "
- "from the v0 desc instead. (This is probably a bug, "
- "because we shouldn't even have both a v0 and a v2 "
- "descriptor for the same service.)");
- /* See flyspray task 1024. */
- intro_key = entry->parsed->pk;
- } else {
- log_info(LD_REND, "Internal error: could not find intro key; we "
- "only have a v2 rend desc with %d intro points.",
- num_intro_points);
- goto err;
- }
+ /* first 20 bytes of payload are the hash of the intro key */
+ intro_key = NULL;
+ SMARTLIST_FOREACH(entry->parsed->intro_nodes, rend_intro_point_t *,
+ intro, {
+ if (!memcmp(introcirc->build_state->chosen_exit->identity_digest,
+ intro->extend_info->identity_digest, DIGEST_LEN)) {
+ intro_key = intro->intro_key;
+ break;
}
+ });
+ if (!intro_key) {
+ log_info(LD_REND, "Our introduction point knowledge changed in "
+ "mid-connect! Could not find intro key; we only have a "
+ "v2 rend desc with %d intro points. Giving up.",
+ smartlist_len(entry->parsed->intro_nodes));
+ goto err;
}
if (crypto_pk_get_digest(intro_key, payload)<0) {
log_warn(LD_BUG, "Internal error: couldn't hash public key.");
@@ -218,7 +209,7 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
introcirc->_base.purpose = CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT;
return 0;
-err:
+ err:
circuit_mark_for_close(TO_CIRCUIT(introcirc), END_CIRC_REASON_INTERNAL);
circuit_mark_for_close(TO_CIRCUIT(rendcirc), END_CIRC_REASON_INTERNAL);
return -1;
@@ -291,7 +282,7 @@ rend_client_introduction_acked(origin_circuit_t *circ,
extend_info = rend_client_get_random_intro(circ->rend_data);
if (!extend_info) {
log_warn(LD_REND, "No introduction points left for %s. Closing.",
- escaped_safe_str(circ->rend_data->onion_address));
+ escaped_safe_str_client(circ->rend_data->onion_address));
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
return -1;
}
@@ -299,7 +290,7 @@ rend_client_introduction_acked(origin_circuit_t *circ,
log_info(LD_REND,
"Got nack for %s from %s. Re-extending circ %d, "
"this time to %s.",
- escaped_safe_str(circ->rend_data->onion_address),
+ escaped_safe_str_client(circ->rend_data->onion_address),
circ->build_state->chosen_exit->nickname,
circ->_base.n_circ_id, extend_info->nickname);
result = circuit_extend_to_new_exit(circ, extend_info);
@@ -307,7 +298,7 @@ rend_client_introduction_acked(origin_circuit_t *circ,
log_info(LD_REND,
"Got nack for %s from %s. Building a new introduction "
"circuit, this time to %s.",
- escaped_safe_str(circ->rend_data->onion_address),
+ escaped_safe_str_client(circ->rend_data->onion_address),
circ->build_state->chosen_exit->nickname,
extend_info->nickname);
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_FINISHED);
@@ -470,45 +461,21 @@ directory_get_from_hs_dir(const char *desc_id, const rend_data_t *rend_query)
rend_query->onion_address, desc_id_base32,
rend_query->auth_type,
(rend_query->auth_type == REND_NO_AUTH ? "[none]" :
- escaped_safe_str(descriptor_cookie_base64)),
+ escaped_safe_str_client(descriptor_cookie_base64)),
hs_dir->nickname, hs_dir->dir_port);
return 1;
}
-/** If we are not currently fetching a rendezvous service descriptor
- * for the service ID <b>query</b>, start a directory connection to fetch a
- * new one.
- */
-void
-rend_client_refetch_renddesc(const char *query)
-{
- if (!get_options()->FetchHidServDescriptors)
- return;
- log_info(LD_REND, "Fetching rendezvous descriptor for service %s",
- escaped_safe_str(query));
- if (connection_get_by_type_state_rendquery(CONN_TYPE_DIR, 0, query, 0)) {
- log_info(LD_REND,"Would fetch a new renddesc here (for %s), but one is "
- "already in progress.", escaped_safe_str(query));
- } else {
- /* not one already; initiate a dir rend desc lookup */
- directory_get_from_dirserver(DIR_PURPOSE_FETCH_RENDDESC,
- ROUTER_PURPOSE_GENERAL, query,
- PDS_RETRY_IF_NO_SERVERS);
- }
-}
-
-/** Start a connection to a hidden service directory to fetch a v2
- * rendezvous service descriptor for the base32-encoded service ID
- * <b>query</b>.
- */
+/** Unless we already have a descriptor for <b>rend_query</b> with at least
+ * one (possibly) working introduction point in it, start a connection to a
+ * hidden service directory to fetch a v2 rendezvous service descriptor. */
void
rend_client_refetch_v2_renddesc(const rend_data_t *rend_query)
{
char descriptor_id[DIGEST_LEN];
int replicas_left_to_try[REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS];
- int i, tries_left, r;
+ int i, tries_left;
rend_cache_entry_t *e = NULL;
- time_t now = time(NULL);
tor_assert(rend_query);
/* Are we configured to fetch descriptors? */
if (!get_options()->FetchHidServDescriptors) {
@@ -517,15 +484,13 @@ rend_client_refetch_v2_renddesc(const rend_data_t *rend_query)
return;
}
/* Before fetching, check if we already have the descriptor here. */
- r = rend_cache_lookup_entry(rend_query->onion_address, -1, &e);
- if (r > 0 && now - e->received < NUM_SECONDS_BEFORE_HS_REFETCH) {
+ if (rend_cache_lookup_entry(rend_query->onion_address, -1, &e) > 0) {
log_info(LD_REND, "We would fetch a v2 rendezvous descriptor, but we "
- "already have a fresh copy of that descriptor here. "
- "Not fetching.");
+ "already have that descriptor here. Not fetching.");
return;
}
log_debug(LD_REND, "Fetching v2 rendezvous descriptor for service %s",
- safe_str(rend_query->onion_address));
+ safe_str_client(rend_query->onion_address));
/* Randomly iterate over the replicas until a descriptor can be fetched
* from one of the consecutive nodes, or no options are left. */
tries_left = REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS;
@@ -551,8 +516,8 @@ rend_client_refetch_v2_renddesc(const rend_data_t *rend_query)
log_info(LD_REND, "Could not pick one of the responsible hidden "
"service directories to fetch descriptors, because "
"we already tried them all unsuccessfully.");
- /* Close pending connections (unless a v0 request is still going on). */
- rend_client_desc_trynow(rend_query->onion_address, 2);
+ /* Close pending connections. */
+ rend_client_desc_trynow(rend_query->onion_address);
return;
}
@@ -573,18 +538,13 @@ rend_client_remove_intro_point(extend_info_t *failed_intro,
r = rend_cache_lookup_entry(rend_query->onion_address, -1, &ent);
if (r<0) {
log_warn(LD_BUG, "Malformed service ID %s.",
- escaped_safe_str(rend_query->onion_address));
+ escaped_safe_str_client(rend_query->onion_address));
return -1;
}
if (r==0) {
log_info(LD_REND, "Unknown service %s. Re-fetching descriptor.",
- escaped_safe_str(rend_query->onion_address));
- /* Fetch both, v0 and v2 rend descriptors in parallel. Use whichever
- * arrives first. Exception: When using client authorization, only
- * fetch v2 descriptors.*/
+ escaped_safe_str_client(rend_query->onion_address));
rend_client_refetch_v2_renddesc(rend_query);
- if (rend_query->auth_type == REND_NO_AUTH)
- rend_client_refetch_renddesc(rend_query->onion_address);
return 0;
}
@@ -601,18 +561,13 @@ rend_client_remove_intro_point(extend_info_t *failed_intro,
if (smartlist_len(ent->parsed->intro_nodes) == 0) {
log_info(LD_REND,
"No more intro points remain for %s. Re-fetching descriptor.",
- escaped_safe_str(rend_query->onion_address));
- /* Fetch both, v0 and v2 rend descriptors in parallel. Use whichever
- * arrives first. Exception: When using client authorization, only
- * fetch v2 descriptors.*/
+ escaped_safe_str_client(rend_query->onion_address));
rend_client_refetch_v2_renddesc(rend_query);
- if (rend_query->auth_type == REND_NO_AUTH)
- rend_client_refetch_renddesc(rend_query->onion_address);
/* move all pending streams back to renddesc_wait */
while ((conn = connection_get_by_type_state_rendquery(CONN_TYPE_AP,
AP_CONN_STATE_CIRCUIT_WAIT,
- rend_query->onion_address, -1))) {
+ rend_query->onion_address))) {
conn->state = AP_CONN_STATE_RENDDESC_WAIT;
}
@@ -620,7 +575,7 @@ rend_client_remove_intro_point(extend_info_t *failed_intro,
}
log_info(LD_REND,"%d options left for %s.",
smartlist_len(ent->parsed->intro_nodes),
- escaped_safe_str(rend_query->onion_address));
+ escaped_safe_str_client(rend_query->onion_address));
return 1;
}
@@ -682,7 +637,8 @@ rend_client_receive_rendezvous(origin_circuit_t *circ, const uint8_t *request,
tor_assert(circ->build_state->pending_final_cpath);
hop = circ->build_state->pending_final_cpath;
tor_assert(hop->dh_handshake_state);
- if (crypto_dh_compute_secret(hop->dh_handshake_state, (char*)request,
+ if (crypto_dh_compute_secret(LOG_PROTOCOL_WARN,
+ hop->dh_handshake_state, (char*)request,
DH_KEY_LEN,
keys, DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) {
log_warn(LD_GENERAL, "Couldn't complete DH handshake.");
@@ -722,24 +678,18 @@ rend_client_receive_rendezvous(origin_circuit_t *circ, const uint8_t *request,
return -1;
}
-/** Find all the apconns in state AP_CONN_STATE_RENDDESC_WAIT that
- * are waiting on query. If there's a working cache entry here
- * with at least one intro point, move them to the next state. If
- * <b>rend_version</b> is non-negative, fail connections that have
- * requested <b>query</b> unless there are still descriptor fetch
- * requests in progress for other descriptor versions than
- * <b>rend_version</b>.
- */
+/** Find all the apconns in state AP_CONN_STATE_RENDDESC_WAIT that are
+ * waiting on <b>query</b>. If there's a working cache entry here with at
+ * least one intro point, move them to the next state. */
void
-rend_client_desc_trynow(const char *query, int rend_version)
+rend_client_desc_trynow(const char *query)
{
edge_connection_t *conn;
rend_cache_entry_t *entry;
time_t now = time(NULL);
smartlist_t *conns = get_connection_array();
- SMARTLIST_FOREACH(conns, connection_t *, _conn,
- {
+ SMARTLIST_FOREACH_BEGIN(conns, connection_t *, _conn) {
if (_conn->type != CONN_TYPE_AP ||
_conn->state != AP_CONN_STATE_RENDDESC_WAIT ||
_conn->marked_for_close)
@@ -771,17 +721,12 @@ rend_client_desc_trynow(const char *query, int rend_version)
connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
}
} else { /* 404, or fetch didn't get that far */
- /* Unless there are requests for another descriptor version pending,
- * close the connection. */
- if (rend_version >= 0 &&
- !connection_get_by_type_state_rendquery(CONN_TYPE_DIR, 0, query,
- rend_version == 0 ? 2 : 0)) {
- log_notice(LD_REND,"Closing stream for '%s.onion': hidden service is "
- "unavailable (try again later).", safe_str(query));
- connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
- }
+ log_notice(LD_REND,"Closing stream for '%s.onion': hidden service is "
+ "unavailable (try again later).",
+ safe_str_client(query));
+ connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
}
- });
+ } SMARTLIST_FOREACH_END(_conn);
}
/** Return a newly allocated extend_info_t* for a randomly chosen introduction
@@ -799,7 +744,7 @@ rend_client_get_random_intro(const rend_data_t *rend_query)
if (rend_cache_lookup_entry(rend_query->onion_address, -1, &entry) < 1) {
log_warn(LD_REND,
"Query '%s' didn't have valid rend desc in cache. Failing.",
- safe_str(rend_query->onion_address));
+ safe_str_client(rend_query->onion_address));
return NULL;
}
@@ -811,7 +756,10 @@ rend_client_get_random_intro(const rend_data_t *rend_query)
intro = smartlist_get(entry->parsed->intro_nodes, i);
/* Do we need to look up the router or is the extend info complete? */
if (!intro->extend_info->onion_key) {
- router = router_get_by_nickname(intro->extend_info->nickname, 0);
+ if (tor_digest_is_zero(intro->extend_info->identity_digest))
+ router = router_get_by_hexdigest(intro->extend_info->nickname);
+ else
+ router = router_get_by_digest(intro->extend_info->identity_digest);
if (!router) {
log_info(LD_REND, "Unknown router with nickname '%s'; trying another.",
intro->extend_info->nickname);
@@ -949,8 +897,7 @@ rend_parse_service_authorization(or_options_t *options, int validate_only)
err:
res = -1;
done:
- if (auth)
- rend_service_authorization_free(auth);
+ rend_service_authorization_free(auth);
SMARTLIST_FOREACH(sl, char *, c, tor_free(c););
smartlist_free(sl);
if (!validate_only && res == 0) {
diff --git a/src/or/rendclient.h b/src/or/rendclient.h
new file mode 100644
index 0000000000..79d37b2a58
--- /dev/null
+++ b/src/or/rendclient.h
@@ -0,0 +1,43 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file rendclient.h
+ * \brief Header file for rendclient.c.
+ **/
+
+#ifndef _TOR_RENDCLIENT_H
+#define _TOR_RENDCLIENT_H
+
+void rend_client_introcirc_has_opened(origin_circuit_t *circ);
+void rend_client_rendcirc_has_opened(origin_circuit_t *circ);
+int rend_client_introduction_acked(origin_circuit_t *circ,
+ const uint8_t *request,
+ size_t request_len);
+void rend_client_refetch_v2_renddesc(const rend_data_t *rend_query);
+int rend_client_remove_intro_point(extend_info_t *failed_intro,
+ const rend_data_t *rend_query);
+int rend_client_rendezvous_acked(origin_circuit_t *circ,
+ const uint8_t *request,
+ size_t request_len);
+int rend_client_receive_rendezvous(origin_circuit_t *circ,
+ const uint8_t *request,
+ size_t request_len);
+void rend_client_desc_trynow(const char *query);
+
+extend_info_t *rend_client_get_random_intro(const rend_data_t *rend_query);
+
+int rend_client_send_introduction(origin_circuit_t *introcirc,
+ origin_circuit_t *rendcirc);
+int rend_parse_service_authorization(or_options_t *options,
+ int validate_only);
+rend_service_authorization_t *rend_client_lookup_service_authorization(
+ const char *onion_address);
+void rend_service_authorization_free_all(void);
+rend_data_t *rend_data_dup(const rend_data_t *request);
+
+#endif
+
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
index 9ee86f6673..85d97e0253 100644
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@ -9,6 +9,15 @@
**/
#include "or.h"
+#include "circuitbuild.h"
+#include "config.h"
+#include "rendclient.h"
+#include "rendcommon.h"
+#include "rendmid.h"
+#include "rendservice.h"
+#include "rephist.h"
+#include "routerlist.h"
+#include "routerparse.h"
/** Return 0 if one and two are the same service ids, else -1 or 1 */
int
@@ -22,6 +31,8 @@ rend_cmp_service_ids(const char *one, const char *two)
void
rend_service_descriptor_free(rend_service_descriptor_t *desc)
{
+ if (!desc)
+ return;
if (desc->pk)
crypto_free_pk_env(desc->pk);
if (desc->intro_nodes) {
@@ -125,7 +136,8 @@ rend_compute_v2_desc_id(char *desc_id_out, const char *service_id,
if (!service_id ||
strlen(service_id) != REND_SERVICE_ID_LEN_BASE32) {
log_warn(LD_REND, "Could not compute v2 descriptor ID: "
- "Illegal service ID: %s", safe_str(service_id));
+ "Illegal service ID: %s",
+ safe_str(service_id));
return -1;
}
if (replica >= REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS) {
@@ -138,7 +150,7 @@ rend_compute_v2_desc_id(char *desc_id_out, const char *service_id,
service_id, REND_SERVICE_ID_LEN_BASE32) < 0) {
log_warn(LD_REND, "Could not compute v2 descriptor ID: "
"Illegal characters in service ID: %s",
- safe_str(service_id));
+ safe_str_client(service_id));
return -1;
}
/* Calculate current time-period. */
@@ -403,8 +415,7 @@ rend_desc_v2_is_parsable(rend_encoded_v2_service_descriptor_t *desc)
&test_intro_size,
&test_encoded_size,
&test_next, desc->desc_str);
- if (test_parsed)
- rend_service_descriptor_free(test_parsed);
+ rend_service_descriptor_free(test_parsed);
tor_free(test_intro_content);
return (res >= 0);
}
@@ -414,6 +425,8 @@ void
rend_encoded_v2_service_descriptor_free(
rend_encoded_v2_service_descriptor_t *desc)
{
+ if (!desc)
+ return;
tor_free(desc->desc_str);
tor_free(desc);
}
@@ -422,10 +435,11 @@ rend_encoded_v2_service_descriptor_free(
void
rend_intro_point_free(rend_intro_point_t *intro)
{
- if (intro->extend_info)
- extend_info_free(intro->extend_info);
- if (intro->intro_key)
- crypto_free_pk_env(intro->intro_key);
+ if (!intro)
+ return;
+
+ extend_info_free(intro->extend_info);
+ crypto_free_pk_env(intro->intro_key);
tor_free(intro);
}
@@ -618,7 +632,8 @@ rend_encode_v2_descriptors(smartlist_t *descs_out,
}
if (router_append_dirobj_signature(desc_str + written,
desc_len - written,
- desc_digest, service_key) < 0) {
+ desc_digest, DIGEST_LEN,
+ service_key) < 0) {
log_warn(LD_BUG, "Couldn't sign desc.");
rend_encoded_v2_service_descriptor_free(enc);
goto err;
@@ -655,61 +670,6 @@ rend_encode_v2_descriptors(smartlist_t *descs_out,
return seconds_valid;
}
-/** Encode a service descriptor for <b>desc</b>, and sign it with
- * <b>key</b>. Store the descriptor in *<b>str_out</b>, and set
- * *<b>len_out</b> to its length.
- */
-int
-rend_encode_service_descriptor(rend_service_descriptor_t *desc,
- crypto_pk_env_t *key,
- char **str_out, size_t *len_out)
-{
- char *cp;
- char *end;
- int i, r;
- size_t asn1len;
- size_t buflen =
- PK_BYTES*2*(smartlist_len(desc->intro_nodes)+2);/*Too long, but ok*/
- cp = *str_out = tor_malloc(buflen);
- end = cp + PK_BYTES*2*(smartlist_len(desc->intro_nodes)+1);
- r = crypto_pk_asn1_encode(desc->pk, cp+2, end-(cp+2));
- if (r < 0) {
- tor_free(*str_out);
- return -1;
- }
- asn1len = r;
- set_uint16(cp, htons((uint16_t)asn1len));
- cp += 2+asn1len;
- set_uint32(cp, htonl((uint32_t)desc->timestamp));
- cp += 4;
- set_uint16(cp, htons((uint16_t)smartlist_len(desc->intro_nodes)));
- cp += 2;
- for (i=0; i < smartlist_len(desc->intro_nodes); ++i) {
- rend_intro_point_t *intro = smartlist_get(desc->intro_nodes, i);
- char ipoint[HEX_DIGEST_LEN+2];
- const size_t ipoint_len = HEX_DIGEST_LEN+1;
- ipoint[0] = '$';
- base16_encode(ipoint+1, HEX_DIGEST_LEN+1,
- intro->extend_info->identity_digest,
- DIGEST_LEN);
- tor_assert(strlen(ipoint) == ipoint_len);
- /* Assert that appending ipoint and its NUL won't over overrun the
- * buffer. */
- tor_assert(cp + ipoint_len+1 < *str_out + buflen);
- memcpy(cp, ipoint, ipoint_len+1);
- cp += ipoint_len+1;
- }
- note_crypto_pk_op(REND_SERVER);
- r = crypto_pk_private_sign_digest(key, cp, *str_out, cp-*str_out);
- if (r<0) {
- tor_free(*str_out);
- return -1;
- }
- cp += r;
- *len_out = (size_t)(cp-*str_out);
- return 0;
-}
-
/** Parse a service descriptor at <b>str</b> (<b>len</b> bytes). On
* success, return a newly alloced service_descriptor_t. On failure,
* return NULL.
@@ -826,22 +786,27 @@ rend_cache_init(void)
/** Helper: free storage held by a single service descriptor cache entry. */
static void
-_rend_cache_entry_free(void *p)
+rend_cache_entry_free(rend_cache_entry_t *e)
{
- rend_cache_entry_t *e = p;
+ if (!e)
+ return;
rend_service_descriptor_free(e->parsed);
tor_free(e->desc);
tor_free(e);
}
+static void
+_rend_cache_entry_free(void *p)
+{
+ rend_cache_entry_free(p);
+}
+
/** Free all storage held by the service descriptor cache. */
void
rend_cache_free_all(void)
{
- if (rend_cache)
- strmap_free(rend_cache, _rend_cache_entry_free);
- if (rend_cache_v2_dir)
- digestmap_free(rend_cache_v2_dir, _rend_cache_entry_free);
+ strmap_free(rend_cache, _rend_cache_entry_free);
+ digestmap_free(rend_cache_v2_dir, _rend_cache_entry_free);
rend_cache = NULL;
rend_cache_v2_dir = NULL;
}
@@ -862,7 +827,7 @@ rend_cache_clean(void)
ent = (rend_cache_entry_t*)val;
if (ent->parsed->timestamp < cutoff) {
iter = strmap_iter_next_rmv(rend_cache, iter);
- _rend_cache_entry_free(ent);
+ rend_cache_entry_free(ent);
} else {
iter = strmap_iter_next(rend_cache, iter);
}
@@ -888,9 +853,9 @@ rend_cache_clean_v2_descs_as_dir(void)
char key_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
base32_encode(key_base32, sizeof(key_base32), key, DIGEST_LEN);
log_info(LD_REND, "Removing descriptor with ID '%s' from cache",
- safe_str(key_base32));
+ safe_str_client(key_base32));
iter = digestmap_iter_next_rmv(rend_cache_v2_dir, iter);
- _rend_cache_entry_free(ent);
+ rend_cache_entry_free(ent);
} else {
iter = digestmap_iter_next(rend_cache_v2_dir, iter);
}
@@ -966,6 +931,11 @@ rend_cache_lookup_entry(const char *query, int version, rend_cache_entry_t **e)
}
if (!*e)
return 0;
+ tor_assert((*e)->parsed && (*e)->parsed->intro_nodes);
+ /* XXX022 hack for now, to return "not found" if there are no intro
+ * points remaining. See bug 997. */
+ if (smartlist_len((*e)->parsed->intro_nodes) == 0)
+ return 0;
return 1;
}
@@ -1044,7 +1014,6 @@ rend_cache_store(const char *desc, size_t desc_len, int published)
char query[REND_SERVICE_ID_LEN_BASE32+1];
char key[REND_SERVICE_ID_LEN_BASE32+2]; /* 0<query>\0 */
time_t now;
- or_options_t *options = get_options();
tor_assert(rend_cache);
parsed = rend_parse_service_descriptor(desc,desc_len);
if (!parsed) {
@@ -1059,13 +1028,15 @@ rend_cache_store(const char *desc, size_t desc_len, int published)
now = time(NULL);
if (parsed->timestamp < now-REND_CACHE_MAX_AGE-REND_CACHE_MAX_SKEW) {
log_fn(LOG_PROTOCOL_WARN, LD_REND,
- "Service descriptor %s is too old.", safe_str(query));
+ "Service descriptor %s is too old.",
+ safe_str_client(query));
rend_service_descriptor_free(parsed);
return -2;
}
if (parsed->timestamp > now+REND_CACHE_MAX_SKEW) {
log_fn(LOG_PROTOCOL_WARN, LD_REND,
- "Service descriptor %s is too far in the future.", safe_str(query));
+ "Service descriptor %s is too far in the future.",
+ safe_str_client(query));
rend_service_descriptor_free(parsed);
return -2;
}
@@ -1073,25 +1044,22 @@ rend_cache_store(const char *desc, size_t desc_len, int published)
tor_snprintf(key, sizeof(key), "2%s", query);
if (!published && strmap_get_lc(rend_cache, key)) {
log_info(LD_REND, "We already have a v2 descriptor for service %s.",
- safe_str(query));
+ safe_str_client(query));
rend_service_descriptor_free(parsed);
return -1;
}
- /* report novel publication to statistics */
- if (published && options->HSAuthorityRecordStats) {
- hs_usage_note_publish_total(query, now);
- }
tor_snprintf(key, sizeof(key), "0%s", query);
e = (rend_cache_entry_t*) strmap_get_lc(rend_cache, key);
if (e && e->parsed->timestamp > parsed->timestamp) {
log_info(LD_REND,"We already have a newer service descriptor %s with the "
- "same ID and version.", safe_str(query));
+ "same ID and version.",
+ safe_str_client(query));
rend_service_descriptor_free(parsed);
return 0;
}
if (e && e->len == desc_len && !memcmp(desc,e->desc,desc_len)) {
log_info(LD_REND,"We already have this service descriptor %s.",
- safe_str(query));
+ safe_str_client(query));
e->received = time(NULL);
rend_service_descriptor_free(parsed);
return 0;
@@ -1099,10 +1067,6 @@ rend_cache_store(const char *desc, size_t desc_len, int published)
if (!e) {
e = tor_malloc_zero(sizeof(rend_cache_entry_t));
strmap_set_lc(rend_cache, key, e);
- /* report novel publication to statistics */
- if (published && options->HSAuthorityRecordStats) {
- hs_usage_note_publish_novel(query, now);
- }
} else {
rend_service_descriptor_free(e->parsed);
tor_free(e->desc);
@@ -1114,7 +1078,7 @@ rend_cache_store(const char *desc, size_t desc_len, int published)
memcpy(e->desc, desc, desc_len);
log_debug(LD_REND,"Successfully stored rend desc '%s', len %d.",
- safe_str(query), (int)desc_len);
+ safe_str_client(query), (int)desc_len);
return 1;
}
@@ -1165,7 +1129,7 @@ rend_cache_store_v2_desc_as_dir(const char *desc)
if (!hid_serv_responsible_for_desc_id(desc_id)) {
log_info(LD_REND, "Service descriptor with desc ID %s is not in "
"interval that we are responsible for.",
- safe_str(desc_id_base32));
+ safe_str_client(desc_id_base32));
goto skip;
}
/* Is descriptor too old? */
@@ -1294,7 +1258,8 @@ rend_cache_store_v2_desc_as_client(const char *desc,
/* Decode/decrypt introduction points. */
if (intro_content) {
if (rend_query->auth_type != REND_NO_AUTH &&
- rend_query->descriptor_cookie) {
+ !tor_mem_is_zero(rend_query->descriptor_cookie,
+ sizeof(rend_query->descriptor_cookie))) {
char *ipos_decrypted = NULL;
size_t ipos_decrypted_size;
if (rend_decrypt_introduction_points(&ipos_decrypted,
@@ -1329,14 +1294,14 @@ rend_cache_store_v2_desc_as_client(const char *desc,
/* Is descriptor too old? */
if (parsed->timestamp < now - REND_CACHE_MAX_AGE-REND_CACHE_MAX_SKEW) {
log_warn(LD_REND, "Service descriptor with service ID %s is too old.",
- safe_str(service_id));
+ safe_str_client(service_id));
retval = -2;
goto err;
}
/* Is descriptor too far in the future? */
if (parsed->timestamp > now + REND_CACHE_MAX_SKEW) {
log_warn(LD_REND, "Service descriptor with service ID %s is too far in "
- "the future.", safe_str(service_id));
+ "the future.", safe_str_client(service_id));
retval = -2;
goto err;
}
@@ -1344,7 +1309,7 @@ rend_cache_store_v2_desc_as_client(const char *desc,
tor_snprintf(key, sizeof(key), "0%s", service_id);
if (strmap_get_lc(rend_cache, key)) {
log_info(LD_REND, "We already have a v0 descriptor for service ID %s.",
- safe_str(service_id));
+ safe_str_client(service_id));
retval = -1;
goto err;
}
@@ -1354,14 +1319,14 @@ rend_cache_store_v2_desc_as_client(const char *desc,
if (e && e->parsed->timestamp > parsed->timestamp) {
log_info(LD_REND, "We already have a newer service descriptor for "
"service ID %s with the same desc ID and version.",
- safe_str(service_id));
+ safe_str_client(service_id));
retval = 0;
goto err;
}
/* Do we already have this descriptor? */
if (e && !strcmp(desc, e->desc)) {
log_info(LD_REND,"We already have this service descriptor %s.",
- safe_str(service_id));
+ safe_str_client(service_id));
e->received = time(NULL);
retval = 0;
goto err;
@@ -1379,12 +1344,11 @@ rend_cache_store_v2_desc_as_client(const char *desc,
strlcpy(e->desc, desc, encoded_size + 1);
e->len = encoded_size;
log_debug(LD_REND,"Successfully stored rend desc '%s', len %d.",
- safe_str(service_id), (int)encoded_size);
+ safe_str_client(service_id), (int)encoded_size);
return 1;
err:
- if (parsed)
- rend_service_descriptor_free(parsed);
+ rend_service_descriptor_free(parsed);
tor_free(intro_content);
return retval;
}
diff --git a/src/or/rendcommon.h b/src/or/rendcommon.h
new file mode 100644
index 0000000000..d3313faf5a
--- /dev/null
+++ b/src/or/rendcommon.h
@@ -0,0 +1,65 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file rendcommon.h
+ * \brief Header file for rendcommon.c.
+ **/
+
+#ifndef _TOR_RENDCOMMON_H
+#define _TOR_RENDCOMMON_H
+
+/** Free all storage associated with <b>data</b> */
+static INLINE void
+rend_data_free(rend_data_t *data)
+{
+ tor_free(data);
+}
+
+int rend_cmp_service_ids(const char *one, const char *two);
+
+void rend_process_relay_cell(circuit_t *circ, const crypt_path_t *layer_hint,
+ int command, size_t length,
+ const uint8_t *payload);
+
+void rend_service_descriptor_free(rend_service_descriptor_t *desc);
+rend_service_descriptor_t *rend_parse_service_descriptor(const char *str,
+ size_t len);
+int rend_get_service_id(crypto_pk_env_t *pk, char *out);
+void rend_encoded_v2_service_descriptor_free(
+ rend_encoded_v2_service_descriptor_t *desc);
+void rend_intro_point_free(rend_intro_point_t *intro);
+
+void rend_cache_init(void);
+void rend_cache_clean(void);
+void rend_cache_clean_v2_descs_as_dir(void);
+void rend_cache_free_all(void);
+int rend_valid_service_id(const char *query);
+int rend_cache_lookup_desc(const char *query, int version, const char **desc,
+ size_t *desc_len);
+int rend_cache_lookup_entry(const char *query, int version,
+ rend_cache_entry_t **entry_out);
+int rend_cache_lookup_v2_desc_as_dir(const char *query, const char **desc);
+int rend_cache_store(const char *desc, size_t desc_len, int published);
+int rend_cache_store_v2_desc_as_client(const char *desc,
+ const rend_data_t *rend_query);
+int rend_cache_store_v2_desc_as_dir(const char *desc);
+int rend_cache_size(void);
+int rend_encode_v2_descriptors(smartlist_t *descs_out,
+ rend_service_descriptor_t *desc, time_t now,
+ uint8_t period, rend_auth_type_t auth_type,
+ crypto_pk_env_t *client_key,
+ smartlist_t *client_cookies);
+int rend_compute_v2_desc_id(char *desc_id_out, const char *service_id,
+ const char *descriptor_cookie,
+ time_t now, uint8_t replica);
+int rend_id_is_in_interval(const char *a, const char *b, const char *c);
+void rend_get_descriptor_id_bytes(char *descriptor_id_out,
+ const char *service_id,
+ const char *secret_id_part);
+
+#endif
+
diff --git a/src/or/rendmid.c b/src/or/rendmid.c
index 23add316a8..bc36a4e117 100644
--- a/src/or/rendmid.c
+++ b/src/or/rendmid.c
@@ -8,6 +8,11 @@
**/
#include "or.h"
+#include "circuitlist.h"
+#include "config.h"
+#include "relay.h"
+#include "rendmid.h"
+#include "rephist.h"
/** Respond to an ESTABLISH_INTRO cell by checking the signed data and
* setting the circuit's purpose and service pk digest.
diff --git a/src/or/rendmid.h b/src/or/rendmid.h
new file mode 100644
index 0000000000..f06dd3d85e
--- /dev/null
+++ b/src/or/rendmid.h
@@ -0,0 +1,25 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file rendmid.h
+ * \brief Header file for rendmid.c.
+ **/
+
+#ifndef _TOR_RENDMID_H
+#define _TOR_RENDMID_H
+
+int rend_mid_establish_intro(or_circuit_t *circ, const uint8_t *request,
+ size_t request_len);
+int rend_mid_introduce(or_circuit_t *circ, const uint8_t *request,
+ size_t request_len);
+int rend_mid_establish_rendezvous(or_circuit_t *circ, const uint8_t *request,
+ size_t request_len);
+int rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request,
+ size_t request_len);
+
+#endif
+
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index f5917bc973..f06c98337a 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -8,10 +8,23 @@
**/
#include "or.h"
+#include "circuitbuild.h"
+#include "circuitlist.h"
+#include "circuituse.h"
+#include "config.h"
+#include "directory.h"
+#include "networkstatus.h"
+#include "rendclient.h"
+#include "rendcommon.h"
+#include "rendservice.h"
+#include "router.h"
+#include "relay.h"
+#include "rephist.h"
+#include "routerlist.h"
+#include "routerparse.h"
static origin_circuit_t *find_intro_circuit(rend_intro_point_t *intro,
- const char *pk_digest,
- int desc_version);
+ const char *pk_digest);
/** Represents the mapping from a virtual port of a rendezvous service to
* a real port on some IP.
@@ -42,8 +55,6 @@ typedef struct rend_service_t {
/* Fields specified in config file */
char *directory; /**< where in the filesystem it stores it */
smartlist_t *ports; /**< List of rend_service_port_config_t */
- int descriptor_version; /**< Rendezvous descriptor version that will be
- * published. */
rend_auth_type_t auth_type; /**< Client authorization type or 0 if no client
* authorization is performed. */
smartlist_t *clients; /**< List of rend_authorized_client_t's of
@@ -58,7 +69,7 @@ typedef struct rend_service_t {
* or are trying to establish. */
time_t intro_period_started; /**< Start of the current period to build
* introduction points. */
- int n_intro_circuits_launched; /**< count of intro circuits we have
+ int n_intro_circuits_launched; /**< Count of intro circuits we have
* established in this period. */
rend_service_descriptor_t *desc; /**< Current hidden service descriptor. */
time_t desc_is_dirty; /**< Time at which changes to the hidden service
@@ -90,7 +101,8 @@ num_rend_services(void)
static void
rend_authorized_client_free(rend_authorized_client_t *client)
{
- if (!client) return;
+ if (!client)
+ return;
if (client->client_key)
crypto_free_pk_env(client->client_key);
tor_free(client->client_name);
@@ -109,7 +121,9 @@ rend_authorized_client_strmap_item_free(void *authorized_client)
static void
rend_service_free(rend_service_t *service)
{
- if (!service) return;
+ if (!service)
+ return;
+
tor_free(service->directory);
SMARTLIST_FOREACH(service->ports, void*, p, tor_free(p));
smartlist_free(service->ports);
@@ -120,15 +134,14 @@ rend_service_free(rend_service_t *service)
rend_intro_point_free(intro););
smartlist_free(service->intro_nodes);
}
- if (service->desc)
- rend_service_descriptor_free(service->desc);
+
+ rend_service_descriptor_free(service->desc);
if (service->clients) {
SMARTLIST_FOREACH(service->clients, rend_authorized_client_t *, c,
rend_authorized_client_free(c););
smartlist_free(service->clients);
}
- if (service->accepted_intros)
- digestmap_free(service->accepted_intros, _tor_free);
+ digestmap_free(service->accepted_intros, _tor_free);
tor_free(service);
}
@@ -137,9 +150,9 @@ rend_service_free(rend_service_t *service)
void
rend_service_free_all(void)
{
- if (!rend_service_list) {
+ if (!rend_service_list)
return;
- }
+
SMARTLIST_FOREACH(rend_service_list, rend_service_t*, ptr,
rend_service_free(ptr));
smartlist_free(rend_service_list);
@@ -156,36 +169,6 @@ rend_add_service(rend_service_t *service)
service->intro_nodes = smartlist_create();
- /* If the service is configured to publish unversioned (v0) and versioned
- * descriptors (v2 or higher), split it up into two separate services
- * (unless it is configured to perform client authorization). */
- if (service->descriptor_version == -1) {
- if (service->auth_type == REND_NO_AUTH) {
- rend_service_t *v0_service = tor_malloc_zero(sizeof(rend_service_t));
- v0_service->directory = tor_strdup(service->directory);
- v0_service->ports = smartlist_create();
- SMARTLIST_FOREACH(service->ports, rend_service_port_config_t *, p, {
- rend_service_port_config_t *copy =
- tor_malloc_zero(sizeof(rend_service_port_config_t));
- memcpy(copy, p, sizeof(rend_service_port_config_t));
- smartlist_add(v0_service->ports, copy);
- });
- v0_service->intro_period_started = service->intro_period_started;
- v0_service->descriptor_version = 0; /* Unversioned descriptor. */
- v0_service->auth_type = REND_NO_AUTH;
- rend_add_service(v0_service);
- }
-
- service->descriptor_version = 2; /* Versioned descriptor. */
- }
-
- if (service->auth_type != REND_NO_AUTH && !service->descriptor_version) {
- log_warn(LD_CONFIG, "Hidden service with client authorization and "
- "version 0 descriptors configured; ignoring.");
- rend_service_free(service);
- return;
- }
-
if (service->auth_type != REND_NO_AUTH &&
smartlist_len(service->clients) == 0) {
log_warn(LD_CONFIG, "Hidden service with client authorization but no "
@@ -297,7 +280,7 @@ rend_config_services(or_options_t *options, int validate_only)
for (line = options->RendConfigLines; line; line = line->next) {
if (!strcasecmp(line->key, "HiddenServiceDir")) {
- if (service) {
+ if (service) { /* register the one we just finished parsing */
if (validate_only)
rend_service_free(service);
else
@@ -307,7 +290,6 @@ rend_config_services(or_options_t *options, int validate_only)
service->directory = tor_strdup(line->value);
service->ports = smartlist_create();
service->intro_period_started = time(NULL);
- service->descriptor_version = -1; /**< All descriptor versions. */
continue;
}
if (!service) {
@@ -433,35 +415,13 @@ rend_config_services(or_options_t *options, int validate_only)
return -1;
}
} else {
- smartlist_t *versions;
- char *version_str;
- int i, version, ver_ok=1, versions_bitmask = 0;
tor_assert(!strcasecmp(line->key, "HiddenServiceVersion"));
- versions = smartlist_create();
- smartlist_split_string(versions, line->value, ",",
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- for (i = 0; i < smartlist_len(versions); i++) {
- version_str = smartlist_get(versions, i);
- if (strlen(version_str) != 1 || strspn(version_str, "02") != 1) {
- log_warn(LD_CONFIG,
- "HiddenServiceVersion can only be 0 and/or 2.");
- SMARTLIST_FOREACH(versions, char *, cp, tor_free(cp));
- smartlist_free(versions);
- rend_service_free(service);
- return -1;
- }
- version = (int)tor_parse_long(version_str, 10, 0, INT_MAX, &ver_ok,
- NULL);
- if (!ver_ok)
- continue;
- versions_bitmask |= 1 << version;
+ if (strcmp(line->value, "2")) {
+ log_warn(LD_CONFIG,
+ "The only supported HiddenServiceVersion is 2.");
+ rend_service_free(service);
+ return -1;
}
- /* If exactly one version is set, change descriptor_version to that
- * value; otherwise leave it at -1. */
- if (versions_bitmask == 1 << 0) service->descriptor_version = 0;
- if (versions_bitmask == 1 << 2) service->descriptor_version = 2;
- SMARTLIST_FOREACH(versions, char *, cp, tor_free(cp));
- smartlist_free(versions);
}
}
if (service) {
@@ -483,8 +443,7 @@ rend_config_services(or_options_t *options, int validate_only)
* probably ok? */
SMARTLIST_FOREACH(rend_service_list, rend_service_t *, new, {
SMARTLIST_FOREACH(old_service_list, rend_service_t *, old, {
- if (!strcmp(old->directory, new->directory) &&
- old->descriptor_version == new->descriptor_version) {
+ if (!strcmp(old->directory, new->directory)) {
smartlist_add_all(new->intro_nodes, old->intro_nodes);
smartlist_clear(old->intro_nodes);
smartlist_add(surviving_services, old);
@@ -507,18 +466,16 @@ rend_config_services(or_options_t *options, int validate_only)
tor_assert(oc->rend_data);
SMARTLIST_FOREACH(surviving_services, rend_service_t *, ptr, {
if (!memcmp(ptr->pk_digest, oc->rend_data->rend_pk_digest,
- DIGEST_LEN) &&
- ptr->descriptor_version == oc->rend_data->rend_desc_version) {
+ DIGEST_LEN)) {
keep_it = 1;
break;
}
});
if (keep_it)
continue;
- log_info(LD_REND, "Closing intro point %s for service %s version %d.",
- safe_str(oc->build_state->chosen_exit->nickname),
- oc->rend_data->onion_address,
- oc->rend_data->rend_desc_version);
+ log_info(LD_REND, "Closing intro point %s for service %s.",
+ safe_str_client(oc->build_state->chosen_exit->nickname),
+ oc->rend_data->onion_address);
circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
/* XXXX Is there another reason we should use here? */
}
@@ -541,14 +498,13 @@ rend_service_update_descriptor(rend_service_t *service)
rend_service_descriptor_t *d;
origin_circuit_t *circ;
int i;
- if (service->desc) {
- rend_service_descriptor_free(service->desc);
- service->desc = NULL;
- }
+
+ rend_service_descriptor_free(service->desc);
+ service->desc = NULL;
+
d = service->desc = tor_malloc_zero(sizeof(rend_service_descriptor_t));
d->pk = crypto_pk_dup_key(service->private_key);
d->timestamp = time(NULL);
- d->version = service->descriptor_version;
d->intro_nodes = smartlist_create();
/* Support intro protocols 2 and 3. */
d->protocols = (1 << 2) + (1 << 3);
@@ -556,7 +512,7 @@ rend_service_update_descriptor(rend_service_t *service)
for (i = 0; i < smartlist_len(service->intro_nodes); ++i) {
rend_intro_point_t *intro_svc = smartlist_get(service->intro_nodes, i);
rend_intro_point_t *intro_desc;
- circ = find_intro_circuit(intro_svc, service->pk_digest, d->version);
+ circ = find_intro_circuit(intro_svc, service->pk_digest);
if (!circ || circ->_base.purpose != CIRCUIT_PURPOSE_S_INTRO)
continue;
@@ -797,17 +753,15 @@ rend_service_load_keys(void)
return r;
}
-/** Return the service whose public key has a digest of <b>digest</b> and
- * which publishes the given descriptor <b>version</b>. Return NULL if no
- * such service exists.
+/** Return the service whose public key has a digest of <b>digest</b>, or
+ * NULL if no such service exists.
*/
static rend_service_t *
-rend_service_get_by_pk_digest_and_version(const char* digest,
- uint8_t version)
+rend_service_get_by_pk_digest(const char* digest)
{
SMARTLIST_FOREACH(rend_service_list, rend_service_t*, s,
- if (!memcmp(s->pk_digest,digest,DIGEST_LEN) &&
- s->descriptor_version == version) return s);
+ if (!memcmp(s->pk_digest,digest,DIGEST_LEN))
+ return s);
return NULL;
}
@@ -944,21 +898,16 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
}
/* look up service depending on circuit. */
- service = rend_service_get_by_pk_digest_and_version(
- circuit->rend_data->rend_pk_digest,
- circuit->rend_data->rend_desc_version);
+ service = rend_service_get_by_pk_digest(
+ circuit->rend_data->rend_pk_digest);
if (!service) {
log_warn(LD_REND, "Got an INTRODUCE2 cell for an unrecognized service %s.",
escaped(serviceid));
return -1;
}
- /* if descriptor version is 2, use intro key instead of service key. */
- if (circuit->rend_data->rend_desc_version == 0) {
- intro_key = service->private_key;
- } else {
- intro_key = circuit->intro_key;
- }
+ /* use intro key instead of service key. */
+ intro_key = circuit->intro_key;
/* first DIGEST_LEN bytes of request is intro or service pk digest */
crypto_pk_get_digest(intro_key, intro_key_digest);
@@ -988,7 +937,7 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
len = r;
if (*buf == 3) {
/* Version 3 INTRODUCE2 cell. */
- time_t ts = 0, now = time(NULL);
+ time_t ts = 0;
v3_shift = 1;
auth_type = buf[1];
switch (auth_type) {
@@ -1082,7 +1031,7 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
router = router_get_by_nickname(rp_nickname, 0);
if (!router) {
log_info(LD_REND, "Couldn't find router %s named in introduce2 cell.",
- escaped_safe_str(rp_nickname));
+ escaped_safe_str_client(rp_nickname));
/* XXXX Add a no-such-router reason? */
reason = END_CIRC_REASON_TORPROTOCOL;
goto err;
@@ -1157,7 +1106,8 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
reason = END_CIRC_REASON_INTERNAL;
goto err;
}
- if (crypto_dh_compute_secret(dh, ptr+REND_COOKIE_LEN, DH_KEY_LEN, keys,
+ if (crypto_dh_compute_secret(LOG_PROTOCOL_WARN, dh, ptr+REND_COOKIE_LEN,
+ DH_KEY_LEN, keys,
DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) {
log_warn(LD_BUG, "Internal error: couldn't complete DH handshake");
reason = END_CIRC_REASON_INTERNAL;
@@ -1167,7 +1117,7 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
circ_needs_uptime = rend_service_requires_uptime(service);
/* help predict this next time */
- rep_hist_note_used_internal(time(NULL), circ_needs_uptime, 1);
+ rep_hist_note_used_internal(now, circ_needs_uptime, 1);
/* Launch a circuit to alice's chosen rendezvous point.
*/
@@ -1183,14 +1133,16 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
if (!launched) { /* give up */
log_warn(LD_REND, "Giving up launching first hop of circuit to rendezvous "
"point %s for service %s.",
- escaped_safe_str(extend_info->nickname), serviceid);
+ escaped_safe_str_client(extend_info->nickname),
+ serviceid);
reason = END_CIRC_REASON_CONNECTFAILED;
goto err;
}
log_info(LD_REND,
"Accepted intro; launching circuit to %s "
"(cookie %s) for service %s.",
- escaped_safe_str(extend_info->nickname), hexcookie, serviceid);
+ escaped_safe_str_client(extend_info->nickname),
+ hexcookie, serviceid);
tor_assert(launched->build_state);
/* Fill in the circuit's state. */
launched->rend_data = tor_malloc_zero(sizeof(rend_data_t));
@@ -1200,11 +1152,10 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
memcpy(launched->rend_data->rend_cookie, r_cookie, REND_COOKIE_LEN);
strlcpy(launched->rend_data->onion_address, service->service_id,
sizeof(launched->rend_data->onion_address));
- launched->rend_data->rend_desc_version = service->descriptor_version;
launched->build_state->pending_final_cpath = cpath =
tor_malloc_zero(sizeof(crypt_path_t));
cpath->magic = CRYPT_PATH_MAGIC;
- launched->build_state->expiry_time = time(NULL) + MAX_REND_TIMEOUT;
+ launched->build_state->expiry_time = now + MAX_REND_TIMEOUT;
cpath->dh_handshake_state = dh;
dh = NULL;
@@ -1286,7 +1237,7 @@ rend_service_launch_establish_intro(rend_service_t *service,
log_info(LD_REND,
"Launching circuit to introduction point %s for service %s",
- escaped_safe_str(intro->extend_info->nickname),
+ escaped_safe_str_client(intro->extend_info->nickname),
service->service_id);
rep_hist_note_used_internal(time(NULL), 1, 0);
@@ -1299,7 +1250,7 @@ rend_service_launch_establish_intro(rend_service_t *service,
if (!launched) {
log_info(LD_REND,
"Can't launch circuit to establish introduction at %s.",
- escaped_safe_str(intro->extend_info->nickname));
+ escaped_safe_str_client(intro->extend_info->nickname));
return -1;
}
@@ -1322,18 +1273,16 @@ rend_service_launch_establish_intro(rend_service_t *service,
strlcpy(launched->rend_data->onion_address, service->service_id,
sizeof(launched->rend_data->onion_address));
memcpy(launched->rend_data->rend_pk_digest, service->pk_digest, DIGEST_LEN);
- launched->rend_data->rend_desc_version = service->descriptor_version;
- if (service->descriptor_version == 2)
- launched->intro_key = crypto_pk_dup_key(intro->intro_key);
+ launched->intro_key = crypto_pk_dup_key(intro->intro_key);
if (launched->_base.state == CIRCUIT_STATE_OPEN)
rend_service_intro_has_opened(launched);
return 0;
}
/** Return the number of introduction points that are or have been
- * established for the given service address and rendezvous version. */
+ * established for the given service address in <b>query</b>. */
static int
-count_established_intro_points(const char *query, int rend_version)
+count_established_intro_points(const char *query)
{
int num_ipos = 0;
circuit_t *circ;
@@ -1344,7 +1293,6 @@ count_established_intro_points(const char *query, int rend_version)
circ->purpose == CIRCUIT_PURPOSE_S_INTRO)) {
origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(circ);
if (oc->rend_data &&
- oc->rend_data->rend_desc_version == rend_version &&
!rend_cmp_service_ids(query, oc->rend_data->onion_address))
num_ipos++;
}
@@ -1374,9 +1322,8 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
base32_encode(serviceid, REND_SERVICE_ID_LEN_BASE32+1,
circuit->rend_data->rend_pk_digest, REND_SERVICE_ID_LEN);
- service = rend_service_get_by_pk_digest_and_version(
- circuit->rend_data->rend_pk_digest,
- circuit->rend_data->rend_desc_version);
+ service = rend_service_get_by_pk_digest(
+ circuit->rend_data->rend_pk_digest);
if (!service) {
log_warn(LD_REND, "Unrecognized service ID %s on introduction circuit %d.",
serviceid, circuit->_base.n_circ_id);
@@ -1386,8 +1333,7 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
/* If we already have enough introduction circuits for this service,
* redefine this one as a general circuit. */
- if (count_established_intro_points(serviceid,
- circuit->rend_data->rend_desc_version) > NUM_INTRO_POINTS) {
+ if (count_established_intro_points(serviceid) > NUM_INTRO_POINTS) {
log_info(LD_CIRC|LD_REND, "We have just finished an introduction "
"circuit, but we already have enough. Redefining purpose to "
"general.");
@@ -1400,13 +1346,8 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
"Established circuit %d as introduction point for service %s",
circuit->_base.n_circ_id, serviceid);
- /* If the introduction point will not be used in an unversioned
- * descriptor, use the intro key instead of the service key in
- * ESTABLISH_INTRO. */
- if (service->descriptor_version == 0)
- intro_key = service->private_key;
- else
- intro_key = circuit->intro_key;
+ /* Use the intro key instead of the service key in ESTABLISH_INTRO. */
+ intro_key = circuit->intro_key;
/* Build the payload for a RELAY_ESTABLISH_INTRO cell. */
r = crypto_pk_asn1_encode(intro_key, buf+2,
RELAY_PAYLOAD_SIZE-2);
@@ -1466,9 +1407,8 @@ rend_service_intro_established(origin_circuit_t *circuit,
goto err;
}
tor_assert(circuit->rend_data);
- service = rend_service_get_by_pk_digest_and_version(
- circuit->rend_data->rend_pk_digest,
- circuit->rend_data->rend_desc_version);
+ service = rend_service_get_by_pk_digest(
+ circuit->rend_data->rend_pk_digest);
if (!service) {
log_warn(LD_REND, "Unknown service on introduction circuit %d.",
circuit->_base.n_circ_id);
@@ -1518,9 +1458,8 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit)
"cookie %s for service %s",
circuit->_base.n_circ_id, hexcookie, serviceid);
- service = rend_service_get_by_pk_digest_and_version(
- circuit->rend_data->rend_pk_digest,
- circuit->rend_data->rend_desc_version);
+ service = rend_service_get_by_pk_digest(
+ circuit->rend_data->rend_pk_digest);
if (!service) {
log_warn(LD_GENERAL, "Internal error: unrecognized service ID on "
"introduction circuit.");
@@ -1576,13 +1515,12 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit)
*/
/** Return the (possibly non-open) introduction circuit ending at
- * <b>intro</b> for the service whose public key is <b>pk_digest</b> and
- * which publishes descriptor of version <b>desc_version</b>. Return
- * NULL if no such service is found.
+ * <b>intro</b> for the service whose public key is <b>pk_digest</b>.
+ * (<b>desc_version</b> is ignored). Return NULL if no such service is
+ * found.
*/
static origin_circuit_t *
-find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest,
- int desc_version)
+find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest)
{
origin_circuit_t *circ = NULL;
@@ -1591,8 +1529,7 @@ find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest,
CIRCUIT_PURPOSE_S_INTRO))) {
if (!memcmp(circ->build_state->chosen_exit->identity_digest,
intro->extend_info->identity_digest, DIGEST_LEN) &&
- circ->rend_data &&
- circ->rend_data->rend_desc_version == desc_version) {
+ circ->rend_data) {
return circ;
}
}
@@ -1602,8 +1539,7 @@ find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest,
CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) {
if (!memcmp(circ->build_state->chosen_exit->identity_digest,
intro->extend_info->identity_digest, DIGEST_LEN) &&
- circ->rend_data &&
- circ->rend_data->rend_desc_version == desc_version) {
+ circ->rend_data) {
return circ;
}
}
@@ -1636,6 +1572,7 @@ directory_post_to_hs_dir(rend_service_descriptor_t *renddesc,
}
for (j = 0; j < smartlist_len(responsible_dirs); j++) {
char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
+ char *hs_dir_ip;
hs_dir = smartlist_get(responsible_dirs, j);
if (smartlist_digest_isin(renddesc->successful_uploads,
hs_dir->identity_digest))
@@ -1657,15 +1594,18 @@ directory_post_to_hs_dir(rend_service_descriptor_t *renddesc,
strlen(desc->desc_str), 0);
base32_encode(desc_id_base32, sizeof(desc_id_base32),
desc->desc_id, DIGEST_LEN);
+ hs_dir_ip = tor_dup_ip(hs_dir->addr);
log_info(LD_REND, "Sending publish request for v2 descriptor for "
"service '%s' with descriptor ID '%s' with validity "
"of %d seconds to hidden service directory '%s' on "
- "port %d.",
- safe_str(service_id),
- safe_str(desc_id_base32),
+ "%s:%d.",
+ safe_str_client(service_id),
+ safe_str_client(desc_id_base32),
seconds_valid,
hs_dir->nickname,
- hs_dir->dir_port);
+ hs_dir_ip,
+ hs_dir->or_port);
+ tor_free(hs_dir_ip);
/* Remember successful upload to this router for next time. */
if (!smartlist_digest_isin(successful_uploads, hs_dir->identity_digest))
smartlist_add(successful_uploads, hs_dir->identity_digest);
@@ -1695,9 +1635,8 @@ directory_post_to_hs_dir(rend_service_descriptor_t *renddesc,
smartlist_free(successful_uploads);
}
-/** Encode and sign up-to-date v0 and/or v2 service descriptors for
- * <b>service</b>, and upload it/them to all the dirservers/to the
- * responsible hidden service directories.
+/** Encode and sign an up-to-date service descriptor for <b>service</b>,
+ * and upload it/them to the responsible hidden service directories.
*/
static void
upload_service_descriptor(rend_service_t *service)
@@ -1709,35 +1648,8 @@ upload_service_descriptor(rend_service_t *service)
rendpostperiod = get_options()->RendPostPeriod;
- /* Upload unversioned (v0) descriptor? */
- if (service->descriptor_version == 0 &&
- get_options()->PublishHidServDescriptors) {
- char *desc;
- size_t desc_len;
- /* Encode the descriptor. */
- if (rend_encode_service_descriptor(service->desc,
- service->private_key,
- &desc, &desc_len)<0) {
- log_warn(LD_BUG, "Internal error: couldn't encode service descriptor; "
- "not uploading.");
- return;
- }
-
- /* Post it to the dirservers */
- rend_get_service_id(service->desc->pk, serviceid);
- log_info(LD_REND, "Sending publish request for hidden service %s",
- serviceid);
- directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_RENDDESC,
- ROUTER_PURPOSE_GENERAL,
- HIDSERV_AUTHORITY, desc, desc_len, 0);
- tor_free(desc);
- service->next_upload_time = now + rendpostperiod;
- uploaded = 1;
- }
-
- /* Upload v2 descriptor? */
- if (service->descriptor_version == 2 &&
- get_options()->PublishHidServDescriptors) {
+ /* Upload descriptor? */
+ if (get_options()->PublishHidServDescriptors) {
networkstatus_t *c = networkstatus_get_latest_consensus();
if (c && smartlist_len(c->routerstatus_list) > 0) {
int seconds_valid, i, j, num_descs;
@@ -1876,8 +1788,7 @@ rend_services_introduce(void)
for (j=0; j < smartlist_len(service->intro_nodes); ++j) {
intro = smartlist_get(service->intro_nodes, j);
router = router_get_by_digest(intro->extend_info->identity_digest);
- if (!router || !find_intro_circuit(intro, service->pk_digest,
- service->descriptor_version)) {
+ if (!router || !find_intro_circuit(intro, service->pk_digest)) {
log_info(LD_REND,"Giving up on %s as intro point for %s.",
intro->extend_info->nickname, service->service_id);
if (service->desc) {
@@ -1929,7 +1840,7 @@ rend_services_introduce(void)
router_crn_flags_t flags = CRN_NEED_UPTIME;
if (get_options()->_AllowInvalid & ALLOW_INVALID_INTRODUCTION)
flags |= CRN_ALLOW_INVALID;
- router = router_choose_random_node(NULL, intro_routers,
+ router = router_choose_random_node(intro_routers,
options->ExcludeNodes, flags);
if (!router) {
log_warn(LD_REND,
@@ -1941,10 +1852,8 @@ rend_services_introduce(void)
smartlist_add(intro_routers, router);
intro = tor_malloc_zero(sizeof(rend_intro_point_t));
intro->extend_info = extend_info_from_router(router);
- if (service->descriptor_version == 2) {
- intro->intro_key = crypto_new_pk_env();
- tor_assert(!crypto_pk_generate_key(intro->intro_key));
- }
+ intro->intro_key = crypto_new_pk_env();
+ tor_assert(!crypto_pk_generate_key(intro->intro_key));
smartlist_add(service->intro_nodes, intro);
log_info(LD_REND, "Picked router %s as an intro point for %s.",
router->nickname, service->service_id);
@@ -2037,8 +1946,7 @@ rend_consider_descriptor_republication(void)
for (i=0; i < smartlist_len(rend_service_list); ++i) {
service = smartlist_get(rend_service_list, i);
- if (service->descriptor_version && service->desc &&
- !service->desc->all_uploads_performed) {
+ if (service->desc && !service->desc->all_uploads_performed) {
/* If we failed in uploading a descriptor last time, try again *without*
* updating the descriptor's contents. */
upload_service_descriptor(service);
@@ -2064,10 +1972,9 @@ rend_service_dump_stats(int severity)
service->directory);
for (j=0; j < smartlist_len(service->intro_nodes); ++j) {
intro = smartlist_get(service->intro_nodes, j);
- safe_name = safe_str(intro->extend_info->nickname);
+ safe_name = safe_str_client(intro->extend_info->nickname);
- circ = find_intro_circuit(intro, service->pk_digest,
- service->descriptor_version);
+ circ = find_intro_circuit(intro, service->pk_digest);
if (!circ) {
log(severity, LD_GENERAL, " Intro point %d at %s: no circuit",
j, safe_name);
@@ -2098,9 +2005,8 @@ rend_service_set_connection_addr_port(edge_connection_t *conn,
log_debug(LD_REND,"beginning to hunt for addr/port");
base32_encode(serviceid, REND_SERVICE_ID_LEN_BASE32+1,
circ->rend_data->rend_pk_digest, REND_SERVICE_ID_LEN);
- service = rend_service_get_by_pk_digest_and_version(
- circ->rend_data->rend_pk_digest,
- circ->rend_data->rend_desc_version);
+ service = rend_service_get_by_pk_digest(
+ circ->rend_data->rend_pk_digest);
if (!service) {
log_warn(LD_REND, "Couldn't find any service associated with pk %s on "
"rendezvous circuit %d; closing.",
diff --git a/src/or/rendservice.h b/src/or/rendservice.h
new file mode 100644
index 0000000000..722cec1561
--- /dev/null
+++ b/src/or/rendservice.h
@@ -0,0 +1,37 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file rendservice.h
+ * \brief Header file for rendservice.c.
+ **/
+
+#ifndef _TOR_RENDSERVICE_H
+#define _TOR_RENDSERVICE_H
+
+int num_rend_services(void);
+int rend_config_services(or_options_t *options, int validate_only);
+int rend_service_load_keys(void);
+void rend_services_introduce(void);
+void rend_consider_services_upload(time_t now);
+void rend_hsdir_routers_changed(void);
+void rend_consider_descriptor_republication(void);
+
+void rend_service_intro_has_opened(origin_circuit_t *circuit);
+int rend_service_intro_established(origin_circuit_t *circuit,
+ const uint8_t *request,
+ size_t request_len);
+void rend_service_rendezvous_has_opened(origin_circuit_t *circuit);
+int rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
+ size_t request_len);
+void rend_service_relaunch_rendezvous(origin_circuit_t *oldcirc);
+int rend_service_set_connection_addr_port(edge_connection_t *conn,
+ origin_circuit_t *circ);
+void rend_service_dump_stats(int severity);
+void rend_service_free_all(void);
+
+#endif
+
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 71ec0bd53c..5a57b954fd 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -6,15 +6,21 @@
* \file rephist.c
* \brief Basic history and "reputation" functionality to remember
* which servers have worked in the past, how much bandwidth we've
- * been using, which ports we tend to want, and so on.
+ * been using, which ports we tend to want, and so on; further,
+ * exit port statistics and cell statistics.
**/
#include "or.h"
+#include "circuitlist.h"
+#include "circuituse.h"
+#include "config.h"
+#include "rephist.h"
+#include "router.h"
+#include "routerlist.h"
#include "ht.h"
static void bw_arrays_init(void);
static void predicted_ports_init(void);
-static void hs_usage_init(void);
/** Total number of bytes currently allocated in fields used by rephist.c. */
uint64_t rephist_total_alloc=0;
@@ -185,7 +191,6 @@ rep_hist_init(void)
history_map = digestmap_new();
bw_arrays_init();
predicted_ports_init();
- hs_usage_init();
}
/** Helper: note that we are no longer connected to the router with history
@@ -795,12 +800,12 @@ rep_hist_record_mtbf_data(time_t now, int missing_means_down)
static char *
rep_hist_format_router_status(or_history_t *hist, time_t now)
{
- char buf[1024];
char sor_buf[ISO_TIME_LEN+1];
char sod_buf[ISO_TIME_LEN+1];
double wfu;
double mtbf;
int up = 0, down = 0;
+ char *cp = NULL;
if (hist->start_of_run) {
format_iso_time(sor_buf, hist->start_of_run);
@@ -813,7 +818,7 @@ rep_hist_format_router_status(or_history_t *hist, time_t now)
wfu = get_weighted_fractional_uptime(hist, now);
mtbf = get_stability(hist, now);
- tor_snprintf(buf, sizeof(buf),
+ tor_asprintf(&cp,
"%s%s%s"
"%s%s%s"
"wfu %0.3lf\n"
@@ -831,8 +836,7 @@ rep_hist_format_router_status(or_history_t *hist, time_t now)
hist->weighted_run_length,
hist->total_run_weights
);
-
- return tor_strdup(buf);
+ return cp;
}
/** The last stability analysis document that we created, or NULL if we never
@@ -1280,13 +1284,21 @@ bw_array_new(void)
static bw_array_t *read_array = NULL;
/** Recent history of bandwidth observations for write operations. */
static bw_array_t *write_array = NULL;
-
-/** Set up read_array and write_array. */
+/** Recent history of bandwidth observations for read operations for the
+ directory protocol. */
+static bw_array_t *dir_read_array = NULL;
+/** Recent history of bandwidth observations for write operations for the
+ directory protocol. */
+static bw_array_t *dir_write_array = NULL;
+
+/** Set up [dir-]read_array and [dir-]write_array. */
static void
bw_arrays_init(void)
{
read_array = bw_array_new();
write_array = bw_array_new();
+ dir_read_array = bw_array_new();
+ dir_write_array = bw_array_new();
}
/** We read <b>num_bytes</b> more bytes in second <b>when</b>.
@@ -1320,6 +1332,24 @@ rep_hist_note_bytes_read(size_t num_bytes, time_t when)
add_obs(read_array, when, num_bytes);
}
+/** We wrote <b>num_bytes</b> more directory bytes in second <b>when</b>.
+ * (like rep_hist_note_bytes_written() above)
+ */
+void
+rep_hist_note_dir_bytes_written(size_t num_bytes, time_t when)
+{
+ add_obs(dir_write_array, when, num_bytes);
+}
+
+/** We read <b>num_bytes</b> more directory bytes in second <b>when</b>.
+ * (like rep_hist_note_bytes_written() above)
+ */
+void
+rep_hist_note_dir_bytes_read(size_t num_bytes, time_t when)
+{
+ add_obs(dir_read_array, when, num_bytes);
+}
+
/** Helper: Return the largest value in b->maxima. (This is equal to the
* most bandwidth used in any NUM_SECS_ROLLING_MEASURE period for the last
* NUM_SECS_BW_SUM_IS_VALID seconds.)
@@ -1355,9 +1385,9 @@ rep_hist_bandwidth_assess(void)
return (int)(U64_TO_DBL(r)/NUM_SECS_ROLLING_MEASURE);
}
-/** Print the bandwidth history of b (either read_array or write_array)
- * into the buffer pointed to by buf. The format is simply comma
- * separated numbers, from oldest to newest.
+/** Print the bandwidth history of b (either [dir-]read_array or
+ * [dir-]write_array) into the buffer pointed to by buf. The format is
+ * simply comma separated numbers, from oldest to newest.
*
* It returns the number of bytes written.
*/
@@ -1410,26 +1440,42 @@ rep_hist_fill_bandwidth_history(char *buf, size_t len, bw_array_t *b)
* history in its descriptor.
*/
char *
-rep_hist_get_bandwidth_lines(int for_extrainfo)
+rep_hist_get_bandwidth_lines(void)
{
char *buf, *cp;
char t[ISO_TIME_LEN+1];
int r;
- bw_array_t *b;
+ bw_array_t *b = NULL;
+ const char *desc = NULL;
size_t len;
- /* opt (read|write)-history yyyy-mm-dd HH:MM:SS (n s) n,n,n,n,n... */
- len = (60+20*NUM_TOTALS)*2;
+ /* opt [dirreq-](read|write)-history yyyy-mm-dd HH:MM:SS (n s) n,n,n... */
+ len = (67+21*NUM_TOTALS)*4;
buf = tor_malloc_zero(len);
cp = buf;
- for (r=0;r<2;++r) {
- b = r?read_array:write_array;
+ for (r=0;r<4;++r) {
+ switch (r) {
+ case 0:
+ b = write_array;
+ desc = "write-history";
+ break;
+ case 1:
+ b = read_array;
+ desc = "read-history";
+ break;
+ case 2:
+ b = dir_write_array;
+ desc = "dirreq-write-history";
+ break;
+ case 3:
+ b = dir_read_array;
+ desc = "dirreq-read-history";
+ break;
+ }
tor_assert(b);
format_iso_time(t, b->next_period-NUM_SECS_BW_SUM_INTERVAL);
- tor_snprintf(cp, len-(cp-buf), "%s%s %s (%d s) ",
- for_extrainfo ? "" : "opt ",
- r ? "read-history" : "write-history", t,
- NUM_SECS_BW_SUM_INTERVAL);
+ tor_snprintf(cp, len-(cp-buf), "%s %s (%d s) ",
+ desc, t, NUM_SECS_BW_SUM_INTERVAL);
cp += strlen(cp);
cp += rep_hist_fill_bandwidth_history(cp, len-(cp-buf), b);
strlcat(cp, "\n", len-(cp-buf));
@@ -1444,20 +1490,41 @@ rep_hist_update_state(or_state_t *state)
{
int len, r;
char *buf, *cp;
- smartlist_t **s_values;
- time_t *s_begins;
- int *s_interval;
- bw_array_t *b;
+ smartlist_t **s_values = NULL;
+ time_t *s_begins = NULL;
+ int *s_interval = NULL;
+ bw_array_t *b = NULL;
len = 20*NUM_TOTALS+1;
buf = tor_malloc_zero(len);
- for (r=0;r<2;++r) {
- b = r?read_array:write_array;
- s_begins = r?&state->BWHistoryReadEnds :&state->BWHistoryWriteEnds;
- s_interval= r?&state->BWHistoryReadInterval:&state->BWHistoryWriteInterval;
- s_values = r?&state->BWHistoryReadValues :&state->BWHistoryWriteValues;
-
+ for (r=0;r<4;++r) {
+ switch (r) {
+ case 0:
+ b = write_array;
+ s_begins = &state->BWHistoryWriteEnds;
+ s_interval = &state->BWHistoryWriteInterval;
+ s_values = &state->BWHistoryWriteValues;
+ break;
+ case 1:
+ b = read_array;
+ s_begins = &state->BWHistoryReadEnds;
+ s_interval = &state->BWHistoryReadInterval;
+ s_values = &state->BWHistoryReadValues;
+ break;
+ case 2:
+ b = dir_write_array;
+ s_begins = &state->BWHistoryDirWriteEnds;
+ s_interval = &state->BWHistoryDirWriteInterval;
+ s_values = &state->BWHistoryDirWriteValues;
+ break;
+ case 3:
+ b = dir_read_array;
+ s_begins = &state->BWHistoryDirReadEnds;
+ s_interval = &state->BWHistoryDirReadInterval;
+ s_values = &state->BWHistoryDirReadValues;
+ break;
+ }
if (*s_values) {
SMARTLIST_FOREACH(*s_values, char *, val, tor_free(val));
smartlist_free(*s_values);
@@ -1497,23 +1564,45 @@ rep_hist_update_state(or_state_t *state)
int
rep_hist_load_state(or_state_t *state, char **err)
{
- time_t s_begins, start;
+ time_t s_begins = 0, start;
time_t now = time(NULL);
uint64_t v;
int r,i,ok;
int all_ok = 1;
- int s_interval;
- smartlist_t *s_values;
- bw_array_t *b;
+ int s_interval = 0;
+ smartlist_t *s_values = NULL;
+ bw_array_t *b = NULL;
/* Assert they already have been malloced */
tor_assert(read_array && write_array);
- for (r=0;r<2;++r) {
- b = r?read_array:write_array;
- s_begins = r?state->BWHistoryReadEnds:state->BWHistoryWriteEnds;
- s_interval = r?state->BWHistoryReadInterval:state->BWHistoryWriteInterval;
- s_values = r?state->BWHistoryReadValues:state->BWHistoryWriteValues;
+ for (r=0;r<4;++r) {
+ switch (r) {
+ case 0:
+ b = write_array;
+ s_begins = state->BWHistoryWriteEnds;
+ s_interval = state->BWHistoryWriteInterval;
+ s_values = state->BWHistoryWriteValues;
+ break;
+ case 1:
+ b = read_array;
+ s_begins = state->BWHistoryReadEnds;
+ s_interval = state->BWHistoryReadInterval;
+ s_values = state->BWHistoryReadValues;
+ break;
+ case 2:
+ b = dir_write_array;
+ s_begins = state->BWHistoryDirWriteEnds;
+ s_interval = state->BWHistoryDirWriteInterval;
+ s_values = state->BWHistoryDirWriteValues;
+ break;
+ case 3:
+ b = dir_read_array;
+ s_begins = state->BWHistoryDirReadEnds;
+ s_interval = state->BWHistoryDirReadInterval;
+ s_values = state->BWHistoryDirReadValues;
+ break;
+ }
if (s_values && s_begins >= now - NUM_SECS_BW_SUM_INTERVAL*NUM_TOTALS) {
start = s_begins - s_interval*(smartlist_len(s_values));
if (start > now)
@@ -1715,8 +1804,8 @@ rep_hist_get_predicted_internal(time_t now, int *need_uptime,
return 0; /* too long ago */
if (predicted_internal_uptime_time + PREDICTED_CIRCS_RELEVANCE_TIME >= now)
*need_uptime = 1;
- if (predicted_internal_capacity_time + PREDICTED_CIRCS_RELEVANCE_TIME >= now)
- *need_capacity = 1;
+ // Always predict that we need capacity.
+ *need_capacity = 1;
return 1;
}
@@ -1845,564 +1934,517 @@ dump_pk_ops(int severity)
pk_op_counts.n_rend_server_ops);
}
-/** Free all storage held by the OR/link history caches, by the
- * bandwidth history arrays, or by the port history. */
+/*** Exit port statistics ***/
+
+/* Some constants */
+/** To what multiple should byte numbers be rounded up? */
+#define EXIT_STATS_ROUND_UP_BYTES 1024
+/** To what multiple should stream counts be rounded up? */
+#define EXIT_STATS_ROUND_UP_STREAMS 4
+/** Number of TCP ports */
+#define EXIT_STATS_NUM_PORTS 65536
+/** Top n ports that will be included in exit stats. */
+#define EXIT_STATS_TOP_N_PORTS 10
+
+/* The following data structures are arrays and no fancy smartlists or maps,
+ * so that all write operations can be done in constant time. This comes at
+ * the price of some memory (1.25 MB) and linear complexity when writing
+ * stats for measuring relays. */
+/** Number of bytes read in current period by exit port */
+static uint64_t *exit_bytes_read = NULL;
+/** Number of bytes written in current period by exit port */
+static uint64_t *exit_bytes_written = NULL;
+/** Number of streams opened in current period by exit port */
+static uint32_t *exit_streams = NULL;
+
+/** Start time of exit stats or 0 if we're not collecting exit stats. */
+static time_t start_of_exit_stats_interval;
+
+/** Initialize exit port stats. */
void
-rep_hist_free_all(void)
+rep_hist_exit_stats_init(time_t now)
{
- digestmap_free(history_map, free_or_history);
- tor_free(read_array);
- tor_free(write_array);
- tor_free(last_stability_doc);
- built_last_stability_doc_at = 0;
- predicted_ports_free();
+ start_of_exit_stats_interval = now;
+ exit_bytes_read = tor_malloc_zero(EXIT_STATS_NUM_PORTS *
+ sizeof(uint64_t));
+ exit_bytes_written = tor_malloc_zero(EXIT_STATS_NUM_PORTS *
+ sizeof(uint64_t));
+ exit_streams = tor_malloc_zero(EXIT_STATS_NUM_PORTS *
+ sizeof(uint32_t));
}
-/****************** hidden service usage statistics ******************/
-
-/** How large are the intervals for which we track and report hidden service
- * use? */
-#define NUM_SECS_HS_USAGE_SUM_INTERVAL (15*60)
-/** How far in the past do we remember and publish hidden service use? */
-#define NUM_SECS_HS_USAGE_SUM_IS_VALID (24*60*60)
-/** How many hidden service usage intervals do we remember? (derived) */
-#define NUM_TOTALS_HS_USAGE (NUM_SECS_HS_USAGE_SUM_IS_VALID/ \
- NUM_SECS_HS_USAGE_SUM_INTERVAL)
-
-/** List element containing a service id and the count. */
-typedef struct hs_usage_list_elem_t {
- /** Service id of this elem. */
- char service_id[REND_SERVICE_ID_LEN_BASE32+1];
- /** Number of occurrences for the given service id. */
- uint32_t count;
- /* Pointer to next list elem */
- struct hs_usage_list_elem_t *next;
-} hs_usage_list_elem_t;
-
-/** Ordered list that stores service ids and the number of observations. It is
- * ordered by the number of occurrences in descending order. Its purpose is to
- * calculate the frequency distribution when the period is over. */
-typedef struct hs_usage_list_t {
- /* Pointer to the first element in the list. */
- hs_usage_list_elem_t *start;
- /* Number of total occurrences for all list elements. */
- uint32_t total_count;
- /* Number of service ids, i.e. number of list elements. */
- uint32_t total_service_ids;
-} hs_usage_list_t;
-
-/** Tracks service-related observations in the current period and their
- * history. */
-typedef struct hs_usage_service_related_observation_t {
- /** Ordered list that stores service ids and the number of observations in
- * the current period. It is ordered by the number of occurrences in
- * descending order. Its purpose is to calculate the frequency distribution
- * when the period is over. */
- hs_usage_list_t *list;
- /** Circular arrays that store the history of observations. totals stores all
- * observations, twenty (ten, five) the number of observations related to a
- * service id being accounted for the top 20 (10, 5) percent of all
- * observations. */
- uint32_t totals[NUM_TOTALS_HS_USAGE];
- uint32_t five[NUM_TOTALS_HS_USAGE];
- uint32_t ten[NUM_TOTALS_HS_USAGE];
- uint32_t twenty[NUM_TOTALS_HS_USAGE];
-} hs_usage_service_related_observation_t;
-
-/** Tracks the history of general period-related observations, i.e. those that
- * cannot be related to a specific service id. */
-typedef struct hs_usage_general_period_related_observations_t {
- /** Circular array that stores the history of observations. */
- uint32_t totals[NUM_TOTALS_HS_USAGE];
-} hs_usage_general_period_related_observations_t;
-
-/** Keeps information about the current observation period and its relation to
- * the histories of observations. */
-typedef struct hs_usage_current_observation_period_t {
- /** Where do we write the next history entry? */
- int next_idx;
- /** How many values in history have been set ever? (upper bound!) */
- int num_set;
- /** When did this period begin? */
- time_t start_of_current_period;
- /** When does the next period begin? */
- time_t start_of_next_period;
-} hs_usage_current_observation_period_t;
-
-/** Usage statistics for the current observation period. */
-static hs_usage_current_observation_period_t *current_period = NULL;
-
-/** Total number of descriptor publish requests in the current observation
- * period. */
-static hs_usage_service_related_observation_t *publish_total = NULL;
-
-/** Number of descriptor publish requests for services that have not been
- * seen before in the current observation period. */
-static hs_usage_service_related_observation_t *publish_novel = NULL;
-
-/** Total number of descriptor fetch requests in the current observation
- * period. */
-static hs_usage_service_related_observation_t *fetch_total = NULL;
-
-/** Number of successful descriptor fetch requests in the current
- * observation period. */
-static hs_usage_service_related_observation_t *fetch_successful = NULL;
-
-/** Number of descriptors stored in the current observation period. */
-static hs_usage_general_period_related_observations_t *descs = NULL;
-
-/** Creates an empty ordered list element. */
-static hs_usage_list_elem_t *
-hs_usage_list_elem_new(void)
+/** Reset counters for exit port statistics. */
+void
+rep_hist_reset_exit_stats(time_t now)
{
- hs_usage_list_elem_t *e;
- e = tor_malloc_zero(sizeof(hs_usage_list_elem_t));
- rephist_total_alloc += sizeof(hs_usage_list_elem_t);
- e->count = 1;
- e->next = NULL;
- return e;
+ start_of_exit_stats_interval = now;
+ memset(exit_bytes_read, 0, EXIT_STATS_NUM_PORTS * sizeof(uint64_t));
+ memset(exit_bytes_written, 0, EXIT_STATS_NUM_PORTS * sizeof(uint64_t));
+ memset(exit_streams, 0, EXIT_STATS_NUM_PORTS * sizeof(uint32_t));
}
-/** Creates an empty ordered list. */
-static hs_usage_list_t *
-hs_usage_list_new(void)
+/** Stop collecting exit port stats in a way that we can re-start doing
+ * so in rep_hist_exit_stats_init(). */
+void
+rep_hist_exit_stats_term(void)
{
- hs_usage_list_t *l;
- l = tor_malloc_zero(sizeof(hs_usage_list_t));
- rephist_total_alloc += sizeof(hs_usage_list_t);
- l->start = NULL;
- l->total_count = 0;
- l->total_service_ids = 0;
- return l;
+ start_of_exit_stats_interval = 0;
+ tor_free(exit_bytes_read);
+ tor_free(exit_bytes_written);
+ tor_free(exit_streams);
}
-/** Creates an empty structure for storing service-related observations. */
-static hs_usage_service_related_observation_t *
-hs_usage_service_related_observation_new(void)
-{
- hs_usage_service_related_observation_t *h;
- h = tor_malloc_zero(sizeof(hs_usage_service_related_observation_t));
- rephist_total_alloc += sizeof(hs_usage_service_related_observation_t);
- h->list = hs_usage_list_new();
- return h;
+/** Helper for qsort: compare two ints. */
+static int
+_compare_int(const void *x, const void *y) {
+ return (*(int*)x - *(int*)y);
}
-/** Creates an empty structure for storing general period-related
- * observations. */
-static hs_usage_general_period_related_observations_t *
-hs_usage_general_period_related_observations_new(void)
-{
- hs_usage_general_period_related_observations_t *p;
- p = tor_malloc_zero(sizeof(hs_usage_general_period_related_observations_t));
- rephist_total_alloc+= sizeof(hs_usage_general_period_related_observations_t);
- return p;
-}
+/** Return a newly allocated string containing the exit port statistics
+ * until <b>now</b>, or NULL if we're not collecting exit stats. */
+char *
+rep_hist_format_exit_stats(time_t now)
+{
+ int i, j, top_elements = 0, cur_min_idx = 0, cur_port;
+ uint64_t top_bytes[EXIT_STATS_TOP_N_PORTS];
+ int top_ports[EXIT_STATS_TOP_N_PORTS];
+ uint64_t cur_bytes = 0, other_read = 0, other_written = 0,
+ total_read = 0, total_written = 0;
+ uint32_t total_streams = 0, other_streams = 0;
+ char *buf;
+ smartlist_t *written_strings, *read_strings, *streams_strings;
+ char *written_string, *read_string, *streams_string;
+ char t[ISO_TIME_LEN+1];
+ char *result;
-/** Creates an empty structure for storing period-specific information. */
-static hs_usage_current_observation_period_t *
-hs_usage_current_observation_period_new(void)
-{
- hs_usage_current_observation_period_t *c;
- time_t now;
- c = tor_malloc_zero(sizeof(hs_usage_current_observation_period_t));
- rephist_total_alloc += sizeof(hs_usage_current_observation_period_t);
- now = time(NULL);
- c->start_of_current_period = now;
- c->start_of_next_period = now + NUM_SECS_HS_USAGE_SUM_INTERVAL;
- return c;
-}
+ if (!start_of_exit_stats_interval)
+ return NULL; /* Not initialized. */
-/** Initializes the structures for collecting hidden service usage data. */
-static void
-hs_usage_init(void)
-{
- current_period = hs_usage_current_observation_period_new();
- publish_total = hs_usage_service_related_observation_new();
- publish_novel = hs_usage_service_related_observation_new();
- fetch_total = hs_usage_service_related_observation_new();
- fetch_successful = hs_usage_service_related_observation_new();
- descs = hs_usage_general_period_related_observations_new();
-}
+ /* Go through all ports to find the n ports that saw most written and
+ * read bytes.
+ *
+ * Invariant: at the end of the loop for iteration i,
+ * total_read is the sum of all exit_bytes_read[0..i]
+ * total_written is the sum of all exit_bytes_written[0..i]
+ * total_stream is the sum of all exit_streams[0..i]
+ *
+ * top_elements = MAX(EXIT_STATS_TOP_N_PORTS,
+ * #{j | 0 <= j <= i && volume(i) > 0})
+ *
+ * For all 0 <= j < top_elements,
+ * top_bytes[j] > 0
+ * 0 <= top_ports[j] <= 65535
+ * top_bytes[j] = volume(top_ports[j])
+ *
+ * There is no j in 0..i and k in 0..top_elements such that:
+ * volume(j) > top_bytes[k] AND j is not in top_ports[0..top_elements]
+ *
+ * There is no j!=cur_min_idx in 0..top_elements such that:
+ * top_bytes[j] < top_bytes[cur_min_idx]
+ *
+ * where volume(x) == exit_bytes_read[x]+exit_bytes_written[x]
+ *
+ * Worst case: O(EXIT_STATS_NUM_PORTS * EXIT_STATS_TOP_N_PORTS)
+ */
+ for (i = 1; i < EXIT_STATS_NUM_PORTS; i++) {
+ total_read += exit_bytes_read[i];
+ total_written += exit_bytes_written[i];
+ total_streams += exit_streams[i];
+ cur_bytes = exit_bytes_read[i] + exit_bytes_written[i];
+ if (cur_bytes == 0) {
+ continue;
+ }
+ if (top_elements < EXIT_STATS_TOP_N_PORTS) {
+ top_bytes[top_elements] = cur_bytes;
+ top_ports[top_elements++] = i;
+ } else if (cur_bytes > top_bytes[cur_min_idx]) {
+ top_bytes[cur_min_idx] = cur_bytes;
+ top_ports[cur_min_idx] = i;
+ } else {
+ continue;
+ }
+ cur_min_idx = 0;
+ for (j = 1; j < top_elements; j++) {
+ if (top_bytes[j] < top_bytes[cur_min_idx]) {
+ cur_min_idx = j;
+ }
+ }
+ }
-/** Clears the given ordered list by resetting its attributes and releasing
- * the memory allocated by its elements. */
-static void
-hs_usage_list_clear(hs_usage_list_t *lst)
-{
- /* walk through elements and free memory */
- hs_usage_list_elem_t *current = lst->start;
- hs_usage_list_elem_t *tmp;
- while (current != NULL) {
- tmp = current->next;
- rephist_total_alloc -= sizeof(hs_usage_list_elem_t);
- tor_free(current);
- current = tmp;
+ /* Add observations of top ports to smartlists. */
+ written_strings = smartlist_create();
+ read_strings = smartlist_create();
+ streams_strings = smartlist_create();
+ other_read = total_read;
+ other_written = total_written;
+ other_streams = total_streams;
+ /* Sort the ports; this puts them out of sync with top_bytes, but we
+ * won't be using top_bytes again anyway */
+ qsort(top_ports, top_elements, sizeof(int), _compare_int);
+ for (j = 0; j < top_elements; j++) {
+ cur_port = top_ports[j];
+ if (exit_bytes_written[cur_port] > 0) {
+ uint64_t num = round_uint64_to_next_multiple_of(
+ exit_bytes_written[cur_port],
+ EXIT_STATS_ROUND_UP_BYTES);
+ num /= 1024;
+ buf = NULL;
+ tor_asprintf(&buf, "%d="U64_FORMAT, cur_port, U64_PRINTF_ARG(num));
+ smartlist_add(written_strings, buf);
+ other_written -= exit_bytes_written[cur_port];
+ }
+ if (exit_bytes_read[cur_port] > 0) {
+ uint64_t num = round_uint64_to_next_multiple_of(
+ exit_bytes_read[cur_port],
+ EXIT_STATS_ROUND_UP_BYTES);
+ num /= 1024;
+ buf = NULL;
+ tor_asprintf(&buf, "%d="U64_FORMAT, cur_port, U64_PRINTF_ARG(num));
+ smartlist_add(read_strings, buf);
+ other_read -= exit_bytes_read[cur_port];
+ }
+ if (exit_streams[cur_port] > 0) {
+ uint32_t num = round_uint32_to_next_multiple_of(
+ exit_streams[cur_port],
+ EXIT_STATS_ROUND_UP_STREAMS);
+ buf = NULL;
+ tor_asprintf(&buf, "%d=%u", cur_port, num);
+ smartlist_add(streams_strings, buf);
+ other_streams -= exit_streams[cur_port];
+ }
}
- /* reset attributes */
- lst->start = NULL;
- lst->total_count = 0;
- lst->total_service_ids = 0;
- return;
-}
-/** Frees the memory used by the given list. */
-static void
-hs_usage_list_free(hs_usage_list_t *lst)
-{
- if (!lst)
- return;
- hs_usage_list_clear(lst);
- rephist_total_alloc -= sizeof(hs_usage_list_t);
- tor_free(lst);
+ /* Add observations of other ports in a single element. */
+ other_written = round_uint64_to_next_multiple_of(other_written,
+ EXIT_STATS_ROUND_UP_BYTES);
+ other_written /= 1024;
+ buf = NULL;
+ tor_asprintf(&buf, "other="U64_FORMAT, U64_PRINTF_ARG(other_written));
+ smartlist_add(written_strings, buf);
+ other_read = round_uint64_to_next_multiple_of(other_read,
+ EXIT_STATS_ROUND_UP_BYTES);
+ other_read /= 1024;
+ buf = NULL;
+ tor_asprintf(&buf, "other="U64_FORMAT, U64_PRINTF_ARG(other_read));
+ smartlist_add(read_strings, buf);
+ other_streams = round_uint32_to_next_multiple_of(other_streams,
+ EXIT_STATS_ROUND_UP_STREAMS);
+ buf = NULL;
+ tor_asprintf(&buf, "other=%u", other_streams);
+ smartlist_add(streams_strings, buf);
+
+ /* Join all observations in single strings. */
+ written_string = smartlist_join_strings(written_strings, ",", 0, NULL);
+ read_string = smartlist_join_strings(read_strings, ",", 0, NULL);
+ streams_string = smartlist_join_strings(streams_strings, ",", 0, NULL);
+ SMARTLIST_FOREACH(written_strings, char *, cp, tor_free(cp));
+ SMARTLIST_FOREACH(read_strings, char *, cp, tor_free(cp));
+ SMARTLIST_FOREACH(streams_strings, char *, cp, tor_free(cp));
+ smartlist_free(written_strings);
+ smartlist_free(read_strings);
+ smartlist_free(streams_strings);
+
+ /* Put everything together. */
+ format_iso_time(t, now);
+ tor_asprintf(&result, "exit-stats-end %s (%d s)\n"
+ "exit-kibibytes-written %s\n"
+ "exit-kibibytes-read %s\n"
+ "exit-streams-opened %s\n",
+ t, (unsigned) (now - start_of_exit_stats_interval),
+ written_string,
+ read_string,
+ streams_string);
+ tor_free(written_string);
+ tor_free(read_string);
+ tor_free(streams_string);
+ return result;
}
-/** Frees the memory used by the given service-related observations. */
-static void
-hs_usage_service_related_observation_free(
- hs_usage_service_related_observation_t *s)
+/** If 24 hours have passed since the beginning of the current exit port
+ * stats period, write exit stats to $DATADIR/stats/exit-stats (possibly
+ * overwriting an existing file) and reset counters. Return when we would
+ * next want to write exit stats or 0 if we never want to write. */
+time_t
+rep_hist_exit_stats_write(time_t now)
{
- if (!s)
- return;
- hs_usage_list_free(s->list);
- rephist_total_alloc -= sizeof(hs_usage_service_related_observation_t);
- tor_free(s);
-}
+ char *statsdir = NULL, *filename = NULL, *str = NULL;
-/** Frees the memory used by the given period-specific observations. */
-static void
-hs_usage_general_period_related_observations_free(
- hs_usage_general_period_related_observations_t *s)
-{
- rephist_total_alloc-=sizeof(hs_usage_general_period_related_observations_t);
- tor_free(s);
-}
+ if (!start_of_exit_stats_interval)
+ return 0; /* Not initialized. */
+ if (start_of_exit_stats_interval + WRITE_STATS_INTERVAL > now)
+ goto done; /* Not ready to write. */
-/** Frees the memory used by period-specific information. */
-static void
-hs_usage_current_observation_period_free(
- hs_usage_current_observation_period_t *s)
-{
- rephist_total_alloc -= sizeof(hs_usage_current_observation_period_t);
- tor_free(s);
-}
+ log_info(LD_HIST, "Writing exit port statistics to disk.");
-/** Frees all memory that was used for collecting hidden service usage data. */
-void
-hs_usage_free_all(void)
-{
- hs_usage_general_period_related_observations_free(descs);
- descs = NULL;
- hs_usage_service_related_observation_free(fetch_successful);
- hs_usage_service_related_observation_free(fetch_total);
- hs_usage_service_related_observation_free(publish_novel);
- hs_usage_service_related_observation_free(publish_total);
- fetch_successful = fetch_total = publish_novel = publish_total = NULL;
- hs_usage_current_observation_period_free(current_period);
- current_period = NULL;
-}
+ /* Generate history string. */
+ str = rep_hist_format_exit_stats(now);
-/** Inserts a new occurrence for the given service id to the given ordered
- * list. */
-static void
-hs_usage_insert_value(hs_usage_list_t *lst, const char *service_id)
-{
- /* search if there is already an elem with same service_id in list */
- hs_usage_list_elem_t *current = lst->start;
- hs_usage_list_elem_t *previous = NULL;
- while (current != NULL && strcasecmp(current->service_id,service_id)) {
- previous = current;
- current = current->next;
- }
- /* found an element with same service_id? */
- if (current == NULL) {
- /* not found! append to end (which could also be the end of a zero-length
- * list), don't need to sort (1 is smallest value). */
- /* create elem */
- hs_usage_list_elem_t *e = hs_usage_list_elem_new();
- /* update list attributes (one new elem, one new occurrence) */
- lst->total_count++;
- lst->total_service_ids++;
- /* copy service id to elem */
- strlcpy(e->service_id,service_id,sizeof(e->service_id));
- /* let either l->start or previously last elem point to new elem */
- if (lst->start == NULL) {
- /* this is the first elem */
- lst->start = e;
- } else {
- /* there were elems in the list before */
- previous->next = e;
- }
- } else {
- /* found! add occurrence to elem and consider resorting */
- /* update list attributes (no new elem, but one new occurrence) */
- lst->total_count++;
- /* add occurrence to elem */
- current->count++;
- /* is it another than the first list elem? and has previous elem fewer
- * count than current? then we need to resort */
- if (previous != NULL && previous->count < current->count) {
- /* yes! we need to resort */
- /* remove current elem first */
- previous->next = current->next;
- /* can we prepend elem to all other elements? */
- if (lst->start->count <= current->count) {
- /* yes! prepend elem */
- current->next = lst->start;
- lst->start = current;
- } else {
- /* no! walk through list a second time and insert at correct place */
- hs_usage_list_elem_t *insert_current = lst->start->next;
- hs_usage_list_elem_t *insert_previous = lst->start;
- while (insert_current != NULL &&
- insert_current->count > current->count) {
- insert_previous = insert_current;
- insert_current = insert_current->next;
- }
- /* insert here */
- current->next = insert_current;
- insert_previous->next = current;
- }
- }
- }
-}
+ /* Reset counters. */
+ rep_hist_reset_exit_stats(now);
-/** Writes the current service-related observations to the history array and
- * clears the observations of the current period. */
-static void
-hs_usage_write_service_related_observations_to_history(
- hs_usage_current_observation_period_t *p,
- hs_usage_service_related_observation_t *h)
-{
- /* walk through the first 20 % of list elements and calculate frequency
- * distributions */
- /* maximum indices for the three frequencies */
- int five_percent_idx = h->list->total_service_ids/20;
- int ten_percent_idx = h->list->total_service_ids/10;
- int twenty_percent_idx = h->list->total_service_ids/5;
- /* temp values */
- uint32_t five_percent = 0;
- uint32_t ten_percent = 0;
- uint32_t twenty_percent = 0;
- /* walk through list */
- hs_usage_list_elem_t *current = h->list->start;
- int i=0;
- while (current != NULL && i <= twenty_percent_idx) {
- twenty_percent += current->count;
- if (i <= ten_percent_idx)
- ten_percent += current->count;
- if (i <= five_percent_idx)
- five_percent += current->count;
- current = current->next;
- i++;
+ /* Try to write to disk. */
+ statsdir = get_datadir_fname("stats");
+ if (check_private_dir(statsdir, CPD_CREATE) < 0) {
+ log_warn(LD_HIST, "Unable to create stats/ directory!");
+ goto done;
}
- /* copy frequencies */
- h->twenty[p->next_idx] = twenty_percent;
- h->ten[p->next_idx] = ten_percent;
- h->five[p->next_idx] = five_percent;
- /* copy total number of observations */
- h->totals[p->next_idx] = h->list->total_count;
- /* free memory of old list */
- hs_usage_list_clear(h->list);
-}
+ filename = get_datadir_fname2("stats", "exit-stats");
+ if (write_str_to_file(filename, str, 0) < 0)
+ log_warn(LD_HIST, "Unable to write exit port statistics to disk!");
-/** Advances to next observation period. */
-static void
-hs_usage_advance_current_observation_period(void)
-{
- /* aggregate observations to history, including frequency distribution
- * arrays */
- hs_usage_write_service_related_observations_to_history(
- current_period, publish_total);
- hs_usage_write_service_related_observations_to_history(
- current_period, publish_novel);
- hs_usage_write_service_related_observations_to_history(
- current_period, fetch_total);
- hs_usage_write_service_related_observations_to_history(
- current_period, fetch_successful);
- /* write current number of descriptors to descs history */
- descs->totals[current_period->next_idx] = rend_cache_size();
- /* advance to next period */
- current_period->next_idx++;
- if (current_period->next_idx == NUM_TOTALS_HS_USAGE)
- current_period->next_idx = 0;
- if (current_period->num_set < NUM_TOTALS_HS_USAGE)
- ++current_period->num_set;
- current_period->start_of_current_period=current_period->start_of_next_period;
- current_period->start_of_next_period += NUM_SECS_HS_USAGE_SUM_INTERVAL;
-}
-
-/** Checks if the current period is up to date, and if not, advances it. */
-static void
-hs_usage_check_if_current_period_is_up_to_date(time_t now)
-{
- while (now > current_period->start_of_next_period) {
- hs_usage_advance_current_observation_period();
- }
+ done:
+ tor_free(str);
+ tor_free(statsdir);
+ tor_free(filename);
+ return start_of_exit_stats_interval + WRITE_STATS_INTERVAL;
}
-/** Adds a service-related observation, maybe after advancing to next
- * observation period. */
-static void
-hs_usage_add_service_related_observation(
- hs_usage_service_related_observation_t *h,
- time_t now,
- const char *service_id)
+/** Note that we wrote <b>num_written</b> bytes and read <b>num_read</b>
+ * bytes to/from an exit connection to <b>port</b>. */
+void
+rep_hist_note_exit_bytes(uint16_t port, size_t num_written,
+ size_t num_read)
{
- if (now < current_period->start_of_current_period) {
- /* don't record old data */
- return;
- }
- /* check if we are up-to-date */
- hs_usage_check_if_current_period_is_up_to_date(now);
- /* add observation */
- hs_usage_insert_value(h->list, service_id);
+ if (!start_of_exit_stats_interval)
+ return; /* Not initialized. */
+ exit_bytes_written[port] += num_written;
+ exit_bytes_read[port] += num_read;
+ log_debug(LD_HIST, "Written %lu bytes and read %lu bytes to/from an "
+ "exit connection to port %d.",
+ (unsigned long)num_written, (unsigned long)num_read, port);
}
-/** Adds the observation of storing a rendezvous service descriptor to our
- * cache in our role as HS authoritative directory. */
+/** Note that we opened an exit stream to <b>port</b>. */
void
-hs_usage_note_publish_total(const char *service_id, time_t now)
+rep_hist_note_exit_stream_opened(uint16_t port)
{
- hs_usage_add_service_related_observation(publish_total, now, service_id);
+ if (!start_of_exit_stats_interval)
+ return; /* Not initialized. */
+ exit_streams[port]++;
+ log_debug(LD_HIST, "Opened exit stream to port %d", port);
}
-/** Adds the observation of storing a novel rendezvous service descriptor to
- * our cache in our role as HS authoritative directory. */
+/*** cell statistics ***/
+
+/** Start of the current buffer stats interval or 0 if we're not
+ * collecting buffer statistics. */
+static time_t start_of_buffer_stats_interval;
+
+/** Initialize buffer stats. */
void
-hs_usage_note_publish_novel(const char *service_id, time_t now)
+rep_hist_buffer_stats_init(time_t now)
{
- hs_usage_add_service_related_observation(publish_novel, now, service_id);
+ start_of_buffer_stats_interval = now;
}
-/** Adds the observation of being requested for a rendezvous service descriptor
- * in our role as HS authoritative directory. */
+typedef struct circ_buffer_stats_t {
+ uint32_t processed_cells;
+ double mean_num_cells_in_queue;
+ double mean_time_cells_in_queue;
+ uint32_t local_circ_id;
+} circ_buffer_stats_t;
+
+/** Holds stats. */
+smartlist_t *circuits_for_buffer_stats = NULL;
+
+/** Remember cell statistics for circuit <b>circ</b> at time
+ * <b>end_of_interval</b> and reset cell counters in case the circuit
+ * remains open in the next measurement interval. */
void
-hs_usage_note_fetch_total(const char *service_id, time_t now)
+rep_hist_buffer_stats_add_circ(circuit_t *circ, time_t end_of_interval)
+{
+ circ_buffer_stats_t *stat;
+ time_t start_of_interval;
+ int interval_length;
+ or_circuit_t *orcirc;
+ if (CIRCUIT_IS_ORIGIN(circ))
+ return;
+ orcirc = TO_OR_CIRCUIT(circ);
+ if (!orcirc->processed_cells)
+ return;
+ if (!circuits_for_buffer_stats)
+ circuits_for_buffer_stats = smartlist_create();
+ start_of_interval = circ->timestamp_created >
+ start_of_buffer_stats_interval ?
+ circ->timestamp_created :
+ start_of_buffer_stats_interval;
+ interval_length = (int) (end_of_interval - start_of_interval);
+ stat = tor_malloc_zero(sizeof(circ_buffer_stats_t));
+ stat->processed_cells = orcirc->processed_cells;
+ /* 1000.0 for s -> ms; 2.0 because of app-ward and exit-ward queues */
+ stat->mean_num_cells_in_queue = interval_length == 0 ? 0.0 :
+ (double) orcirc->total_cell_waiting_time /
+ (double) interval_length / 1000.0 / 2.0;
+ stat->mean_time_cells_in_queue =
+ (double) orcirc->total_cell_waiting_time /
+ (double) orcirc->processed_cells;
+ smartlist_add(circuits_for_buffer_stats, stat);
+ orcirc->total_cell_waiting_time = 0;
+ orcirc->processed_cells = 0;
+}
+
+/** Sorting helper: return -1, 1, or 0 based on comparison of two
+ * circ_buffer_stats_t */
+static int
+_buffer_stats_compare_entries(const void **_a, const void **_b)
{
- hs_usage_add_service_related_observation(fetch_total, now, service_id);
+ const circ_buffer_stats_t *a = *_a, *b = *_b;
+ if (a->processed_cells < b->processed_cells)
+ return 1;
+ else if (a->processed_cells > b->processed_cells)
+ return -1;
+ else
+ return 0;
}
-/** Adds the observation of being requested for a rendezvous service descriptor
- * in our role as HS authoritative directory and being able to answer that
- * request successfully. */
+/** Stop collecting cell stats in a way that we can re-start doing so in
+ * rep_hist_buffer_stats_init(). */
void
-hs_usage_note_fetch_successful(const char *service_id, time_t now)
+rep_hist_buffer_stats_term(void)
{
- hs_usage_add_service_related_observation(fetch_successful, now, service_id);
+ start_of_buffer_stats_interval = 0;
+ if (!circuits_for_buffer_stats)
+ circuits_for_buffer_stats = smartlist_create();
+ SMARTLIST_FOREACH(circuits_for_buffer_stats, circ_buffer_stats_t *,
+ stat, tor_free(stat));
+ smartlist_clear(circuits_for_buffer_stats);
}
-/** Writes the given circular array to a string. */
-static size_t
-hs_usage_format_history(char *buf, size_t len, uint32_t *data)
+/** Write buffer statistics to $DATADIR/stats/buffer-stats and return when
+ * we would next want to write exit stats. */
+time_t
+rep_hist_buffer_stats_write(time_t now)
{
- char *cp = buf; /* pointer where we are in the buffer */
- int i, n;
- if (current_period->num_set <= current_period->next_idx) {
- i = 0; /* not been through circular array */
- } else {
- i = current_period->next_idx;
+ char *statsdir = NULL, *filename = NULL;
+ char written[ISO_TIME_LEN+1];
+ open_file_t *open_file = NULL;
+ FILE *out;
+#define SHARES 10
+ int processed_cells[SHARES], circs_in_share[SHARES],
+ number_of_circuits, i;
+ double queued_cells[SHARES], time_in_queue[SHARES];
+ smartlist_t *str_build = smartlist_create();
+ char *str = NULL, *buf=NULL;
+ circuit_t *circ;
+
+ if (!start_of_buffer_stats_interval)
+ return 0; /* Not initialized. */
+ if (start_of_buffer_stats_interval + WRITE_STATS_INTERVAL > now)
+ goto done; /* Not ready to write */
+
+ /* add current circuits to stats */
+ for (circ = _circuit_get_global_list(); circ; circ = circ->next)
+ rep_hist_buffer_stats_add_circ(circ, now);
+ /* calculate deciles */
+ memset(processed_cells, 0, SHARES * sizeof(int));
+ memset(circs_in_share, 0, SHARES * sizeof(int));
+ memset(queued_cells, 0, SHARES * sizeof(double));
+ memset(time_in_queue, 0, SHARES * sizeof(double));
+ if (!circuits_for_buffer_stats)
+ circuits_for_buffer_stats = smartlist_create();
+ smartlist_sort(circuits_for_buffer_stats,
+ _buffer_stats_compare_entries);
+ number_of_circuits = smartlist_len(circuits_for_buffer_stats);
+ if (number_of_circuits < 1) {
+ log_info(LD_HIST, "Attempt to write cell statistics to disk failed. "
+ "We haven't seen a single circuit to report about.");
+ goto done;
}
- for (n = 0; n < current_period->num_set; ++n,++i) {
- if (i >= NUM_TOTALS_HS_USAGE)
- i -= NUM_TOTALS_HS_USAGE;
- tor_assert(i < NUM_TOTALS_HS_USAGE);
- if (n == (current_period->num_set-1))
- tor_snprintf(cp, len-(cp-buf), "%d", data[i]);
- else
- tor_snprintf(cp, len-(cp-buf), "%d,", data[i]);
- cp += strlen(cp);
+ i = 0;
+ SMARTLIST_FOREACH_BEGIN(circuits_for_buffer_stats,
+ circ_buffer_stats_t *, stat)
+ {
+ int share = i++ * SHARES / number_of_circuits;
+ processed_cells[share] += stat->processed_cells;
+ queued_cells[share] += stat->mean_num_cells_in_queue;
+ time_in_queue[share] += stat->mean_time_cells_in_queue;
+ circs_in_share[share]++;
}
- return cp-buf;
-}
-
-/** Writes the complete usage history as hidden service authoritative directory
- * to a string. */
-static char *
-hs_usage_format_statistics(void)
-{
- char *buf, *cp, *s = NULL;
- char t[ISO_TIME_LEN+1];
- int r;
- uint32_t *data = NULL;
- size_t len;
- len = (70+20*NUM_TOTALS_HS_USAGE)*11;
- buf = tor_malloc_zero(len);
- cp = buf;
- for (r = 0; r < 11; ++r) {
- switch (r) {
- case 0:
- s = (char*) "publish-total-history";
- data = publish_total->totals;
- break;
- case 1:
- s = (char*) "publish-novel-history";
- data = publish_novel->totals;
- break;
- case 2:
- s = (char*) "publish-top-5-percent-history";
- data = publish_total->five;
- break;
- case 3:
- s = (char*) "publish-top-10-percent-history";
- data = publish_total->ten;
- break;
- case 4:
- s = (char*) "publish-top-20-percent-history";
- data = publish_total->twenty;
- break;
- case 5:
- s = (char*) "fetch-total-history";
- data = fetch_total->totals;
- break;
- case 6:
- s = (char*) "fetch-successful-history";
- data = fetch_successful->totals;
- break;
- case 7:
- s = (char*) "fetch-top-5-percent-history";
- data = fetch_total->five;
- break;
- case 8:
- s = (char*) "fetch-top-10-percent-history";
- data = fetch_total->ten;
- break;
- case 9:
- s = (char*) "fetch-top-20-percent-history";
- data = fetch_total->twenty;
- break;
- case 10:
- s = (char*) "desc-total-history";
- data = descs->totals;
- break;
- }
- format_iso_time(t, current_period->start_of_current_period);
- tor_snprintf(cp, len-(cp-buf), "%s %s (%d s) ", s, t,
- NUM_SECS_HS_USAGE_SUM_INTERVAL);
- cp += strlen(cp);
- cp += hs_usage_format_history(cp, len-(cp-buf), data);
- strlcat(cp, "\n", len-(cp-buf));
- ++cp;
+ SMARTLIST_FOREACH_END(stat);
+ /* clear buffer stats history */
+ SMARTLIST_FOREACH(circuits_for_buffer_stats, circ_buffer_stats_t *,
+ stat, tor_free(stat));
+ smartlist_clear(circuits_for_buffer_stats);
+ /* write to file */
+ statsdir = get_datadir_fname("stats");
+ if (check_private_dir(statsdir, CPD_CREATE) < 0)
+ goto done;
+ filename = get_datadir_fname2("stats", "buffer-stats");
+ out = start_writing_to_stdio_file(filename, OPEN_FLAGS_APPEND,
+ 0600, &open_file);
+ if (!out)
+ goto done;
+ format_iso_time(written, now);
+ if (fprintf(out, "cell-stats-end %s (%d s)\n", written,
+ (unsigned) (now - start_of_buffer_stats_interval)) < 0)
+ goto done;
+ for (i = 0; i < SHARES; i++) {
+ tor_asprintf(&buf,"%d", !circs_in_share[i] ? 0 :
+ processed_cells[i] / circs_in_share[i]);
+ smartlist_add(str_build, buf);
}
- return buf;
+ str = smartlist_join_strings(str_build, ",", 0, NULL);
+ if (fprintf(out, "cell-processed-cells %s\n", str) < 0)
+ goto done;
+ tor_free(str);
+ SMARTLIST_FOREACH(str_build, char *, c, tor_free(c));
+ smartlist_clear(str_build);
+ for (i = 0; i < SHARES; i++) {
+ tor_asprintf(&buf, "%.2f", circs_in_share[i] == 0 ? 0.0 :
+ queued_cells[i] / (double) circs_in_share[i]);
+ smartlist_add(str_build, buf);
+ }
+ str = smartlist_join_strings(str_build, ",", 0, NULL);
+ if (fprintf(out, "cell-queued-cells %s\n", str) < 0)
+ goto done;
+ tor_free(str);
+ SMARTLIST_FOREACH(str_build, char *, c, tor_free(c));
+ smartlist_clear(str_build);
+ for (i = 0; i < SHARES; i++) {
+ tor_asprintf(&buf, "%.0f", circs_in_share[i] == 0 ? 0.0 :
+ time_in_queue[i] / (double) circs_in_share[i]);
+ smartlist_add(str_build, buf);
+ }
+ str = smartlist_join_strings(str_build, ",", 0, NULL);
+ if (fprintf(out, "cell-time-in-queue %s\n", str) < 0)
+ goto done;
+ tor_free(str);
+ SMARTLIST_FOREACH(str_build, char *, c, tor_free(c));
+ smartlist_free(str_build);
+ str_build = NULL;
+ if (fprintf(out, "cell-circuits-per-decile %d\n",
+ (number_of_circuits + SHARES - 1) / SHARES) < 0)
+ goto done;
+ finish_writing_to_file(open_file);
+ open_file = NULL;
+ start_of_buffer_stats_interval = now;
+ done:
+ if (open_file)
+ abort_writing_to_file(open_file);
+ tor_free(filename);
+ tor_free(statsdir);
+ if (str_build) {
+ SMARTLIST_FOREACH(str_build, char *, c, tor_free(c));
+ smartlist_free(str_build);
+ }
+ tor_free(str);
+#undef SHARES
+ return start_of_buffer_stats_interval + WRITE_STATS_INTERVAL;
}
-/** Write current statistics about hidden service usage to file. */
+/** Free all storage held by the OR/link history caches, by the
+ * bandwidth history arrays, by the port history, or by statistics . */
void
-hs_usage_write_statistics_to_file(time_t now)
+rep_hist_free_all(void)
{
- char *buf;
- size_t len;
- char *fname;
- or_options_t *options = get_options();
- /* check if we are up-to-date */
- hs_usage_check_if_current_period_is_up_to_date(now);
- buf = hs_usage_format_statistics();
- len = strlen(options->DataDirectory) + 16;
- fname = tor_malloc(len);
- tor_snprintf(fname, len, "%s"PATH_SEPARATOR"hsusage",
- options->DataDirectory);
- write_str_to_file(fname,buf,0);
- tor_free(buf);
- tor_free(fname);
+ digestmap_free(history_map, free_or_history);
+ tor_free(read_array);
+ tor_free(write_array);
+ tor_free(last_stability_doc);
+ tor_free(exit_bytes_read);
+ tor_free(exit_bytes_written);
+ tor_free(exit_streams);
+ built_last_stability_doc_at = 0;
+ predicted_ports_free();
}
diff --git a/src/or/rephist.h b/src/or/rephist.h
new file mode 100644
index 0000000000..8f5a34dacf
--- /dev/null
+++ b/src/or/rephist.h
@@ -0,0 +1,80 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file rephist.h
+ * \brief Header file for rephist.c.
+ **/
+
+#ifndef _TOR_REPHIST_H
+#define _TOR_REPHIST_H
+
+void rep_hist_init(void);
+void rep_hist_note_connect_failed(const char* nickname, time_t when);
+void rep_hist_note_connect_succeeded(const char* nickname, time_t when);
+void rep_hist_note_disconnect(const char* nickname, time_t when);
+void rep_hist_note_connection_died(const char* nickname, time_t when);
+void rep_hist_note_extend_succeeded(const char *from_name,
+ const char *to_name);
+void rep_hist_note_extend_failed(const char *from_name, const char *to_name);
+void rep_hist_dump_stats(time_t now, int severity);
+void rep_hist_note_bytes_read(size_t num_bytes, time_t when);
+void rep_hist_note_bytes_written(size_t num_bytes, time_t when);
+
+void rep_hist_note_dir_bytes_read(size_t num_bytes, time_t when);
+void rep_hist_note_dir_bytes_written(size_t num_bytes, time_t when);
+
+int rep_hist_bandwidth_assess(void);
+char *rep_hist_get_bandwidth_lines(void);
+void rep_hist_update_state(or_state_t *state);
+int rep_hist_load_state(or_state_t *state, char **err);
+void rep_history_clean(time_t before);
+
+void rep_hist_note_router_reachable(const char *id, time_t when);
+void rep_hist_note_router_unreachable(const char *id, time_t when);
+int rep_hist_record_mtbf_data(time_t now, int missing_means_down);
+int rep_hist_load_mtbf_data(time_t now);
+
+time_t rep_hist_downrate_old_runs(time_t now);
+double rep_hist_get_stability(const char *id, time_t when);
+double rep_hist_get_weighted_fractional_uptime(const char *id, time_t when);
+long rep_hist_get_weighted_time_known(const char *id, time_t when);
+int rep_hist_have_measured_enough_stability(void);
+const char *rep_hist_get_router_stability_doc(time_t now);
+
+void rep_hist_note_used_port(time_t now, uint16_t port);
+smartlist_t *rep_hist_get_predicted_ports(time_t now);
+void rep_hist_note_used_resolve(time_t now);
+void rep_hist_note_used_internal(time_t now, int need_uptime,
+ int need_capacity);
+int rep_hist_get_predicted_internal(time_t now, int *need_uptime,
+ int *need_capacity);
+
+int any_predicted_circuits(time_t now);
+int rep_hist_circbuilding_dormant(time_t now);
+
+void note_crypto_pk_op(pk_op_t operation);
+void dump_pk_ops(int severity);
+
+void rep_hist_free_all(void);
+
+void rep_hist_exit_stats_init(time_t now);
+void rep_hist_reset_exit_stats(time_t now);
+void rep_hist_exit_stats_term(void);
+char *rep_hist_format_exit_stats(time_t now);
+time_t rep_hist_exit_stats_write(time_t now);
+void rep_hist_note_exit_bytes(uint16_t port, size_t num_written,
+ size_t num_read);
+void rep_hist_note_exit_stream_opened(uint16_t port);
+
+void rep_hist_buffer_stats_init(time_t now);
+void rep_hist_buffer_stats_add_circ(circuit_t *circ,
+ time_t end_of_interval);
+time_t rep_hist_buffer_stats_write(time_t now);
+void rep_hist_buffer_stats_term(void);
+
+#endif
+
diff --git a/src/or/router.c b/src/or/router.c
index 8661e7a224..66ef8ec52e 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -7,6 +7,24 @@
#define ROUTER_PRIVATE
#include "or.h"
+#include "circuitlist.h"
+#include "circuituse.h"
+#include "config.h"
+#include "connection.h"
+#include "control.h"
+#include "directory.h"
+#include "dirserv.h"
+#include "dns.h"
+#include "geoip.h"
+#include "hibernate.h"
+#include "main.h"
+#include "networkstatus.h"
+#include "policies.h"
+#include "relay.h"
+#include "rephist.h"
+#include "router.h"
+#include "routerlist.h"
+#include "routerparse.h"
/**
* \file router.c
@@ -31,11 +49,15 @@ static crypto_pk_env_t *onionkey=NULL;
/** Previous private onionskin decryption key: used to decode CREATE cells
* generated by clients that have an older version of our descriptor. */
static crypto_pk_env_t *lastonionkey=NULL;
-/** Private "identity key": used to sign directory info and TLS
+/** Private server "identity key": used to sign directory info and TLS
* certificates. Never changes. */
-static crypto_pk_env_t *identitykey=NULL;
-/** Digest of identitykey. */
-static char identitykey_digest[DIGEST_LEN];
+static crypto_pk_env_t *server_identitykey=NULL;
+/** Digest of server_identitykey. */
+static char server_identitykey_digest[DIGEST_LEN];
+/** Private client "identity key": used to sign bridges' and clients'
+ * outbound TLS certificates. Regenerated on startup and on IP address
+ * change. */
+static crypto_pk_env_t *client_identitykey=NULL;
/** Signing key used for v3 directory material; only set for authorities. */
static crypto_pk_env_t *authority_signing_key = NULL;
/** Key certificate to authenticate v3 directory material; only set for
@@ -61,8 +83,7 @@ static void
set_onion_key(crypto_pk_env_t *k)
{
tor_mutex_acquire(key_lock);
- if (onionkey)
- crypto_free_pk_env(onionkey);
+ crypto_free_pk_env(onionkey);
onionkey = k;
onionkey_set_at = time(NULL);
tor_mutex_release(key_lock);
@@ -106,32 +127,78 @@ get_onion_key_set_at(void)
return onionkey_set_at;
}
-/** Set the current identity key to k.
+/** Set the current server identity key to <b>k</b>.
*/
void
-set_identity_key(crypto_pk_env_t *k)
+set_server_identity_key(crypto_pk_env_t *k)
{
- if (identitykey)
- crypto_free_pk_env(identitykey);
- identitykey = k;
- crypto_pk_get_digest(identitykey, identitykey_digest);
+ crypto_free_pk_env(server_identitykey);
+ server_identitykey = k;
+ crypto_pk_get_digest(server_identitykey, server_identitykey_digest);
}
-/** Returns the current identity key; requires that the identity key has been
- * set.
+/** Make sure that we have set up our identity keys to match or not match as
+ * appropriate, and die with an assertion if we have not. */
+static void
+assert_identity_keys_ok(void)
+{
+ tor_assert(client_identitykey);
+ if (public_server_mode(get_options())) {
+ /* assert that we have set the client and server keys to be equal */
+ tor_assert(server_identitykey);
+ tor_assert(0==crypto_pk_cmp_keys(client_identitykey, server_identitykey));
+ } else {
+ /* assert that we have set the client and server keys to be unequal */
+ if (server_identitykey)
+ tor_assert(0!=crypto_pk_cmp_keys(client_identitykey,
+ server_identitykey));
+ }
+}
+
+/** Returns the current server identity key; requires that the key has
+ * been set, and that we are running as a Tor server.
+ */
+crypto_pk_env_t *
+get_server_identity_key(void)
+{
+ tor_assert(server_identitykey);
+ tor_assert(server_mode(get_options()));
+ assert_identity_keys_ok();
+ return server_identitykey;
+}
+
+/** Return true iff the server identity key has been set. */
+int
+server_identity_key_is_set(void)
+{
+ return server_identitykey != NULL;
+}
+
+/** Set the current client identity key to <b>k</b>.
+ */
+void
+set_client_identity_key(crypto_pk_env_t *k)
+{
+ crypto_free_pk_env(client_identitykey);
+ client_identitykey = k;
+}
+
+/** Returns the current client identity key for use on outgoing TLS
+ * connections; requires that the key has been set.
*/
crypto_pk_env_t *
-get_identity_key(void)
+get_tlsclient_identity_key(void)
{
- tor_assert(identitykey);
- return identitykey;
+ tor_assert(client_identitykey);
+ assert_identity_keys_ok();
+ return client_identitykey;
}
-/** Return true iff the identity key has been set. */
+/** Return true iff the client identity key has been set. */
int
-identity_key_is_set(void)
+client_identity_key_is_set(void)
{
- return identitykey != NULL;
+ return client_identitykey != NULL;
}
/** Return the key certificate for this v3 (voting) authority, or NULL
@@ -201,8 +268,7 @@ rotate_onion_key(void)
}
log_info(LD_GENERAL, "Rotating onion key");
tor_mutex_acquire(key_lock);
- if (lastonionkey)
- crypto_free_pk_env(lastonionkey);
+ crypto_free_pk_env(lastonionkey);
lastonionkey = onionkey;
onionkey = prkey;
now = time(NULL);
@@ -331,10 +397,9 @@ load_authority_keyset(int legacy, crypto_pk_env_t **key_out,
goto done;
}
- if (*key_out)
- crypto_free_pk_env(*key_out);
- if (*cert_out)
- authority_cert_free(*cert_out);
+ crypto_free_pk_env(*key_out);
+ authority_cert_free(*cert_out);
+
*key_out = signing_key;
*cert_out = parsed;
r = 0;
@@ -344,10 +409,8 @@ load_authority_keyset(int legacy, crypto_pk_env_t **key_out,
done:
tor_free(fname);
tor_free(cert);
- if (signing_key)
- crypto_free_pk_env(signing_key);
- if (parsed)
- authority_cert_free(parsed);
+ crypto_free_pk_env(signing_key);
+ authority_cert_free(parsed);
return r;
}
@@ -442,7 +505,9 @@ init_keys(void)
key_lock = tor_mutex_new();
/* There are a couple of paths that put us here before */
- if (crypto_global_init(get_options()->HardwareAccel)) {
+ if (crypto_global_init(get_options()->HardwareAccel,
+ get_options()->AccelName,
+ get_options()->AccelDir)) {
log_err(LD_BUG, "Unable to initialize OpenSSL. Exiting.");
return -1;
}
@@ -456,9 +521,12 @@ init_keys(void)
crypto_free_pk_env(prkey);
return -1;
}
- set_identity_key(prkey);
- /* Create a TLS context; default the client nickname to "client". */
- if (tor_tls_context_new(get_identity_key(), MAX_SSL_KEY_LIFETIME) < 0) {
+ set_client_identity_key(prkey);
+ /* Create a TLS context. */
+ if (tor_tls_context_init(0,
+ get_tlsclient_identity_key(),
+ NULL,
+ MAX_SSL_KEY_LIFETIME) < 0) {
log_err(LD_GENERAL,"Error creating TLS context for Tor client.");
return -1;
}
@@ -493,13 +561,28 @@ init_keys(void)
}
}
- /* 1. Read identity key. Make it if none is found. */
+ /* 1b. Read identity key. Make it if none is found. */
keydir = get_datadir_fname2("keys", "secret_id_key");
log_info(LD_GENERAL,"Reading/making identity key \"%s\"...",keydir);
prkey = init_key_from_file(keydir, 1, LOG_ERR);
tor_free(keydir);
if (!prkey) return -1;
- set_identity_key(prkey);
+ set_server_identity_key(prkey);
+
+ /* 1c. If we are configured as a bridge, generate a client key;
+ * otherwise, set the server identity key as our client identity
+ * key. */
+ if (public_server_mode(options)) {
+ set_client_identity_key(crypto_pk_dup_key(prkey)); /* set above */
+ } else {
+ if (!(prkey = crypto_new_pk_env()))
+ return -1;
+ if (crypto_pk_generate_key(prkey)) {
+ crypto_free_pk_env(prkey);
+ return -1;
+ }
+ set_client_identity_key(prkey);
+ }
/* 2. Read onion key. Make it if none is found. */
keydir = get_datadir_fname2("keys", "secret_onion_key");
@@ -536,7 +619,10 @@ init_keys(void)
tor_free(keydir);
/* 3. Initialize link key and TLS context. */
- if (tor_tls_context_new(get_identity_key(), MAX_SSL_KEY_LIFETIME) < 0) {
+ if (tor_tls_context_init(public_server_mode(options),
+ get_tlsclient_identity_key(),
+ get_server_identity_key(),
+ MAX_SSL_KEY_LIFETIME) < 0) {
log_err(LD_GENERAL,"Error initializing TLS context");
return -1;
}
@@ -547,7 +633,8 @@ init_keys(void)
const char *m = NULL;
routerinfo_t *ri;
/* We need to add our own fingerprint so it gets recognized. */
- if (dirserv_add_own_fingerprint(options->Nickname, get_identity_key())) {
+ if (dirserv_add_own_fingerprint(options->Nickname,
+ get_server_identity_key())) {
log_err(LD_GENERAL,"Error adding own fingerprint to approved set");
return -1;
}
@@ -568,7 +655,8 @@ init_keys(void)
/* 5. Dump fingerprint to 'fingerprint' */
keydir = get_datadir_fname("fingerprint");
log_info(LD_GENERAL,"Dumping fingerprint to \"%s\"...",keydir);
- if (crypto_pk_get_fingerprint(get_identity_key(), fingerprint, 0)<0) {
+ if (crypto_pk_get_fingerprint(get_server_identity_key(),
+ fingerprint, 0) < 0) {
log_err(LD_GENERAL,"Error computing fingerprint");
tor_free(keydir);
return -1;
@@ -606,7 +694,7 @@ init_keys(void)
return -1;
}
/* 6b. [authdirserver only] add own key to approved directories. */
- crypto_pk_get_digest(get_identity_key(), digest);
+ crypto_pk_get_digest(get_server_identity_key(), digest);
type = ((options->V1AuthoritativeDir ? V1_AUTHORITY : NO_AUTHORITY) |
(options->V2AuthoritativeDir ? V2_AUTHORITY : NO_AUTHORITY) |
(options->V3AuthoritativeDir ? V3_AUTHORITY : NO_AUTHORITY) |
@@ -962,6 +1050,28 @@ server_mode(or_options_t *options)
return (options->ORPort != 0 || options->ORListenAddress);
}
+/** Return true iff we are trying to be a non-bridge server.
+ */
+int
+public_server_mode(or_options_t *options)
+{
+ if (!server_mode(options)) return 0;
+ return (!options->BridgeRelay);
+}
+
+/** Return true iff the combination of options in <b>options</b> and parameters
+ * in the consensus mean that we don't want to allow exits from circuits
+ * we got from addresses not known to be servers. */
+int
+should_refuse_unknown_exits(or_options_t *options)
+{
+ if (options->RefuseUnknownExits_ != -1) {
+ return options->RefuseUnknownExits_;
+ } else {
+ return networkstatus_get_param(NULL, "refuseunknownexits", 1);
+ }
+}
+
/** Remember if we've advertised ourselves to the dirservers. */
static int server_is_advertised=0;
@@ -989,7 +1099,7 @@ proxy_mode(or_options_t *options)
{
return (options->SocksPort != 0 || options->SocksListenAddress ||
options->TransPort != 0 || options->TransListenAddress ||
- options->NatdPort != 0 || options->NatdListenAddress ||
+ options->NATDPort != 0 || options->NATDListenAddress ||
options->DNSPort != 0 || options->DNSListenAddress);
}
@@ -1124,12 +1234,24 @@ router_compare_to_my_exit_policy(edge_connection_t *conn)
desc_routerinfo->exit_policy) != ADDR_POLICY_ACCEPTED;
}
+/** Return true iff my exit policy is reject *:*. Return -1 if we don't
+ * have a descriptor */
+int
+router_my_exit_policy_is_reject_star(void)
+{
+ if (!router_get_my_routerinfo()) /* make sure desc_routerinfo exists */
+ return -1;
+
+ return desc_routerinfo->policy_is_reject_star;
+}
+
/** Return true iff I'm a server and <b>digest</b> is equal to
- * my identity digest. */
+ * my server identity key digest. */
int
router_digest_is_me(const char *digest)
{
- return identitykey && !memcmp(identitykey_digest, digest, DIGEST_LEN);
+ return (server_identitykey &&
+ !memcmp(server_identitykey_digest, digest, DIGEST_LEN));
}
/** Return true iff I'm a server and <b>digest</b> is equal to
@@ -1219,6 +1341,8 @@ static int router_guess_address_from_dir_headers(uint32_t *guess);
int
router_pick_published_address(or_options_t *options, uint32_t *addr)
{
+ char buf[INET_NTOA_BUF_LEN];
+ struct in_addr a;
if (resolve_my_address(LOG_INFO, options, addr, NULL) < 0) {
log_info(LD_CONFIG, "Could not determine our address locally. "
"Checking if directory headers provide any hints.");
@@ -1228,6 +1352,9 @@ router_pick_published_address(or_options_t *options, uint32_t *addr)
return -1;
}
}
+ a.s_addr = htonl(*addr);
+ tor_inet_ntoa(&a, buf, sizeof(buf));
+ log_info(LD_CONFIG,"Success: chose address '%s'.", buf);
return 0;
}
@@ -1250,7 +1377,7 @@ router_rebuild_descriptor(int force)
if (router_pick_published_address(options, &addr) < 0) {
/* Stop trying to rebuild our descriptor every second. We'll
- * learn that it's time to try again when server_has_changed_ip()
+ * learn that it's time to try again when ip_address_changed()
* marks it dirty. */
desc_clean_since = time(NULL);
return -1;
@@ -1266,7 +1393,7 @@ router_rebuild_descriptor(int force)
ri->cache_info.published_on = time(NULL);
ri->onion_pkey = crypto_pk_dup_key(get_onion_key()); /* must invoke from
* main thread */
- ri->identity_pkey = crypto_pk_dup_key(get_identity_key());
+ ri->identity_pkey = crypto_pk_dup_key(get_server_identity_key());
if (crypto_pk_get_digest(ri->identity_pkey,
ri->cache_info.identity_digest)<0) {
routerinfo_free(ri);
@@ -1285,7 +1412,9 @@ router_rebuild_descriptor(int force)
policies_parse_exit_policy(options->ExitPolicy, &ri->exit_policy,
options->ExitPolicyRejectPrivate,
- ri->address);
+ ri->address, !options->BridgeRelay);
+ ri->policy_is_reject_star =
+ policy_is_reject_star(ri->exit_policy);
if (desc_routerinfo) { /* inherit values */
ri->is_valid = desc_routerinfo->is_valid;
@@ -1356,26 +1485,30 @@ router_rebuild_descriptor(int force)
ei->cache_info.published_on = ri->cache_info.published_on;
memcpy(ei->cache_info.identity_digest, ri->cache_info.identity_digest,
DIGEST_LEN);
- ei->cache_info.signed_descriptor_body = tor_malloc(8192);
- if (extrainfo_dump_to_string(ei->cache_info.signed_descriptor_body, 8192,
- ei, get_identity_key()) < 0) {
+ if (extrainfo_dump_to_string(&ei->cache_info.signed_descriptor_body,
+ ei, get_server_identity_key()) < 0) {
log_warn(LD_BUG, "Couldn't generate extra-info descriptor.");
- routerinfo_free(ri);
extrainfo_free(ei);
- return -1;
+ ei = NULL;
+ } else {
+ ei->cache_info.signed_descriptor_len =
+ strlen(ei->cache_info.signed_descriptor_body);
+ router_get_extrainfo_hash(ei->cache_info.signed_descriptor_body,
+ ei->cache_info.signed_descriptor_digest);
}
- ei->cache_info.signed_descriptor_len =
- strlen(ei->cache_info.signed_descriptor_body);
- router_get_extrainfo_hash(ei->cache_info.signed_descriptor_body,
- ei->cache_info.signed_descriptor_digest);
/* Now finish the router descriptor. */
- memcpy(ri->cache_info.extra_info_digest,
- ei->cache_info.signed_descriptor_digest,
- DIGEST_LEN);
+ if (ei) {
+ memcpy(ri->cache_info.extra_info_digest,
+ ei->cache_info.signed_descriptor_digest,
+ DIGEST_LEN);
+ } else {
+ /* ri was allocated with tor_malloc_zero, so there is no need to
+ * zero ri->cache_info.extra_info_digest here. */
+ }
ri->cache_info.signed_descriptor_body = tor_malloc(8192);
if (router_dump_router_to_string(ri->cache_info.signed_descriptor_body, 8192,
- ri, get_identity_key())<0) {
+ ri, get_server_identity_key()) < 0) {
log_warn(LD_BUG, "Couldn't generate router descriptor.");
routerinfo_free(ri);
extrainfo_free(ei);
@@ -1390,7 +1523,7 @@ router_rebuild_descriptor(int force)
/* Let bridges serve their own descriptors unencrypted, so they can
* pass reachability testing. (If they want to be harder to notice,
* they can always leave the DirPort off). */
- if (!options->BridgeRelay)
+ if (ei && !options->BridgeRelay)
ei->cache_info.send_unencrypted = 1;
router_get_router_hash(ri->cache_info.signed_descriptor_body,
@@ -1399,13 +1532,13 @@ router_rebuild_descriptor(int force)
routerinfo_set_country(ri);
- tor_assert(! routerinfo_incompatible_with_extrainfo(ri, ei, NULL, NULL));
+ if (ei) {
+ tor_assert(! routerinfo_incompatible_with_extrainfo(ri, ei, NULL, NULL));
+ }
- if (desc_routerinfo)
- routerinfo_free(desc_routerinfo);
+ routerinfo_free(desc_routerinfo);
desc_routerinfo = ri;
- if (desc_extrainfo)
- extrainfo_free(desc_extrainfo);
+ extrainfo_free(desc_extrainfo);
desc_extrainfo = ei;
desc_clean_since = time(NULL);
@@ -1586,8 +1719,6 @@ router_guess_address_from_dir_headers(uint32_t *guess)
return -1;
}
-extern const char tor_svn_revision[]; /* from tor_main.c */
-
/** Set <b>platform</b> (max length <b>len</b>) to a NUL-terminated short
* string describing the version of Tor and the operating system we're
* currently running on.
@@ -1618,6 +1749,7 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
char digest[DIGEST_LEN];
char published[ISO_TIME_LEN+1];
char fingerprint[FINGERPRINT_LEN+1];
+ int has_extra_info_digest;
char extra_info_digest[HEX_DIGEST_LEN+1];
size_t onion_pkeylen, identity_pkeylen;
size_t written;
@@ -1646,7 +1778,7 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
return -1;
}
- /* PEM-encode the identity key key */
+ /* PEM-encode the identity key */
if (crypto_pk_write_public_key_to_string(router->identity_pkey,
&identity_pkey,&identity_pkeylen)<0) {
log_warn(LD_BUG,"write identity_pkey to string failed!");
@@ -1668,8 +1800,13 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
family_line = tor_strdup("");
}
- base16_encode(extra_info_digest, sizeof(extra_info_digest),
- router->cache_info.extra_info_digest, DIGEST_LEN);
+ has_extra_info_digest =
+ ! tor_digest_is_zero(router->cache_info.extra_info_digest);
+
+ if (has_extra_info_digest) {
+ base16_encode(extra_info_digest, sizeof(extra_info_digest),
+ router->cache_info.extra_info_digest, DIGEST_LEN);
+ }
/* Generate the easy portion of the router descriptor. */
result = tor_snprintf(s, maxlen,
@@ -1680,7 +1817,7 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
"opt fingerprint %s\n"
"uptime %ld\n"
"bandwidth %d %d %d\n"
- "opt extra-info-digest %s\n%s"
+ "%s%s%s%s"
"onion-key\n%s"
"signing-key\n%s"
"%s%s%s%s",
@@ -1695,7 +1832,9 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
(int) router->bandwidthrate,
(int) router->bandwidthburst,
(int) router->bandwidthcapacity,
- extra_info_digest,
+ has_extra_info_digest ? "opt extra-info-digest " : "",
+ has_extra_info_digest ? extra_info_digest : "",
+ has_extra_info_digest ? "\n" : "",
options->DownloadExtraInfo ? "opt caches-extra-info\n" : "",
onion_pkey, identity_pkey,
family_line,
@@ -1752,7 +1891,8 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
}
}
- if (written+256 > maxlen) { /* Not enough room for signature. */
+ if (written + DIROBJ_MAX_SIG_LEN > maxlen) {
+ /* Not enough room for signature. */
log_warn(LD_BUG,"not enough room left in descriptor for signature!");
return -1;
}
@@ -1767,7 +1907,7 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
note_crypto_pk_op(SIGN_RTR);
if (router_append_dirobj_signature(s+written,maxlen-written,
- digest,ident_key)<0) {
+ digest,DIGEST_LEN,ident_key)<0) {
log_warn(LD_BUG, "Couldn't sign router descriptor");
return -1;
}
@@ -1802,11 +1942,62 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
return (int)written+1;
}
-/** Write the contents of <b>extrainfo</b> to the <b>maxlen</b>-byte string
- * <b>s</b>, signing them with <b>ident_key</b>. Return 0 on success,
- * negative on failure. */
+/** Load the contents of <b>filename</b>, find the last line starting with
+ * <b>end_line</b>, ensure that its timestamp is not more than 25 hours in
+ * the past or more than 1 hour in the future with respect to <b>now</b>,
+ * and write the file contents starting with that line to *<b>out</b>.
+ * Return 1 for success, 0 if the file does not exist, or -1 if the file
+ * does not contain a line matching these criteria or other failure. */
+static int
+load_stats_file(const char *filename, const char *end_line, time_t now,
+ char **out)
+{
+ int r = -1;
+ char *fname = get_datadir_fname(filename);
+ char *contents, *start = NULL, *tmp, timestr[ISO_TIME_LEN+1];
+ time_t written;
+ switch (file_status(fname)) {
+ case FN_FILE:
+ /* X022 Find an alternative to reading the whole file to memory. */
+ if ((contents = read_file_to_str(fname, 0, NULL))) {
+ tmp = strstr(contents, end_line);
+ /* Find last block starting with end_line */
+ while (tmp) {
+ start = tmp;
+ tmp = strstr(tmp + 1, end_line);
+ }
+ if (!start)
+ goto notfound;
+ if (strlen(start) < strlen(end_line) + 1 + sizeof(timestr))
+ goto notfound;
+ strlcpy(timestr, start + 1 + strlen(end_line), sizeof(timestr));
+ if (parse_iso_time(timestr, &written) < 0)
+ goto notfound;
+ if (written < now - (25*60*60) || written > now + (1*60*60))
+ goto notfound;
+ *out = tor_strdup(start);
+ r = 1;
+ }
+ notfound:
+ tor_free(contents);
+ break;
+ case FN_NOENT:
+ r = 0;
+ break;
+ case FN_ERROR:
+ case FN_DIR:
+ default:
+ break;
+ }
+ tor_free(fname);
+ return r;
+}
+
+/** Write the contents of <b>extrainfo</b> and aggregated statistics to
+ * *<b>s_out</b>, signing them with <b>ident_key</b>. Return 0 on
+ * success, negative on failure. */
int
-extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo,
+extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo,
crypto_pk_env_t *ident_key)
{
or_options_t *options = get_options();
@@ -1815,87 +2006,128 @@ extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo,
char digest[DIGEST_LEN];
char *bandwidth_usage;
int result;
- size_t len;
+ static int write_stats_to_extrainfo = 1;
+ char sig[DIROBJ_MAX_SIG_LEN+1];
+ char *s, *pre, *contents, *cp, *s_dup = NULL;
+ time_t now = time(NULL);
+ smartlist_t *chunks = smartlist_create();
+ extrainfo_t *ei_tmp = NULL;
base16_encode(identity, sizeof(identity),
extrainfo->cache_info.identity_digest, DIGEST_LEN);
format_iso_time(published, extrainfo->cache_info.published_on);
- bandwidth_usage = rep_hist_get_bandwidth_lines(1);
+ bandwidth_usage = rep_hist_get_bandwidth_lines();
- result = tor_snprintf(s, maxlen,
- "extra-info %s %s\n"
- "published %s\n%s",
- extrainfo->nickname, identity,
- published, bandwidth_usage);
+ tor_asprintf(&pre, "extra-info %s %s\npublished %s\n%s",
+ extrainfo->nickname, identity,
+ published, bandwidth_usage);
tor_free(bandwidth_usage);
- if (result<0)
- return -1;
+ smartlist_add(chunks, pre);
+
+ if (options->ExtraInfoStatistics && write_stats_to_extrainfo) {
+ log_info(LD_GENERAL, "Adding stats to extra-info descriptor.");
+ if (options->DirReqStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"dirreq-stats",
+ "dirreq-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) {
+ smartlist_add(chunks, contents);
+ }
+ if (options->CellStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"buffer-stats",
+ "cell-stats-end", now, &contents) > 0) {
+ smartlist_add(chunks, contents);
+ }
+ if (options->ExitPortStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"exit-stats",
+ "exit-stats-end", now, &contents) > 0) {
+ smartlist_add(chunks, contents);
+ }
+ }
- if (should_record_bridge_info(options)) {
- char *geoip_summary = extrainfo_get_client_geoip_summary(time(NULL));
- if (geoip_summary) {
- char geoip_start[ISO_TIME_LEN+1];
- format_iso_time(geoip_start, geoip_get_history_start());
- result = tor_snprintf(s+strlen(s), maxlen-strlen(s),
- "geoip-start-time %s\n"
- "geoip-client-origins %s\n",
- geoip_start, geoip_summary);
- control_event_clients_seen(geoip_start, geoip_summary);
- tor_free(geoip_summary);
- if (result<0)
- return -1;
+ if (should_record_bridge_info(options) && write_stats_to_extrainfo) {
+ const char *bridge_stats = geoip_get_bridge_stats_extrainfo(now);
+ if (bridge_stats) {
+ smartlist_add(chunks, tor_strdup(bridge_stats));
}
}
- len = strlen(s);
- strlcat(s+len, "router-signature\n", maxlen-len);
- len += strlen(s+len);
- if (router_get_extrainfo_hash(s, digest)<0)
- return -1;
- if (router_append_dirobj_signature(s+len, maxlen-len, digest, ident_key)<0)
- return -1;
+ smartlist_add(chunks, tor_strdup("router-signature\n"));
+ s = smartlist_join_strings(chunks, "", 0, NULL);
+
+ while (strlen(s) > MAX_EXTRAINFO_UPLOAD_SIZE - DIROBJ_MAX_SIG_LEN) {
+ /* So long as there are at least two chunks (one for the initial
+ * extra-info line and one for the router-signature), we can keep removing
+ * things. */
+ if (smartlist_len(chunks) > 2) {
+ /* We remove the next-to-last element (remember, len-1 is the last
+ element), since we need to keep the router-signature element. */
+ int idx = smartlist_len(chunks) - 2;
+ char *e = smartlist_get(chunks, idx);
+ smartlist_del_keeporder(chunks, idx);
+ log_warn(LD_GENERAL, "We just generated an extra-info descriptor "
+ "with statistics that exceeds the 50 KB "
+ "upload limit. Removing last added "
+ "statistics.");
+ tor_free(e);
+ tor_free(s);
+ s = smartlist_join_strings(chunks, "", 0, NULL);
+ } else {
+ log_warn(LD_BUG, "We just generated an extra-info descriptors that "
+ "exceeds the 50 KB upload limit.");
+ goto err;
+ }
+ }
-#ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
- {
- char *cp, *s_dup;
- extrainfo_t *ei_tmp;
- cp = s_dup = tor_strdup(s);
- ei_tmp = extrainfo_parse_entry_from_string(cp, NULL, 1, NULL);
- if (!ei_tmp) {
- log_err(LD_BUG,
- "We just generated an extrainfo descriptor we can't parse.");
- log_err(LD_BUG, "Descriptor was: <<%s>>", s);
- tor_free(s_dup);
- return -1;
+ memset(sig, 0, sizeof(sig));
+ if (router_get_extrainfo_hash(s, digest) < 0 ||
+ router_append_dirobj_signature(sig, sizeof(sig), digest, DIGEST_LEN,
+ ident_key) < 0) {
+ log_warn(LD_BUG, "Could not append signature to extra-info "
+ "descriptor.");
+ goto err;
+ }
+ smartlist_add(chunks, tor_strdup(sig));
+ tor_free(s);
+ s = smartlist_join_strings(chunks, "", 0, NULL);
+
+ cp = s_dup = tor_strdup(s);
+ ei_tmp = extrainfo_parse_entry_from_string(cp, NULL, 1, NULL);
+ if (!ei_tmp) {
+ if (write_stats_to_extrainfo) {
+ log_warn(LD_GENERAL, "We just generated an extra-info descriptor "
+ "with statistics that we can't parse. Not "
+ "adding statistics to this or any future "
+ "extra-info descriptors.");
+ write_stats_to_extrainfo = 0;
+ result = extrainfo_dump_to_string(s_out, extrainfo, ident_key);
+ goto done;
+ } else {
+ log_warn(LD_BUG, "We just generated an extrainfo descriptor we "
+ "can't parse.");
+ goto err;
}
- tor_free(s_dup);
- extrainfo_free(ei_tmp);
}
-#endif
- return (int)strlen(s)+1;
-}
+ *s_out = s;
+ s = NULL; /* prevent free */
+ result = 0;
+ goto done;
-/** Wrapper function for geoip_get_client_history(). It first discards
- * any items in the client history that are too old -- it dumps anything
- * more than 48 hours old, but it only considers whether to dump at most
- * once per 48 hours, so we aren't too precise to an observer (see also
- * r14780).
- */
-char *
-extrainfo_get_client_geoip_summary(time_t now)
-{
- static time_t last_purged_at = 0;
- int geoip_purge_interval = 48*60*60;
-#ifdef ENABLE_GEOIP_STATS
- if (get_options()->DirRecordUsageByCountry)
- geoip_purge_interval = get_options()->DirRecordUsageRetainIPs;
-#endif
- if (now > last_purged_at+geoip_purge_interval) {
- geoip_remove_old_clients(now-geoip_purge_interval);
- last_purged_at = now;
- }
- return geoip_get_client_history(now, GEOIP_CLIENT_CONNECT);
+ err:
+ result = -1;
+
+ done:
+ tor_free(s);
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_free(chunks);
+ tor_free(s_dup);
+ extrainfo_free(ei_tmp);
+
+ return result;
}
/** Return true iff <b>s</b> is a legally valid server nickname. */
@@ -2022,26 +2254,17 @@ router_purpose_from_string(const char *s)
void
router_free_all(void)
{
- if (onionkey)
- crypto_free_pk_env(onionkey);
- if (lastonionkey)
- crypto_free_pk_env(lastonionkey);
- if (identitykey)
- crypto_free_pk_env(identitykey);
- if (key_lock)
- tor_mutex_free(key_lock);
- if (desc_routerinfo)
- routerinfo_free(desc_routerinfo);
- if (desc_extrainfo)
- extrainfo_free(desc_extrainfo);
- if (authority_signing_key)
- crypto_free_pk_env(authority_signing_key);
- if (authority_key_certificate)
- authority_cert_free(authority_key_certificate);
- if (legacy_signing_key)
- crypto_free_pk_env(legacy_signing_key);
- if (legacy_key_certificate)
- authority_cert_free(legacy_key_certificate);
+ crypto_free_pk_env(onionkey);
+ crypto_free_pk_env(lastonionkey);
+ crypto_free_pk_env(server_identitykey);
+ crypto_free_pk_env(client_identitykey);
+ tor_mutex_free(key_lock);
+ routerinfo_free(desc_routerinfo);
+ extrainfo_free(desc_extrainfo);
+ crypto_free_pk_env(authority_signing_key);
+ authority_cert_free(authority_key_certificate);
+ crypto_free_pk_env(legacy_signing_key);
+ authority_cert_free(legacy_key_certificate);
if (warned_nonexistent_family) {
SMARTLIST_FOREACH(warned_nonexistent_family, char *, cp, tor_free(cp));
diff --git a/src/or/router.h b/src/or/router.h
new file mode 100644
index 0000000000..0bfa2d5545
--- /dev/null
+++ b/src/or/router.h
@@ -0,0 +1,101 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file router.h
+ * \brief Header file for router.c.
+ **/
+
+#ifndef _TOR_ROUTER_H
+#define _TOR_ROUTER_H
+
+crypto_pk_env_t *get_onion_key(void);
+time_t get_onion_key_set_at(void);
+void set_server_identity_key(crypto_pk_env_t *k);
+crypto_pk_env_t *get_server_identity_key(void);
+int server_identity_key_is_set(void);
+void set_client_identity_key(crypto_pk_env_t *k);
+crypto_pk_env_t *get_tlsclient_identity_key(void);
+int client_identity_key_is_set(void);
+authority_cert_t *get_my_v3_authority_cert(void);
+crypto_pk_env_t *get_my_v3_authority_signing_key(void);
+authority_cert_t *get_my_v3_legacy_cert(void);
+crypto_pk_env_t *get_my_v3_legacy_signing_key(void);
+void dup_onion_keys(crypto_pk_env_t **key, crypto_pk_env_t **last);
+void rotate_onion_key(void);
+crypto_pk_env_t *init_key_from_file(const char *fname, int generate,
+ int severity);
+void v3_authority_check_key_expiry(void);
+
+int init_keys(void);
+
+int check_whether_orport_reachable(void);
+int check_whether_dirport_reachable(void);
+void consider_testing_reachability(int test_or, int test_dir);
+void router_orport_found_reachable(void);
+void router_dirport_found_reachable(void);
+void router_perform_bandwidth_test(int num_circs, time_t now);
+
+int authdir_mode(or_options_t *options);
+int authdir_mode_v1(or_options_t *options);
+int authdir_mode_v2(or_options_t *options);
+int authdir_mode_v3(or_options_t *options);
+int authdir_mode_any_main(or_options_t *options);
+int authdir_mode_any_nonhidserv(or_options_t *options);
+int authdir_mode_handles_descs(or_options_t *options, int purpose);
+int authdir_mode_publishes_statuses(or_options_t *options);
+int authdir_mode_tests_reachability(or_options_t *options);
+int authdir_mode_bridge(or_options_t *options);
+
+int server_mode(or_options_t *options);
+int public_server_mode(or_options_t *options);
+int advertised_server_mode(void);
+int proxy_mode(or_options_t *options);
+void consider_publishable_server(int force);
+int should_refuse_unknown_exits(or_options_t *options);
+
+void router_upload_dir_desc_to_dirservers(int force);
+void mark_my_descriptor_dirty_if_older_than(time_t when);
+void mark_my_descriptor_dirty(void);
+void check_descriptor_bandwidth_changed(time_t now);
+void check_descriptor_ipaddress_changed(time_t now);
+void router_new_address_suggestion(const char *suggestion,
+ const dir_connection_t *d_conn);
+int router_compare_to_my_exit_policy(edge_connection_t *conn);
+int router_my_exit_policy_is_reject_star(void);
+routerinfo_t *router_get_my_routerinfo(void);
+extrainfo_t *router_get_my_extrainfo(void);
+const char *router_get_my_descriptor(void);
+int router_digest_is_me(const char *digest);
+int router_extrainfo_digest_is_me(const char *digest);
+int router_is_me(routerinfo_t *router);
+int router_fingerprint_is_me(const char *fp);
+int router_pick_published_address(or_options_t *options, uint32_t *addr);
+int router_rebuild_descriptor(int force);
+int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
+ crypto_pk_env_t *ident_key);
+int extrainfo_dump_to_string(char **s, extrainfo_t *extrainfo,
+ crypto_pk_env_t *ident_key);
+int is_legal_nickname(const char *s);
+int is_legal_nickname_or_hexdigest(const char *s);
+int is_legal_hexdigest(const char *s);
+void router_get_verbose_nickname(char *buf, const routerinfo_t *router);
+void routerstatus_get_verbose_nickname(char *buf,
+ const routerstatus_t *router);
+void router_reset_warnings(void);
+void router_reset_reachability(void);
+void router_free_all(void);
+
+const char *router_purpose_to_string(uint8_t p);
+uint8_t router_purpose_from_string(const char *s);
+
+#ifdef ROUTER_PRIVATE
+/* Used only by router.c and test.c */
+void get_platform_str(char *platform, size_t len);
+#endif
+
+#endif
+
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 2fc80738f8..670574a9d3 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -12,6 +12,25 @@
**/
#include "or.h"
+#include "circuitbuild.h"
+#include "config.h"
+#include "connection.h"
+#include "control.h"
+#include "directory.h"
+#include "dirserv.h"
+#include "dirvote.h"
+#include "geoip.h"
+#include "hibernate.h"
+#include "main.h"
+#include "networkstatus.h"
+#include "policies.h"
+#include "reasons.h"
+#include "rendcommon.h"
+#include "rendservice.h"
+#include "rephist.h"
+#include "router.h"
+#include "routerlist.h"
+#include "routerparse.h"
// #define DEBUG_ROUTERLIST
@@ -26,8 +45,8 @@ static void mark_all_trusteddirservers_up(void);
static int router_nickname_matches(routerinfo_t *router, const char *nickname);
static void trusted_dir_server_free(trusted_dir_server_t *ds);
static void launch_router_descriptor_downloads(smartlist_t *downloadable,
+ routerstatus_t *source,
time_t now);
-static void update_consensus_router_descriptor_downloads(time_t now);
static int signed_desc_digest_is_recognized(signed_descriptor_t *desc);
static void update_router_have_minimum_dir_info(void);
static const char *signed_descriptor_get_body_impl(signed_descriptor_t *desc,
@@ -156,21 +175,24 @@ already_have_cert(authority_cert_t *cert)
/** Load a bunch of new key certificates from the string <b>contents</b>. If
* <b>from_store</b> is true, the certificates are from the cache, and we
- * don't need to flush them to disk. If <b>from_store</b> is false, we need
- * to flush any changed certificates to disk. Return 0 on success, -1 on
- * failure. */
+ * don't need to flush them to disk. If <b>flush</b> is true, we need
+ * to flush any changed certificates to disk now. Return 0 on success, -1
+ * if any certs fail to parse. */
int
trusted_dirs_load_certs_from_string(const char *contents, int from_store,
int flush)
{
trusted_dir_server_t *ds;
const char *s, *eos;
+ int failure_code = 0;
for (s = contents; *s; s = eos) {
authority_cert_t *cert = authority_cert_parse_from_string(s, &eos);
cert_list_t *cl;
- if (!cert)
+ if (!cert) {
+ failure_code = -1;
break;
+ }
ds = trusteddirserver_get_by_v3_auth_digest(
cert->cache_info.identity_digest);
log_debug(LD_DIR, "Parsed certificate for %s",
@@ -181,15 +203,15 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store,
log_info(LD_DIR, "Skipping %s certificate for %s that we "
"already have.",
from_store ? "cached" : "downloaded",
- ds ? ds->nickname : "??");
+ ds ? ds->nickname : "an old or new authority");
/* a duplicate on a download should be treated as a failure, since it
* probably means we wanted a different secret key or we are trying to
* replace an expired cert that has not in fact been updated. */
if (!from_store) {
- log_warn(LD_DIR, "Got a certificate for %s that we already have. "
- "Maybe they haven't updated it. Waiting for a while.",
- ds ? ds->nickname : "??");
+ log_warn(LD_DIR, "Got a certificate for %s, but we already have it. "
+ "Maybe they haven't updated it. Waiting for a while.",
+ ds ? ds->nickname : "an old or new authority");
authority_cert_dl_failed(cert->cache_info.identity_digest, 404);
}
@@ -224,7 +246,7 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store,
ds->dir_port != cert->dir_port)) {
char *a = tor_dup_ip(cert->addr);
log_notice(LD_DIR, "Updating address for directory authority %s "
- "from %s:%d to %s:%d based on in certificate.",
+ "from %s:%d to %s:%d based on certificate.",
ds->nickname, ds->address, (int)ds->dir_port,
a, cert->dir_port);
tor_free(a);
@@ -241,8 +263,11 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store,
if (flush)
trusted_dirs_flush_certs_to_disk();
+ /* call this even if failure_code is <0, since some certs might have
+ * succeeded. */
networkstatus_note_certs_arrived();
- return 0;
+
+ return failure_code;
}
/** Save all v3 key certificates to the cached-certs file. */
@@ -415,6 +440,23 @@ authority_cert_dl_failed(const char *id_digest, int status)
download_status_failed(&cl->dl_status, status);
}
+/** Return true iff when we've been getting enough failures when trying to
+ * download the certificate with ID digest <b>id_digest</b> that we're willing
+ * to start bugging the user about it. */
+int
+authority_cert_dl_looks_uncertain(const char *id_digest)
+{
+#define N_AUTH_CERT_DL_FAILURES_TO_BUG_USER 2
+ cert_list_t *cl;
+ int n_failures;
+ if (!trusted_dir_certs ||
+ !(cl = digestmap_get(trusted_dir_certs, id_digest)))
+ return 0;
+
+ n_failures = download_status_get_n_failures(&cl->dl_status);
+ return n_failures >= N_AUTH_CERT_DL_FAILURES_TO_BUG_USER;
+}
+
/** How many times will we try to fetch a certificate before giving up? */
#define MAX_CERT_DL_FAILURES 8
@@ -442,17 +484,18 @@ authority_certs_fetch_missing(networkstatus_t *status, time_t now)
list_pending_downloads(pending, DIR_PURPOSE_FETCH_CERTIFICATE, "fp/");
if (status) {
- SMARTLIST_FOREACH(status->voters, networkstatus_voter_info_t *, voter,
- {
- if (tor_digest_is_zero(voter->signing_key_digest))
- continue; /* This authority never signed this consensus, so don't
- * go looking for a cert with key digest 0000000000. */
- if (!cache &&
- !trusteddirserver_get_by_v3_auth_digest(voter->identity_digest))
- continue; /* We are not a cache, and we don't know this authority.*/
- cl = get_cert_list(voter->identity_digest);
+ SMARTLIST_FOREACH_BEGIN(status->voters, networkstatus_voter_info_t *,
+ voter) {
+ if (!smartlist_len(voter->sigs))
+ continue; /* This authority never signed this consensus, so don't
+ * go looking for a cert with key digest 0000000000. */
+ if (!cache &&
+ !trusteddirserver_get_by_v3_auth_digest(voter->identity_digest))
+ continue; /* We are not a cache, and we don't know this authority.*/
+ cl = get_cert_list(voter->identity_digest);
+ SMARTLIST_FOREACH_BEGIN(voter->sigs, document_signature_t *, sig) {
cert = authority_cert_get_by_digests(voter->identity_digest,
- voter->signing_key_digest);
+ sig->signing_key_digest);
if (cert) {
if (now < cert->expires)
download_status_reset(&cl->dl_status);
@@ -463,37 +506,36 @@ authority_certs_fetch_missing(networkstatus_t *status, time_t now)
!digestmap_get(pending, voter->identity_digest)) {
log_notice(LD_DIR, "We're missing a certificate from authority "
"with signing key %s: launching request.",
- hex_str(voter->signing_key_digest, DIGEST_LEN));
- smartlist_add(missing_digests, voter->identity_digest);
+ hex_str(sig->signing_key_digest, DIGEST_LEN));
+ smartlist_add(missing_digests, sig->identity_digest);
}
- });
+ } SMARTLIST_FOREACH_END(sig);
+ } SMARTLIST_FOREACH_END(voter);
}
- SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
- {
- int found = 0;
- if (!(ds->type & V3_AUTHORITY))
- continue;
- if (smartlist_digest_isin(missing_digests, ds->v3_identity_digest))
- continue;
- cl = get_cert_list(ds->v3_identity_digest);
- SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert,
- {
- if (!ftime_definitely_after(now, cert->expires)) {
- /* It's not expired, and we weren't looking for something to
- * verify a consensus with. Call it done. */
- download_status_reset(&cl->dl_status);
- found = 1;
- break;
- }
- });
- if (!found &&
- download_status_is_ready(&cl->dl_status, now,MAX_CERT_DL_FAILURES) &&
- !digestmap_get(pending, ds->v3_identity_digest)) {
- log_notice(LD_DIR, "No current certificate known for authority %s; "
- "launching request.", ds->nickname);
- smartlist_add(missing_digests, ds->v3_identity_digest);
+ SMARTLIST_FOREACH_BEGIN(trusted_dir_servers, trusted_dir_server_t *, ds) {
+ int found = 0;
+ if (!(ds->type & V3_AUTHORITY))
+ continue;
+ if (smartlist_digest_isin(missing_digests, ds->v3_identity_digest))
+ continue;
+ cl = get_cert_list(ds->v3_identity_digest);
+ SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, {
+ if (!ftime_definitely_after(now, cert->expires)) {
+ /* It's not expired, and we weren't looking for something to
+ * verify a consensus with. Call it done. */
+ download_status_reset(&cl->dl_status);
+ found = 1;
+ break;
}
});
+ if (!found &&
+ download_status_is_ready(&cl->dl_status, now,MAX_CERT_DL_FAILURES) &&
+ !digestmap_get(pending, ds->v3_identity_digest)) {
+ log_notice(LD_DIR, "No current certificate known for authority %s; "
+ "launching request.", ds->nickname);
+ smartlist_add(missing_digests, ds->v3_identity_digest);
+ }
+ } SMARTLIST_FOREACH_END(ds);
if (!smartlist_len(missing_digests)) {
goto done;
@@ -749,8 +791,7 @@ router_rebuild_store(int flags, desc_store_t *store)
store->journal_len = 0;
store->bytes_dropped = 0;
done:
- if (signed_descriptors)
- smartlist_free(signed_descriptors);
+ smartlist_free(signed_descriptors);
tor_free(fname);
tor_free(fname_tmp);
if (chunk_list) {
@@ -968,8 +1009,9 @@ router_get_trusteddirserver_by_digest(const char *digest)
return NULL;
}
-/** Return the trusted_dir_server_t for the directory authority whose identity
- * key hashes to <b>digest</b>, or NULL if no such authority is known.
+/** Return the trusted_dir_server_t for the directory authority whose
+ * v3 identity key hashes to <b>digest</b>, or NULL if no such authority
+ * is known.
*/
trusted_dir_server_t *
trusteddirserver_get_by_v3_auth_digest(const char *digest)
@@ -1089,9 +1131,10 @@ router_pick_directory_server_impl(authority_type_t type, int flags)
} SMARTLIST_FOREACH_END(status);
if (smartlist_len(tunnel)) {
- result = routerstatus_sl_choose_by_bandwidth(tunnel);
+ result = routerstatus_sl_choose_by_bandwidth(tunnel, WEIGHT_FOR_DIR);
} else if (smartlist_len(overloaded_tunnel)) {
- result = routerstatus_sl_choose_by_bandwidth(overloaded_tunnel);
+ result = routerstatus_sl_choose_by_bandwidth(overloaded_tunnel,
+ WEIGHT_FOR_DIR);
} else if (smartlist_len(trusted_tunnel)) {
/* FFFF We don't distinguish between trusteds and overloaded trusteds
* yet. Maybe one day we should. */
@@ -1099,9 +1142,10 @@ router_pick_directory_server_impl(authority_type_t type, int flags)
* is a feature, but it could easily be a bug. -RD */
result = smartlist_choose(trusted_tunnel);
} else if (smartlist_len(direct)) {
- result = routerstatus_sl_choose_by_bandwidth(direct);
+ result = routerstatus_sl_choose_by_bandwidth(direct, WEIGHT_FOR_DIR);
} else if (smartlist_len(overloaded_direct)) {
- result = routerstatus_sl_choose_by_bandwidth(overloaded_direct);
+ result = routerstatus_sl_choose_by_bandwidth(overloaded_direct,
+ WEIGHT_FOR_DIR);
} else {
result = smartlist_choose(trusted_direct);
}
@@ -1230,6 +1274,13 @@ mark_all_trusteddirservers_up(void)
router_dir_info_changed();
}
+/** Return true iff r1 and r2 have the same address and OR port. */
+int
+routers_have_same_or_addr(const routerinfo_t *r1, const routerinfo_t *r2)
+{
+ return r1->addr == r2->addr && r1->or_port == r2->or_port;
+}
+
/** Reset all internal variables used to count failed downloads of network
* status objects. */
void
@@ -1521,6 +1572,29 @@ router_get_advertised_bandwidth_capped(routerinfo_t *router)
return result;
}
+/** When weighting bridges, enforce these values as lower and upper
+ * bound for believable bandwidth, because there is no way for us
+ * to verify a bridge's bandwidth currently. */
+#define BRIDGE_MIN_BELIEVABLE_BANDWIDTH 20000 /* 20 kB/sec */
+#define BRIDGE_MAX_BELIEVABLE_BANDWIDTH 100000 /* 100 kB/sec */
+
+/** Return the smaller of the router's configured BandwidthRate
+ * and its advertised capacity, making sure to stay within the
+ * interval between bridge-min-believe-bw and
+ * bridge-max-believe-bw. */
+static uint32_t
+bridge_get_advertised_bandwidth_bounded(routerinfo_t *router)
+{
+ uint32_t result = router->bandwidthcapacity;
+ if (result > router->bandwidthrate)
+ result = router->bandwidthrate;
+ if (result > BRIDGE_MAX_BELIEVABLE_BANDWIDTH)
+ result = BRIDGE_MAX_BELIEVABLE_BANDWIDTH;
+ else if (result < BRIDGE_MIN_BELIEVABLE_BANDWIDTH)
+ result = BRIDGE_MIN_BELIEVABLE_BANDWIDTH;
+ return result;
+}
+
/** Return bw*1000, unless bw*1000 would overflow, in which case return
* INT32_MAX. */
static INLINE int32_t
@@ -1531,6 +1605,219 @@ kb_to_bytes(uint32_t bw)
/** Helper function:
* choose a random element of smartlist <b>sl</b>, weighted by
+ * the advertised bandwidth of each element using the consensus
+ * bandwidth weights.
+ *
+ * If <b>statuses</b> is zero, then <b>sl</b> is a list of
+ * routerinfo_t's. Otherwise it's a list of routerstatus_t's.
+ *
+ * If <b>rule</b>==WEIGHT_FOR_EXIT. we're picking an exit node: consider all
+ * nodes' bandwidth equally regardless of their Exit status, since there may
+ * be some in the list because they exit to obscure ports. If
+ * <b>rule</b>==NO_WEIGHTING, we're picking a non-exit node: weight
+ * exit-node's bandwidth less depending on the smallness of the fraction of
+ * Exit-to-total bandwidth. If <b>rule</b>==WEIGHT_FOR_GUARD, we're picking a
+ * guard node: consider all guard's bandwidth equally. Otherwise, weight
+ * guards proportionally less.
+ */
+static void *
+smartlist_choose_by_bandwidth_weights(smartlist_t *sl,
+ bandwidth_weight_rule_t rule,
+ int statuses)
+{
+ int64_t weight_scale;
+ int64_t rand_bw;
+ double Wg = -1, Wm = -1, We = -1, Wd = -1;
+ double Wgb = -1, Wmb = -1, Web = -1, Wdb = -1;
+ double weighted_bw = 0;
+ double *bandwidths;
+ double tmp = 0;
+ unsigned int i;
+ int have_unknown = 0; /* true iff sl contains element not in consensus. */
+
+ /* Can't choose exit and guard at same time */
+ tor_assert(rule == NO_WEIGHTING ||
+ rule == WEIGHT_FOR_EXIT ||
+ rule == WEIGHT_FOR_GUARD ||
+ rule == WEIGHT_FOR_MID ||
+ rule == WEIGHT_FOR_DIR);
+
+ if (smartlist_len(sl) == 0) {
+ log_info(LD_CIRC,
+ "Empty routerlist passed in to consensus weight node "
+ "selection for rule %s",
+ bandwidth_weight_rule_to_string(rule));
+ return NULL;
+ }
+
+ weight_scale = networkstatus_get_param(NULL, "bwweightscale",
+ BW_WEIGHT_SCALE);
+
+ if (rule == WEIGHT_FOR_GUARD) {
+ Wg = networkstatus_get_bw_weight(NULL, "Wgg", -1);
+ Wm = networkstatus_get_bw_weight(NULL, "Wgm", -1); /* Bridges */
+ We = 0;
+ Wd = networkstatus_get_bw_weight(NULL, "Wgd", -1);
+
+ Wgb = networkstatus_get_bw_weight(NULL, "Wgb", -1);
+ Wmb = networkstatus_get_bw_weight(NULL, "Wmb", -1);
+ Web = networkstatus_get_bw_weight(NULL, "Web", -1);
+ Wdb = networkstatus_get_bw_weight(NULL, "Wdb", -1);
+ } else if (rule == WEIGHT_FOR_MID) {
+ Wg = networkstatus_get_bw_weight(NULL, "Wmg", -1);
+ Wm = networkstatus_get_bw_weight(NULL, "Wmm", -1);
+ We = networkstatus_get_bw_weight(NULL, "Wme", -1);
+ Wd = networkstatus_get_bw_weight(NULL, "Wmd", -1);
+
+ Wgb = networkstatus_get_bw_weight(NULL, "Wgb", -1);
+ Wmb = networkstatus_get_bw_weight(NULL, "Wmb", -1);
+ Web = networkstatus_get_bw_weight(NULL, "Web", -1);
+ Wdb = networkstatus_get_bw_weight(NULL, "Wdb", -1);
+ } else if (rule == WEIGHT_FOR_EXIT) {
+ // Guards CAN be exits if they have weird exit policies
+ // They are d then I guess...
+ We = networkstatus_get_bw_weight(NULL, "Wee", -1);
+ Wm = networkstatus_get_bw_weight(NULL, "Wem", -1); /* Odd exit policies */
+ Wd = networkstatus_get_bw_weight(NULL, "Wed", -1);
+ Wg = networkstatus_get_bw_weight(NULL, "Weg", -1); /* Odd exit policies */
+
+ Wgb = networkstatus_get_bw_weight(NULL, "Wgb", -1);
+ Wmb = networkstatus_get_bw_weight(NULL, "Wmb", -1);
+ Web = networkstatus_get_bw_weight(NULL, "Web", -1);
+ Wdb = networkstatus_get_bw_weight(NULL, "Wdb", -1);
+ } else if (rule == WEIGHT_FOR_DIR) {
+ We = networkstatus_get_bw_weight(NULL, "Wbe", -1);
+ Wm = networkstatus_get_bw_weight(NULL, "Wbm", -1);
+ Wd = networkstatus_get_bw_weight(NULL, "Wbd", -1);
+ Wg = networkstatus_get_bw_weight(NULL, "Wbg", -1);
+
+ Wgb = Wmb = Web = Wdb = weight_scale;
+ } else if (rule == NO_WEIGHTING) {
+ Wg = Wm = We = Wd = weight_scale;
+ Wgb = Wmb = Web = Wdb = weight_scale;
+ }
+
+ if (Wg < 0 || Wm < 0 || We < 0 || Wd < 0 || Wgb < 0 || Wmb < 0 || Wdb < 0
+ || Web < 0) {
+ log_debug(LD_CIRC,
+ "Got negative bandwidth weights. Defaulting to old selection"
+ " algorithm.");
+ return NULL; // Use old algorithm.
+ }
+
+ Wg /= weight_scale;
+ Wm /= weight_scale;
+ We /= weight_scale;
+ Wd /= weight_scale;
+
+ Wgb /= weight_scale;
+ Wmb /= weight_scale;
+ Web /= weight_scale;
+ Wdb /= weight_scale;
+
+ bandwidths = tor_malloc_zero(sizeof(double)*smartlist_len(sl));
+
+ // Cycle through smartlist and total the bandwidth.
+ for (i = 0; i < (unsigned)smartlist_len(sl); ++i) {
+ int is_exit = 0, is_guard = 0, is_dir = 0, this_bw = 0, is_me = 0;
+ double weight = 1;
+ if (statuses) {
+ routerstatus_t *status = smartlist_get(sl, i);
+ is_exit = status->is_exit;
+ is_guard = status->is_possible_guard;
+ is_dir = (status->dir_port != 0);
+ if (!status->has_bandwidth) {
+ tor_free(bandwidths);
+ /* This should never happen, unless all the authorites downgrade
+ * to 0.2.0 or rogue routerstatuses get inserted into our consensus. */
+ log_warn(LD_BUG,
+ "Consensus is not listing bandwidths. Defaulting back to "
+ "old router selection algorithm.");
+ return NULL;
+ }
+ this_bw = kb_to_bytes(status->bandwidth);
+ if (router_digest_is_me(status->identity_digest))
+ is_me = 1;
+ } else {
+ routerstatus_t *rs;
+ routerinfo_t *router = smartlist_get(sl, i);
+ rs = router_get_consensus_status_by_id(
+ router->cache_info.identity_digest);
+ is_exit = router->is_exit;
+ is_guard = router->is_possible_guard;
+ is_dir = (router->dir_port != 0);
+ if (rs && rs->has_bandwidth) {
+ this_bw = kb_to_bytes(rs->bandwidth);
+ } else { /* bridge or other descriptor not in our consensus */
+ this_bw = bridge_get_advertised_bandwidth_bounded(router);
+ have_unknown = 1;
+ }
+ if (router_digest_is_me(router->cache_info.identity_digest))
+ is_me = 1;
+ }
+ if (is_guard && is_exit) {
+ weight = (is_dir ? Wdb*Wd : Wd);
+ } else if (is_guard) {
+ weight = (is_dir ? Wgb*Wg : Wg);
+ } else if (is_exit) {
+ weight = (is_dir ? Web*We : We);
+ } else { // middle
+ weight = (is_dir ? Wmb*Wm : Wm);
+ }
+
+ bandwidths[i] = weight*this_bw;
+ weighted_bw += weight*this_bw;
+ if (is_me)
+ sl_last_weighted_bw_of_me = weight*this_bw;
+ }
+
+ /* XXXX022 this is a kludge to expose these values. */
+ sl_last_total_weighted_bw = weighted_bw;
+
+ log_debug(LD_CIRC, "Choosing node for rule %s based on weights "
+ "Wg=%lf Wm=%lf We=%lf Wd=%lf with total bw %lf",
+ bandwidth_weight_rule_to_string(rule),
+ Wg, Wm, We, Wd, weighted_bw);
+
+ /* If there is no bandwidth, choose at random */
+ if (DBL_TO_U64(weighted_bw) == 0) {
+ /* Don't warn when using bridges/relays not in the consensus */
+ if (!have_unknown)
+ log_warn(LD_CIRC,
+ "Weighted bandwidth is %lf in node selection for rule %s",
+ weighted_bw, bandwidth_weight_rule_to_string(rule));
+ tor_free(bandwidths);
+ return smartlist_choose(sl);
+ }
+
+ rand_bw = crypto_rand_uint64(DBL_TO_U64(weighted_bw));
+ rand_bw++; /* crypto_rand_uint64() counts from 0, and we need to count
+ * from 1 below. See bug 1203 for details. */
+
+ /* Last, count through sl until we get to the element we picked */
+ tmp = 0.0;
+ for (i=0; i < (unsigned)smartlist_len(sl); i++) {
+ tmp += bandwidths[i];
+ if (tmp >= rand_bw)
+ break;
+ }
+
+ if (i == (unsigned)smartlist_len(sl)) {
+ /* This was once possible due to round-off error, but shouldn't be able
+ * to occur any longer. */
+ tor_fragile_assert();
+ --i;
+ log_warn(LD_BUG, "Round-off error in computing bandwidth had an effect on "
+ " which router we chose. Please tell the developers. "
+ "%lf " U64_FORMAT " %lf", tmp, U64_PRINTF_ARG(rand_bw),
+ weighted_bw);
+ }
+ tor_free(bandwidths);
+ return smartlist_get(sl, i);
+}
+
+/** Helper function:
+ * choose a random element of smartlist <b>sl</b>, weighted by
* the advertised bandwidth of each element.
*
* If <b>statuses</b> is zero, then <b>sl</b> is a list of
@@ -1565,11 +1852,24 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, bandwidth_weight_rule_t rule,
bitarray_t *guard_bits;
int me_idx = -1;
+ // This function does not support WEIGHT_FOR_DIR
+ // or WEIGHT_FOR_MID
+ if (rule == WEIGHT_FOR_DIR || rule == WEIGHT_FOR_MID) {
+ rule = NO_WEIGHTING;
+ }
+
/* Can't choose exit and guard at same time */
tor_assert(rule == NO_WEIGHTING ||
rule == WEIGHT_FOR_EXIT ||
rule == WEIGHT_FOR_GUARD);
+ if (smartlist_len(sl) == 0) {
+ log_info(LD_CIRC,
+ "Empty routerlist passed in to old node selection for rule %s",
+ bandwidth_weight_rule_to_string(rule));
+ return NULL;
+ }
+
/* First count the total bandwidth weight, and make a list
* of each value. <0 means "unknown; no routerinfo." We use the
* bits of negative values to remember whether the router was fast (-x)&1
@@ -1620,7 +1920,7 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, bandwidth_weight_rule_t rule,
flags |= is_exit ? 2 : 0;
flags |= is_guard ? 4 : 0;
} else /* bridge or other descriptor not in our consensus */
- this_bw = router_get_advertised_bandwidth_capped(router);
+ this_bw = bridge_get_advertised_bandwidth_bounded(router);
}
if (is_exit)
bitarray_set(exit_bits, i);
@@ -1628,6 +1928,8 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, bandwidth_weight_rule_t rule,
bitarray_set(guard_bits, i);
if (is_known) {
bandwidths[i] = (int32_t) this_bw; // safe since MAX_BELIEVABLE<INT32_MAX
+ // XXX this is no longer true! We don't always cap the bw anymore. Can
+ // a consensus make us overflow?-sh
tor_assert(bandwidths[i] >= 0);
if (is_guard)
total_guard_bw += this_bw;
@@ -1691,12 +1993,12 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, bandwidth_weight_rule_t rule,
* For detailed derivation of this formula, see
* http://archives.seul.org/or/dev/Jul-2007/msg00056.html
*/
- if (rule == WEIGHT_FOR_EXIT)
+ if (rule == WEIGHT_FOR_EXIT || !total_exit_bw)
exit_weight = 1.0;
else
exit_weight = 1.0 - all_bw/(3.0*exit_bw);
- if (rule == WEIGHT_FOR_GUARD)
+ if (rule == WEIGHT_FOR_GUARD || !total_guard_bw)
guard_weight = 1.0;
else
guard_weight = 1.0 - all_bw/(3.0*guard_bw);
@@ -1745,6 +2047,8 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, bandwidth_weight_rule_t rule,
/* Almost done: choose a random value from the bandwidth weights. */
rand_bw = crypto_rand_uint64(total_bw);
+ rand_bw++; /* crypto_rand_uint64() counts from 0, and we need to count
+ * from 1 below. See bug 1203 for details. */
/* Last, count through sl until we get to the element we picked */
tmp = 0;
@@ -1788,26 +2092,34 @@ routerinfo_t *
routerlist_sl_choose_by_bandwidth(smartlist_t *sl,
bandwidth_weight_rule_t rule)
{
- return smartlist_choose_by_bandwidth(sl, rule, 0);
+ routerinfo_t *ret;
+ if ((ret = smartlist_choose_by_bandwidth_weights(sl, rule, 0))) {
+ return ret;
+ } else {
+ return smartlist_choose_by_bandwidth(sl, rule, 0);
+ }
}
/** Choose a random element of status list <b>sl</b>, weighted by
* the advertised bandwidth of each status.
*/
routerstatus_t *
-routerstatus_sl_choose_by_bandwidth(smartlist_t *sl)
+routerstatus_sl_choose_by_bandwidth(smartlist_t *sl,
+ bandwidth_weight_rule_t rule)
{
/* We are choosing neither exit nor guard here. Weight accordingly. */
- return smartlist_choose_by_bandwidth(sl, NO_WEIGHTING, 1);
+ routerstatus_t *ret;
+ if ((ret = smartlist_choose_by_bandwidth_weights(sl, rule, 1))) {
+ return ret;
+ } else {
+ return smartlist_choose_by_bandwidth(sl, rule, 1);
+ }
}
-/** Return a random running router from the routerlist. If any node
- * named in <b>preferred</b> is available, pick one of those. Never
+/** Return a random running router from the routerlist. Never
* pick a node whose routerinfo is in
* <b>excludedsmartlist</b>, or whose routerinfo matches <b>excludedset</b>,
- * even if they are the only nodes
- * available. If <b>CRN_STRICT_PREFERRED</b> is set in flags, never pick
- * any node besides those in <b>preferred</b>.
+ * even if they are the only nodes available.
* If <b>CRN_NEED_UPTIME</b> is set in flags and any router has more than
* a minimum uptime, return one of those.
* If <b>CRN_NEED_CAPACITY</b> is set in flags, weight your choice by the
@@ -1820,8 +2132,7 @@ routerstatus_sl_choose_by_bandwidth(smartlist_t *sl)
* node (that is, possibly discounting exit nodes).
*/
routerinfo_t *
-router_choose_random_node(const char *preferred,
- smartlist_t *excludedsmartlist,
+router_choose_random_node(smartlist_t *excludedsmartlist,
routerset_t *excludedset,
router_crn_flags_t flags)
{
@@ -1829,18 +2140,16 @@ router_choose_random_node(const char *preferred,
const int need_capacity = (flags & CRN_NEED_CAPACITY) != 0;
const int need_guard = (flags & CRN_NEED_GUARD) != 0;
const int allow_invalid = (flags & CRN_ALLOW_INVALID) != 0;
- const int strict = (flags & CRN_STRICT_PREFERRED) != 0;
const int weight_for_exit = (flags & CRN_WEIGHT_AS_EXIT) != 0;
- smartlist_t *sl, *excludednodes;
+ smartlist_t *sl=smartlist_create(),
+ *excludednodes=smartlist_create();
routerinfo_t *choice = NULL, *r;
bandwidth_weight_rule_t rule;
tor_assert(!(weight_for_exit && need_guard));
rule = weight_for_exit ? WEIGHT_FOR_EXIT :
- (need_guard ? WEIGHT_FOR_GUARD : NO_WEIGHTING);
-
- excludednodes = smartlist_create();
+ (need_guard ? WEIGHT_FOR_GUARD : WEIGHT_FOR_MID);
/* Exclude relays that allow single hop exit circuits, if the user
* wants to (such relays might be risky) */
@@ -1857,60 +2166,35 @@ router_choose_random_node(const char *preferred,
routerlist_add_family(excludednodes, r);
}
- /* Try the preferred nodes first. Ignore need_uptime and need_capacity
- * and need_guard, since the user explicitly asked for these nodes. */
- if (preferred) {
- sl = smartlist_create();
- add_nickname_list_to_smartlist(sl,preferred,1);
- smartlist_subtract(sl,excludednodes);
- if (excludedsmartlist)
- smartlist_subtract(sl,excludedsmartlist);
- if (excludedset)
- routerset_subtract_routers(sl,excludedset);
- choice = smartlist_choose(sl);
- smartlist_free(sl);
- }
- if (!choice && !strict) {
- /* Then give up on our preferred choices: any node
- * will do that has the required attributes. */
- sl = smartlist_create();
- router_add_running_routers_to_smartlist(sl, allow_invalid,
- need_uptime, need_capacity,
- need_guard);
- smartlist_subtract(sl,excludednodes);
- if (excludedsmartlist)
- smartlist_subtract(sl,excludedsmartlist);
- if (excludedset)
- routerset_subtract_routers(sl,excludedset);
-
- if (need_capacity || need_guard)
- choice = routerlist_sl_choose_by_bandwidth(sl, rule);
- else
- choice = smartlist_choose(sl);
-
- smartlist_free(sl);
- if (!choice && (need_uptime || need_capacity || need_guard)) {
- /* try once more -- recurse but with fewer restrictions. */
- log_info(LD_CIRC,
- "We couldn't find any live%s%s%s routers; falling back "
- "to list of all routers.",
- need_capacity?", fast":"",
- need_uptime?", stable":"",
- need_guard?", guard":"");
- flags &= ~ (CRN_NEED_UPTIME|CRN_NEED_CAPACITY|CRN_NEED_GUARD);
- choice = router_choose_random_node(
- NULL, excludedsmartlist, excludedset, flags);
- }
+ router_add_running_routers_to_smartlist(sl, allow_invalid,
+ need_uptime, need_capacity,
+ need_guard);
+ smartlist_subtract(sl,excludednodes);
+ if (excludedsmartlist)
+ smartlist_subtract(sl,excludedsmartlist);
+ if (excludedset)
+ routerset_subtract_routers(sl,excludedset);
+
+ // Always weight by bandwidth
+ choice = routerlist_sl_choose_by_bandwidth(sl, rule);
+
+ smartlist_free(sl);
+ if (!choice && (need_uptime || need_capacity || need_guard)) {
+ /* try once more -- recurse but with fewer restrictions. */
+ log_info(LD_CIRC,
+ "We couldn't find any live%s%s%s routers; falling back "
+ "to list of all routers.",
+ need_capacity?", fast":"",
+ need_uptime?", stable":"",
+ need_guard?", guard":"");
+ flags &= ~ (CRN_NEED_UPTIME|CRN_NEED_CAPACITY|CRN_NEED_GUARD);
+ choice = router_choose_random_node(
+ excludedsmartlist, excludedset, flags);
}
smartlist_free(excludednodes);
if (!choice) {
- if (strict) {
- log_warn(LD_CIRC, "All preferred nodes were down when trying to choose "
- "node, and the Strict[...]Nodes option is set. Failing.");
- } else {
- log_warn(LD_CIRC,
- "No available nodes when trying to choose node. Failing.");
- }
+ log_warn(LD_CIRC,
+ "No available nodes when trying to choose node. Failing.");
}
return choice;
}
@@ -1989,9 +2273,6 @@ router_get_by_nickname(const char *nickname, int warn_if_unnamed)
return router_get_by_hexdigest(nickname);
if (!strcasecmp(nickname, UNNAMED_ROUTER_NICKNAME))
return NULL;
- if (server_mode(get_options()) &&
- !strcasecmp(nickname, get_options()->Nickname))
- return router_get_my_routerinfo();
maybedigest = (strlen(nickname) >= HEX_DIGEST_LEN) &&
(base16_decode(digest,DIGEST_LEN,nickname,HEX_DIGEST_LEN) == 0);
@@ -2370,6 +2651,9 @@ extrainfo_free(extrainfo_t *extrainfo)
static void
signed_descriptor_free(signed_descriptor_t *sd)
{
+ if (!sd)
+ return;
+
tor_free(sd->signed_descriptor_body);
/* XXXX remove this once more bugs go away. */
@@ -2377,12 +2661,15 @@ signed_descriptor_free(signed_descriptor_t *sd)
tor_free(sd);
}
-/** Extract a signed_descriptor_t from a routerinfo, and free the routerinfo.
+/** Extract a signed_descriptor_t from a general routerinfo, and free the
+ * routerinfo.
*/
static signed_descriptor_t *
signed_descriptor_from_routerinfo(routerinfo_t *ri)
{
- signed_descriptor_t *sd = tor_malloc_zero(sizeof(signed_descriptor_t));
+ signed_descriptor_t *sd;
+ tor_assert(ri->purpose == ROUTER_PURPOSE_GENERAL);
+ sd = tor_malloc_zero(sizeof(signed_descriptor_t));
memcpy(sd, &(ri->cache_info), sizeof(signed_descriptor_t));
sd->routerlist_index = -1;
ri->cache_info.signed_descriptor_body = NULL;
@@ -2401,7 +2688,8 @@ _extrainfo_free(void *e)
void
routerlist_free(routerlist_t *rl)
{
- tor_assert(rl);
+ if (!rl)
+ return;
rimap_free(rl->identity_map, NULL);
sdmap_free(rl->desc_digest_map, NULL);
sdmap_free(rl->desc_by_eid_map, NULL);
@@ -2440,46 +2728,6 @@ dump_routerlist_mem_usage(int severity)
"In %d old descriptors: "U64_FORMAT" bytes.",
smartlist_len(routerlist->routers), U64_PRINTF_ARG(livedescs),
smartlist_len(routerlist->old_routers), U64_PRINTF_ARG(olddescs));
-
-#if 0
- {
- const smartlist_t *networkstatus_v2_list = networkstatus_get_v2_list();
- networkstatus_t *consensus = networkstatus_get_latest_consensus();
- log(severity, LD_DIR, "Now let's look through old_descriptors!");
- SMARTLIST_FOREACH(routerlist->old_routers, signed_descriptor_t *, sd, {
- int in_v2 = 0;
- int in_v3 = 0;
- char published[ISO_TIME_LEN+1];
- char last_valid_until[ISO_TIME_LEN+1];
- char last_served_at[ISO_TIME_LEN+1];
- char id[HEX_DIGEST_LEN+1];
- routerstatus_t *rs;
- format_iso_time(published, sd->published_on);
- format_iso_time(last_valid_until, sd->last_listed_as_valid_until);
- format_iso_time(last_served_at, sd->last_served_at);
- base16_encode(id, sizeof(id), sd->identity_digest, DIGEST_LEN);
- SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
- {
- rs = networkstatus_v2_find_entry(ns, sd->identity_digest);
- if (rs && !memcmp(rs->descriptor_digest,
- sd->signed_descriptor_digest, DIGEST_LEN)) {
- in_v2 = 1; break;
- }
- });
- if (consensus) {
- rs = networkstatus_vote_find_entry(consensus, sd->identity_digest);
- if (rs && !memcmp(rs->descriptor_digest,
- sd->signed_descriptor_digest, DIGEST_LEN))
- in_v3 = 1;
- }
- log(severity, LD_DIR,
- "Old descriptor for %s (published %s) %sin v2 ns, %sin v3 "
- "consensus. Last valid until %s; last served at %s.",
- id, published, in_v2 ? "" : "not ", in_v3 ? "" : "not ",
- last_valid_until, last_served_at);
- });
- }
-#endif
}
/** Debugging helper: If <b>idx</b> is nonnegative, assert that <b>ri</b> is
@@ -2512,6 +2760,7 @@ static void
routerlist_insert(routerlist_t *rl, routerinfo_t *ri)
{
routerinfo_t *ri_old;
+ signed_descriptor_t *sd_old;
{
/* XXXX Remove if this slows us down. */
routerinfo_t *ri_generated = router_get_my_routerinfo();
@@ -2521,8 +2770,16 @@ routerlist_insert(routerlist_t *rl, routerinfo_t *ri)
ri_old = rimap_set(rl->identity_map, ri->cache_info.identity_digest, ri);
tor_assert(!ri_old);
- sdmap_set(rl->desc_digest_map, ri->cache_info.signed_descriptor_digest,
- &(ri->cache_info));
+
+ sd_old = sdmap_set(rl->desc_digest_map,
+ ri->cache_info.signed_descriptor_digest,
+ &(ri->cache_info));
+ if (sd_old) {
+ rl->desc_store.bytes_dropped += sd_old->signed_descriptor_len;
+ sdmap_remove(rl->desc_by_eid_map, sd_old->extra_info_digest);
+ signed_descriptor_free(sd_old);
+ }
+
if (!tor_digest_is_zero(ri->cache_info.extra_info_digest))
sdmap_set(rl->desc_by_eid_map, ri->cache_info.extra_info_digest,
&ri->cache_info);
@@ -2741,6 +2998,7 @@ routerlist_replace(routerlist_t *rl, routerinfo_t *ri_old,
routerinfo_t *ri_new)
{
int idx;
+ int same_descriptors;
routerinfo_t *ri_tmp;
extrainfo_t *ei_tmp;
@@ -2785,8 +3043,15 @@ routerlist_replace(routerlist_t *rl, routerinfo_t *ri_old,
&ri_new->cache_info);
}
+ same_descriptors = ! memcmp(ri_old->cache_info.signed_descriptor_digest,
+ ri_new->cache_info.signed_descriptor_digest,
+ DIGEST_LEN);
+
if (should_cache_old_descriptors() &&
- ri_old->purpose == ROUTER_PURPOSE_GENERAL) {
+ ri_old->purpose == ROUTER_PURPOSE_GENERAL &&
+ !same_descriptors) {
+ /* ri_old is going to become a signed_descriptor_t and go into
+ * old_routers */
signed_descriptor_t *sd = signed_descriptor_from_routerinfo(ri_old);
smartlist_add(rl->old_routers, sd);
sd->routerlist_index = smartlist_len(rl->old_routers)-1;
@@ -2794,24 +3059,27 @@ routerlist_replace(routerlist_t *rl, routerinfo_t *ri_old,
if (!tor_digest_is_zero(sd->extra_info_digest))
sdmap_set(rl->desc_by_eid_map, sd->extra_info_digest, sd);
} else {
- if (memcmp(ri_old->cache_info.signed_descriptor_digest,
- ri_new->cache_info.signed_descriptor_digest,
- DIGEST_LEN)) {
- /* digests don't match; digestmap_set didn't replace */
+ /* We're dropping ri_old. */
+ if (!same_descriptors) {
+ /* digests don't match; The sdmap_set above didn't replace */
sdmap_remove(rl->desc_digest_map,
ri_old->cache_info.signed_descriptor_digest);
- }
- ei_tmp = eimap_remove(rl->extra_info_map,
- ri_old->cache_info.extra_info_digest);
- if (ei_tmp) {
- rl->extrainfo_store.bytes_dropped +=
- ei_tmp->cache_info.signed_descriptor_len;
- extrainfo_free(ei_tmp);
- }
- if (!tor_digest_is_zero(ri_old->cache_info.extra_info_digest)) {
- sdmap_remove(rl->desc_by_eid_map,
- ri_old->cache_info.extra_info_digest);
+ if (memcmp(ri_old->cache_info.extra_info_digest,
+ ri_new->cache_info.extra_info_digest, DIGEST_LEN)) {
+ ei_tmp = eimap_remove(rl->extra_info_map,
+ ri_old->cache_info.extra_info_digest);
+ if (ei_tmp) {
+ rl->extrainfo_store.bytes_dropped +=
+ ei_tmp->cache_info.signed_descriptor_len;
+ extrainfo_free(ei_tmp);
+ }
+ }
+
+ if (!tor_digest_is_zero(ri_old->cache_info.extra_info_digest)) {
+ sdmap_remove(rl->desc_by_eid_map,
+ ri_old->cache_info.extra_info_digest);
+ }
}
rl->desc_store.bytes_dropped += ri_old->cache_info.signed_descriptor_len;
routerinfo_free(ri_old);
@@ -2849,8 +3117,7 @@ routerlist_reparse_old(routerlist_t *rl, signed_descriptor_t *sd)
void
routerlist_free_all(void)
{
- if (routerlist)
- routerlist_free(routerlist);
+ routerlist_free(routerlist);
routerlist = NULL;
if (warned_nicknames) {
SMARTLIST_FOREACH(warned_nicknames, char *, cp, tor_free(cp));
@@ -2957,15 +3224,33 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
id_digest = router->cache_info.identity_digest;
+ old_router = router_get_by_digest(id_digest);
+
/* Make sure that we haven't already got this exact descriptor. */
if (sdmap_get(routerlist->desc_digest_map,
router->cache_info.signed_descriptor_digest)) {
- log_info(LD_DIR,
- "Dropping descriptor that we already have for router '%s'",
- router->nickname);
- *msg = "Router descriptor was not new.";
- routerinfo_free(router);
- return ROUTER_WAS_NOT_NEW;
+ /* If we have this descriptor already and the new descriptor is a bridge
+ * descriptor, replace it. If we had a bridge descriptor before and the
+ * new one is not a bridge descriptor, don't replace it. */
+
+ /* Only members of routerlist->identity_map can be bridges; we don't
+ * put bridges in old_routers. */
+ const int was_bridge = old_router &&
+ old_router->purpose == ROUTER_PURPOSE_BRIDGE;
+
+ if (routerinfo_is_a_configured_bridge(router) &&
+ router->purpose == ROUTER_PURPOSE_BRIDGE &&
+ !was_bridge) {
+ log_info(LD_DIR, "Replacing non-bridge descriptor with bridge "
+ "descriptor for router '%s'", router->nickname);
+ } else {
+ log_info(LD_DIR,
+ "Dropping descriptor that we already have for router '%s'",
+ router->nickname);
+ *msg = "Router descriptor was not new.";
+ routerinfo_free(router);
+ return ROUTER_WAS_NOT_NEW;
+ }
}
if (authdir) {
@@ -3002,15 +3287,14 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
{
routerstatus_t *rs =
- networkstatus_v2_find_entry(ns, router->cache_info.identity_digest);
+ networkstatus_v2_find_entry(ns, id_digest);
if (rs && !memcmp(rs->descriptor_digest,
router->cache_info.signed_descriptor_digest,
DIGEST_LEN))
rs->need_to_mirror = 0;
});
if (consensus) {
- routerstatus_t *rs = networkstatus_vote_find_entry(consensus,
- router->cache_info.identity_digest);
+ routerstatus_t *rs = networkstatus_vote_find_entry(consensus, id_digest);
if (rs && !memcmp(rs->descriptor_digest,
router->cache_info.signed_descriptor_digest,
DIGEST_LEN)) {
@@ -3032,13 +3316,11 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
}
/* If we have a router with the same identity key, choose the newer one. */
- old_router = rimap_get(routerlist->identity_map,
- router->cache_info.identity_digest);
if (old_router) {
if (!in_consensus && (router->cache_info.published_on <=
old_router->cache_info.published_on)) {
/* Same key, but old. This one is not listed in the consensus. */
- log_debug(LD_DIR, "Skipping not-new descriptor for router '%s'",
+ log_debug(LD_DIR, "Not-new descriptor for router '%s'",
router->nickname);
/* Only journal this desc if we'll be serving it. */
if (!from_cache && should_cache_old_descriptors())
@@ -3052,8 +3334,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
log_debug(LD_DIR, "Replacing entry for router '%s/%s' [%s]",
router->nickname, old_router->nickname,
hex_str(id_digest,DIGEST_LEN));
- if (router->addr == old_router->addr &&
- router->or_port == old_router->or_port) {
+ if (routers_have_same_or_addr(router, old_router)) {
/* these carry over when the address and orport are unchanged. */
router->last_reachable = old_router->last_reachable;
router->testing_since = old_router->testing_since;
@@ -3081,9 +3362,10 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
/* We haven't seen a router with this identity before. Add it to the end of
* the list. */
routerlist_insert(routerlist, router);
- if (!from_cache)
+ if (!from_cache) {
signed_desc_append_to_journal(&router->cache_info,
&routerlist->desc_store);
+ }
directory_set_dirty();
return ROUTER_ADDED_SUCCESSFULLY;
}
@@ -3400,15 +3682,19 @@ routerlist_remove_old_routers(void)
/** We just added a new set of descriptors. Take whatever extra steps
* we need. */
-static void
+void
routerlist_descriptors_added(smartlist_t *sl, int from_cache)
{
tor_assert(sl);
control_event_descriptors_changed(sl);
- SMARTLIST_FOREACH(sl, routerinfo_t *, ri,
+ SMARTLIST_FOREACH_BEGIN(sl, routerinfo_t *, ri) {
if (ri->purpose == ROUTER_PURPOSE_BRIDGE)
learned_bridge_descriptor(ri, from_cache);
- );
+ if (ri->needs_retest_if_added) {
+ ri->needs_retest_if_added = 0;
+ dirserv_single_reachability_test(approx_time(), ri);
+ }
+ } SMARTLIST_FOREACH_END(ri);
}
/**
@@ -3739,12 +4025,8 @@ add_trusted_dir_server(const char *nickname, const char *address,
if (ent->or_port)
ent->fake_status.version_supports_begindir = 1;
-/* XX021 - wait until authorities are upgraded */
-#if 0
+
ent->fake_status.version_supports_conditional_consensus = 1;
-#else
- ent->fake_status.version_supports_conditional_consensus = 0;
-#endif
smartlist_add(trusted_dir_servers, ent);
router_dir_info_changed();
@@ -3759,10 +4041,8 @@ authority_cert_free(authority_cert_t *cert)
return;
tor_free(cert->cache_info.signed_descriptor_body);
- if (cert->signing_key)
- crypto_free_pk_env(cert->signing_key);
- if (cert->identity_key)
- crypto_free_pk_env(cert->identity_key);
+ crypto_free_pk_env(cert->signing_key);
+ crypto_free_pk_env(cert->identity_key);
tor_free(cert);
}
@@ -3771,6 +4051,9 @@ authority_cert_free(authority_cert_t *cert)
static void
trusted_dir_server_free(trusted_dir_server_t *ds)
{
+ if (!ds)
+ return;
+
tor_free(ds->nickname);
tor_free(ds->description);
tor_free(ds->address);
@@ -3824,7 +4107,7 @@ list_pending_downloads(digestmap_t *result,
const char *resource = TO_DIR_CONN(conn)->requested_resource;
if (!strcmpstart(resource, prefix))
dir_split_resource_into_fingerprints(resource + p_len,
- tmp, NULL, 1, 0);
+ tmp, NULL, DSR_HEX);
}
});
SMARTLIST_FOREACH(tmp, char *, d,
@@ -3926,7 +4209,7 @@ client_would_use_router(routerstatus_t *rs, time_t now, or_options_t *options)
* this number per server. */
#define MIN_DL_PER_REQUEST 4
/** To prevent a single screwy cache from confusing us by selective reply,
- * try to split our requests into at least this this many requests. */
+ * try to split our requests into at least this many requests. */
#define MIN_REQUESTS 3
/** If we want fewer than this many descriptors, wait until we
* want more, or until MAX_CLIENT_INTERVAL_WITHOUT_REQUEST has
@@ -3940,7 +4223,8 @@ client_would_use_router(routerstatus_t *rs, time_t now, or_options_t *options)
* whether to delay fetching until we have more. If we don't want to delay,
* launch one or more requests to the appropriate directory authorities. */
static void
-launch_router_descriptor_downloads(smartlist_t *downloadable, time_t now)
+launch_router_descriptor_downloads(smartlist_t *downloadable,
+ routerstatus_t *source, time_t now)
{
int should_delay = 0, n_downloadable;
or_options_t *options = get_options();
@@ -3993,7 +4277,7 @@ launch_router_descriptor_downloads(smartlist_t *downloadable, time_t now)
pds_flags |= PDS_NO_EXISTING_SERVERDESC_FETCH;
}
- n_per_request = (n_downloadable+MIN_REQUESTS-1) / MIN_REQUESTS;
+ n_per_request = CEIL_DIV(n_downloadable, MIN_REQUESTS);
if (n_per_request > MAX_DL_PER_REQUEST)
n_per_request = MAX_DL_PER_REQUEST;
if (n_per_request < MIN_DL_PER_REQUEST)
@@ -4006,11 +4290,11 @@ launch_router_descriptor_downloads(smartlist_t *downloadable, time_t now)
log_info(LD_DIR,
"Launching %d request%s for %d router%s, %d at a time",
- (n_downloadable+n_per_request-1)/n_per_request,
+ CEIL_DIV(n_downloadable, n_per_request),
req_plural, n_downloadable, rtr_plural, n_per_request);
smartlist_sort_digests(downloadable);
for (i=0; i < n_downloadable; i += n_per_request) {
- initiate_descriptor_downloads(NULL, DIR_PURPOSE_FETCH_SERVERDESC,
+ initiate_descriptor_downloads(source, DIR_PURPOSE_FETCH_SERVERDESC,
downloadable, i, i+n_per_request,
pds_flags);
}
@@ -4166,18 +4450,18 @@ update_router_descriptor_cache_downloads_v2(time_t now)
digestmap_free(map,NULL);
}
-/** For any descriptor that we want that's currently listed in the live
- * consensus, download it as appropriate. */
-static void
-update_consensus_router_descriptor_downloads(time_t now)
+/** For any descriptor that we want that's currently listed in
+ * <b>consensus</b>, download it as appropriate. */
+void
+update_consensus_router_descriptor_downloads(time_t now, int is_vote,
+ networkstatus_t *consensus)
{
or_options_t *options = get_options();
digestmap_t *map = NULL;
smartlist_t *no_longer_old = smartlist_create();
smartlist_t *downloadable = smartlist_create();
+ routerstatus_t *source = NULL;
int authdir = authdir_mode(options);
- networkstatus_t *consensus =
- networkstatus_get_reasonably_live_consensus(now);
int n_delayed=0, n_have=0, n_would_reject=0, n_wouldnt_use=0,
n_inprogress=0, n_in_oldrouters=0;
@@ -4186,10 +4470,24 @@ update_consensus_router_descriptor_downloads(time_t now)
if (!consensus)
goto done;
+ if (is_vote) {
+ /* where's it from, so we know whom to ask for descriptors */
+ trusted_dir_server_t *ds;
+ networkstatus_voter_info_t *voter = smartlist_get(consensus->voters, 0);
+ tor_assert(voter);
+ ds = trusteddirserver_get_by_v3_auth_digest(voter->identity_digest);
+ if (ds)
+ source = &(ds->fake_status);
+ else
+ log_warn(LD_DIR, "couldn't lookup source from vote?");
+ }
+
map = digestmap_new();
list_pending_descriptor_downloads(map, 0);
- SMARTLIST_FOREACH(consensus->routerstatus_list, routerstatus_t *, rs,
+ SMARTLIST_FOREACH(consensus->routerstatus_list, void *, rsp,
{
+ routerstatus_t *rs =
+ is_vote ? &(((vote_routerstatus_t *)rsp)->status) : rsp;
signed_descriptor_t *sd;
if ((sd = router_get_by_descriptor_digest(rs->descriptor_digest))) {
routerinfo_t *ri;
@@ -4224,6 +4522,18 @@ update_consensus_router_descriptor_downloads(time_t now)
++n_wouldnt_use;
continue; /* We would never use it ourself. */
}
+ if (is_vote && source) {
+ char time_bufnew[ISO_TIME_LEN+1];
+ char time_bufold[ISO_TIME_LEN+1];
+ routerinfo_t *oldrouter = router_get_by_digest(rs->identity_digest);
+ format_iso_time(time_bufnew, rs->published_on);
+ if (oldrouter)
+ format_iso_time(time_bufold, oldrouter->cache_info.published_on);
+ log_info(LD_DIR, "Learned about %s (%s vs %s) from %s's vote (%s)",
+ rs->nickname, time_bufnew,
+ oldrouter ? time_bufold : "none",
+ source->nickname, oldrouter ? "known" : "unknown");
+ }
smartlist_add(downloadable, rs->descriptor_digest);
});
@@ -4257,7 +4567,7 @@ update_consensus_router_descriptor_downloads(time_t now)
smartlist_len(downloadable), n_delayed, n_have, n_in_oldrouters,
n_would_reject, n_wouldnt_use, n_inprogress);
- launch_router_descriptor_downloads(downloadable, now);
+ launch_router_descriptor_downloads(downloadable, source, now);
digestmap_free(map, NULL);
done:
@@ -4282,7 +4592,8 @@ update_router_descriptor_downloads(time_t now)
if (directory_fetches_dir_info_early(options)) {
update_router_descriptor_cache_downloads_v2(now);
}
- update_consensus_router_descriptor_downloads(now);
+ update_consensus_router_descriptor_downloads(now, 0,
+ networkstatus_get_reasonably_live_consensus(now));
/* XXXX021 we could be smarter here; see notes on bug 652. */
/* If we're a server that doesn't have a configured address, we rely on
@@ -4419,16 +4730,21 @@ 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>. */
+ * *<b>num_present</b>. If <b>in_set</b> is non-NULL, only consider those
+ * routers in <b>in_set</b>.
+ */
static void
count_usable_descriptors(int *num_present, int *num_usable,
const networkstatus_t *consensus,
- or_options_t *options, time_t now)
+ or_options_t *options, time_t now,
+ routerset_t *in_set)
{
*num_present = 0, *num_usable=0;
SMARTLIST_FOREACH(consensus->routerstatus_list, routerstatus_t *, rs,
{
+ if (in_set && ! routerset_contains_routerstatus(in_set, rs))
+ continue;
if (client_would_use_router(rs, now, options)) {
++*num_usable; /* the consensus says we want it. */
if (router_get_by_descriptor_digest(rs->descriptor_digest)) {
@@ -4457,7 +4773,7 @@ count_loading_descriptors_progress(void)
return 0; /* can't count descriptors if we have no list of them */
count_usable_descriptors(&num_present, &num_usable,
- consensus, get_options(), now);
+ consensus, get_options(), now, NULL);
if (num_usable == 0)
return 0; /* don't div by 0 */
@@ -4501,22 +4817,39 @@ update_router_have_minimum_dir_info(void)
goto done;
}
- count_usable_descriptors(&num_present, &num_usable, consensus, options, now);
+ count_usable_descriptors(&num_present, &num_usable, consensus, options, now,
+ NULL);
if (num_present < num_usable/4) {
tor_snprintf(dir_info_status, sizeof(dir_info_status),
"We have only %d/%d usable descriptors.", num_present, num_usable);
res = 0;
control_event_bootstrap(BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS, 0);
+ goto done;
} else if (num_present < 2) {
tor_snprintf(dir_info_status, sizeof(dir_info_status),
"Only %d descriptor%s here and believed reachable!",
num_present, num_present ? "" : "s");
res = 0;
- } else {
- res = 1;
+ goto done;
}
+ /* Check for entry nodes. */
+ if (options->EntryNodes) {
+ count_usable_descriptors(&num_present, &num_usable, consensus, options,
+ now, options->EntryNodes);
+
+ if (!num_usable || !num_present) {
+ tor_snprintf(dir_info_status, sizeof(dir_info_status),
+ "We have only %d/%d usable entry node descriptors.",
+ num_present, num_usable);
+ res = 0;
+ goto done;
+ }
+ }
+
+ res = 1;
+
done:
if (res && !have_min_dir_info) {
log(LOG_NOTICE, LD_DIR,
@@ -4529,6 +4862,13 @@ update_router_have_minimum_dir_info(void)
log(quiet ? LOG_INFO : LOG_NOTICE, LD_DIR,
"Our directory information is no longer up-to-date "
"enough to build circuits: %s", dir_info_status);
+
+ /* a) make us log when we next complete a circuit, so we know when Tor
+ * is back up and usable, and b) disable some activities that Tor
+ * should only do while circuits are working, like reachability tests
+ * and fetching bridge descriptors only over circuits. */
+ can_complete_circuit = 0;
+
control_event_client_status(LOG_NOTICE, "NOT_ENOUGH_DIR_INFO");
}
have_min_dir_info = res;
@@ -4814,8 +5154,8 @@ esc_router_info(routerinfo_t *router)
static char *info=NULL;
char *esc_contact, *esc_platform;
size_t len;
- if (info)
- tor_free(info);
+ tor_free(info);
+
if (!router)
return NULL; /* we're exiting; just free the memory we use */
@@ -4950,9 +5290,8 @@ void
routerset_refresh_countries(routerset_t *target)
{
int cc;
- if (target->countries) {
- bitarray_free(target->countries);
- }
+ bitarray_free(target->countries);
+
if (!geoip_is_loaded()) {
target->countries = NULL;
target->n_countries = 0;
@@ -5026,7 +5365,9 @@ routerset_parse(routerset_t *target, const char *s, const char *description)
return r;
}
-/** DOCDOC */
+/** Called when we change a node set, or when we reload the geoip list:
+ * recompute all country info in all configuration node sets and in the
+ * routerlist. */
void
refresh_all_country_info(void)
{
@@ -5194,9 +5535,13 @@ routerset_get_all_routers(smartlist_t *out, const routerset_t *routerset,
}
}
-/** Add to <b>target</b> every routerinfo_t from <b>source</b> that is in
- * <b>include</b>, but not excluded in a more specific fashion by
- * <b>exclude</b>. If <b>running_only</b>, only include running routers.
+/** Add to <b>target</b> every routerinfo_t from <b>source</b> except:
+ *
+ * 1) Don't add it if <b>include</b> is non-empty and the relay isn't in
+ * <b>include</b>; and
+ * 2) Don't add it if <b>exclude</b> is non-empty and the relay is
+ * excluded in a more specific fashion by <b>exclude</b>.
+ * 3) If <b>running_only</b>, don't add non-running routers.
*/
void
routersets_get_disjunction(smartlist_t *target,
@@ -5266,35 +5611,15 @@ routerset_equal(const routerset_t *old, const routerset_t *new)
});
return 1;
-
-#if 0
- /* XXXX: This won't work if the names/digests are identical but in a
- different order. Checking for exact equality would be heavy going,
- is it worth it? -RH*/
- /* This code is totally bogus; sizeof doesn't work even remotely like this
- * code seems to think. Let's revert to a string-based comparison for
- * now. -NM*/
- if (sizeof(old->names) != sizeof(new->names))
- return 0;
-
- if (memcmp(old->names,new->names,sizeof(new->names)))
- return 0;
- if (sizeof(old->digests) != sizeof(new->digests))
- return 0;
- if (memcmp(old->digests,new->digests,sizeof(new->digests)))
- return 0;
- if (sizeof(old->countries) != sizeof(new->countries))
- return 0;
- if (memcmp(old->countries,new->countries,sizeof(new->countries)))
- return 0;
- return 1;
-#endif
}
/** Free all storage held in <b>routerset</b>. */
void
routerset_free(routerset_t *routerset)
{
+ if (!routerset)
+ return;
+
SMARTLIST_FOREACH(routerset->list, char *, cp, tor_free(cp));
smartlist_free(routerset->list);
SMARTLIST_FOREACH(routerset->policies, addr_policy_t *, p,
@@ -5305,8 +5630,7 @@ routerset_free(routerset_t *routerset)
strmap_free(routerset->names, NULL);
digestmap_free(routerset->digests, NULL);
- if (routerset->countries)
- bitarray_free(routerset->countries);
+ bitarray_free(routerset->countries);
tor_free(routerset);
}
diff --git a/src/or/routerlist.h b/src/or/routerlist.h
new file mode 100644
index 0000000000..574bce7ffc
--- /dev/null
+++ b/src/or/routerlist.h
@@ -0,0 +1,196 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file routerlist.h
+ * \brief Header file for routerlist.c.
+ **/
+
+#ifndef _TOR_ROUTERLIST_H
+#define _TOR_ROUTERLIST_H
+
+int get_n_authorities(authority_type_t type);
+int trusted_dirs_reload_certs(void);
+int trusted_dirs_load_certs_from_string(const char *contents, int from_store,
+ int flush);
+void trusted_dirs_flush_certs_to_disk(void);
+authority_cert_t *authority_cert_get_newest_by_id(const char *id_digest);
+authority_cert_t *authority_cert_get_by_sk_digest(const char *sk_digest);
+authority_cert_t *authority_cert_get_by_digests(const char *id_digest,
+ const char *sk_digest);
+void authority_cert_get_all(smartlist_t *certs_out);
+void authority_cert_dl_failed(const char *id_digest, int status);
+void authority_certs_fetch_missing(networkstatus_t *status, time_t now);
+int router_reload_router_list(void);
+int authority_cert_dl_looks_uncertain(const char *id_digest);
+smartlist_t *router_get_trusted_dir_servers(void);
+
+routerstatus_t *router_pick_directory_server(authority_type_t type, int flags);
+trusted_dir_server_t *router_get_trusteddirserver_by_digest(const char *d);
+trusted_dir_server_t *trusteddirserver_get_by_v3_auth_digest(const char *d);
+routerstatus_t *router_pick_trusteddirserver(authority_type_t type, int flags);
+int router_get_my_share_of_directory_requests(double *v2_share_out,
+ double *v3_share_out);
+void router_reset_status_download_failures(void);
+void routerlist_add_family(smartlist_t *sl, routerinfo_t *router);
+int routers_in_same_family(routerinfo_t *r1, routerinfo_t *r2);
+int routers_have_same_or_addr(const routerinfo_t *r1, const routerinfo_t *r2);
+void add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
+ int must_be_running);
+int router_nickname_is_in_list(routerinfo_t *router, const char *list);
+routerinfo_t *routerlist_find_my_routerinfo(void);
+routerinfo_t *router_find_exact_exit_enclave(const char *address,
+ uint16_t port);
+int router_is_unreliable(routerinfo_t *router, int need_uptime,
+ int need_capacity, int need_guard);
+uint32_t router_get_advertised_bandwidth(routerinfo_t *router);
+uint32_t router_get_advertised_bandwidth_capped(routerinfo_t *router);
+
+routerinfo_t *routerlist_sl_choose_by_bandwidth(smartlist_t *sl,
+ bandwidth_weight_rule_t rule);
+routerstatus_t *routerstatus_sl_choose_by_bandwidth(smartlist_t *sl,
+ bandwidth_weight_rule_t rule);
+
+routerinfo_t *router_choose_random_node(smartlist_t *excludedsmartlist,
+ struct routerset_t *excludedset,
+ router_crn_flags_t flags);
+
+routerinfo_t *router_get_by_nickname(const char *nickname,
+ int warn_if_unnamed);
+int router_digest_version_as_new_as(const char *digest, const char *cutoff);
+int router_digest_is_trusted_dir_type(const char *digest,
+ authority_type_t type);
+#define router_digest_is_trusted_dir(d) \
+ router_digest_is_trusted_dir_type((d), NO_AUTHORITY)
+
+int router_addr_is_trusted_dir(uint32_t addr);
+int hexdigest_to_digest(const char *hexdigest, char *digest);
+routerinfo_t *router_get_by_hexdigest(const char *hexdigest);
+routerinfo_t *router_get_by_digest(const char *digest);
+signed_descriptor_t *router_get_by_descriptor_digest(const char *digest);
+signed_descriptor_t *router_get_by_extrainfo_digest(const char *digest);
+signed_descriptor_t *extrainfo_get_by_descriptor_digest(const char *digest);
+const char *signed_descriptor_get_body(signed_descriptor_t *desc);
+const char *signed_descriptor_get_annotations(signed_descriptor_t *desc);
+routerlist_t *router_get_routerlist(void);
+void routerinfo_free(routerinfo_t *router);
+void extrainfo_free(extrainfo_t *extrainfo);
+void routerlist_free(routerlist_t *rl);
+void dump_routerlist_mem_usage(int severity);
+void routerlist_remove(routerlist_t *rl, routerinfo_t *ri, int make_old,
+ time_t now);
+void routerlist_free_all(void);
+void routerlist_reset_warnings(void);
+void router_set_status(const char *digest, int up);
+
+static int WRA_WAS_ADDED(was_router_added_t s);
+static int WRA_WAS_OUTDATED(was_router_added_t s);
+static int WRA_WAS_REJECTED(was_router_added_t s);
+/** Return true iff the descriptor was added. It might still be necessary to
+ * check whether the descriptor generator should be notified.
+ */
+static INLINE int
+WRA_WAS_ADDED(was_router_added_t s) {
+ return s == ROUTER_ADDED_SUCCESSFULLY || s == ROUTER_ADDED_NOTIFY_GENERATOR;
+}
+/** Return true iff the descriptor was not added because it was either:
+ * - not in the consensus
+ * - neither in the consensus nor in any networkstatus document
+ * - it was outdated.
+ */
+static INLINE int WRA_WAS_OUTDATED(was_router_added_t s)
+{
+ return (s == ROUTER_WAS_NOT_NEW ||
+ s == ROUTER_NOT_IN_CONSENSUS ||
+ s == ROUTER_NOT_IN_CONSENSUS_OR_NETWORKSTATUS);
+}
+static INLINE int WRA_WAS_REJECTED(was_router_added_t s)
+{
+ return (s == ROUTER_AUTHDIR_REJECTS);
+}
+was_router_added_t router_add_to_routerlist(routerinfo_t *router,
+ const char **msg,
+ int from_cache,
+ int from_fetch);
+was_router_added_t router_add_extrainfo_to_routerlist(
+ extrainfo_t *ei, const char **msg,
+ int from_cache, int from_fetch);
+void routerlist_descriptors_added(smartlist_t *sl, int from_cache);
+void routerlist_remove_old_routers(void);
+int router_load_single_router(const char *s, uint8_t purpose, int cache,
+ const char **msg);
+int router_load_routers_from_string(const char *s, const char *eos,
+ saved_location_t saved_location,
+ smartlist_t *requested_fingerprints,
+ int descriptor_digests,
+ const char *prepend_annotations);
+void router_load_extrainfo_from_string(const char *s, const char *eos,
+ saved_location_t saved_location,
+ smartlist_t *requested_fingerprints,
+ int descriptor_digests);
+
+void routerlist_retry_directory_downloads(time_t now);
+int router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port,
+ int need_uptime);
+int router_exit_policy_rejects_all(routerinfo_t *router);
+trusted_dir_server_t *add_trusted_dir_server(const char *nickname,
+ const char *address,
+ uint16_t dir_port, uint16_t or_port,
+ const char *digest, const char *v3_auth_digest,
+ authority_type_t type);
+void authority_cert_free(authority_cert_t *cert);
+void clear_trusted_dir_servers(void);
+int any_trusted_dir_is_v1_authority(void);
+void update_consensus_router_descriptor_downloads(time_t now, int is_vote,
+ networkstatus_t *consensus);
+void update_router_descriptor_downloads(time_t now);
+void update_extrainfo_downloads(time_t now);
+int router_have_minimum_dir_info(void);
+void router_dir_info_changed(void);
+const char *get_dir_info_status_string(void);
+int count_loading_descriptors_progress(void);
+void router_reset_descriptor_download_failures(void);
+int router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2);
+int routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei,
+ signed_descriptor_t *sd,
+ const char **msg);
+
+void routerlist_assert_ok(routerlist_t *rl);
+const char *esc_router_info(routerinfo_t *router);
+void routers_sort_by_identity(smartlist_t *routers);
+
+routerset_t *routerset_new(void);
+int routerset_parse(routerset_t *target, const char *s,
+ const char *description);
+void routerset_union(routerset_t *target, const routerset_t *source);
+int routerset_is_list(const routerset_t *set);
+int routerset_needs_geoip(const routerset_t *set);
+int routerset_contains_router(const routerset_t *set, routerinfo_t *ri);
+int routerset_contains_routerstatus(const routerset_t *set,
+ routerstatus_t *rs);
+int routerset_contains_extendinfo(const routerset_t *set,
+ const extend_info_t *ei);
+void routerset_get_all_routers(smartlist_t *out, const routerset_t *routerset,
+ int running_only);
+void routersets_get_disjunction(smartlist_t *target, const smartlist_t *source,
+ const routerset_t *include,
+ const routerset_t *exclude, int running_only);
+void routerset_subtract_routers(smartlist_t *out,
+ const routerset_t *routerset);
+char *routerset_to_string(const routerset_t *routerset);
+void routerset_refresh_countries(routerset_t *target);
+int routerset_equal(const routerset_t *old, const routerset_t *new);
+void routerset_free(routerset_t *routerset);
+void routerinfo_set_country(routerinfo_t *ri);
+void routerlist_refresh_countries(void);
+void refresh_all_country_info(void);
+
+int hid_serv_get_responsible_directories(smartlist_t *responsible_dirs,
+ const char *id);
+int hid_serv_acting_as_directory(void);
+int hid_serv_responsible_for_desc_id(const char *id);
+
+#endif
+
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 3d8ca14317..1ce105abab 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -10,7 +10,20 @@
**/
#include "or.h"
+#include "config.h"
+#include "dirserv.h"
+#include "dirvote.h"
+#include "policies.h"
+#include "rendcommon.h"
+#include "router.h"
+#include "routerlist.h"
#include "memarea.h"
+#include "microdesc.h"
+#include "networkstatus.h"
+#include "rephist.h"
+#include "routerparse.h"
+#undef log
+#include <math.h>
/****************************************************************************/
@@ -55,6 +68,7 @@ typedef enum {
K_S,
K_V,
K_W,
+ K_M,
K_EVENTDNS,
K_EXTRA_INFO,
K_EXTRA_INFO_DIGEST,
@@ -62,6 +76,31 @@ typedef enum {
K_HIDDEN_SERVICE_DIR,
K_ALLOW_SINGLE_HOP_EXITS,
+ K_DIRREQ_END,
+ K_DIRREQ_V2_IPS,
+ K_DIRREQ_V3_IPS,
+ K_DIRREQ_V2_REQS,
+ K_DIRREQ_V3_REQS,
+ K_DIRREQ_V2_SHARE,
+ K_DIRREQ_V3_SHARE,
+ K_DIRREQ_V2_RESP,
+ K_DIRREQ_V3_RESP,
+ K_DIRREQ_V2_DIR,
+ K_DIRREQ_V3_DIR,
+ K_DIRREQ_V2_TUN,
+ K_DIRREQ_V3_TUN,
+ K_ENTRY_END,
+ K_ENTRY_IPS,
+ K_CELL_END,
+ K_CELL_PROCESSED,
+ K_CELL_QUEUED,
+ K_CELL_TIME,
+ K_CELL_CIRCS,
+ K_EXIT_END,
+ K_EXIT_WRITTEN,
+ K_EXIT_READ,
+ K_EXIT_OPENED,
+
K_DIR_KEY_CERTIFICATE_VERSION,
K_DIR_IDENTITY_KEY,
K_DIR_KEY_PUBLISHED,
@@ -78,13 +117,18 @@ typedef enum {
K_KNOWN_FLAGS,
K_PARAMS,
+ K_BW_WEIGHTS,
K_VOTE_DIGEST,
K_CONSENSUS_DIGEST,
+ K_ADDITIONAL_DIGEST,
+ K_ADDITIONAL_SIGNATURE,
K_CONSENSUS_METHODS,
K_CONSENSUS_METHOD,
K_LEGACY_DIR_KEY,
+ K_DIRECTORY_FOOTER,
A_PURPOSE,
+ A_LAST_LISTED,
_A_UNKNOWN,
R_RENDEZVOUS_SERVICE_DESCRIPTOR,
@@ -122,7 +166,7 @@ typedef enum {
* type.
*
* This structure is only allocated in memareas; do not allocate it on
- * the heap, or token_free() won't work.
+ * the heap, or token_clear() won't work.
*/
typedef struct directory_token_t {
directory_keyword tp; /**< Type of the token. */
@@ -258,6 +302,31 @@ static token_rule_t extrainfo_token_table[] = {
T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ),
T01("read-history", K_READ_HISTORY, ARGS, NO_OBJ ),
T01("write-history", K_WRITE_HISTORY, ARGS, NO_OBJ ),
+ T01("dirreq-stats-end", K_DIRREQ_END, ARGS, NO_OBJ ),
+ T01("dirreq-v2-ips", K_DIRREQ_V2_IPS, ARGS, NO_OBJ ),
+ T01("dirreq-v3-ips", K_DIRREQ_V3_IPS, ARGS, NO_OBJ ),
+ T01("dirreq-v2-reqs", K_DIRREQ_V2_REQS, ARGS, NO_OBJ ),
+ T01("dirreq-v3-reqs", K_DIRREQ_V3_REQS, ARGS, NO_OBJ ),
+ T01("dirreq-v2-share", K_DIRREQ_V2_SHARE, ARGS, NO_OBJ ),
+ T01("dirreq-v3-share", K_DIRREQ_V3_SHARE, ARGS, NO_OBJ ),
+ T01("dirreq-v2-resp", K_DIRREQ_V2_RESP, ARGS, NO_OBJ ),
+ T01("dirreq-v3-resp", K_DIRREQ_V3_RESP, ARGS, NO_OBJ ),
+ T01("dirreq-v2-direct-dl", K_DIRREQ_V2_DIR, ARGS, NO_OBJ ),
+ T01("dirreq-v3-direct-dl", K_DIRREQ_V3_DIR, ARGS, NO_OBJ ),
+ T01("dirreq-v2-tunneled-dl", K_DIRREQ_V2_TUN, ARGS, NO_OBJ ),
+ T01("dirreq-v3-tunneled-dl", K_DIRREQ_V3_TUN, ARGS, NO_OBJ ),
+ T01("entry-stats-end", K_ENTRY_END, ARGS, NO_OBJ ),
+ T01("entry-ips", K_ENTRY_IPS, ARGS, NO_OBJ ),
+ T01("cell-stats-end", K_CELL_END, ARGS, NO_OBJ ),
+ T01("cell-processed-cells", K_CELL_PROCESSED, ARGS, NO_OBJ ),
+ T01("cell-queued-cells", K_CELL_QUEUED, ARGS, NO_OBJ ),
+ T01("cell-time-in-queue", K_CELL_TIME, ARGS, NO_OBJ ),
+ T01("cell-circuits-per-decile", K_CELL_CIRCS, ARGS, NO_OBJ ),
+ T01("exit-stats-end", K_EXIT_END, ARGS, NO_OBJ ),
+ T01("exit-kibibytes-written", K_EXIT_WRITTEN, ARGS, NO_OBJ ),
+ T01("exit-kibibytes-read", K_EXIT_READ, ARGS, NO_OBJ ),
+ T01("exit-streams-opened", K_EXIT_OPENED, ARGS, NO_OBJ ),
+
T1_START( "extra-info", K_EXTRA_INFO, GE(2), NO_OBJ ),
END_OF_TABLE
@@ -267,10 +336,11 @@ static token_rule_t extrainfo_token_table[] = {
* documents. */
static token_rule_t rtrstatus_token_table[] = {
T01("p", K_P, CONCAT_ARGS, NO_OBJ ),
- T1( "r", K_R, GE(8), NO_OBJ ),
+ T1( "r", K_R, GE(7), NO_OBJ ),
T1( "s", K_S, ARGS, NO_OBJ ),
T01("v", K_V, CONCAT_ARGS, NO_OBJ ),
T01("w", K_W, ARGS, NO_OBJ ),
+ T0N("m", K_M, CONCAT_ARGS, NO_OBJ ),
T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ),
END_OF_TABLE
};
@@ -375,7 +445,7 @@ static token_rule_t client_keys_token_table[] = {
/** List of tokens allowed in V3 networkstatus votes. */
static token_rule_t networkstatus_token_table[] = {
- T1("network-status-version", K_NETWORK_STATUS_VERSION,
+ T1_START("network-status-version", K_NETWORK_STATUS_VERSION,
GE(1), NO_OBJ ),
T1("vote-status", K_VOTE_STATUS, GE(1), NO_OBJ ),
T1("published", K_PUBLISHED, CONCAT_ARGS, NO_OBJ ),
@@ -403,7 +473,7 @@ static token_rule_t networkstatus_token_table[] = {
/** List of tokens allowed in V3 networkstatus consensuses. */
static token_rule_t networkstatus_consensus_token_table[] = {
- T1("network-status-version", K_NETWORK_STATUS_VERSION,
+ T1_START("network-status-version", K_NETWORK_STATUS_VERSION,
GE(1), NO_OBJ ),
T1("vote-status", K_VOTE_STATUS, GE(1), NO_OBJ ),
T1("valid-after", K_VALID_AFTER, CONCAT_ARGS, NO_OBJ ),
@@ -430,17 +500,29 @@ static token_rule_t networkstatus_consensus_token_table[] = {
/** List of tokens allowable in the footer of v1/v2 directory/networkstatus
* footers. */
static token_rule_t networkstatus_vote_footer_token_table[] = {
- T( "directory-signature", K_DIRECTORY_SIGNATURE, GE(2), NEED_OBJ ),
+ T01("directory-footer", K_DIRECTORY_FOOTER, NO_ARGS, NO_OBJ ),
+ T01("bandwidth-weights", K_BW_WEIGHTS, ARGS, NO_OBJ ),
+ T( "directory-signature", K_DIRECTORY_SIGNATURE, GE(2), NEED_OBJ ),
END_OF_TABLE
};
/** List of tokens allowable in detached networkstatus signature documents. */
static token_rule_t networkstatus_detached_signature_token_table[] = {
T1_START("consensus-digest", K_CONSENSUS_DIGEST, GE(1), NO_OBJ ),
+ T("additional-digest", K_ADDITIONAL_DIGEST,GE(3), NO_OBJ ),
T1("valid-after", K_VALID_AFTER, CONCAT_ARGS, NO_OBJ ),
T1("fresh-until", K_FRESH_UNTIL, CONCAT_ARGS, NO_OBJ ),
T1("valid-until", K_VALID_UNTIL, CONCAT_ARGS, NO_OBJ ),
- T1N("directory-signature", K_DIRECTORY_SIGNATURE, GE(2), NEED_OBJ ),
+ T("additional-signature", K_ADDITIONAL_SIGNATURE, GE(4), NEED_OBJ ),
+ T1N("directory-signature", K_DIRECTORY_SIGNATURE, GE(2), NEED_OBJ ),
+ END_OF_TABLE
+};
+
+static token_rule_t microdesc_token_table[] = {
+ T1_START("onion-key", K_ONION_KEY, NO_ARGS, NEED_KEY_1024),
+ T01("family", K_FAMILY, ARGS, NO_OBJ ),
+ T01("p", K_P, CONCAT_ARGS, NO_OBJ ),
+ A01("@last-listed", A_LAST_LISTED, CONCAT_ARGS, NO_OBJ ),
END_OF_TABLE
};
@@ -453,9 +535,13 @@ static addr_policy_t *router_parse_addr_policy_private(directory_token_t *tok);
static int router_get_hash_impl(const char *s, size_t s_len, char *digest,
const char *start_str, const char *end_str,
- char end_char);
-
-static void token_free(directory_token_t *tok);
+ char end_char,
+ digest_algorithm_t alg);
+static int router_get_hashes_impl(const char *s, size_t s_len,
+ digests_t *digests,
+ const char *start_str, const char *end_str,
+ char end_char);
+static void token_clear(directory_token_t *tok);
static smartlist_t *find_all_exitpolicy(smartlist_t *s);
static directory_token_t *_find_by_keyword(smartlist_t *s,
directory_keyword keyword,
@@ -479,6 +565,7 @@ static directory_token_t *get_next_token(memarea_t *area,
#define CST_CHECK_AUTHORITY (1<<0)
#define CST_NO_CHECK_OBJTYPE (1<<1)
static int check_signature_token(const char *digest,
+ ssize_t digest_len,
directory_token_t *tok,
crypto_pk_env_t *pkey,
int flags,
@@ -499,6 +586,34 @@ static int tor_version_same_series(tor_version_t *a, tor_version_t *b);
#define DUMP_AREA(a,name) STMT_NIL
#endif
+/** Last time we dumped a descriptor to disk. */
+static time_t last_desc_dumped = 0;
+
+/** For debugging purposes, dump unparseable descriptor *<b>desc</b> of
+ * type *<b>type</b> to file $DATADIR/unparseable-desc. Do not write more
+ * than one descriptor to disk per minute. If there is already such a
+ * file in the data directory, overwrite it. */
+static void
+dump_desc(const char *desc, const char *type)
+{
+ time_t now = time(NULL);
+ tor_assert(desc);
+ tor_assert(type);
+ if (!last_desc_dumped || last_desc_dumped + 60 < now) {
+ char *debugfile = get_datadir_fname("unparseable-desc");
+ size_t filelen = 50 + strlen(type) + strlen(desc);
+ char *content = tor_malloc_zero(filelen);
+ tor_snprintf(content, filelen, "Unable to parse descriptor of type "
+ "%s:\n%s", type, desc);
+ write_str_to_file(debugfile, content, 0);
+ log_info(LD_DIR, "Unable to parse descriptor of type %s. See file "
+ "unparseable-desc in data directory for details.", type);
+ tor_free(content);
+ tor_free(debugfile);
+ last_desc_dumped = now;
+ }
+}
+
/** Set <b>digest</b> to the SHA-1 digest of the hash of the directory in
* <b>s</b>. Return 0 on success, -1 on failure.
*/
@@ -506,7 +621,8 @@ int
router_get_dir_hash(const char *s, char *digest)
{
return router_get_hash_impl(s, strlen(s), digest,
- "signed-directory","\ndirectory-signature",'\n');
+ "signed-directory","\ndirectory-signature",'\n',
+ DIGEST_SHA1);
}
/** Set <b>digest</b> to the SHA-1 digest of the hash of the first router in
@@ -516,7 +632,8 @@ int
router_get_router_hash(const char *s, size_t s_len, char *digest)
{
return router_get_hash_impl(s, s_len, digest,
- "router ","\nrouter-signature", '\n');
+ "router ","\nrouter-signature", '\n',
+ DIGEST_SHA1);
}
/** Set <b>digest</b> to the SHA-1 digest of the hash of the running-routers
@@ -526,7 +643,8 @@ int
router_get_runningrouters_hash(const char *s, char *digest)
{
return router_get_hash_impl(s, strlen(s), digest,
- "network-status","\ndirectory-signature", '\n');
+ "network-status","\ndirectory-signature", '\n',
+ DIGEST_SHA1);
}
/** Set <b>digest</b> to the SHA-1 digest of the hash of the network-status
@@ -536,18 +654,31 @@ router_get_networkstatus_v2_hash(const char *s, char *digest)
{
return router_get_hash_impl(s, strlen(s), digest,
"network-status-version","\ndirectory-signature",
- '\n');
+ '\n',
+ DIGEST_SHA1);
+}
+
+/** Set <b>digests</b> to all the digests of the consensus document in
+ * <b>s</b> */
+int
+router_get_networkstatus_v3_hashes(const char *s, digests_t *digests)
+{
+ return router_get_hashes_impl(s,strlen(s),digests,
+ "network-status-version",
+ "\ndirectory-signature",
+ ' ');
}
/** Set <b>digest</b> to the SHA-1 digest of the hash of the network-status
* string in <b>s</b>. Return 0 on success, -1 on failure. */
int
-router_get_networkstatus_v3_hash(const char *s, char *digest)
+router_get_networkstatus_v3_hash(const char *s, char *digest,
+ digest_algorithm_t alg)
{
return router_get_hash_impl(s, strlen(s), digest,
"network-status-version",
"\ndirectory-signature",
- ' ');
+ ' ', alg);
}
/** Set <b>digest</b> to the SHA-1 digest of the hash of the extrainfo
@@ -556,7 +687,7 @@ int
router_get_extrainfo_hash(const char *s, char *digest)
{
return router_get_hash_impl(s, strlen(s), digest, "extra-info",
- "\nrouter-signature",'\n');
+ "\nrouter-signature",'\n', DIGEST_SHA1);
}
/** Helper: used to generate signatures for routers, directories and
@@ -568,14 +699,15 @@ router_get_extrainfo_hash(const char *s, char *digest)
*/
int
router_append_dirobj_signature(char *buf, size_t buf_len, const char *digest,
- crypto_pk_env_t *private_key)
+ size_t digest_len, crypto_pk_env_t *private_key)
{
char *signature;
size_t i;
+ int siglen;
signature = tor_malloc(crypto_pk_keysize(private_key));
- if (crypto_pk_private_sign(private_key, signature, digest, DIGEST_LEN) < 0) {
-
+ siglen = crypto_pk_private_sign(private_key, signature, digest, digest_len);
+ if (siglen < 0) {
log_warn(LD_BUG,"Couldn't sign digest.");
goto err;
}
@@ -583,7 +715,7 @@ router_append_dirobj_signature(char *buf, size_t buf_len, const char *digest,
goto truncated;
i = strlen(buf);
- if (base64_encode(buf+i, buf_len-i, signature, 128) < 0) {
+ if (base64_encode(buf+i, buf_len-i, signature, siglen) < 0) {
log_warn(LD_BUG,"couldn't base64-encode signature");
goto err;
}
@@ -690,7 +822,7 @@ router_parse_directory(const char *str)
char digest[DIGEST_LEN];
time_t published_on;
int r;
- const char *end, *cp;
+ const char *end, *cp, *str_dup = str;
smartlist_t *tokens = NULL;
crypto_pk_env_t *declared_key = NULL;
memarea_t *area = memarea_new();
@@ -726,11 +858,11 @@ router_parse_directory(const char *str)
}
declared_key = find_dir_signing_key(str, str+strlen(str));
note_crypto_pk_op(VERIFY_DIR);
- if (check_signature_token(digest, tok, declared_key,
+ if (check_signature_token(digest, DIGEST_LEN, tok, declared_key,
CST_CHECK_AUTHORITY, "directory")<0)
goto err;
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_clear(tokens);
memarea_clear(area);
@@ -763,11 +895,12 @@ router_parse_directory(const char *str)
r = 0;
goto done;
err:
+ dump_desc(str_dup, "v1 directory");
r = -1;
done:
if (declared_key) crypto_free_pk_env(declared_key);
if (tokens) {
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
}
if (area) {
@@ -789,7 +922,7 @@ router_parse_runningrouters(const char *str)
int r = -1;
crypto_pk_env_t *declared_key = NULL;
smartlist_t *tokens = NULL;
- const char *eos = str + strlen(str);
+ const char *eos = str + strlen(str), *str_dup = str;
memarea_t *area = NULL;
if (router_get_runningrouters_hash(str, digest)) {
@@ -818,7 +951,7 @@ router_parse_runningrouters(const char *str)
}
declared_key = find_dir_signing_key(str, eos);
note_crypto_pk_op(VERIFY_DIR);
- if (check_signature_token(digest, tok, declared_key,
+ if (check_signature_token(digest, DIGEST_LEN, tok, declared_key,
CST_CHECK_AUTHORITY, "running-routers")
< 0)
goto err;
@@ -830,9 +963,10 @@ router_parse_runningrouters(const char *str)
r = 0;
err:
+ dump_desc(str_dup, "v1 running-routers");
if (declared_key) crypto_free_pk_env(declared_key);
if (tokens) {
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
}
if (area) {
@@ -882,7 +1016,7 @@ find_dir_signing_key(const char *str, const char *eos)
}
done:
- if (tok) token_free(tok);
+ if (tok) token_clear(tok);
if (area) {
DUMP_AREA(area, "dir-signing-key token");
memarea_drop_all(area);
@@ -918,6 +1052,7 @@ dir_signing_key_is_trusted(crypto_pk_env_t *key)
*/
static int
check_signature_token(const char *digest,
+ ssize_t digest_len,
directory_token_t *tok,
crypto_pk_env_t *pkey,
int flags,
@@ -948,14 +1083,14 @@ check_signature_token(const char *digest,
signed_digest = tor_malloc(tok->object_size);
if (crypto_pk_public_checksig(pkey, signed_digest, tok->object_body,
tok->object_size)
- != DIGEST_LEN) {
+ < digest_len) {
log_warn(LD_DIR, "Error reading %s: invalid signature.", doctype);
tor_free(signed_digest);
return -1;
}
// log_debug(LD_DIR,"Signed %s hash starts %s", doctype,
// hex_str(signed_digest,4));
- if (memcmp(digest, signed_digest, DIGEST_LEN)) {
+ if (memcmp(digest, signed_digest, digest_len)) {
log_warn(LD_DIR, "Error reading %s: signature does not match.", doctype);
tor_free(signed_digest);
return -1;
@@ -1141,7 +1276,7 @@ router_parse_entry_from_string(const char *s, const char *end,
smartlist_t *tokens = NULL, *exit_policy_tokens = NULL;
directory_token_t *tok;
struct in_addr in;
- const char *start_of_annotations, *cp;
+ const char *start_of_annotations, *cp, *s_dup = s;
size_t prepend_len = prepend_annotations ? strlen(prepend_annotations) : 0;
int ok = 1;
memarea_t *area = NULL;
@@ -1419,7 +1554,7 @@ router_parse_entry_from_string(const char *s, const char *end,
verified_digests = digestmap_new();
digestmap_set(verified_digests, signed_digest, (void*)(uintptr_t)1);
#endif
- if (check_signature_token(digest, tok, router->identity_pkey, 0,
+ if (check_signature_token(digest, DIGEST_LEN, tok, router->identity_pkey, 0,
"router descriptor") < 0)
goto err;
@@ -1437,16 +1572,15 @@ router_parse_entry_from_string(const char *s, const char *end,
goto done;
err:
+ dump_desc(s_dup, "router descriptor");
routerinfo_free(router);
router = NULL;
done:
if (tokens) {
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
}
- if (exit_policy_tokens) {
- smartlist_free(exit_policy_tokens);
- }
+ smartlist_free(exit_policy_tokens);
if (area) {
DUMP_AREA(area, "routerinfo");
memarea_drop_all(area);
@@ -1471,6 +1605,7 @@ extrainfo_parse_entry_from_string(const char *s, const char *end,
crypto_pk_env_t *key = NULL;
routerinfo_t *router = NULL;
memarea_t *area = NULL;
+ const char *s_dup = s;
if (!end) {
end = s + strlen(s);
@@ -1545,7 +1680,8 @@ extrainfo_parse_entry_from_string(const char *s, const char *end,
if (key) {
note_crypto_pk_op(VERIFY_RTR);
- if (check_signature_token(digest, tok, key, 0, "extra-info") < 0)
+ if (check_signature_token(digest, DIGEST_LEN, tok, key, 0,
+ "extra-info") < 0)
goto err;
if (router)
@@ -1559,12 +1695,12 @@ extrainfo_parse_entry_from_string(const char *s, const char *end,
goto done;
err:
- if (extrainfo)
- extrainfo_free(extrainfo);
+ dump_desc(s_dup, "extra-info descriptor");
+ extrainfo_free(extrainfo);
extrainfo = NULL;
done:
if (tokens) {
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
}
if (area) {
@@ -1588,6 +1724,7 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
size_t len;
int found;
memarea_t *area = NULL;
+ const char *s_dup = s;
s = eat_whitespace(s);
eos = strstr(s, "\ndir-key-certification");
@@ -1612,7 +1749,7 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
goto err;
}
if (router_get_hash_impl(s, strlen(s), digest, "dir-key-certificate-version",
- "\ndir-key-certification", '\n') < 0)
+ "\ndir-key-certification", '\n', DIGEST_SHA1) < 0)
goto err;
tok = smartlist_get(tokens, 0);
if (tok->tp != K_DIR_KEY_CERTIFICATE_VERSION || strcmp(tok->args[0], "3")) {
@@ -1705,7 +1842,7 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
}
}
if (!found) {
- if (check_signature_token(digest, tok, cert->identity_key, 0,
+ if (check_signature_token(digest, DIGEST_LEN, tok, cert->identity_key, 0,
"key certificate")) {
goto err;
}
@@ -1714,6 +1851,7 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
/* XXXX Once all authorities generate cross-certified certificates,
* make this field mandatory. */
if (check_signature_token(cert->cache_info.identity_digest,
+ DIGEST_LEN,
tok,
cert->signing_key,
CST_NO_CHECK_OBJTYPE,
@@ -1733,7 +1871,7 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
if (end_of_string) {
*end_of_string = eat_whitespace(eos);
}
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
if (area) {
DUMP_AREA(area, "authority cert");
@@ -1741,8 +1879,9 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
}
return cert;
err:
+ dump_desc(s_dup, "authority cert");
authority_cert_free(cert);
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
if (area) {
DUMP_AREA(area, "authority cert");
@@ -1753,23 +1892,28 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
/** Helper: given a string <b>s</b>, return the start of the next router-status
* object (starting with "r " at the start of a line). If none is found,
- * return the start of the next directory signature. If none is found, return
- * the end of the string. */
+ * return the start of the directory footer, or the next directory signature.
+ * If none is found, return the end of the string. */
static INLINE const char *
find_start_of_next_routerstatus(const char *s)
{
- const char *eos = strstr(s, "\nr ");
- if (eos) {
- const char *eos2 = tor_memstr(s, eos-s, "\ndirectory-signature");
- if (eos2 && eos2 < eos)
- return eos2;
- else
- return eos+1;
- } else {
- if ((eos = strstr(s, "\ndirectory-signature")))
- return eos+1;
- return s + strlen(s);
- }
+ const char *eos, *footer, *sig;
+ if ((eos = strstr(s, "\nr ")))
+ ++eos;
+ else
+ eos = s + strlen(s);
+
+ footer = tor_memstr(s, eos-s, "\ndirectory-footer");
+ sig = tor_memstr(s, eos-s, "\ndirectory-signature");
+
+ if (footer && sig)
+ return MIN(footer, sig) + 1;
+ else if (footer)
+ return footer+1;
+ else if (sig)
+ return sig+1;
+ else
+ return eos;
}
/** Given a string at *<b>s</b>, containing a routerstatus object, and an
@@ -1783,22 +1927,29 @@ find_start_of_next_routerstatus(const char *s)
* If <b>consensus_method</b> is nonzero, this routerstatus is part of a
* consensus, and we should parse it according to the method used to
* make that consensus.
+ *
+ * Parse according to the syntax used by the consensus flavor <b>flav</b>.
**/
static routerstatus_t *
routerstatus_parse_entry_from_string(memarea_t *area,
const char **s, smartlist_t *tokens,
networkstatus_t *vote,
vote_routerstatus_t *vote_rs,
- int consensus_method)
+ int consensus_method,
+ consensus_flavor_t flav)
{
- const char *eos;
+ const char *eos, *s_dup = *s;
routerstatus_t *rs = NULL;
directory_token_t *tok;
char timebuf[ISO_TIME_LEN+1];
struct in_addr in;
+ int offset = 0;
tor_assert(tokens);
tor_assert(bool_eq(vote, vote_rs));
+ if (!consensus_method)
+ flav = FLAV_NS;
+
eos = find_start_of_next_routerstatus(*s);
if (tokenize_string(area,*s, eos, tokens, rtrstatus_token_table,0)) {
@@ -1810,7 +1961,15 @@ routerstatus_parse_entry_from_string(memarea_t *area,
goto err;
}
tok = find_by_keyword(tokens, K_R);
- tor_assert(tok->n_args >= 8);
+ tor_assert(tok->n_args >= 7);
+ if (flav == FLAV_NS) {
+ if (tok->n_args < 8) {
+ log_warn(LD_DIR, "Too few arguments to r");
+ goto err;
+ }
+ } else {
+ offset = -1;
+ }
if (vote_rs) {
rs = &vote_rs->status;
} else {
@@ -1831,29 +1990,34 @@ routerstatus_parse_entry_from_string(memarea_t *area,
goto err;
}
- if (digest_from_base64(rs->descriptor_digest, tok->args[2])) {
- log_warn(LD_DIR, "Error decoding descriptor digest %s",
- escaped(tok->args[2]));
- goto err;
+ if (flav == FLAV_NS) {
+ if (digest_from_base64(rs->descriptor_digest, tok->args[2])) {
+ log_warn(LD_DIR, "Error decoding descriptor digest %s",
+ escaped(tok->args[2]));
+ goto err;
+ }
}
if (tor_snprintf(timebuf, sizeof(timebuf), "%s %s",
- tok->args[3], tok->args[4]) < 0 ||
+ tok->args[3+offset], tok->args[4+offset]) < 0 ||
parse_iso_time(timebuf, &rs->published_on)<0) {
- log_warn(LD_DIR, "Error parsing time '%s %s'",
- tok->args[3], tok->args[4]);
+ log_warn(LD_DIR, "Error parsing time '%s %s' [%d %d]",
+ tok->args[3+offset], tok->args[4+offset],
+ offset, (int)flav);
goto err;
}
- if (tor_inet_aton(tok->args[5], &in) == 0) {
+ if (tor_inet_aton(tok->args[5+offset], &in) == 0) {
log_warn(LD_DIR, "Error parsing router address in network-status %s",
- escaped(tok->args[5]));
+ escaped(tok->args[5+offset]));
goto err;
}
rs->addr = ntohl(in.s_addr);
- rs->or_port =(uint16_t) tor_parse_long(tok->args[6],10,0,65535,NULL,NULL);
- rs->dir_port = (uint16_t) tor_parse_long(tok->args[7],10,0,65535,NULL,NULL);
+ rs->or_port = (uint16_t) tor_parse_long(tok->args[6+offset],
+ 10,0,65535,NULL,NULL);
+ rs->dir_port = (uint16_t) tor_parse_long(tok->args[7+offset],
+ 10,0,65535,NULL,NULL);
tok = find_opt_by_keyword(tokens, K_S);
if (tok && vote) {
@@ -1939,6 +2103,17 @@ routerstatus_parse_entry_from_string(memarea_t *area,
goto err;
}
rs->has_bandwidth = 1;
+ } else if (!strcmpstart(tok->args[i], "Measured=")) {
+ int ok;
+ rs->measured_bw =
+ (uint32_t)tor_parse_ulong(strchr(tok->args[i], '=')+1,
+ 10, 0, UINT32_MAX, &ok, NULL);
+ if (!ok) {
+ log_warn(LD_DIR, "Invalid Measured Bandwidth %s",
+ escaped(tok->args[i]));
+ goto err;
+ }
+ rs->has_measured_bw = 1;
}
}
}
@@ -1960,16 +2135,29 @@ routerstatus_parse_entry_from_string(memarea_t *area,
rs->has_exitsummary = 1;
}
+ if (vote_rs) {
+ SMARTLIST_FOREACH_BEGIN(tokens, directory_token_t *, t) {
+ if (t->tp == K_M && t->n_args) {
+ vote_microdesc_hash_t *line =
+ tor_malloc(sizeof(vote_microdesc_hash_t));
+ line->next = vote_rs->microdesc;
+ line->microdesc_hash_line = tor_strdup(t->args[0]);
+ vote_rs->microdesc = line;
+ }
+ } SMARTLIST_FOREACH_END(t);
+ }
+
if (!strcasecmp(rs->nickname, UNNAMED_ROUTER_NICKNAME))
rs->is_named = 0;
goto done;
err:
+ dump_desc(s_dup, "routerstatus entry");
if (rs && !vote_rs)
routerstatus_free(rs);
rs = NULL;
done:
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_clear(tokens);
if (area) {
DUMP_AREA(area, "routerstatus entry");
@@ -1981,8 +2169,8 @@ routerstatus_parse_entry_from_string(memarea_t *area,
}
/** Helper to sort a smartlist of pointers to routerstatus_t */
-static int
-_compare_routerstatus_entries(const void **_a, const void **_b)
+int
+compare_routerstatus_entries(const void **_a, const void **_b)
{
const routerstatus_t *a = *_a, *b = *_b;
return memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN);
@@ -2006,7 +2194,7 @@ _free_duplicate_routerstatus_entry(void *e)
networkstatus_v2_t *
networkstatus_v2_parse_from_string(const char *s)
{
- const char *eos;
+ const char *eos, *s_dup = s;
smartlist_t *tokens = smartlist_create();
smartlist_t *footer_tokens = smartlist_create();
networkstatus_v2_t *ns = NULL;
@@ -2120,17 +2308,17 @@ networkstatus_v2_parse_from_string(const char *s)
ns->entries = smartlist_create();
s = eos;
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_clear(tokens);
memarea_clear(area);
while (!strcmpstart(s, "r ")) {
routerstatus_t *rs;
if ((rs = routerstatus_parse_entry_from_string(area, &s, tokens,
- NULL, NULL, 0)))
+ NULL, NULL, 0, 0)))
smartlist_add(ns->entries, rs);
}
- smartlist_sort(ns->entries, _compare_routerstatus_entries);
- smartlist_uniq(ns->entries, _compare_routerstatus_entries,
+ smartlist_sort(ns->entries, compare_routerstatus_entries);
+ smartlist_uniq(ns->entries, compare_routerstatus_entries,
_free_duplicate_routerstatus_entry);
if (tokenize_string(area,s, NULL, footer_tokens, dir_footer_token_table,0)) {
@@ -2149,19 +2337,19 @@ networkstatus_v2_parse_from_string(const char *s)
}
note_crypto_pk_op(VERIFY_DIR);
- if (check_signature_token(ns_digest, tok, ns->signing_key, 0,
+ if (check_signature_token(ns_digest, DIGEST_LEN, tok, ns->signing_key, 0,
"network-status") < 0)
goto err;
goto done;
err:
- if (ns)
- networkstatus_v2_free(ns);
+ dump_desc(s_dup, "v2 networkstatus");
+ networkstatus_v2_free(ns);
ns = NULL;
done:
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
- SMARTLIST_FOREACH(footer_tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(footer_tokens, directory_token_t *, t, token_clear(t));
smartlist_free(footer_tokens);
if (area) {
DUMP_AREA(area, "v2 networkstatus");
@@ -2170,6 +2358,394 @@ networkstatus_v2_parse_from_string(const char *s)
return ns;
}
+/** Verify the bandwidth weights of a network status document */
+int
+networkstatus_verify_bw_weights(networkstatus_t *ns)
+{
+ int64_t weight_scale;
+ int64_t G=0, M=0, E=0, D=0, T=0;
+ double Wgg, Wgm, Wgd, Wmg, Wmm, Wme, Wmd, Weg, Wem, Wee, Wed;
+ double Gtotal=0, Mtotal=0, Etotal=0;
+ const char *casename = NULL;
+ int valid = 1;
+
+ weight_scale = networkstatus_get_param(ns, "bwweightscale", BW_WEIGHT_SCALE);
+ Wgg = networkstatus_get_bw_weight(ns, "Wgg", -1);
+ Wgm = networkstatus_get_bw_weight(ns, "Wgm", -1);
+ Wgd = networkstatus_get_bw_weight(ns, "Wgd", -1);
+ Wmg = networkstatus_get_bw_weight(ns, "Wmg", -1);
+ Wmm = networkstatus_get_bw_weight(ns, "Wmm", -1);
+ Wme = networkstatus_get_bw_weight(ns, "Wme", -1);
+ Wmd = networkstatus_get_bw_weight(ns, "Wmd", -1);
+ Weg = networkstatus_get_bw_weight(ns, "Weg", -1);
+ Wem = networkstatus_get_bw_weight(ns, "Wem", -1);
+ Wee = networkstatus_get_bw_weight(ns, "Wee", -1);
+ Wed = networkstatus_get_bw_weight(ns, "Wed", -1);
+
+ if (Wgg<0 || Wgm<0 || Wgd<0 || Wmg<0 || Wmm<0 || Wme<0 || Wmd<0 || Weg<0
+ || Wem<0 || Wee<0 || Wed<0) {
+ log_warn(LD_BUG, "No bandwidth weights produced in consensus!");
+ return 0;
+ }
+
+ // First, sanity check basic summing properties that hold for all cases
+ // We use > 1 as the check for these because they are computed as integers.
+ // Sometimes there are rounding errors.
+ if (fabs(Wmm - weight_scale) > 1) {
+ log_warn(LD_BUG, "Wmm=%lf != "I64_FORMAT,
+ Wmm, I64_PRINTF_ARG(weight_scale));
+ valid = 0;
+ }
+
+ if (fabs(Wem - Wee) > 1) {
+ log_warn(LD_BUG, "Wem=%lf != Wee=%lf", Wem, Wee);
+ valid = 0;
+ }
+
+ if (fabs(Wgm - Wgg) > 1) {
+ log_warn(LD_BUG, "Wgm=%lf != Wgg=%lf", Wgm, Wgg);
+ valid = 0;
+ }
+
+ if (fabs(Weg - Wed) > 1) {
+ log_warn(LD_BUG, "Wed=%lf != Weg=%lf", Wed, Weg);
+ valid = 0;
+ }
+
+ if (fabs(Wgg + Wmg - weight_scale) > 0.001*weight_scale) {
+ log_warn(LD_BUG, "Wgg=%lf != "I64_FORMAT" - Wmg=%lf", Wgg,
+ I64_PRINTF_ARG(weight_scale), Wmg);
+ valid = 0;
+ }
+
+ if (fabs(Wee + Wme - weight_scale) > 0.001*weight_scale) {
+ log_warn(LD_BUG, "Wee=%lf != "I64_FORMAT" - Wme=%lf", Wee,
+ I64_PRINTF_ARG(weight_scale), Wme);
+ valid = 0;
+ }
+
+ if (fabs(Wgd + Wmd + Wed - weight_scale) > 0.001*weight_scale) {
+ log_warn(LD_BUG, "Wgd=%lf + Wmd=%lf + Wed=%lf != "I64_FORMAT,
+ Wgd, Wmd, Wed, I64_PRINTF_ARG(weight_scale));
+ valid = 0;
+ }
+
+ Wgg /= weight_scale;
+ Wgm /= weight_scale;
+ Wgd /= weight_scale;
+
+ Wmg /= weight_scale;
+ Wmm /= weight_scale;
+ Wme /= weight_scale;
+ Wmd /= weight_scale;
+
+ Weg /= weight_scale;
+ Wem /= weight_scale;
+ Wee /= weight_scale;
+ Wed /= weight_scale;
+
+ // Then, gather G, M, E, D, T to determine case
+ SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, routerstatus_t *, rs) {
+ if (rs->has_bandwidth) {
+ T += rs->bandwidth;
+ if (rs->is_exit && rs->is_possible_guard) {
+ D += rs->bandwidth;
+ Gtotal += Wgd*rs->bandwidth;
+ Mtotal += Wmd*rs->bandwidth;
+ Etotal += Wed*rs->bandwidth;
+ } else if (rs->is_exit) {
+ E += rs->bandwidth;
+ Mtotal += Wme*rs->bandwidth;
+ Etotal += Wee*rs->bandwidth;
+ } else if (rs->is_possible_guard) {
+ G += rs->bandwidth;
+ Gtotal += Wgg*rs->bandwidth;
+ Mtotal += Wmg*rs->bandwidth;
+ } else {
+ M += rs->bandwidth;
+ Mtotal += Wmm*rs->bandwidth;
+ }
+ } else {
+ log_warn(LD_BUG, "Missing consensus bandwidth for router %s",
+ rs->nickname);
+ }
+ } SMARTLIST_FOREACH_END(rs);
+
+ // Finally, check equality conditions depending upon case 1, 2 or 3
+ // Full equality cases: 1, 3b
+ // Partial equality cases: 2b (E=G), 3a (M=E)
+ // Fully unknown: 2a
+ if (3*E >= T && 3*G >= T) {
+ // Case 1: Neither are scarce
+ casename = "Case 1";
+ if (fabs(Etotal-Mtotal) > 0.01*MAX(Etotal,Mtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Etotal %lf != Mtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Etotal, Mtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Etotal %lf != Gtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Etotal, Gtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ if (fabs(Gtotal-Mtotal) > 0.01*MAX(Gtotal,Mtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Mtotal %lf != Gtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Mtotal, Gtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ } else if (3*E < T && 3*G < T) {
+ int64_t R = MIN(E, G);
+ int64_t S = MAX(E, G);
+ /*
+ * Case 2: Both Guards and Exits are scarce
+ * Balance D between E and G, depending upon
+ * D capacity and scarcity. Devote no extra
+ * bandwidth to middle nodes.
+ */
+ if (R+D < S) { // Subcase a
+ double Rtotal, Stotal;
+ if (E < G) {
+ Rtotal = Etotal;
+ Stotal = Gtotal;
+ } else {
+ Rtotal = Gtotal;
+ Stotal = Etotal;
+ }
+ casename = "Case 2a";
+ // Rtotal < Stotal
+ if (Rtotal > Stotal) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Rtotal %lf > Stotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Rtotal, Stotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ // Rtotal < T/3
+ if (3*Rtotal > T) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: 3*Rtotal %lf > T "
+ I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
+ " D="I64_FORMAT" T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Rtotal*3, I64_PRINTF_ARG(T),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ // Stotal < T/3
+ if (3*Stotal > T) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: 3*Stotal %lf > T "
+ I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
+ " D="I64_FORMAT" T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Stotal*3, I64_PRINTF_ARG(T),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ // Mtotal > T/3
+ if (3*Mtotal < T) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: 3*Mtotal %lf < T "
+ I64_FORMAT". "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Mtotal*3, I64_PRINTF_ARG(T),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ } else { // Subcase b: R+D > S
+ casename = "Case 2b";
+
+ /* Check the rare-M redirect case. */
+ if (D != 0 && 3*M < T) {
+ casename = "Case 2b (balanced)";
+ if (fabs(Etotal-Mtotal) > 0.01*MAX(Etotal,Mtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Etotal %lf != Mtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Etotal, Mtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Etotal %lf != Gtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Etotal, Gtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ if (fabs(Gtotal-Mtotal) > 0.01*MAX(Gtotal,Mtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Mtotal %lf != Gtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Mtotal, Gtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ } else {
+ if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Etotal %lf != Gtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Etotal, Gtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ }
+ }
+ } else { // if (E < T/3 || G < T/3) {
+ int64_t S = MIN(E, G);
+ int64_t NS = MAX(E, G);
+ if (3*(S+D) < T) { // Subcase a:
+ double Stotal;
+ double NStotal;
+ if (G < E) {
+ casename = "Case 3a (G scarce)";
+ Stotal = Gtotal;
+ NStotal = Etotal;
+ } else { // if (G >= E) {
+ casename = "Case 3a (E scarce)";
+ NStotal = Gtotal;
+ Stotal = Etotal;
+ }
+ // Stotal < T/3
+ if (3*Stotal > T) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: 3*Stotal %lf > T "
+ I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
+ " D="I64_FORMAT" T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Stotal*3, I64_PRINTF_ARG(T),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ if (NS >= M) {
+ if (fabs(NStotal-Mtotal) > 0.01*MAX(NStotal,Mtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: NStotal %lf != Mtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, NStotal, Mtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ } else {
+ // if NS < M, NStotal > T/3 because only one of G or E is scarce
+ if (3*NStotal < T) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: 3*NStotal %lf < T "
+ I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT
+ " E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, NStotal*3, I64_PRINTF_ARG(T),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ }
+ } else { // Subcase b: S+D >= T/3
+ casename = "Case 3b";
+ if (fabs(Etotal-Mtotal) > 0.01*MAX(Etotal,Mtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Etotal %lf != Mtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Etotal, Mtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Etotal %lf != Gtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Etotal, Gtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ if (fabs(Gtotal-Mtotal) > 0.01*MAX(Gtotal,Mtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Mtotal %lf != Gtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Mtotal, Gtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ }
+ }
+
+ if (valid)
+ log_notice(LD_DIR, "Bandwidth-weight %s is verified and valid.",
+ casename);
+
+ return valid;
+}
/** Parse a v3 networkstatus vote, opinion, or consensus (depending on
* ns_type), from <b>s</b>, and return the result. Return NULL on failure. */
@@ -2181,19 +2757,21 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
smartlist_t *rs_tokens = NULL, *footer_tokens = NULL;
networkstatus_voter_info_t *voter = NULL;
networkstatus_t *ns = NULL;
- char ns_digest[DIGEST_LEN];
- const char *cert, *end_of_header, *end_of_footer;
+ digests_t ns_digests;
+ const char *cert, *end_of_header, *end_of_footer, *s_dup = s;
directory_token_t *tok;
int ok;
struct in_addr in;
int i, inorder, n_signatures = 0;
memarea_t *area = NULL, *rs_area = NULL;
+ consensus_flavor_t flav = FLAV_NS;
+
tor_assert(s);
if (eos_out)
*eos_out = NULL;
- if (router_get_networkstatus_v3_hash(s, ns_digest)) {
+ if (router_get_networkstatus_v3_hashes(s, &ns_digests)) {
log_warn(LD_DIR, "Unable to compute digest of network-status");
goto err;
}
@@ -2209,7 +2787,23 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
}
ns = tor_malloc_zero(sizeof(networkstatus_t));
- memcpy(ns->networkstatus_digest, ns_digest, DIGEST_LEN);
+ memcpy(&ns->digests, &ns_digests, sizeof(ns_digests));
+
+ tok = find_by_keyword(tokens, K_NETWORK_STATUS_VERSION);
+ tor_assert(tok);
+ if (tok->n_args > 1) {
+ int flavor = networkstatus_parse_flavor_name(tok->args[1]);
+ if (flavor < 0) {
+ log_warn(LD_DIR, "Can't parse document with unknown flavor %s",
+ escaped(tok->args[2]));
+ goto err;
+ }
+ ns->flavor = flav = flavor;
+ }
+ if (flav != FLAV_NS && ns_type != NS_TYPE_CONSENSUS) {
+ log_warn(LD_DIR, "Flavor found on non-consenus networkstatus.");
+ goto err;
+ }
if (ns_type != NS_TYPE_CONSENSUS) {
const char *end_of_cert = NULL;
@@ -2363,8 +2957,9 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
if (voter)
smartlist_add(ns->voters, voter);
voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
+ voter->sigs = smartlist_create();
if (ns->type != NS_TYPE_CONSENSUS)
- memcpy(voter->vote_digest, ns_digest, DIGEST_LEN);
+ memcpy(voter->vote_digest, ns_digests.d[DIGEST_SHA1], DIGEST_LEN);
voter->nickname = tor_strdup(tok->args[0]);
if (strlen(tok->args[1]) != HEX_DIGEST_LEN ||
@@ -2456,7 +3051,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
if (ns->type != NS_TYPE_CONSENSUS) {
vote_routerstatus_t *rs = tor_malloc_zero(sizeof(vote_routerstatus_t));
if (routerstatus_parse_entry_from_string(rs_area, &s, rs_tokens, ns,
- rs, 0))
+ rs, 0, 0))
smartlist_add(ns->routerstatus_list, rs);
else {
tor_free(rs->version);
@@ -2466,7 +3061,8 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
routerstatus_t *rs;
if ((rs = routerstatus_parse_entry_from_string(rs_area, &s, rs_tokens,
NULL, NULL,
- ns->consensus_method)))
+ ns->consensus_method,
+ flav)))
smartlist_add(ns->routerstatus_list, rs);
}
}
@@ -2499,14 +3095,73 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
goto err;
}
- SMARTLIST_FOREACH(footer_tokens, directory_token_t *, _tok,
{
+ int found_sig = 0;
+ SMARTLIST_FOREACH_BEGIN(footer_tokens, directory_token_t *, _tok) {
+ tok = _tok;
+ if (tok->tp == K_DIRECTORY_SIGNATURE)
+ found_sig = 1;
+ else if (found_sig) {
+ log_warn(LD_DIR, "Extraneous token after first directory-signature");
+ goto err;
+ }
+ } SMARTLIST_FOREACH_END(_tok);
+ }
+
+ if ((tok = find_opt_by_keyword(footer_tokens, K_DIRECTORY_FOOTER))) {
+ if (tok != smartlist_get(footer_tokens, 0)) {
+ log_warn(LD_DIR, "Misplaced directory-footer token");
+ goto err;
+ }
+ }
+
+ tok = find_opt_by_keyword(footer_tokens, K_BW_WEIGHTS);
+ if (tok) {
+ ns->weight_params = smartlist_create();
+ for (i = 0; i < tok->n_args; ++i) {
+ int ok=0;
+ char *eq = strchr(tok->args[i], '=');
+ if (!eq) {
+ log_warn(LD_DIR, "Bad element '%s' in weight params",
+ escaped(tok->args[i]));
+ goto err;
+ }
+ tor_parse_long(eq+1, 10, INT32_MIN, INT32_MAX, &ok, NULL);
+ if (!ok) {
+ log_warn(LD_DIR, "Bad element '%s' in params", escaped(tok->args[i]));
+ goto err;
+ }
+ smartlist_add(ns->weight_params, tor_strdup(tok->args[i]));
+ }
+ }
+
+ SMARTLIST_FOREACH_BEGIN(footer_tokens, directory_token_t *, _tok) {
char declared_identity[DIGEST_LEN];
networkstatus_voter_info_t *v;
+ document_signature_t *sig;
+ const char *id_hexdigest = NULL;
+ const char *sk_hexdigest = NULL;
+ digest_algorithm_t alg = DIGEST_SHA1;
tok = _tok;
if (tok->tp != K_DIRECTORY_SIGNATURE)
continue;
tor_assert(tok->n_args >= 2);
+ if (tok->n_args == 2) {
+ id_hexdigest = tok->args[0];
+ sk_hexdigest = tok->args[1];
+ } else {
+ const char *algname = tok->args[0];
+ int a;
+ id_hexdigest = tok->args[1];
+ sk_hexdigest = tok->args[2];
+ a = crypto_digest_algorithm_parse_name(algname);
+ if (a<0) {
+ log_warn(LD_DIR, "Unknown digest algorithm %s; skipping",
+ escaped(algname));
+ continue;
+ }
+ alg = a;
+ }
if (!tok->object_type ||
strcmp(tok->object_type, "SIGNATURE") ||
@@ -2515,11 +3170,11 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
goto err;
}
- if (strlen(tok->args[0]) != HEX_DIGEST_LEN ||
+ if (strlen(id_hexdigest) != HEX_DIGEST_LEN ||
base16_decode(declared_identity, sizeof(declared_identity),
- tok->args[0], HEX_DIGEST_LEN) < 0) {
+ id_hexdigest, HEX_DIGEST_LEN) < 0) {
log_warn(LD_DIR, "Error decoding declared identity %s in "
- "network-status vote.", escaped(tok->args[0]));
+ "network-status vote.", escaped(id_hexdigest));
goto err;
}
if (!(v = networkstatus_get_voter_by_id(ns, declared_identity))) {
@@ -2527,11 +3182,15 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
"any declared directory source.");
goto err;
}
- if (strlen(tok->args[1]) != HEX_DIGEST_LEN ||
- base16_decode(v->signing_key_digest, sizeof(v->signing_key_digest),
- tok->args[1], HEX_DIGEST_LEN) < 0) {
- log_warn(LD_DIR, "Error decoding declared digest %s in "
- "network-status vote.", escaped(tok->args[1]));
+ sig = tor_malloc_zero(sizeof(document_signature_t));
+ memcpy(sig->identity_digest, v->identity_digest, DIGEST_LEN);
+ sig->alg = alg;
+ if (strlen(sk_hexdigest) != HEX_DIGEST_LEN ||
+ base16_decode(sig->signing_key_digest, sizeof(sig->signing_key_digest),
+ sk_hexdigest, HEX_DIGEST_LEN) < 0) {
+ log_warn(LD_DIR, "Error decoding declared signing key digest %s in "
+ "network-status vote.", escaped(sk_hexdigest));
+ tor_free(sig);
goto err;
}
@@ -2540,35 +3199,49 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
DIGEST_LEN)) {
log_warn(LD_DIR, "Digest mismatch between declared and actual on "
"network-status vote.");
+ tor_free(sig);
goto err;
}
}
+ if (voter_get_sig_by_algorithm(v, sig->alg)) {
+ /* We already parsed a vote with this algorithm from this voter. Use the
+ first one. */
+ log_fn(LOG_PROTOCOL_WARN, LD_DIR, "We received a networkstatus "
+ "that contains two votes from the same voter with the same "
+ "algorithm. Ignoring the second vote.");
+ tor_free(sig);
+ continue;
+ }
+
if (ns->type != NS_TYPE_CONSENSUS) {
- if (check_signature_token(ns_digest, tok, ns->cert->signing_key, 0,
- "network-status vote"))
+ if (check_signature_token(ns_digests.d[DIGEST_SHA1], DIGEST_LEN,
+ tok, ns->cert->signing_key, 0,
+ "network-status vote")) {
+ tor_free(sig);
goto err;
- v->good_signature = 1;
+ }
+ sig->good_signature = 1;
} else {
- if (tok->object_size >= INT_MAX)
+ if (tok->object_size >= INT_MAX) {
+ tor_free(sig);
goto err;
- /* We already parsed a vote from this voter. Use the first one. */
- if (v->signature) {
- log_fn(LOG_PROTOCOL_WARN, LD_DIR, "We received a networkstatus "
- "that contains two votes from the same voter. Ignoring "
- "the second vote.");
- continue;
}
-
- v->signature = tor_memdup(tok->object_body, tok->object_size);
- v->signature_len = (int) tok->object_size;
+ sig->signature = tor_memdup(tok->object_body, tok->object_size);
+ sig->signature_len = (int) tok->object_size;
}
+ smartlist_add(v->sigs, sig);
+
++n_signatures;
- });
+ } SMARTLIST_FOREACH_END(_tok);
if (! n_signatures) {
log_warn(LD_DIR, "No signatures on networkstatus vote.");
goto err;
+ } else if (ns->type == NS_TYPE_VOTE && n_signatures != 1) {
+ log_warn(LD_DIR, "Received more than one signature on a "
+ "network-status vote.");
+ goto err;
}
if (eos_out)
@@ -2576,27 +3249,31 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
goto done;
err:
- if (ns)
- networkstatus_vote_free(ns);
+ dump_desc(s_dup, "v3 networkstatus");
+ networkstatus_vote_free(ns);
ns = NULL;
done:
if (tokens) {
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
}
if (voter) {
+ if (voter->sigs) {
+ SMARTLIST_FOREACH(voter->sigs, document_signature_t *, sig,
+ document_signature_free(sig));
+ smartlist_free(voter->sigs);
+ }
tor_free(voter->nickname);
tor_free(voter->address);
tor_free(voter->contact);
- tor_free(voter->signature);
tor_free(voter);
}
if (rs_tokens) {
- SMARTLIST_FOREACH(rs_tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(rs_tokens, directory_token_t *, t, token_clear(t));
smartlist_free(rs_tokens);
}
if (footer_tokens) {
- SMARTLIST_FOREACH(footer_tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(footer_tokens, directory_token_t *, t, token_clear(t));
smartlist_free(footer_tokens);
}
if (area) {
@@ -2609,6 +3286,35 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
return ns;
}
+/** Return the digests_t that holds the digests of the
+ * <b>flavor_name</b>-flavored networkstatus according to the detached
+ * signatures document <b>sigs</b>, allocating a new digests_t as neeeded. */
+static digests_t *
+detached_get_digests(ns_detached_signatures_t *sigs, const char *flavor_name)
+{
+ digests_t *d = strmap_get(sigs->digests, flavor_name);
+ if (!d) {
+ d = tor_malloc_zero(sizeof(digests_t));
+ strmap_set(sigs->digests, flavor_name, d);
+ }
+ return d;
+}
+
+/** Return the list of signatures of the <b>flavor_name</b>-flavored
+ * networkstatus according to the detached signatures document <b>sigs</b>,
+ * allocating a new digests_t as neeeded. */
+static smartlist_t *
+detached_get_signatures(ns_detached_signatures_t *sigs,
+ const char *flavor_name)
+{
+ smartlist_t *sl = strmap_get(sigs->signatures, flavor_name);
+ if (!sl) {
+ sl = smartlist_create();
+ strmap_set(sigs->signatures, flavor_name, sl);
+ }
+ return sl;
+}
+
/** Parse a detached v3 networkstatus signature document between <b>s</b> and
* <b>eos</b> and return the result. Return -1 on failure. */
ns_detached_signatures_t *
@@ -2618,10 +3324,13 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos)
* networkstatus_parse_vote_from_string(). */
directory_token_t *tok;
memarea_t *area = NULL;
+ digests_t *digests;
smartlist_t *tokens = smartlist_create();
ns_detached_signatures_t *sigs =
tor_malloc_zero(sizeof(ns_detached_signatures_t));
+ sigs->digests = strmap_new();
+ sigs->signatures = strmap_new();
if (!eos)
eos = s + strlen(s);
@@ -2633,18 +3342,57 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos)
goto err;
}
- tok = find_by_keyword(tokens, K_CONSENSUS_DIGEST);
- if (strlen(tok->args[0]) != HEX_DIGEST_LEN) {
- log_warn(LD_DIR, "Wrong length on consensus-digest in detached "
- "networkstatus signatures");
- goto err;
- }
- if (base16_decode(sigs->networkstatus_digest, DIGEST_LEN,
- tok->args[0], strlen(tok->args[0])) < 0) {
- log_warn(LD_DIR, "Bad encoding on on consensus-digest in detached "
- "networkstatus signatures");
- goto err;
- }
+ /* Grab all the digest-like tokens. */
+ SMARTLIST_FOREACH_BEGIN(tokens, directory_token_t *, _tok) {
+ const char *algname;
+ digest_algorithm_t alg;
+ const char *flavor;
+ const char *hexdigest;
+ size_t expected_length;
+
+ tok = _tok;
+
+ if (tok->tp == K_CONSENSUS_DIGEST) {
+ algname = "sha1";
+ alg = DIGEST_SHA1;
+ flavor = "ns";
+ hexdigest = tok->args[0];
+ } else if (tok->tp == K_ADDITIONAL_DIGEST) {
+ int a = crypto_digest_algorithm_parse_name(tok->args[1]);
+ if (a<0) {
+ log_warn(LD_DIR, "Unrecognized algorithm name %s", tok->args[0]);
+ continue;
+ }
+ alg = (digest_algorithm_t) a;
+ flavor = tok->args[0];
+ algname = tok->args[1];
+ hexdigest = tok->args[2];
+ } else {
+ continue;
+ }
+
+ expected_length =
+ (alg == DIGEST_SHA1) ? HEX_DIGEST_LEN : HEX_DIGEST256_LEN;
+
+ if (strlen(hexdigest) != expected_length) {
+ log_warn(LD_DIR, "Wrong length on consensus-digest in detached "
+ "networkstatus signatures");
+ goto err;
+ }
+ digests = detached_get_digests(sigs, flavor);
+ tor_assert(digests);
+ if (!tor_mem_is_zero(digests->d[alg], DIGEST256_LEN)) {
+ log_warn(LD_DIR, "Multiple digests for %s with %s on detached "
+ "signatures document", flavor, algname);
+ continue;
+ }
+ if (base16_decode(digests->d[alg], DIGEST256_LEN,
+ hexdigest, strlen(hexdigest)) < 0) {
+ log_warn(LD_DIR, "Bad encoding on consensus-digest in detached "
+ "networkstatus signatures");
+ goto err;
+ }
+ } SMARTLIST_FOREACH_END(_tok);
tok = find_by_keyword(tokens, K_VALID_AFTER);
if (parse_iso_time(tok->args[0], &sigs->valid_after)) {
@@ -2664,57 +3412,102 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos)
goto err;
}
- sigs->signatures = smartlist_create();
- SMARTLIST_FOREACH(tokens, directory_token_t *, _tok,
- {
- char id_digest[DIGEST_LEN];
- char sk_digest[DIGEST_LEN];
- networkstatus_voter_info_t *voter;
+ SMARTLIST_FOREACH_BEGIN(tokens, directory_token_t *, _tok) {
+ const char *id_hexdigest;
+ const char *sk_hexdigest;
+ const char *algname;
+ const char *flavor;
+ digest_algorithm_t alg;
+
+ char id_digest[DIGEST_LEN];
+ char sk_digest[DIGEST_LEN];
+ smartlist_t *siglist;
+ document_signature_t *sig;
+ int is_duplicate;
- tok = _tok;
- if (tok->tp != K_DIRECTORY_SIGNATURE)
- continue;
+ tok = _tok;
+ if (tok->tp == K_DIRECTORY_SIGNATURE) {
tor_assert(tok->n_args >= 2);
+ flavor = "ns";
+ algname = "sha1";
+ id_hexdigest = tok->args[0];
+ sk_hexdigest = tok->args[1];
+ } else if (tok->tp == K_ADDITIONAL_SIGNATURE) {
+ tor_assert(tok->n_args >= 4);
+ flavor = tok->args[0];
+ algname = tok->args[1];
+ id_hexdigest = tok->args[2];
+ sk_hexdigest = tok->args[3];
+ } else {
+ continue;
+ }
- if (!tok->object_type ||
- strcmp(tok->object_type, "SIGNATURE") ||
- tok->object_size < 128 || tok->object_size > 512) {
- log_warn(LD_DIR, "Bad object type or length on directory-signature");
- goto err;
+ {
+ int a = crypto_digest_algorithm_parse_name(algname);
+ if (a<0) {
+ log_warn(LD_DIR, "Unrecognized algorithm name %s", algname);
+ continue;
}
+ alg = (digest_algorithm_t) a;
+ }
- if (strlen(tok->args[0]) != HEX_DIGEST_LEN ||
- base16_decode(id_digest, sizeof(id_digest),
- tok->args[0], HEX_DIGEST_LEN) < 0) {
- log_warn(LD_DIR, "Error decoding declared identity %s in "
- "network-status vote.", escaped(tok->args[0]));
- goto err;
- }
- if (strlen(tok->args[1]) != HEX_DIGEST_LEN ||
- base16_decode(sk_digest, sizeof(sk_digest),
- tok->args[1], HEX_DIGEST_LEN) < 0) {
- log_warn(LD_DIR, "Error decoding declared digest %s in "
- "network-status vote.", escaped(tok->args[1]));
- goto err;
- }
+ if (!tok->object_type ||
+ strcmp(tok->object_type, "SIGNATURE") ||
+ tok->object_size < 128 || tok->object_size > 512) {
+ log_warn(LD_DIR, "Bad object type or length on directory-signature");
+ goto err;
+ }
- voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
- memcpy(voter->identity_digest, id_digest, DIGEST_LEN);
- memcpy(voter->signing_key_digest, sk_digest, DIGEST_LEN);
- if (tok->object_size >= INT_MAX)
- goto err;
- voter->signature = tor_memdup(tok->object_body, tok->object_size);
- voter->signature_len = (int) tok->object_size;
+ if (strlen(id_hexdigest) != HEX_DIGEST_LEN ||
+ base16_decode(id_digest, sizeof(id_digest),
+ id_hexdigest, HEX_DIGEST_LEN) < 0) {
+ log_warn(LD_DIR, "Error decoding declared identity %s in "
+ "network-status vote.", escaped(id_hexdigest));
+ goto err;
+ }
+ if (strlen(sk_hexdigest) != HEX_DIGEST_LEN ||
+ base16_decode(sk_digest, sizeof(sk_digest),
+ sk_hexdigest, HEX_DIGEST_LEN) < 0) {
+ log_warn(LD_DIR, "Error decoding declared signing key digest %s in "
+ "network-status vote.", escaped(sk_hexdigest));
+ goto err;
+ }
- smartlist_add(sigs->signatures, voter);
+ siglist = detached_get_signatures(sigs, flavor);
+ is_duplicate = 0;
+ SMARTLIST_FOREACH(siglist, document_signature_t *, s, {
+ if (s->alg == alg &&
+ !memcmp(id_digest, s->identity_digest, DIGEST_LEN) &&
+ !memcmp(sk_digest, s->signing_key_digest, DIGEST_LEN)) {
+ is_duplicate = 1;
+ }
});
+ if (is_duplicate) {
+ log_warn(LD_DIR, "Two signatures with identical keys and algorithm "
+ "found.");
+ continue;
+ }
+
+ sig = tor_malloc_zero(sizeof(document_signature_t));
+ sig->alg = alg;
+ memcpy(sig->identity_digest, id_digest, DIGEST_LEN);
+ memcpy(sig->signing_key_digest, sk_digest, DIGEST_LEN);
+ if (tok->object_size >= INT_MAX) {
+ tor_free(sig);
+ goto err;
+ }
+ sig->signature = tor_memdup(tok->object_body, tok->object_size);
+ sig->signature_len = (int) tok->object_size;
+
+ smartlist_add(siglist, sig);
+ } SMARTLIST_FOREACH_END(_tok);
goto done;
err:
ns_detached_signatures_free(sigs);
sigs = NULL;
done:
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
if (area) {
DUMP_AREA(area, "detached signatures");
@@ -2770,7 +3563,7 @@ router_parse_addr_policy_item_from_string(const char *s, int assume_action)
err:
r = NULL;
done:
- token_free(tok);
+ token_clear(tok);
if (area) {
DUMP_AREA(area, "policy item");
memarea_drop_all(area);
@@ -2893,9 +3686,8 @@ assert_addr_policy_ok(smartlist_t *lst)
/** Free all resources allocated for <b>tok</b> */
static void
-token_free(directory_token_t *tok)
+token_clear(directory_token_t *tok)
{
- tor_assert(tok);
if (tok->key)
crypto_free_pk_env(tok->key);
}
@@ -2907,7 +3699,7 @@ token_free(directory_token_t *tok)
#define RET_ERR(msg) \
STMT_BEGIN \
- if (tok) token_free(tok); \
+ if (tok) token_clear(tok); \
tok = ALLOC_ZERO(sizeof(directory_token_t)); \
tok->tp = _ERR; \
tok->error = STRDUP(msg); \
@@ -3188,7 +3980,7 @@ tokenize_string(memarea_t *area,
tok = get_next_token(area, s, end, table);
if (tok->tp == _ERR) {
log_warn(LD_DIR, "parse error: %s", tok->error);
- token_free(tok);
+ token_clear(tok);
return -1;
}
++counts[tok->tp];
@@ -3302,17 +4094,11 @@ find_all_exitpolicy(smartlist_t *s)
return out;
}
-/** Compute the SHA-1 digest of the substring of <b>s</b> taken from the first
- * occurrence of <b>start_str</b> through the first instance of c after the
- * first subsequent occurrence of <b>end_str</b>; store the 20-byte result in
- * <b>digest</b>; return 0 on success.
- *
- * If no such substring exists, return -1.
- */
static int
-router_get_hash_impl(const char *s, size_t s_len, char *digest,
+router_get_hash_impl_helper(const char *s, size_t s_len,
const char *start_str,
- const char *end_str, char end_c)
+ const char *end_str, char end_c,
+ const char **start_out, const char **end_out)
{
const char *start, *end;
start = tor_memstr(s, s_len, start_str);
@@ -3339,14 +4125,214 @@ router_get_hash_impl(const char *s, size_t s_len, char *digest,
}
++end;
- if (crypto_digest(digest, start, end-start)) {
- log_warn(LD_BUG,"couldn't compute digest");
+ *start_out = start;
+ *end_out = end;
+ return 0;
+}
+
+/** Compute the digest of the substring of <b>s</b> taken from the first
+ * occurrence of <b>start_str</b> through the first instance of c after the
+ * first subsequent occurrence of <b>end_str</b>; store the 20-byte result in
+ * <b>digest</b>; return 0 on success.
+ *
+ * If no such substring exists, return -1.
+ */
+static int
+router_get_hash_impl(const char *s, size_t s_len, char *digest,
+ const char *start_str,
+ const char *end_str, char end_c,
+ digest_algorithm_t alg)
+{
+ const char *start=NULL, *end=NULL;
+ if (router_get_hash_impl_helper(s,s_len,start_str,end_str,end_c,
+ &start,&end)<0)
return -1;
+
+ if (alg == DIGEST_SHA1) {
+ if (crypto_digest(digest, start, end-start)) {
+ log_warn(LD_BUG,"couldn't compute digest");
+ return -1;
+ }
+ } else {
+ if (crypto_digest256(digest, start, end-start, alg)) {
+ log_warn(LD_BUG,"couldn't compute digest");
+ return -1;
+ }
}
return 0;
}
+/** As router_get_hash_impl, but compute all hashes. */
+static int
+router_get_hashes_impl(const char *s, size_t s_len, digests_t *digests,
+ const char *start_str,
+ const char *end_str, char end_c)
+{
+ const char *start=NULL, *end=NULL;
+ if (router_get_hash_impl_helper(s,s_len,start_str,end_str,end_c,
+ &start,&end)<0)
+ return -1;
+
+ if (crypto_digest_all(digests, start, end-start)) {
+ log_warn(LD_BUG,"couldn't compute digests");
+ return -1;
+ }
+
+ return 0;
+}
+
+/** Assuming that s starts with a microdesc, return the start of the
+ * *NEXT* one. Return NULL on "not found." */
+static const char *
+find_start_of_next_microdesc(const char *s, const char *eos)
+{
+ int started_with_annotations;
+ s = eat_whitespace_eos(s, eos);
+ if (!s)
+ return NULL;
+
+#define CHECK_LENGTH() STMT_BEGIN \
+ if (s+32 > eos) \
+ return NULL; \
+ STMT_END
+
+#define NEXT_LINE() STMT_BEGIN \
+ s = memchr(s, '\n', eos-s); \
+ if (!s || s+1 >= eos) \
+ return NULL; \
+ s++; \
+ STMT_END
+
+ CHECK_LENGTH();
+
+ started_with_annotations = (*s == '@');
+
+ if (started_with_annotations) {
+ /* Start by advancing to the first non-annotation line. */
+ while (*s == '@')
+ NEXT_LINE();
+ }
+ CHECK_LENGTH();
+
+ /* Now we should be pointed at an onion-key line. If we are, then skip
+ * it. */
+ if (!strcmpstart(s, "onion-key"))
+ NEXT_LINE();
+
+ /* Okay, now we're pointed at the first line of the microdescriptor which is
+ not an annotation or onion-key. The next line that _is_ an annotation or
+ onion-key is the start of the next microdescriptor. */
+ while (s+32 < eos) {
+ if (*s == '@' || !strcmpstart(s, "onion-key"))
+ return s;
+ NEXT_LINE();
+ }
+ return NULL;
+
+#undef CHECK_LENGTH
+#undef NEXT_LINE
+}
+
+/** Parse as many microdescriptors as are found from the string starting at
+ * <b>s</b> and ending at <b>eos</b>. If allow_annotations is set, read any
+ * annotations we recognize and ignore ones we don't. If <b>copy_body</b> is
+ * true, then strdup the bodies of the microdescriptors. Return all newly
+ * parsed microdescriptors in a newly allocated smartlist_t. */
+smartlist_t *
+microdescs_parse_from_string(const char *s, const char *eos,
+ int allow_annotations, int copy_body)
+{
+ smartlist_t *tokens;
+ smartlist_t *result;
+ microdesc_t *md = NULL;
+ memarea_t *area;
+ const char *start = s;
+ const char *start_of_next_microdesc;
+ int flags = allow_annotations ? TS_ANNOTATIONS_OK : 0;
+
+ directory_token_t *tok;
+
+ if (!eos)
+ eos = s + strlen(s);
+
+ s = eat_whitespace_eos(s, eos);
+ area = memarea_new();
+ result = smartlist_create();
+ tokens = smartlist_create();
+
+ while (s < eos) {
+ start_of_next_microdesc = find_start_of_next_microdesc(s, eos);
+ if (!start_of_next_microdesc)
+ start_of_next_microdesc = eos;
+
+ if (tokenize_string(area, s, start_of_next_microdesc, tokens,
+ microdesc_token_table, flags)) {
+ log_warn(LD_DIR, "Unparseable microdescriptor");
+ goto next;
+ }
+
+ md = tor_malloc_zero(sizeof(microdesc_t));
+ {
+ const char *cp = tor_memstr(s, start_of_next_microdesc-s,
+ "onion-key");
+ tor_assert(cp);
+
+ md->bodylen = start_of_next_microdesc - cp;
+ if (copy_body)
+ md->body = tor_strndup(cp, md->bodylen);
+ else
+ md->body = (char*)cp;
+ md->off = cp - start;
+ }
+
+ if ((tok = find_opt_by_keyword(tokens, A_LAST_LISTED))) {
+ if (parse_iso_time(tok->args[0], &md->last_listed)) {
+ log_warn(LD_DIR, "Bad last-listed time in microdescriptor");
+ goto next;
+ }
+ }
+
+ tok = find_by_keyword(tokens, K_ONION_KEY);
+ md->onion_pkey = tok->key;
+ tok->key = NULL;
+
+ if ((tok = find_opt_by_keyword(tokens, K_FAMILY))) {
+ int i;
+ md->family = smartlist_create();
+ for (i=0;i<tok->n_args;++i) {
+ if (!is_legal_nickname_or_hexdigest(tok->args[i])) {
+ log_warn(LD_DIR, "Illegal nickname %s in family line",
+ escaped(tok->args[i]));
+ goto next;
+ }
+ smartlist_add(md->family, tor_strdup(tok->args[i]));
+ }
+ }
+
+ if ((tok = find_opt_by_keyword(tokens, K_P))) {
+ md->exitsummary = tor_strdup(tok->args[0]);
+ }
+
+ crypto_digest256(md->digest, md->body, md->bodylen, DIGEST_SHA256);
+
+ smartlist_add(result, md);
+
+ md = NULL;
+ next:
+ microdesc_free(md);
+
+ memarea_clear(area);
+ smartlist_clear(tokens);
+ s = start_of_next_microdesc;
+ }
+
+ memarea_drop_all(area);
+ smartlist_free(tokens);
+
+ return result;
+}
+
/** Parse the Tor version of the platform string <b>platform</b>,
* and compare it to the version in <b>cutoff</b>. Return 1 if
* the router is at least as new as the cutoff, else return 0.
@@ -3371,7 +4357,7 @@ tor_version_as_new_as(const char *platform, const char *cutoff)
if (!*start) return 0;
s = (char *)find_whitespace(start); /* also finds '\0', which is fine */
s2 = (char*)eat_whitespace(s);
- if (!strcmpstart(s2, "(r"))
+ if (!strcmpstart(s2, "(r") || !strcmpstart(s2, "(git-"))
s = (char*)find_whitespace(s2);
if ((size_t)(s-start+1) >= sizeof(tmp)) /* too big, no */
@@ -3467,6 +4453,23 @@ tor_version_parse(const char *s, tor_version_t *out)
if (!strcmpstart(cp, "(r")) {
cp += 2;
out->svn_revision = (int) strtol(cp,&eos,10);
+ } else if (!strcmpstart(cp, "(git-")) {
+ char *close_paren = strchr(cp, ')');
+ int hexlen;
+ char digest[DIGEST_LEN];
+ if (! close_paren)
+ return -1;
+ cp += 5;
+ if (close_paren-cp > HEX_DIGEST_LEN)
+ return -1;
+ hexlen = (int)(close_paren-cp);
+ memset(digest, 0, sizeof(digest));
+ if ( hexlen == 0 || (hexlen % 2) == 1)
+ return -1;
+ if (base16_decode(digest, hexlen/2, cp, hexlen))
+ return -1;
+ memcpy(out->git_tag, digest, hexlen/2);
+ out->git_tag_len = hexlen/2;
}
return 0;
@@ -3492,8 +4495,14 @@ tor_version_compare(tor_version_t *a, tor_version_t *b)
return i;
else if ((i = strcmp(a->status_tag, b->status_tag)))
return i;
+ else if ((i = a->svn_revision - b->svn_revision))
+ return i;
+ else if ((i = a->git_tag_len - b->git_tag_len))
+ return i;
+ else if (a->git_tag_len)
+ return memcmp(a->git_tag, b->git_tag, a->git_tag_len);
else
- return a->svn_revision - b->svn_revision;
+ return 0;
}
/** Return true iff versions <b>a</b> and <b>b</b> belong to the same series.
@@ -3582,7 +4591,7 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
/* Compute descriptor hash for later validation. */
if (router_get_hash_impl(desc, strlen(desc), desc_hash,
"rendezvous-service-descriptor ",
- "\nsignature", '\n') < 0) {
+ "\nsignature", '\n', DIGEST_SHA1) < 0) {
log_warn(LD_REND, "Couldn't compute descriptor hash.");
goto err;
}
@@ -3701,7 +4710,7 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
/* Parse and verify signature. */
tok = find_by_keyword(tokens, R_SIGNATURE);
note_crypto_pk_op(VERIFY_RTR);
- if (check_signature_token(desc_hash, tok, result->pk, 0,
+ if (check_signature_token(desc_hash, DIGEST_LEN, tok, result->pk, 0,
"v2 rendezvous service descriptor") < 0)
goto err;
/* Verify that descriptor ID belongs to public key and secret ID part. */
@@ -3715,12 +4724,11 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
}
goto done;
err:
- if (result)
- rend_service_descriptor_free(result);
+ rend_service_descriptor_free(result);
result = NULL;
done:
if (tokens) {
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
}
if (area)
@@ -3878,7 +4886,7 @@ rend_parse_introduction_points(rend_service_descriptor_t *parsed,
eos = eos+1;
tor_assert(eos <= intro_points_encoded+intro_points_encoded_size);
/* Free tokens and clear token list. */
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_clear(tokens);
memarea_clear(area);
/* Tokenize string. */
@@ -3951,7 +4959,7 @@ rend_parse_introduction_points(rend_service_descriptor_t *parsed,
done:
/* Free tokens and clear token list. */
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
if (area)
memarea_drop_all(area);
@@ -3990,7 +4998,7 @@ rend_parse_client_keys(strmap_t *parsed_clients, const char *ckstr)
else
eos = eos + 1;
/* Free tokens and clear token list. */
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_clear(tokens);
memarea_clear(area);
/* Tokenize string. */
@@ -4062,7 +5070,7 @@ rend_parse_client_keys(strmap_t *parsed_clients, const char *ckstr)
result = -1;
done:
/* Free tokens and clear token list. */
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
if (area)
memarea_drop_all(area);
diff --git a/src/or/routerparse.h b/src/or/routerparse.h
new file mode 100644
index 0000000000..f41743bcfb
--- /dev/null
+++ b/src/or/routerparse.h
@@ -0,0 +1,88 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file routerpase.h
+ * \brief Header file for routerparse.c.
+ **/
+
+#ifndef _TOR_ROUTERPARSE_H
+#define _TOR_ROUTERPARSE_H
+
+int router_get_router_hash(const char *s, size_t s_len, char *digest);
+int router_get_dir_hash(const char *s, char *digest);
+int router_get_runningrouters_hash(const char *s, char *digest);
+int router_get_networkstatus_v2_hash(const char *s, char *digest);
+int router_get_networkstatus_v3_hash(const char *s, char *digest,
+ digest_algorithm_t algorithm);
+int router_get_networkstatus_v3_hashes(const char *s, digests_t *digests);
+int router_get_extrainfo_hash(const char *s, char *digest);
+#define DIROBJ_MAX_SIG_LEN 256
+int router_append_dirobj_signature(char *buf, size_t buf_len,
+ const char *digest,
+ size_t digest_len,
+ crypto_pk_env_t *private_key);
+int router_parse_list_from_string(const char **s, const char *eos,
+ smartlist_t *dest,
+ saved_location_t saved_location,
+ int is_extrainfo,
+ int allow_annotations,
+ const char *prepend_annotations);
+int router_parse_runningrouters(const char *str);
+int router_parse_directory(const char *str);
+
+routerinfo_t *router_parse_entry_from_string(const char *s, const char *end,
+ int cache_copy,
+ int allow_annotations,
+ const char *prepend_annotations);
+extrainfo_t *extrainfo_parse_entry_from_string(const char *s, const char *end,
+ int cache_copy, struct digest_ri_map_t *routermap);
+addr_policy_t *router_parse_addr_policy_item_from_string(const char *s,
+ int assume_action);
+version_status_t tor_version_is_obsolete(const char *myversion,
+ const char *versionlist);
+int tor_version_parse(const char *s, tor_version_t *out);
+int tor_version_as_new_as(const char *platform, const char *cutoff);
+int tor_version_compare(tor_version_t *a, tor_version_t *b);
+void sort_version_list(smartlist_t *lst, int remove_duplicates);
+void assert_addr_policy_ok(smartlist_t *t);
+void dump_distinct_digest_count(int severity);
+
+int compare_routerstatus_entries(const void **_a, const void **_b);
+networkstatus_v2_t *networkstatus_v2_parse_from_string(const char *s);
+int networkstatus_verify_bw_weights(networkstatus_t *ns);
+networkstatus_t *networkstatus_parse_vote_from_string(const char *s,
+ const char **eos_out,
+ networkstatus_type_t ns_type);
+ns_detached_signatures_t *networkstatus_parse_detached_signatures(
+ const char *s, const char *eos);
+
+smartlist_t *microdescs_parse_from_string(const char *s, const char *eos,
+ int allow_annotations,
+ int copy_body);
+
+authority_cert_t *authority_cert_parse_from_string(const char *s,
+ const char **end_of_string);
+int rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
+ char *desc_id_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);
+int rend_decrypt_introduction_points(char **ipos_decrypted,
+ size_t *ipos_decrypted_size,
+ const char *descriptor_cookie,
+ const char *ipos_encrypted,
+ size_t ipos_encrypted_size);
+int rend_parse_introduction_points(rend_service_descriptor_t *parsed,
+ const char *intro_points_encoded,
+ size_t intro_points_encoded_size);
+int rend_parse_client_keys(strmap_t *parsed_clients, const char *str);
+
+void tor_gettimeofday_cache_clear(void);
+
+#endif
+
diff --git a/src/or/test.c b/src/or/test.c
deleted file mode 100644
index 14ba953544..0000000000
--- a/src/or/test.c
+++ /dev/null
@@ -1,4911 +0,0 @@
-/* Copyright (c) 2001-2004, Roger Dingledine.
- * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2010, The Tor Project, Inc. */
-/* See LICENSE for licensing information */
-
-/* Ordinarily defined in tor_main.c; this bit is just here to provide one
- * since we're not linking to tor_main.c */
-const char tor_svn_revision[] = "";
-
-/**
- * \file test.c
- * \brief Unit tests for many pieces of the lower level Tor modules.
- **/
-
-#include "orconfig.h"
-
-#include <stdio.h>
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#ifdef MS_WINDOWS
-/* For mkdir() */
-#include <direct.h>
-#else
-#include <dirent.h>
-#endif
-
-/* These macros pull in declarations for some functions and structures that
- * are typically file-private. */
-#define BUFFERS_PRIVATE
-#define CONFIG_PRIVATE
-#define CONTROL_PRIVATE
-#define CRYPTO_PRIVATE
-#define DIRSERV_PRIVATE
-#define DIRVOTE_PRIVATE
-#define GEOIP_PRIVATE
-#define MEMPOOL_PRIVATE
-#define ROUTER_PRIVATE
-
-#include "or.h"
-#include "test.h"
-#include "torgzip.h"
-#include "mempool.h"
-#include "memarea.h"
-
-#ifdef USE_DMALLOC
-#include <dmalloc.h>
-#include <openssl/crypto.h>
-#endif
-
-/** Set to true if any unit test has failed. Mostly, this is set by the macros
- * in test.h */
-int have_failed = 0;
-
-/** Temporary directory (set up by setup_directory) under which we store all
- * our files during testing. */
-static char temp_dir[256];
-
-/** Select and create the temporary directory we'll use to run our unit tests.
- * Store it in <b>temp_dir</b>. Exit immediately if we can't create it.
- * idempotent. */
-static void
-setup_directory(void)
-{
- static int is_setup = 0;
- int r;
- if (is_setup) return;
-
-#ifdef MS_WINDOWS
- // XXXX
- tor_snprintf(temp_dir, sizeof(temp_dir),
- "c:\\windows\\temp\\tor_test_%d", (int)getpid());
- r = mkdir(temp_dir);
-#else
- tor_snprintf(temp_dir, sizeof(temp_dir), "/tmp/tor_test_%d", (int) getpid());
- r = mkdir(temp_dir, 0700);
-#endif
- if (r) {
- fprintf(stderr, "Can't create directory %s:", temp_dir);
- perror("");
- exit(1);
- }
- is_setup = 1;
-}
-
-/** Return a filename relative to our testing temporary directory */
-static const char *
-get_fname(const char *name)
-{
- static char buf[1024];
- setup_directory();
- tor_snprintf(buf,sizeof(buf),"%s/%s",temp_dir,name);
- return buf;
-}
-
-/** Remove all files stored under the temporary directory, and the directory
- * itself. */
-static void
-remove_directory(void)
-{
- smartlist_t *elements = tor_listdir(temp_dir);
- if (elements) {
- SMARTLIST_FOREACH(elements, const char *, cp,
- {
- size_t len = strlen(cp)+strlen(temp_dir)+16;
- char *tmp = tor_malloc(len);
- tor_snprintf(tmp, len, "%s"PATH_SEPARATOR"%s", temp_dir, cp);
- unlink(tmp);
- tor_free(tmp);
- });
- SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
- smartlist_free(elements);
- }
- rmdir(temp_dir);
-}
-
-/** Define this if unit tests spend too much time generating public keys*/
-#undef CACHE_GENERATED_KEYS
-
-static crypto_pk_env_t *pregen_keys[5] = {NULL, NULL, NULL, NULL, NULL};
-#define N_PREGEN_KEYS ((int)(sizeof(pregen_keys)/sizeof(pregen_keys[0])))
-
-/** Generate and return a new keypair for use in unit tests. If we're using
- * the key cache optimization, we might reuse keys: we only guarantee that
- * keys made with distinct values for <b>idx</b> are different. The value of
- * <b>idx</b> must be at least 0, and less than N_PREGEN_KEYS. */
-static crypto_pk_env_t *
-pk_generate(int idx)
-{
-#ifdef CACHE_GENERATED_KEYS
- tor_assert(idx < N_PREGEN_KEYS);
- if (! pregen_keys[idx]) {
- pregen_keys[idx] = crypto_new_pk_env();
- tor_assert(!crypto_pk_generate_key(pregen_keys[idx]));
- }
- return crypto_pk_dup_key(pregen_keys[idx]);
-#else
- crypto_pk_env_t *result;
- (void) idx;
- result = crypto_new_pk_env();
- tor_assert(!crypto_pk_generate_key(result));
- return result;
-#endif
-}
-
-/** Free all storage used for the cached key optimization. */
-static void
-free_pregenerated_keys(void)
-{
- unsigned idx;
- for (idx = 0; idx < N_PREGEN_KEYS; ++idx) {
- if (pregen_keys[idx]) {
- crypto_free_pk_env(pregen_keys[idx]);
- pregen_keys[idx] = NULL;
- }
- }
-}
-
-/** Run unit tests for buffers.c */
-static void
-test_buffers(void)
-{
- char str[256];
- char str2[256];
-
- buf_t *buf = NULL, *buf2 = NULL;
- const char *cp;
-
- int j;
- size_t r;
-
- /****
- * buf_new
- ****/
- if (!(buf = buf_new()))
- test_fail();
-
- //test_eq(buf_capacity(buf), 4096);
- test_eq(buf_datalen(buf), 0);
-
- /****
- * General pointer frobbing
- */
- for (j=0;j<256;++j) {
- str[j] = (char)j;
- }
- write_to_buf(str, 256, buf);
- write_to_buf(str, 256, buf);
- test_eq(buf_datalen(buf), 512);
- fetch_from_buf(str2, 200, buf);
- test_memeq(str, str2, 200);
- test_eq(buf_datalen(buf), 312);
- memset(str2, 0, sizeof(str2));
-
- fetch_from_buf(str2, 256, buf);
- test_memeq(str+200, str2, 56);
- test_memeq(str, str2+56, 200);
- test_eq(buf_datalen(buf), 56);
- memset(str2, 0, sizeof(str2));
- /* Okay, now we should be 512 bytes into the 4096-byte buffer. If we add
- * another 3584 bytes, we hit the end. */
- for (j=0;j<15;++j) {
- write_to_buf(str, 256, buf);
- }
- assert_buf_ok(buf);
- test_eq(buf_datalen(buf), 3896);
- fetch_from_buf(str2, 56, buf);
- test_eq(buf_datalen(buf), 3840);
- test_memeq(str+200, str2, 56);
- for (j=0;j<15;++j) {
- memset(str2, 0, sizeof(str2));
- fetch_from_buf(str2, 256, buf);
- test_memeq(str, str2, 256);
- }
- test_eq(buf_datalen(buf), 0);
- buf_free(buf);
- buf = NULL;
-
- /* Okay, now make sure growing can work. */
- buf = buf_new_with_capacity(16);
- //test_eq(buf_capacity(buf), 16);
- write_to_buf(str+1, 255, buf);
- //test_eq(buf_capacity(buf), 256);
- fetch_from_buf(str2, 254, buf);
- test_memeq(str+1, str2, 254);
- //test_eq(buf_capacity(buf), 256);
- assert_buf_ok(buf);
- write_to_buf(str, 32, buf);
- //test_eq(buf_capacity(buf), 256);
- assert_buf_ok(buf);
- write_to_buf(str, 256, buf);
- assert_buf_ok(buf);
- //test_eq(buf_capacity(buf), 512);
- test_eq(buf_datalen(buf), 33+256);
- fetch_from_buf(str2, 33, buf);
- test_eq(*str2, str[255]);
-
- test_memeq(str2+1, str, 32);
- //test_eq(buf_capacity(buf), 512);
- test_eq(buf_datalen(buf), 256);
- fetch_from_buf(str2, 256, buf);
- test_memeq(str, str2, 256);
-
- /* now try shrinking: case 1. */
- buf_free(buf);
- buf = buf_new_with_capacity(33668);
- for (j=0;j<67;++j) {
- write_to_buf(str,255, buf);
- }
- //test_eq(buf_capacity(buf), 33668);
- test_eq(buf_datalen(buf), 17085);
- for (j=0; j < 40; ++j) {
- fetch_from_buf(str2, 255,buf);
- test_memeq(str2, str, 255);
- }
-
- /* now try shrinking: case 2. */
- buf_free(buf);
- buf = buf_new_with_capacity(33668);
- for (j=0;j<67;++j) {
- write_to_buf(str,255, buf);
- }
- for (j=0; j < 20; ++j) {
- fetch_from_buf(str2, 255,buf);
- test_memeq(str2, str, 255);
- }
- for (j=0;j<80;++j) {
- write_to_buf(str,255, buf);
- }
- //test_eq(buf_capacity(buf),33668);
- for (j=0; j < 120; ++j) {
- fetch_from_buf(str2, 255,buf);
- test_memeq(str2, str, 255);
- }
-
- /* Move from buf to buf. */
- buf_free(buf);
- buf = buf_new_with_capacity(4096);
- buf2 = buf_new_with_capacity(4096);
- for (j=0;j<100;++j)
- write_to_buf(str, 255, buf);
- test_eq(buf_datalen(buf), 25500);
- for (j=0;j<100;++j) {
- r = 10;
- move_buf_to_buf(buf2, buf, &r);
- test_eq(r, 0);
- }
- test_eq(buf_datalen(buf), 24500);
- test_eq(buf_datalen(buf2), 1000);
- for (j=0;j<3;++j) {
- fetch_from_buf(str2, 255, buf2);
- test_memeq(str2, str, 255);
- }
- r = 8192; /*big move*/
- move_buf_to_buf(buf2, buf, &r);
- test_eq(r, 0);
- r = 30000; /* incomplete move */
- move_buf_to_buf(buf2, buf, &r);
- test_eq(r, 13692);
- for (j=0;j<97;++j) {
- fetch_from_buf(str2, 255, buf2);
- test_memeq(str2, str, 255);
- }
- buf_free(buf);
- buf_free(buf2);
- buf = buf2 = NULL;
-
- buf = buf_new_with_capacity(5);
- cp = "Testing. This is a moderately long Testing string.";
- for (j = 0; cp[j]; j++)
- write_to_buf(cp+j, 1, buf);
- test_eq(0, buf_find_string_offset(buf, "Testing", 7));
- test_eq(1, buf_find_string_offset(buf, "esting", 6));
- test_eq(1, buf_find_string_offset(buf, "est", 3));
- test_eq(39, buf_find_string_offset(buf, "ing str", 7));
- test_eq(35, buf_find_string_offset(buf, "Testing str", 11));
- test_eq(32, buf_find_string_offset(buf, "ng ", 3));
- test_eq(43, buf_find_string_offset(buf, "string.", 7));
- test_eq(-1, buf_find_string_offset(buf, "shrdlu", 6));
- test_eq(-1, buf_find_string_offset(buf, "Testing thing", 13));
- test_eq(-1, buf_find_string_offset(buf, "ngx", 3));
- buf_free(buf);
- buf = NULL;
-
-#if 0
- {
- int s;
- int eof;
- int i;
- buf_t *buf2;
- /****
- * read_to_buf
- ****/
- s = open(get_fname("data"), O_WRONLY|O_CREAT|O_TRUNC, 0600);
- write(s, str, 256);
- close(s);
-
- s = open(get_fname("data"), O_RDONLY, 0);
- eof = 0;
- errno = 0; /* XXXX */
- i = read_to_buf(s, 10, buf, &eof);
- printf("%s\n", strerror(errno));
- test_eq(i, 10);
- test_eq(eof, 0);
- //test_eq(buf_capacity(buf), 4096);
- test_eq(buf_datalen(buf), 10);
-
- test_memeq(str, (char*)_buf_peek_raw_buffer(buf), 10);
-
- /* Test reading 0 bytes. */
- i = read_to_buf(s, 0, buf, &eof);
- //test_eq(buf_capacity(buf), 512*1024);
- test_eq(buf_datalen(buf), 10);
- test_eq(eof, 0);
- test_eq(i, 0);
-
- /* Now test when buffer is filled exactly. */
- buf2 = buf_new_with_capacity(6);
- i = read_to_buf(s, 6, buf2, &eof);
- //test_eq(buf_capacity(buf2), 6);
- test_eq(buf_datalen(buf2), 6);
- test_eq(eof, 0);
- test_eq(i, 6);
- test_memeq(str+10, (char*)_buf_peek_raw_buffer(buf2), 6);
- buf_free(buf2);
- buf2 = NULL;
-
- /* Now test when buffer is filled with more data to read. */
- buf2 = buf_new_with_capacity(32);
- i = read_to_buf(s, 128, buf2, &eof);
- //test_eq(buf_capacity(buf2), 128);
- test_eq(buf_datalen(buf2), 32);
- test_eq(eof, 0);
- test_eq(i, 32);
- buf_free(buf2);
- buf2 = NULL;
-
- /* Now read to eof. */
- test_assert(buf_capacity(buf) > 256);
- i = read_to_buf(s, 1024, buf, &eof);
- test_eq(i, (256-32-10-6));
- test_eq(buf_capacity(buf), MAX_BUF_SIZE);
- test_eq(buf_datalen(buf), 256-6-32);
- test_memeq(str, (char*)_buf_peek_raw_buffer(buf), 10); /* XXX Check rest. */
- test_eq(eof, 0);
-
- i = read_to_buf(s, 1024, buf, &eof);
- test_eq(i, 0);
- test_eq(buf_capacity(buf), MAX_BUF_SIZE);
- test_eq(buf_datalen(buf), 256-6-32);
- test_eq(eof, 1);
- }
-#endif
-
- done:
- if (buf)
- buf_free(buf);
- if (buf2)
- buf_free(buf2);
-}
-
-/** Run unit tests for Diffie-Hellman functionality. */
-static void
-test_crypto_dh(void)
-{
- crypto_dh_env_t *dh1 = crypto_dh_new();
- crypto_dh_env_t *dh2 = crypto_dh_new();
- char p1[DH_BYTES];
- char p2[DH_BYTES];
- char s1[DH_BYTES];
- char s2[DH_BYTES];
- ssize_t s1len, s2len;
-
- test_eq(crypto_dh_get_bytes(dh1), DH_BYTES);
- test_eq(crypto_dh_get_bytes(dh2), DH_BYTES);
-
- memset(p1, 0, DH_BYTES);
- memset(p2, 0, DH_BYTES);
- test_memeq(p1, p2, DH_BYTES);
- test_assert(! crypto_dh_get_public(dh1, p1, DH_BYTES));
- test_memneq(p1, p2, DH_BYTES);
- test_assert(! crypto_dh_get_public(dh2, p2, DH_BYTES));
- test_memneq(p1, p2, DH_BYTES);
-
- memset(s1, 0, DH_BYTES);
- memset(s2, 0xFF, DH_BYTES);
- s1len = crypto_dh_compute_secret(dh1, p2, DH_BYTES, s1, 50);
- s2len = crypto_dh_compute_secret(dh2, p1, DH_BYTES, s2, 50);
- test_assert(s1len > 0);
- test_eq(s1len, s2len);
- test_memeq(s1, s2, s1len);
-
- {
- /* XXXX Now fabricate some bad values and make sure they get caught,
- * Check 0, 1, N-1, >= N, etc.
- */
- }
-
- done:
- crypto_dh_free(dh1);
- crypto_dh_free(dh2);
-}
-
-/** Run unit tests for our random number generation function and its wrappers.
- */
-static void
-test_crypto_rng(void)
-{
- int i, j, allok;
- char data1[100], data2[100];
-
- /* Try out RNG. */
- test_assert(! crypto_seed_rng(0));
- crypto_rand(data1, 100);
- crypto_rand(data2, 100);
- test_memneq(data1,data2,100);
- allok = 1;
- for (i = 0; i < 100; ++i) {
- uint64_t big;
- char *host;
- j = crypto_rand_int(100);
- if (i < 0 || i >= 100)
- allok = 0;
- big = crypto_rand_uint64(U64_LITERAL(1)<<40);
- if (big >= (U64_LITERAL(1)<<40))
- allok = 0;
- big = crypto_rand_uint64(U64_LITERAL(5));
- if (big >= 5)
- allok = 0;
- host = crypto_random_hostname(3,8,"www.",".onion");
- if (strcmpstart(host,"www.") ||
- strcmpend(host,".onion") ||
- strlen(host) < 13 ||
- strlen(host) > 18)
- allok = 0;
- tor_free(host);
- }
- test_assert(allok);
- done:
- ;
-}
-
-/** Run unit tests for our AES functionality */
-static void
-test_crypto_aes(void)
-{
- char *data1 = NULL, *data2 = NULL, *data3 = NULL;
- crypto_cipher_env_t *env1 = NULL, *env2 = NULL;
- int i, j;
-
- data1 = tor_malloc(1024);
- data2 = tor_malloc(1024);
- data3 = tor_malloc(1024);
-
- /* Now, test encryption and decryption with stream cipher. */
- data1[0]='\0';
- for (i = 1023; i>0; i -= 35)
- strncat(data1, "Now is the time for all good onions", i);
-
- memset(data2, 0, 1024);
- memset(data3, 0, 1024);
- env1 = crypto_new_cipher_env();
- test_neq(env1, 0);
- env2 = crypto_new_cipher_env();
- test_neq(env2, 0);
- j = crypto_cipher_generate_key(env1);
- crypto_cipher_set_key(env2, crypto_cipher_get_key(env1));
- crypto_cipher_encrypt_init_cipher(env1);
- crypto_cipher_decrypt_init_cipher(env2);
-
- /* Try encrypting 512 chars. */
- crypto_cipher_encrypt(env1, data2, data1, 512);
- crypto_cipher_decrypt(env2, data3, data2, 512);
- test_memeq(data1, data3, 512);
- test_memneq(data1, data2, 512);
-
- /* Now encrypt 1 at a time, and get 1 at a time. */
- for (j = 512; j < 560; ++j) {
- crypto_cipher_encrypt(env1, data2+j, data1+j, 1);
- }
- for (j = 512; j < 560; ++j) {
- crypto_cipher_decrypt(env2, data3+j, data2+j, 1);
- }
- test_memeq(data1, data3, 560);
- /* Now encrypt 3 at a time, and get 5 at a time. */
- for (j = 560; j < 1024-5; j += 3) {
- crypto_cipher_encrypt(env1, data2+j, data1+j, 3);
- }
- for (j = 560; j < 1024-5; j += 5) {
- crypto_cipher_decrypt(env2, data3+j, data2+j, 5);
- }
- test_memeq(data1, data3, 1024-5);
- /* Now make sure that when we encrypt with different chunk sizes, we get
- the same results. */
- crypto_free_cipher_env(env2);
- env2 = NULL;
-
- memset(data3, 0, 1024);
- env2 = crypto_new_cipher_env();
- test_neq(env2, 0);
- crypto_cipher_set_key(env2, crypto_cipher_get_key(env1));
- crypto_cipher_encrypt_init_cipher(env2);
- for (j = 0; j < 1024-16; j += 17) {
- crypto_cipher_encrypt(env2, data3+j, data1+j, 17);
- }
- for (j= 0; j < 1024-16; ++j) {
- if (data2[j] != data3[j]) {
- printf("%d: %d\t%d\n", j, (int) data2[j], (int) data3[j]);
- }
- }
- test_memeq(data2, data3, 1024-16);
- crypto_free_cipher_env(env1);
- env1 = NULL;
- crypto_free_cipher_env(env2);
- env2 = NULL;
-
- /* NIST test vector for aes. */
- env1 = crypto_new_cipher_env(); /* IV starts at 0 */
- crypto_cipher_set_key(env1, "\x80\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00");
- crypto_cipher_encrypt_init_cipher(env1);
- crypto_cipher_encrypt(env1, data1,
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00", 16);
- test_memeq_hex(data1, "0EDD33D3C621E546455BD8BA1418BEC8");
-
- /* Now test rollover. All these values are originally from a python
- * script. */
- crypto_cipher_set_iv(env1, "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\xff\xff\xff\xff\xff\xff\xff\xff");
- memset(data2, 0, 1024);
- crypto_cipher_encrypt(env1, data1, data2, 32);
- test_memeq_hex(data1, "335fe6da56f843199066c14a00a40231"
- "cdd0b917dbc7186908a6bfb5ffd574d3");
-
- crypto_cipher_set_iv(env1, "\x00\x00\x00\x00\xff\xff\xff\xff"
- "\xff\xff\xff\xff\xff\xff\xff\xff");
- memset(data2, 0, 1024);
- crypto_cipher_encrypt(env1, data1, data2, 32);
- test_memeq_hex(data1, "e627c6423fa2d77832a02b2794094b73"
- "3e63c721df790d2c6469cc1953a3ffac");
-
- crypto_cipher_set_iv(env1, "\xff\xff\xff\xff\xff\xff\xff\xff"
- "\xff\xff\xff\xff\xff\xff\xff\xff");
- memset(data2, 0, 1024);
- crypto_cipher_encrypt(env1, data1, data2, 32);
- test_memeq_hex(data1, "2aed2bff0de54f9328efd070bf48f70a"
- "0EDD33D3C621E546455BD8BA1418BEC8");
-
- /* Now check rollover on inplace cipher. */
- crypto_cipher_set_iv(env1, "\xff\xff\xff\xff\xff\xff\xff\xff"
- "\xff\xff\xff\xff\xff\xff\xff\xff");
- crypto_cipher_crypt_inplace(env1, data2, 64);
- test_memeq_hex(data2, "2aed2bff0de54f9328efd070bf48f70a"
- "0EDD33D3C621E546455BD8BA1418BEC8"
- "93e2c5243d6839eac58503919192f7ae"
- "1908e67cafa08d508816659c2e693191");
- crypto_cipher_set_iv(env1, "\xff\xff\xff\xff\xff\xff\xff\xff"
- "\xff\xff\xff\xff\xff\xff\xff\xff");
- crypto_cipher_crypt_inplace(env1, data2, 64);
- test_assert(tor_mem_is_zero(data2, 64));
-
- done:
- if (env1)
- crypto_free_cipher_env(env1);
- if (env2)
- crypto_free_cipher_env(env2);
- tor_free(data1);
- tor_free(data2);
- tor_free(data3);
-}
-
-/** Run unit tests for our SHA-1 functionality */
-static void
-test_crypto_sha(void)
-{
- crypto_digest_env_t *d1 = NULL, *d2 = NULL;
- int i;
- char key[80];
- char digest[20];
- char data[50];
- char d_out1[DIGEST_LEN], d_out2[DIGEST_LEN];
-
- /* Test SHA-1 with a test vector from the specification. */
- i = crypto_digest(data, "abc", 3);
- test_memeq_hex(data, "A9993E364706816ABA3E25717850C26C9CD0D89D");
-
- /* Test HMAC-SHA-1 with test cases from RFC2202. */
-
- /* Case 1. */
- memset(key, 0x0b, 20);
- crypto_hmac_sha1(digest, key, 20, "Hi There", 8);
- test_streq(hex_str(digest, 20),
- "B617318655057264E28BC0B6FB378C8EF146BE00");
- /* Case 2. */
- crypto_hmac_sha1(digest, "Jefe", 4, "what do ya want for nothing?", 28);
- test_streq(hex_str(digest, 20),
- "EFFCDF6AE5EB2FA2D27416D5F184DF9C259A7C79");
-
- /* Case 4. */
- base16_decode(key, 25,
- "0102030405060708090a0b0c0d0e0f10111213141516171819", 50);
- memset(data, 0xcd, 50);
- crypto_hmac_sha1(digest, key, 25, data, 50);
- test_streq(hex_str(digest, 20),
- "4C9007F4026250C6BC8414F9BF50C86C2D7235DA");
-
- /* Case . */
- memset(key, 0xaa, 80);
- crypto_hmac_sha1(digest, key, 80,
- "Test Using Larger Than Block-Size Key - Hash Key First",
- 54);
- test_streq(hex_str(digest, 20),
- "AA4AE5E15272D00E95705637CE8A3B55ED402112");
-
- /* Incremental digest code. */
- d1 = crypto_new_digest_env();
- test_assert(d1);
- crypto_digest_add_bytes(d1, "abcdef", 6);
- d2 = crypto_digest_dup(d1);
- test_assert(d2);
- crypto_digest_add_bytes(d2, "ghijkl", 6);
- crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
- crypto_digest(d_out2, "abcdefghijkl", 12);
- test_memeq(d_out1, d_out2, DIGEST_LEN);
- crypto_digest_assign(d2, d1);
- crypto_digest_add_bytes(d2, "mno", 3);
- crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
- crypto_digest(d_out2, "abcdefmno", 9);
- test_memeq(d_out1, d_out2, DIGEST_LEN);
- crypto_digest_get_digest(d1, d_out1, sizeof(d_out1));
- crypto_digest(d_out2, "abcdef", 6);
- test_memeq(d_out1, d_out2, DIGEST_LEN);
-
- done:
- if (d1)
- crypto_free_digest_env(d1);
- if (d2)
- crypto_free_digest_env(d2);
-}
-
-/** Run unit tests for our public key crypto functions */
-static void
-test_crypto_pk(void)
-{
- crypto_pk_env_t *pk1 = NULL, *pk2 = NULL;
- char *encoded = NULL;
- char data1[1024], data2[1024], data3[1024];
- size_t size;
- int i, j, p, len;
-
- /* Public-key ciphers */
- pk1 = pk_generate(0);
- pk2 = crypto_new_pk_env();
- test_assert(pk1 && pk2);
- test_assert(! crypto_pk_write_public_key_to_string(pk1, &encoded, &size));
- test_assert(! crypto_pk_read_public_key_from_string(pk2, encoded, size));
- test_eq(0, crypto_pk_cmp_keys(pk1, pk2));
-
- test_eq(128, crypto_pk_keysize(pk1));
- test_eq(128, crypto_pk_keysize(pk2));
-
- test_eq(128, crypto_pk_public_encrypt(pk2, data1, "Hello whirled.", 15,
- PK_PKCS1_OAEP_PADDING));
- test_eq(128, crypto_pk_public_encrypt(pk1, data2, "Hello whirled.", 15,
- PK_PKCS1_OAEP_PADDING));
- /* oaep padding should make encryption not match */
- test_memneq(data1, data2, 128);
- test_eq(15, crypto_pk_private_decrypt(pk1, data3, data1, 128,
- PK_PKCS1_OAEP_PADDING,1));
- test_streq(data3, "Hello whirled.");
- memset(data3, 0, 1024);
- test_eq(15, crypto_pk_private_decrypt(pk1, data3, data2, 128,
- PK_PKCS1_OAEP_PADDING,1));
- test_streq(data3, "Hello whirled.");
- /* Can't decrypt with public key. */
- test_eq(-1, crypto_pk_private_decrypt(pk2, data3, data2, 128,
- PK_PKCS1_OAEP_PADDING,1));
- /* Try again with bad padding */
- memcpy(data2+1, "XYZZY", 5); /* This has fails ~ once-in-2^40 */
- test_eq(-1, crypto_pk_private_decrypt(pk1, data3, data2, 128,
- PK_PKCS1_OAEP_PADDING,1));
-
- /* File operations: save and load private key */
- test_assert(! crypto_pk_write_private_key_to_filename(pk1,
- get_fname("pkey1")));
- /* failing case for read: can't read. */
- test_assert(crypto_pk_read_private_key_from_filename(pk2,
- get_fname("xyzzy")) < 0);
- write_str_to_file(get_fname("xyzzy"), "foobar", 6);
- /* Failing case for read: no key. */
- test_assert(crypto_pk_read_private_key_from_filename(pk2,
- get_fname("xyzzy")) < 0);
- test_assert(! crypto_pk_read_private_key_from_filename(pk2,
- get_fname("pkey1")));
- test_eq(15, crypto_pk_private_decrypt(pk2, data3, data1, 128,
- PK_PKCS1_OAEP_PADDING,1));
-
- /* Now try signing. */
- strlcpy(data1, "Ossifrage", 1024);
- test_eq(128, crypto_pk_private_sign(pk1, data2, data1, 10));
- test_eq(10, crypto_pk_public_checksig(pk1, data3, data2, 128));
- test_streq(data3, "Ossifrage");
- /* Try signing digests. */
- test_eq(128, crypto_pk_private_sign_digest(pk1, data2, data1, 10));
- test_eq(20, crypto_pk_public_checksig(pk1, data3, data2, 128));
- test_eq(0, crypto_pk_public_checksig_digest(pk1, data1, 10, data2, 128));
- test_eq(-1, crypto_pk_public_checksig_digest(pk1, data1, 11, data2, 128));
- /*XXXX test failed signing*/
-
- /* Try encoding */
- crypto_free_pk_env(pk2);
- pk2 = NULL;
- i = crypto_pk_asn1_encode(pk1, data1, 1024);
- test_assert(i>0);
- pk2 = crypto_pk_asn1_decode(data1, i);
- test_assert(crypto_pk_cmp_keys(pk1,pk2) == 0);
-
- /* Try with hybrid encryption wrappers. */
- crypto_rand(data1, 1024);
- for (i = 0; i < 3; ++i) {
- for (j = 85; j < 140; ++j) {
- memset(data2,0,1024);
- memset(data3,0,1024);
- if (i == 0 && j < 129)
- continue;
- p = (i==0)?PK_NO_PADDING:
- (i==1)?PK_PKCS1_PADDING:PK_PKCS1_OAEP_PADDING;
- len = crypto_pk_public_hybrid_encrypt(pk1,data2,data1,j,p,0);
- test_assert(len>=0);
- len = crypto_pk_private_hybrid_decrypt(pk1,data3,data2,len,p,1);
- test_eq(len,j);
- test_memeq(data1,data3,j);
- }
- }
-
- /* Try copy_full */
- crypto_free_pk_env(pk2);
- pk2 = crypto_pk_copy_full(pk1);
- test_assert(pk2 != NULL);
- test_neq_ptr(pk1, pk2);
- test_assert(crypto_pk_cmp_keys(pk1,pk2) == 0);
-
- done:
- if (pk1)
- crypto_free_pk_env(pk1);
- if (pk2)
- crypto_free_pk_env(pk2);
- tor_free(encoded);
-}
-
-/** Run unit tests for misc crypto functionality. */
-static void
-test_crypto(void)
-{
- char *data1 = NULL, *data2 = NULL, *data3 = NULL;
- int i, j, idx;
-
- data1 = tor_malloc(1024);
- data2 = tor_malloc(1024);
- data3 = tor_malloc(1024);
- test_assert(data1 && data2 && data3);
-
- /* Base64 tests */
- memset(data1, 6, 1024);
- for (idx = 0; idx < 10; ++idx) {
- i = base64_encode(data2, 1024, data1, idx);
- test_assert(i >= 0);
- j = base64_decode(data3, 1024, data2, i);
- test_eq(j,idx);
- test_memeq(data3, data1, idx);
- }
-
- strlcpy(data1, "Test string that contains 35 chars.", 1024);
- strlcat(data1, " 2nd string that contains 35 chars.", 1024);
-
- i = base64_encode(data2, 1024, data1, 71);
- j = base64_decode(data3, 1024, data2, i);
- test_eq(j, 71);
- test_streq(data3, data1);
- test_assert(data2[i] == '\0');
-
- crypto_rand(data1, DIGEST_LEN);
- memset(data2, 100, 1024);
- digest_to_base64(data2, data1);
- test_eq(BASE64_DIGEST_LEN, strlen(data2));
- test_eq(100, data2[BASE64_DIGEST_LEN+2]);
- memset(data3, 99, 1024);
- test_eq(digest_from_base64(data3, data2), 0);
- test_memeq(data1, data3, DIGEST_LEN);
- test_eq(99, data3[DIGEST_LEN+1]);
-
- test_assert(digest_from_base64(data3, "###") < 0);
-
- /* Base32 tests */
- strlcpy(data1, "5chrs", 1024);
- /* bit pattern is: [35 63 68 72 73] ->
- * [00110101 01100011 01101000 01110010 01110011]
- * By 5s: [00110 10101 10001 10110 10000 11100 10011 10011]
- */
- base32_encode(data2, 9, data1, 5);
- test_streq(data2, "gvrwq4tt");
-
- strlcpy(data1, "\xFF\xF5\x6D\x44\xAE\x0D\x5C\xC9\x62\xC4", 1024);
- base32_encode(data2, 30, data1, 10);
- test_streq(data2, "772w2rfobvomsywe");
-
- /* Base16 tests */
- strlcpy(data1, "6chrs\xff", 1024);
- base16_encode(data2, 13, data1, 6);
- test_streq(data2, "3663687273FF");
-
- strlcpy(data1, "f0d678affc000100", 1024);
- i = base16_decode(data2, 8, data1, 16);
- test_eq(i,0);
- test_memeq(data2, "\xf0\xd6\x78\xaf\xfc\x00\x01\x00",8);
-
- /* now try some failing base16 decodes */
- test_eq(-1, base16_decode(data2, 8, data1, 15)); /* odd input len */
- test_eq(-1, base16_decode(data2, 7, data1, 16)); /* dest too short */
- strlcpy(data1, "f0dz!8affc000100", 1024);
- test_eq(-1, base16_decode(data2, 8, data1, 16));
-
- tor_free(data1);
- tor_free(data2);
- tor_free(data3);
-
- /* Add spaces to fingerprint */
- {
- data1 = tor_strdup("ABCD1234ABCD56780000ABCD1234ABCD56780000");
- test_eq(strlen(data1), 40);
- data2 = tor_malloc(FINGERPRINT_LEN+1);
- add_spaces_to_fp(data2, FINGERPRINT_LEN+1, data1);
- test_streq(data2, "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 0000");
- tor_free(data1);
- tor_free(data2);
- }
-
- /* Check fingerprint */
- {
- test_assert(crypto_pk_check_fingerprint_syntax(
- "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 0000"));
- test_assert(!crypto_pk_check_fingerprint_syntax(
- "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 000"));
- test_assert(!crypto_pk_check_fingerprint_syntax(
- "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 00000"));
- test_assert(!crypto_pk_check_fingerprint_syntax(
- "ABCD 1234 ABCD 5678 0000 ABCD1234 ABCD 5678 0000"));
- test_assert(!crypto_pk_check_fingerprint_syntax(
- "ABCD 1234 ABCD 5678 0000 ABCD1234 ABCD 5678 00000"));
- test_assert(!crypto_pk_check_fingerprint_syntax(
- "ACD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 00000"));
- }
-
- done:
- tor_free(data1);
- tor_free(data2);
- tor_free(data3);
-}
-
-/** Run unit tests for our secret-to-key passphrase hashing functionality. */
-static void
-test_crypto_s2k(void)
-{
- char buf[29];
- char buf2[29];
- char *buf3 = NULL;
- int i;
-
- memset(buf, 0, sizeof(buf));
- memset(buf2, 0, sizeof(buf2));
- buf3 = tor_malloc(65536);
- memset(buf3, 0, 65536);
-
- secret_to_key(buf+9, 20, "", 0, buf);
- crypto_digest(buf2+9, buf3, 1024);
- test_memeq(buf, buf2, 29);
-
- memcpy(buf,"vrbacrda",8);
- memcpy(buf2,"vrbacrda",8);
- buf[8] = 96;
- buf2[8] = 96;
- secret_to_key(buf+9, 20, "12345678", 8, buf);
- for (i = 0; i < 65536; i += 16) {
- memcpy(buf3+i, "vrbacrda12345678", 16);
- }
- crypto_digest(buf2+9, buf3, 65536);
- test_memeq(buf, buf2, 29);
-
- done:
- tor_free(buf3);
-}
-
-/** Helper: return a tristate based on comparing the strings in *<b>a</b> and
- * *<b>b</b>. */
-static int
-_compare_strs(const void **a, const void **b)
-{
- const char *s1 = *a, *s2 = *b;
- return strcmp(s1, s2);
-}
-
-/** Helper: return a tristate based on comparing the strings in *<b>a</b> and
- * *<b>b</b>, excluding a's first character, and ignoring case. */
-static int
-_compare_without_first_ch(const void *a, const void **b)
-{
- const char *s1 = a, *s2 = *b;
- return strcasecmp(s1+1, s2);
-}
-
-/** Test basic utility functionality. */
-static void
-test_util(void)
-{
- struct timeval start, end;
- struct tm a_time;
- char timestr[RFC1123_TIME_LEN+1];
- char buf[1024];
- time_t t_res;
- int i;
- uint32_t u32;
- uint16_t u16;
- char *cp, *k, *v;
- const char *str;
-
- start.tv_sec = 5;
- start.tv_usec = 5000;
-
- end.tv_sec = 5;
- end.tv_usec = 5000;
-
- test_eq(0L, tv_udiff(&start, &end));
-
- end.tv_usec = 7000;
-
- test_eq(2000L, tv_udiff(&start, &end));
-
- end.tv_sec = 6;
-
- test_eq(1002000L, tv_udiff(&start, &end));
-
- end.tv_usec = 0;
-
- test_eq(995000L, tv_udiff(&start, &end));
-
- end.tv_sec = 4;
-
- test_eq(-1005000L, tv_udiff(&start, &end));
-
- end.tv_usec = 999990;
- start.tv_sec = 1;
- start.tv_usec = 500;
-
- /* The test values here are confirmed to be correct on a platform
- * with a working timegm. */
- a_time.tm_year = 2003-1900;
- a_time.tm_mon = 7;
- a_time.tm_mday = 30;
- a_time.tm_hour = 6;
- a_time.tm_min = 14;
- a_time.tm_sec = 55;
- test_eq((time_t) 1062224095UL, tor_timegm(&a_time));
- a_time.tm_year = 2004-1900; /* Try a leap year, after feb. */
- test_eq((time_t) 1093846495UL, tor_timegm(&a_time));
- a_time.tm_mon = 1; /* Try a leap year, in feb. */
- a_time.tm_mday = 10;
- test_eq((time_t) 1076393695UL, tor_timegm(&a_time));
-
- format_rfc1123_time(timestr, 0);
- test_streq("Thu, 01 Jan 1970 00:00:00 GMT", timestr);
- format_rfc1123_time(timestr, (time_t)1091580502UL);
- test_streq("Wed, 04 Aug 2004 00:48:22 GMT", timestr);
-
- t_res = 0;
- i = parse_rfc1123_time(timestr, &t_res);
- test_eq(i,0);
- test_eq(t_res, (time_t)1091580502UL);
- test_eq(-1, parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res));
- tor_gettimeofday(&start);
-
- /* Tests for corner cases of strl operations */
- test_eq(5, strlcpy(buf, "Hello", 0));
- strlcpy(buf, "Hello", sizeof(buf));
- test_eq(10, strlcat(buf, "Hello", 5));
-
- /* Test tor_strstrip() */
- strlcpy(buf, "Testing 1 2 3", sizeof(buf));
- tor_strstrip(buf, ",!");
- test_streq(buf, "Testing 1 2 3");
- strlcpy(buf, "!Testing 1 2 3?", sizeof(buf));
- tor_strstrip(buf, "!? ");
- test_streq(buf, "Testing123");
-
- /* Test parse_addr_port */
- cp = NULL; u32 = 3; u16 = 3;
- test_assert(!parse_addr_port(LOG_WARN, "1.2.3.4", &cp, &u32, &u16));
- test_streq(cp, "1.2.3.4");
- test_eq(u32, 0x01020304u);
- test_eq(u16, 0);
- tor_free(cp);
- test_assert(!parse_addr_port(LOG_WARN, "4.3.2.1:99", &cp, &u32, &u16));
- test_streq(cp, "4.3.2.1");
- test_eq(u32, 0x04030201u);
- test_eq(u16, 99);
- tor_free(cp);
- test_assert(!parse_addr_port(LOG_WARN, "nonexistent.address:4040",
- &cp, NULL, &u16));
- test_streq(cp, "nonexistent.address");
- test_eq(u16, 4040);
- tor_free(cp);
- test_assert(!parse_addr_port(LOG_WARN, "localhost:9999", &cp, &u32, &u16));
- test_streq(cp, "localhost");
- test_eq(u32, 0x7f000001u);
- test_eq(u16, 9999);
- tor_free(cp);
- u32 = 3;
- test_assert(!parse_addr_port(LOG_WARN, "localhost", NULL, &u32, &u16));
- test_eq(cp, NULL);
- test_eq(u32, 0x7f000001u);
- test_eq(u16, 0);
- tor_free(cp);
- test_eq(0, addr_mask_get_bits(0x0u));
- test_eq(32, addr_mask_get_bits(0xFFFFFFFFu));
- test_eq(16, addr_mask_get_bits(0xFFFF0000u));
- test_eq(31, addr_mask_get_bits(0xFFFFFFFEu));
- test_eq(1, addr_mask_get_bits(0x80000000u));
-
- /* Test tor_parse_long. */
- test_eq(10L, tor_parse_long("10",10,0,100,NULL,NULL));
- test_eq(0L, tor_parse_long("10",10,50,100,NULL,NULL));
- test_eq(-50L, tor_parse_long("-50",10,-100,100,NULL,NULL));
-
- /* Test tor_parse_ulong */
- test_eq(10UL, tor_parse_ulong("10",10,0,100,NULL,NULL));
- test_eq(0UL, tor_parse_ulong("10",10,50,100,NULL,NULL));
-
- /* Test tor_parse_uint64. */
- test_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
- test_assert(i == 1);
- test_streq(cp, " x");
- test_assert(U64_LITERAL(12345678901) ==
- tor_parse_uint64("12345678901",10,0,UINT64_MAX, &i, &cp));
- test_assert(i == 1);
- test_streq(cp, "");
- test_assert(U64_LITERAL(0) ==
- tor_parse_uint64("12345678901",10,500,INT32_MAX, &i, &cp));
- test_assert(i == 0);
-
- /* Test failing snprintf cases */
- test_eq(-1, tor_snprintf(buf, 0, "Foo"));
- test_eq(-1, tor_snprintf(buf, 2, "Foo"));
-
- /* Test printf with uint64 */
- tor_snprintf(buf, sizeof(buf), "x!"U64_FORMAT"!x",
- U64_PRINTF_ARG(U64_LITERAL(12345678901)));
- test_streq(buf, "x!12345678901!x");
-
- /* Test parse_config_line_from_str */
- strlcpy(buf, "k v\n" " key value with spaces \n" "keykey val\n"
- "k2\n"
- "k3 \n" "\n" " \n" "#comment\n"
- "k4#a\n" "k5#abc\n" "k6 val #with comment\n"
- "kseven \"a quoted 'string\"\n"
- "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n"
- , sizeof(buf));
- str = buf;
-
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k");
- test_streq(v, "v");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "key value with"));
-
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "key");
- test_streq(v, "value with spaces");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "keykey"));
-
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "keykey");
- test_streq(v, "val");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "k2\n"));
-
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k2");
- test_streq(v, "");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "k3 \n"));
-
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k3");
- test_streq(v, "");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "#comment"));
-
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k4");
- test_streq(v, "");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "k5#abc"));
-
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k5");
- test_streq(v, "");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "k6"));
-
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k6");
- test_streq(v, "val");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "kseven"));
-
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "kseven");
- test_streq(v, "a quoted \'string");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "k8 "));
-
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k8");
- test_streq(v, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
- tor_free(k); tor_free(v);
- test_streq(str, "");
-
- /* Test for strcmpstart and strcmpend. */
- test_assert(strcmpstart("abcdef", "abcdef")==0);
- test_assert(strcmpstart("abcdef", "abc")==0);
- test_assert(strcmpstart("abcdef", "abd")<0);
- test_assert(strcmpstart("abcdef", "abb")>0);
- test_assert(strcmpstart("ab", "abb")<0);
-
- test_assert(strcmpend("abcdef", "abcdef")==0);
- test_assert(strcmpend("abcdef", "def")==0);
- test_assert(strcmpend("abcdef", "deg")<0);
- test_assert(strcmpend("abcdef", "dee")>0);
- test_assert(strcmpend("ab", "abb")<0);
-
- test_assert(strcasecmpend("AbcDEF", "abcdef")==0);
- test_assert(strcasecmpend("abcdef", "dEF")==0);
- test_assert(strcasecmpend("abcDEf", "deg")<0);
- test_assert(strcasecmpend("abcdef", "DEE")>0);
- test_assert(strcasecmpend("ab", "abB")<0);
-
- /* Test mem_is_zero */
- memset(buf,0,128);
- buf[128] = 'x';
- test_assert(tor_digest_is_zero(buf));
- test_assert(tor_mem_is_zero(buf, 10));
- test_assert(tor_mem_is_zero(buf, 20));
- test_assert(tor_mem_is_zero(buf, 128));
- test_assert(!tor_mem_is_zero(buf, 129));
- buf[60] = (char)255;
- test_assert(!tor_mem_is_zero(buf, 128));
- buf[0] = (char)1;
- test_assert(!tor_mem_is_zero(buf, 10));
-
- /* Test inet_ntop */
- {
- char tmpbuf[TOR_ADDR_BUF_LEN];
- const char *ip = "176.192.208.224";
- struct in_addr in;
- tor_inet_pton(AF_INET, ip, &in);
- tor_inet_ntop(AF_INET, &in, tmpbuf, sizeof(tmpbuf));
- test_streq(tmpbuf, ip);
- }
-
- /* Test 'escaped' */
- test_streq("\"\"", escaped(""));
- test_streq("\"abcd\"", escaped("abcd"));
- test_streq("\"\\\\\\n\\r\\t\\\"\\'\"", escaped("\\\n\r\t\"\'"));
- test_streq("\"z\\001abc\\277d\"", escaped("z\001abc\277d"));
- test_assert(NULL == escaped(NULL));
-
- /* Test strndup and memdup */
- {
- const char *s = "abcdefghijklmnopqrstuvwxyz";
- cp = tor_strndup(s, 30);
- test_streq(cp, s); /* same string, */
- test_neq(cp, s); /* but different pointers. */
- tor_free(cp);
-
- cp = tor_strndup(s, 5);
- test_streq(cp, "abcde");
- tor_free(cp);
-
- s = "a\0b\0c\0d\0e\0";
- cp = tor_memdup(s,10);
- test_memeq(cp, s, 10); /* same ram, */
- test_neq(cp, s); /* but different pointers. */
- tor_free(cp);
- }
-
- /* Test str-foo functions */
- cp = tor_strdup("abcdef");
- test_assert(tor_strisnonupper(cp));
- cp[3] = 'D';
- test_assert(!tor_strisnonupper(cp));
- tor_strupper(cp);
- test_streq(cp, "ABCDEF");
- test_assert(tor_strisprint(cp));
- cp[3] = 3;
- test_assert(!tor_strisprint(cp));
- tor_free(cp);
-
- /* Test eat_whitespace. */
- {
- const char *s = " \n a";
- test_eq_ptr(eat_whitespace(s), s+4);
- s = "abcd";
- test_eq_ptr(eat_whitespace(s), s);
- s = "#xyz\nab";
- test_eq_ptr(eat_whitespace(s), s+5);
- }
-
- /* Test memmem and memstr */
- {
- const char *haystack = "abcde";
- tor_assert(!tor_memmem(haystack, 5, "ef", 2));
- test_eq_ptr(tor_memmem(haystack, 5, "cd", 2), haystack + 2);
- test_eq_ptr(tor_memmem(haystack, 5, "cde", 3), haystack + 2);
- haystack = "ababcad";
- test_eq_ptr(tor_memmem(haystack, 7, "abc", 3), haystack + 2);
- test_eq_ptr(tor_memstr(haystack, 7, "abc"), haystack + 2);
- test_assert(!tor_memstr(haystack, 7, "fe"));
- test_assert(!tor_memstr(haystack, 7, "longerthantheoriginal"));
- }
-
- /* Test wrap_string */
- {
- smartlist_t *sl = smartlist_create();
- wrap_string(sl, "This is a test of string wrapping functionality: woot.",
- 10, "", "");
- cp = smartlist_join_strings(sl, "", 0, NULL);
- test_streq(cp,
- "This is a\ntest of\nstring\nwrapping\nfunctional\nity: woot.\n");
- tor_free(cp);
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
-
- wrap_string(sl, "This is a test of string wrapping functionality: woot.",
- 16, "### ", "# ");
- cp = smartlist_join_strings(sl, "", 0, NULL);
- test_streq(cp,
- "### This is a\n# test of string\n# wrapping\n# functionality:\n"
- "# woot.\n");
-
- tor_free(cp);
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_free(sl);
- }
-
- tor_gettimeofday(&start);
- /* now make sure time works. */
- tor_gettimeofday(&end);
- /* We might've timewarped a little. */
- test_assert(tv_udiff(&start, &end) >= -5000);
-
- /* Test tor_log2(). */
- test_eq(tor_log2(64), 6);
- test_eq(tor_log2(65), 6);
- test_eq(tor_log2(63), 5);
- test_eq(tor_log2(1), 0);
- test_eq(tor_log2(2), 1);
- test_eq(tor_log2(3), 1);
- test_eq(tor_log2(4), 2);
- test_eq(tor_log2(5), 2);
- test_eq(tor_log2(U64_LITERAL(40000000000000000)), 55);
- test_eq(tor_log2(UINT64_MAX), 63);
-
- /* Test round_to_power_of_2 */
- test_eq(round_to_power_of_2(120), 128);
- test_eq(round_to_power_of_2(128), 128);
- test_eq(round_to_power_of_2(130), 128);
- test_eq(round_to_power_of_2(U64_LITERAL(40000000000000000)),
- U64_LITERAL(1)<<55);
- test_eq(round_to_power_of_2(0), 2);
-
- done:
- ;
-}
-
-/** Helper: assert that IPv6 addresses <b>a</b> and <b>b</b> are the same. On
- * failure, reports an error, describing the addresses as <b>e1</b> and
- * <b>e2</b>, and reporting the line number as <b>line</b>. */
-static void
-_test_eq_ip6(struct in6_addr *a, struct in6_addr *b, const char *e1,
- const char *e2, int line)
-{
- int i;
- int ok = 1;
- for (i = 0; i < 16; ++i) {
- if (a->s6_addr[i] != b->s6_addr[i]) {
- ok = 0;
- break;
- }
- }
- if (ok) {
- printf("."); fflush(stdout);
- } else {
- char buf1[128], *cp1;
- char buf2[128], *cp2;
- have_failed = 1;
- cp1 = buf1; cp2 = buf2;
- for (i=0; i<16; ++i) {
- tor_snprintf(cp1, sizeof(buf1)-(cp1-buf1), "%02x", a->s6_addr[i]);
- tor_snprintf(cp2, sizeof(buf2)-(cp2-buf2), "%02x", b->s6_addr[i]);
- cp1 += 2; cp2 += 2;
- if ((i%2)==1 && i != 15) {
- *cp1++ = ':';
- *cp2++ = ':';
- }
- }
- *cp1 = *cp2 = '\0';
- printf("Line %d: assertion failed: (%s == %s)\n"
- " %s != %s\n", line, e1, e2, buf1, buf2);
- fflush(stdout);
- }
-}
-
-/** Helper: Assert that two strings both decode as IPv6 addresses with
- * tor_inet_pton(), and both decode to the same address. */
-#define test_pton6_same(a,b) STMT_BEGIN \
- test_eq(tor_inet_pton(AF_INET6, a, &a1), 1); \
- test_eq(tor_inet_pton(AF_INET6, b, &a2), 1); \
- _test_eq_ip6(&a1,&a2,#a,#b,__LINE__); \
- STMT_END
-
-/** Helper: Assert that <b>a</b> is recognized as a bad IPv6 address by
- * tor_inet_pton(). */
-#define test_pton6_bad(a) \
- test_eq(0, tor_inet_pton(AF_INET6, a, &a1))
-
-/** Helper: assert that <b>a</b>, when parsed by tor_inet_pton() and displayed
- * with tor_inet_ntop(), yields <b>b</b>. Also assert that <b>b</b> parses to
- * the same value as <b>a</b>. */
-#define test_ntop6_reduces(a,b) STMT_BEGIN \
- test_eq(tor_inet_pton(AF_INET6, a, &a1), 1); \
- test_streq(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)), b); \
- test_eq(tor_inet_pton(AF_INET6, b, &a2), 1); \
- _test_eq_ip6(&a1, &a2, a, b, __LINE__); \
- STMT_END
-
-/** Helper: assert that <b>a</b> parses by tor_inet_pton() into a address that
- * passes tor_addr_is_internal() with <b>for_listening</b>. */
-#define test_internal_ip(a,for_listening) STMT_BEGIN \
- test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
- t1.family = AF_INET6; \
- if (!tor_addr_is_internal(&t1, for_listening)) \
- test_fail_msg( a "was not internal."); \
- STMT_END
-
-/** Helper: assert that <b>a</b> parses by tor_inet_pton() into a address that
- * does not pass tor_addr_is_internal() with <b>for_listening</b>. */
-#define test_external_ip(a,for_listening) STMT_BEGIN \
- test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
- t1.family = AF_INET6; \
- if (tor_addr_is_internal(&t1, for_listening)) \
- test_fail_msg(a "was not external."); \
- STMT_END
-
-/** Helper: Assert that <b>a</b> and <b>b</b>, when parsed by
- * tor_inet_pton(), give addresses that compare in the order defined by
- * <b>op</b> with tor_addr_compare(). */
-#define test_addr_compare(a, op, b) STMT_BEGIN \
- test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
- test_eq(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), 1); \
- t1.family = t2.family = AF_INET6; \
- r = tor_addr_compare(&t1,&t2,CMP_SEMANTIC); \
- if (!(r op 0)) \
- test_fail_msg("failed: tor_addr_compare("a","b") "#op" 0"); \
- STMT_END
-
-/** Helper: Assert that <b>a</b> and <b>b</b>, when parsed by
- * tor_inet_pton(), give addresses that compare in the order defined by
- * <b>op</b> with tor_addr_compare_masked() with <b>m</b> masked. */
-#define test_addr_compare_masked(a, op, b, m) STMT_BEGIN \
- test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
- test_eq(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), 1); \
- t1.family = t2.family = AF_INET6; \
- r = tor_addr_compare_masked(&t1,&t2,m,CMP_SEMANTIC); \
- if (!(r op 0)) \
- test_fail_msg("failed: tor_addr_compare_masked("a","b","#m") "#op" 0"); \
- STMT_END
-
-/** Helper: assert that <b>xx</b> is parseable as a masked IPv6 address with
- * ports by tor_parse_mask_addr_ports(), with family <b>f</b>, IP address
- * as 4 32-bit words <b>ip1...ip4</b>, mask bits as <b>mm</b>, and port range
- * as <b>pt1..pt2</b>. */
-#define test_addr_mask_ports_parse(xx, f, ip1, ip2, ip3, ip4, mm, pt1, pt2) \
- STMT_BEGIN \
- test_eq(tor_addr_parse_mask_ports(xx, &t1, &mask, &port1, &port2), f); \
- p1=tor_inet_ntop(AF_INET6, &t1.addr.in6_addr, bug, sizeof(bug)); \
- test_eq(htonl(ip1), tor_addr_to_in6_addr32(&t1)[0]); \
- test_eq(htonl(ip2), tor_addr_to_in6_addr32(&t1)[1]); \
- test_eq(htonl(ip3), tor_addr_to_in6_addr32(&t1)[2]); \
- test_eq(htonl(ip4), tor_addr_to_in6_addr32(&t1)[3]); \
- test_eq(mask, mm); \
- test_eq(port1, pt1); \
- test_eq(port2, pt2); \
- STMT_END
-
-/** Run unit tests for IPv6 encoding/decoding/manipulation functions. */
-static void
-test_util_ip6_helpers(void)
-{
- char buf[TOR_ADDR_BUF_LEN], bug[TOR_ADDR_BUF_LEN];
- struct in6_addr a1, a2;
- tor_addr_t t1, t2;
- int r, i;
- uint16_t port1, port2;
- maskbits_t mask;
- const char *p1;
- struct sockaddr_storage sa_storage;
- struct sockaddr_in *sin;
- struct sockaddr_in6 *sin6;
-
- // struct in_addr b1, b2;
- /* Test tor_inet_ntop and tor_inet_pton: IPv6 */
-
- /* ==== Converting to and from sockaddr_t. */
- sin = (struct sockaddr_in *)&sa_storage;
- sin->sin_family = AF_INET;
- sin->sin_port = 9090;
- sin->sin_addr.s_addr = htonl(0x7f7f0102); /*127.127.1.2*/
- tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, NULL);
- test_eq(tor_addr_family(&t1), AF_INET);
- test_eq(tor_addr_to_ipv4h(&t1), 0x7f7f0102);
-
- memset(&sa_storage, 0, sizeof(sa_storage));
- test_eq(sizeof(struct sockaddr_in),
- tor_addr_to_sockaddr(&t1, 1234, (struct sockaddr *)&sa_storage,
- sizeof(sa_storage)));
- test_eq(1234, ntohs(sin->sin_port));
- test_eq(0x7f7f0102, ntohl(sin->sin_addr.s_addr));
-
- memset(&sa_storage, 0, sizeof(sa_storage));
- sin6 = (struct sockaddr_in6 *)&sa_storage;
- sin6->sin6_family = AF_INET6;
- sin6->sin6_port = htons(7070);
- sin6->sin6_addr.s6_addr[0] = 128;
- tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, NULL);
- test_eq(tor_addr_family(&t1), AF_INET6);
- p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0);
- test_streq(p1, "8000::");
-
- memset(&sa_storage, 0, sizeof(sa_storage));
- test_eq(sizeof(struct sockaddr_in6),
- tor_addr_to_sockaddr(&t1, 9999, (struct sockaddr *)&sa_storage,
- sizeof(sa_storage)));
- test_eq(AF_INET6, sin6->sin6_family);
- test_eq(9999, ntohs(sin6->sin6_port));
- test_eq(0x80000000, ntohl(S6_ADDR32(sin6->sin6_addr)[0]));
-
- /* ==== tor_addr_lookup: static cases. (Can't test dns without knowing we
- * have a good resolver. */
- test_eq(0, tor_addr_lookup("127.128.129.130", AF_UNSPEC, &t1));
- test_eq(AF_INET, tor_addr_family(&t1));
- test_eq(tor_addr_to_ipv4h(&t1), 0x7f808182);
-
- test_eq(0, tor_addr_lookup("9000::5", AF_UNSPEC, &t1));
- test_eq(AF_INET6, tor_addr_family(&t1));
- test_eq(0x90, tor_addr_to_in6_addr8(&t1)[0]);
- test_assert(tor_mem_is_zero((char*)tor_addr_to_in6_addr8(&t1)+1, 14));
- test_eq(0x05, tor_addr_to_in6_addr8(&t1)[15]);
-
- /* === Test pton: valid af_inet6 */
- /* Simple, valid parsing. */
- r = tor_inet_pton(AF_INET6,
- "0102:0304:0506:0708:090A:0B0C:0D0E:0F10", &a1);
- test_assert(r==1);
- for (i=0;i<16;++i) { test_eq(i+1, (int)a1.s6_addr[i]); }
- /* ipv4 ending. */
- test_pton6_same("0102:0304:0506:0708:090A:0B0C:0D0E:0F10",
- "0102:0304:0506:0708:090A:0B0C:13.14.15.16");
- /* shortened words. */
- test_pton6_same("0001:0099:BEEF:0000:0123:FFFF:0001:0001",
- "1:99:BEEF:0:0123:FFFF:1:1");
- /* zeros at the beginning */
- test_pton6_same("0000:0000:0000:0000:0009:C0A8:0001:0001",
- "::9:c0a8:1:1");
- test_pton6_same("0000:0000:0000:0000:0009:C0A8:0001:0001",
- "::9:c0a8:0.1.0.1");
- /* zeros in the middle. */
- test_pton6_same("fe80:0000:0000:0000:0202:1111:0001:0001",
- "fe80::202:1111:1:1");
- /* zeros at the end. */
- test_pton6_same("1000:0001:0000:0007:0000:0000:0000:0000",
- "1000:1:0:7::");
-
- /* === Test ntop: af_inet6 */
- test_ntop6_reduces("0:0:0:0:0:0:0:0", "::");
-
- test_ntop6_reduces("0001:0099:BEEF:0006:0123:FFFF:0001:0001",
- "1:99:beef:6:123:ffff:1:1");
-
- //test_ntop6_reduces("0:0:0:0:0:0:c0a8:0101", "::192.168.1.1");
- test_ntop6_reduces("0:0:0:0:0:ffff:c0a8:0101", "::ffff:192.168.1.1");
- test_ntop6_reduces("002:0:0000:0:3::4", "2::3:0:0:4");
- test_ntop6_reduces("0:0::1:0:3", "::1:0:3");
- test_ntop6_reduces("008:0::0", "8::");
- test_ntop6_reduces("0:0:0:0:0:ffff::1", "::ffff:0.0.0.1");
- test_ntop6_reduces("abcd:0:0:0:0:0:7f00::", "abcd::7f00:0");
- test_ntop6_reduces("0000:0000:0000:0000:0009:C0A8:0001:0001",
- "::9:c0a8:1:1");
- test_ntop6_reduces("fe80:0000:0000:0000:0202:1111:0001:0001",
- "fe80::202:1111:1:1");
- test_ntop6_reduces("1000:0001:0000:0007:0000:0000:0000:0000",
- "1000:1:0:7::");
-
- /* === Test pton: invalid in6. */
- test_pton6_bad("foobar.");
- test_pton6_bad("55555::");
- test_pton6_bad("9:-60::");
- test_pton6_bad("1:2:33333:4:0002:3::");
- //test_pton6_bad("1:2:3333:4:00002:3::");// BAD, but glibc doesn't say so.
- test_pton6_bad("1:2:3333:4:fish:3::");
- test_pton6_bad("1:2:3:4:5:6:7:8:9");
- test_pton6_bad("1:2:3:4:5:6:7");
- test_pton6_bad("1:2:3:4:5:6:1.2.3.4.5");
- test_pton6_bad("1:2:3:4:5:6:1.2.3");
- test_pton6_bad("::1.2.3");
- test_pton6_bad("::1.2.3.4.5");
- test_pton6_bad("99");
- test_pton6_bad("");
- test_pton6_bad("1::2::3:4");
- test_pton6_bad("a:::b:c");
- test_pton6_bad(":::a:b:c");
- test_pton6_bad("a:b:c:::");
-
- /* test internal checking */
- test_external_ip("fbff:ffff::2:7", 0);
- test_internal_ip("fc01::2:7", 0);
- test_internal_ip("fdff:ffff::f:f", 0);
- test_external_ip("fe00::3:f", 0);
-
- test_external_ip("fe7f:ffff::2:7", 0);
- test_internal_ip("fe80::2:7", 0);
- test_internal_ip("febf:ffff::f:f", 0);
-
- test_internal_ip("fec0::2:7:7", 0);
- test_internal_ip("feff:ffff::e:7:7", 0);
- test_external_ip("ff00::e:7:7", 0);
-
- test_internal_ip("::", 0);
- test_internal_ip("::1", 0);
- test_internal_ip("::1", 1);
- test_internal_ip("::", 0);
- test_external_ip("::", 1);
- test_external_ip("::2", 0);
- test_external_ip("2001::", 0);
- test_external_ip("ffff::", 0);
-
- test_external_ip("::ffff:0.0.0.0", 1);
- test_internal_ip("::ffff:0.0.0.0", 0);
- test_internal_ip("::ffff:0.255.255.255", 0);
- test_external_ip("::ffff:1.0.0.0", 0);
-
- test_external_ip("::ffff:9.255.255.255", 0);
- test_internal_ip("::ffff:10.0.0.0", 0);
- test_internal_ip("::ffff:10.255.255.255", 0);
- test_external_ip("::ffff:11.0.0.0", 0);
-
- test_external_ip("::ffff:126.255.255.255", 0);
- test_internal_ip("::ffff:127.0.0.0", 0);
- test_internal_ip("::ffff:127.255.255.255", 0);
- test_external_ip("::ffff:128.0.0.0", 0);
-
- test_external_ip("::ffff:172.15.255.255", 0);
- test_internal_ip("::ffff:172.16.0.0", 0);
- test_internal_ip("::ffff:172.31.255.255", 0);
- test_external_ip("::ffff:172.32.0.0", 0);
-
- test_external_ip("::ffff:192.167.255.255", 0);
- test_internal_ip("::ffff:192.168.0.0", 0);
- test_internal_ip("::ffff:192.168.255.255", 0);
- test_external_ip("::ffff:192.169.0.0", 0);
-
- test_external_ip("::ffff:169.253.255.255", 0);
- test_internal_ip("::ffff:169.254.0.0", 0);
- test_internal_ip("::ffff:169.254.255.255", 0);
- test_external_ip("::ffff:169.255.0.0", 0);
- test_assert(is_internal_IP(0x7f000001, 0));
-
- /* tor_addr_compare(tor_addr_t x2) */
- test_addr_compare("ffff::", ==, "ffff::0");
- test_addr_compare("0::3:2:1", <, "0::ffff:0.3.2.1");
- test_addr_compare("0::2:2:1", <, "0::ffff:0.3.2.1");
- test_addr_compare("0::ffff:0.3.2.1", >, "0::0:0:0");
- test_addr_compare("0::ffff:5.2.2.1", <, "::ffff:6.0.0.0"); /* XXXX wrong. */
- tor_addr_parse_mask_ports("[::ffff:2.3.4.5]", &t1, NULL, NULL, NULL);
- tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL);
- test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) == 0);
- tor_addr_parse_mask_ports("[::ffff:2.3.4.4]", &t1, NULL, NULL, NULL);
- tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL);
- test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) < 0);
-
- /* test compare_masked */
- test_addr_compare_masked("ffff::", ==, "ffff::0", 128);
- test_addr_compare_masked("ffff::", ==, "ffff::0", 64);
- test_addr_compare_masked("0::2:2:1", <, "0::8000:2:1", 81);
- test_addr_compare_masked("0::2:2:1", ==, "0::8000:2:1", 80);
-
- /* Test decorated addr_to_string. */
- test_eq(AF_INET6, tor_addr_from_str(&t1, "[123:45:6789::5005:11]"));
- p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
- test_streq(p1, "[123:45:6789::5005:11]");
- test_eq(AF_INET, tor_addr_from_str(&t1, "18.0.0.1"));
- p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
- test_streq(p1, "18.0.0.1");
-
- /* Test tor_addr_parse_reverse_lookup_name */
- i = tor_addr_parse_reverse_lookup_name(&t1, "Foobar.baz", AF_UNSPEC, 0);
- test_eq(0, i);
- i = tor_addr_parse_reverse_lookup_name(&t1, "Foobar.baz", AF_UNSPEC, 1);
- test_eq(0, i);
- i = tor_addr_parse_reverse_lookup_name(&t1, "1.0.168.192.in-addr.arpa",
- AF_UNSPEC, 1);
- test_eq(1, i);
- test_eq(tor_addr_family(&t1), AF_INET);
- p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
- test_streq(p1, "192.168.0.1");
- i = tor_addr_parse_reverse_lookup_name(&t1, "192.168.0.99", AF_UNSPEC, 0);
- test_eq(0, i);
- i = tor_addr_parse_reverse_lookup_name(&t1, "192.168.0.99", AF_UNSPEC, 1);
- test_eq(1, i);
- p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
- test_streq(p1, "192.168.0.99");
- memset(&t1, 0, sizeof(t1));
- i = tor_addr_parse_reverse_lookup_name(&t1,
- "0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f."
- "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
- "ip6.ARPA",
- AF_UNSPEC, 0);
- test_eq(1, i);
- p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
- test_streq(p1, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]");
- /* Failing cases. */
- i = tor_addr_parse_reverse_lookup_name(&t1,
- "6.7.8.9.a.b.c.d.e.f."
- "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
- "ip6.ARPA",
- AF_UNSPEC, 0);
- test_eq(i, -1);
- i = tor_addr_parse_reverse_lookup_name(&t1,
- "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.f.0."
- "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
- "ip6.ARPA",
- AF_UNSPEC, 0);
- test_eq(i, -1);
- i = tor_addr_parse_reverse_lookup_name(&t1,
- "6.7.8.9.a.b.c.d.e.f.X.0.0.0.0.9."
- "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
- "ip6.ARPA",
- AF_UNSPEC, 0);
- test_eq(i, -1);
- i = tor_addr_parse_reverse_lookup_name(&t1, "32.1.1.in-addr.arpa",
- AF_UNSPEC, 0);
- test_eq(i, -1);
- i = tor_addr_parse_reverse_lookup_name(&t1, ".in-addr.arpa",
- AF_UNSPEC, 0);
- test_eq(i, -1);
- i = tor_addr_parse_reverse_lookup_name(&t1, "1.2.3.4.5.in-addr.arpa",
- AF_UNSPEC, 0);
- test_eq(i, -1);
- i = tor_addr_parse_reverse_lookup_name(&t1, "1.2.3.4.5.in-addr.arpa",
- AF_INET6, 0);
- test_eq(i, -1);
- i = tor_addr_parse_reverse_lookup_name(&t1,
- "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.0."
- "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
- "ip6.ARPA",
- AF_INET, 0);
- test_eq(i, -1);
-
- /* test tor_addr_parse_mask_ports */
- test_addr_mask_ports_parse("[::f]/17:47-95", AF_INET6,
- 0, 0, 0, 0x0000000f, 17, 47, 95);
- //test_addr_parse("[::fefe:4.1.1.7/120]:999-1000");
- //test_addr_parse_check("::fefe:401:107", 120, 999, 1000);
- test_addr_mask_ports_parse("[::ffff:4.1.1.7]/120:443", AF_INET6,
- 0, 0, 0x0000ffff, 0x04010107, 120, 443, 443);
- test_addr_mask_ports_parse("[abcd:2::44a:0]:2-65000", AF_INET6,
- 0xabcd0002, 0, 0, 0x044a0000, 128, 2, 65000);
-
- r=tor_addr_parse_mask_ports("[fefef::]/112", &t1, NULL, NULL, NULL);
- test_assert(r == -1);
- r=tor_addr_parse_mask_ports("efef::/112", &t1, NULL, NULL, NULL);
- test_assert(r == -1);
- r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f::]", &t1, NULL, NULL, NULL);
- test_assert(r == -1);
- r=tor_addr_parse_mask_ports("[::f:f:f:f:f:f:f:f]", &t1, NULL, NULL, NULL);
- test_assert(r == -1);
- r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f:f]", &t1, NULL, NULL, NULL);
- test_assert(r == -1);
- /* Test for V4-mapped address with mask < 96. (arguably not valid) */
- r=tor_addr_parse_mask_ports("[::ffff:1.1.2.2/33]", &t1, &mask, NULL, NULL);
- test_assert(r == -1);
- r=tor_addr_parse_mask_ports("1.1.2.2/33", &t1, &mask, NULL, NULL);
- test_assert(r == -1);
- r=tor_addr_parse_mask_ports("1.1.2.2/31", &t1, &mask, NULL, NULL);
- test_assert(r == AF_INET);
- r=tor_addr_parse_mask_ports("[efef::]/112", &t1, &mask, &port1, &port2);
- test_assert(r == AF_INET6);
- test_assert(port1 == 1);
- test_assert(port2 == 65535);
-
- /* make sure inet address lengths >= max */
- test_assert(INET_NTOA_BUF_LEN >= sizeof("255.255.255.255"));
- test_assert(TOR_ADDR_BUF_LEN >=
- sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"));
-
- test_assert(sizeof(tor_addr_t) >= sizeof(struct in6_addr));
-
- /* get interface addresses */
- r = get_interface_address6(LOG_DEBUG, AF_INET, &t1);
- i = get_interface_address6(LOG_DEBUG, AF_INET6, &t2);
-#if 0
- tor_inet_ntop(AF_INET, &t1.sa.sin_addr, buf, sizeof(buf));
- printf("\nv4 address: %s (family=%i)", buf, IN_FAMILY(&t1));
- tor_inet_ntop(AF_INET6, &t2.sa6.sin6_addr, buf, sizeof(buf));
- printf("\nv6 address: %s (family=%i)", buf, IN_FAMILY(&t2));
-#endif
-
- done:
- ;
-}
-
-/** Run unit tests for basic dynamic-sized array functionality. */
-static void
-test_util_smartlist_basic(void)
-{
- smartlist_t *sl;
-
- /* XXXX test sort_digests, uniq_strings, uniq_digests */
-
- /* Test smartlist add, del_keeporder, insert, get. */
- sl = smartlist_create();
- smartlist_add(sl, (void*)1);
- smartlist_add(sl, (void*)2);
- smartlist_add(sl, (void*)3);
- smartlist_add(sl, (void*)4);
- smartlist_del_keeporder(sl, 1);
- smartlist_insert(sl, 1, (void*)22);
- smartlist_insert(sl, 0, (void*)0);
- smartlist_insert(sl, 5, (void*)555);
- test_eq_ptr((void*)0, smartlist_get(sl,0));
- test_eq_ptr((void*)1, smartlist_get(sl,1));
- test_eq_ptr((void*)22, smartlist_get(sl,2));
- test_eq_ptr((void*)3, smartlist_get(sl,3));
- test_eq_ptr((void*)4, smartlist_get(sl,4));
- test_eq_ptr((void*)555, smartlist_get(sl,5));
- /* Try deleting in the middle. */
- smartlist_del(sl, 1);
- test_eq_ptr((void*)555, smartlist_get(sl, 1));
- /* Try deleting at the end. */
- smartlist_del(sl, 4);
- test_eq(4, smartlist_len(sl));
-
- /* test isin. */
- test_assert(smartlist_isin(sl, (void*)3));
- test_assert(!smartlist_isin(sl, (void*)99));
-
- done:
- smartlist_free(sl);
-}
-
-/** Run unit tests for smartlist-of-strings functionality. */
-static void
-test_util_smartlist_strings(void)
-{
- smartlist_t *sl = smartlist_create();
- char *cp=NULL, *cp_alloc=NULL;
- size_t sz;
-
- /* Test split and join */
- test_eq(0, smartlist_len(sl));
- smartlist_split_string(sl, "abc", ":", 0, 0);
- test_eq(1, smartlist_len(sl));
- test_streq("abc", smartlist_get(sl, 0));
- smartlist_split_string(sl, "a::bc::", "::", 0, 0);
- test_eq(4, smartlist_len(sl));
- test_streq("a", smartlist_get(sl, 1));
- test_streq("bc", smartlist_get(sl, 2));
- test_streq("", smartlist_get(sl, 3));
- cp_alloc = smartlist_join_strings(sl, "", 0, NULL);
- test_streq(cp_alloc, "abcabc");
- tor_free(cp_alloc);
- cp_alloc = smartlist_join_strings(sl, "!", 0, NULL);
- test_streq(cp_alloc, "abc!a!bc!");
- tor_free(cp_alloc);
- cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
- test_streq(cp_alloc, "abcXYaXYbcXY");
- tor_free(cp_alloc);
- cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
- test_streq(cp_alloc, "abcXYaXYbcXYXY");
- tor_free(cp_alloc);
- cp_alloc = smartlist_join_strings(sl, "", 1, NULL);
- test_streq(cp_alloc, "abcabc");
- tor_free(cp_alloc);
-
- smartlist_split_string(sl, "/def/ /ghijk", "/", 0, 0);
- test_eq(8, smartlist_len(sl));
- test_streq("", smartlist_get(sl, 4));
- test_streq("def", smartlist_get(sl, 5));
- test_streq(" ", smartlist_get(sl, 6));
- test_streq("ghijk", smartlist_get(sl, 7));
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
-
- smartlist_split_string(sl, "a,bbd,cdef", ",", SPLIT_SKIP_SPACE, 0);
- test_eq(3, smartlist_len(sl));
- test_streq("a", smartlist_get(sl,0));
- test_streq("bbd", smartlist_get(sl,1));
- test_streq("cdef", smartlist_get(sl,2));
- smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>",
- SPLIT_SKIP_SPACE, 0);
- test_eq(8, smartlist_len(sl));
- test_streq("z", smartlist_get(sl,3));
- test_streq("zhasd", smartlist_get(sl,4));
- test_streq("", smartlist_get(sl,5));
- test_streq("bnud", smartlist_get(sl,6));
- test_streq("", smartlist_get(sl,7));
-
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
-
- smartlist_split_string(sl, " ab\tc \td ef ", NULL,
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- test_eq(4, smartlist_len(sl));
- test_streq("ab", smartlist_get(sl,0));
- test_streq("c", smartlist_get(sl,1));
- test_streq("d", smartlist_get(sl,2));
- test_streq("ef", smartlist_get(sl,3));
- smartlist_split_string(sl, "ghi\tj", NULL,
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- test_eq(6, smartlist_len(sl));
- test_streq("ghi", smartlist_get(sl,4));
- test_streq("j", smartlist_get(sl,5));
-
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
-
- cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
- test_streq(cp_alloc, "");
- tor_free(cp_alloc);
- cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
- test_streq(cp_alloc, "XY");
- tor_free(cp_alloc);
-
- smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>",
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- test_eq(3, smartlist_len(sl));
- test_streq("z", smartlist_get(sl, 0));
- test_streq("zhasd", smartlist_get(sl, 1));
- test_streq("bnud", smartlist_get(sl, 2));
- smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>",
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
- test_eq(5, smartlist_len(sl));
- test_streq("z", smartlist_get(sl, 3));
- test_streq("zhasd <> <> bnud<>", smartlist_get(sl, 4));
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
-
- smartlist_split_string(sl, "abcd\n", "\n",
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- test_eq(1, smartlist_len(sl));
- test_streq("abcd", smartlist_get(sl, 0));
- smartlist_split_string(sl, "efgh", "\n",
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- test_eq(2, smartlist_len(sl));
- test_streq("efgh", smartlist_get(sl, 1));
-
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
-
- /* Test swapping, shuffling, and sorting. */
- smartlist_split_string(sl, "the,onion,router,by,arma,and,nickm", ",", 0, 0);
- test_eq(7, smartlist_len(sl));
- smartlist_sort(sl, _compare_strs);
- cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
- test_streq(cp_alloc,"and,arma,by,nickm,onion,router,the");
- tor_free(cp_alloc);
- smartlist_swap(sl, 1, 5);
- cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
- test_streq(cp_alloc,"and,router,by,nickm,onion,arma,the");
- tor_free(cp_alloc);
- smartlist_shuffle(sl);
- test_eq(7, smartlist_len(sl));
- test_assert(smartlist_string_isin(sl, "and"));
- test_assert(smartlist_string_isin(sl, "router"));
- test_assert(smartlist_string_isin(sl, "by"));
- test_assert(smartlist_string_isin(sl, "nickm"));
- test_assert(smartlist_string_isin(sl, "onion"));
- test_assert(smartlist_string_isin(sl, "arma"));
- test_assert(smartlist_string_isin(sl, "the"));
-
- /* Test bsearch. */
- smartlist_sort(sl, _compare_strs);
- test_streq("nickm", smartlist_bsearch(sl, "zNicKM",
- _compare_without_first_ch));
- test_streq("and", smartlist_bsearch(sl, " AND", _compare_without_first_ch));
- test_eq_ptr(NULL, smartlist_bsearch(sl, " ANz", _compare_without_first_ch));
-
- /* Test bsearch_idx */
- {
- int f;
- test_eq(0, smartlist_bsearch_idx(sl," aaa",_compare_without_first_ch,&f));
- test_eq(f, 0);
- test_eq(0, smartlist_bsearch_idx(sl," and",_compare_without_first_ch,&f));
- test_eq(f, 1);
- test_eq(1, smartlist_bsearch_idx(sl," arm",_compare_without_first_ch,&f));
- test_eq(f, 0);
- test_eq(1, smartlist_bsearch_idx(sl," arma",_compare_without_first_ch,&f));
- test_eq(f, 1);
- test_eq(2, smartlist_bsearch_idx(sl," armb",_compare_without_first_ch,&f));
- test_eq(f, 0);
- test_eq(7, smartlist_bsearch_idx(sl," zzzz",_compare_without_first_ch,&f));
- test_eq(f, 0);
- }
-
- /* Test reverse() and pop_last() */
- smartlist_reverse(sl);
- cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
- test_streq(cp_alloc,"the,router,onion,nickm,by,arma,and");
- tor_free(cp_alloc);
- cp_alloc = smartlist_pop_last(sl);
- test_streq(cp_alloc, "and");
- tor_free(cp_alloc);
- test_eq(smartlist_len(sl), 6);
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
- cp_alloc = smartlist_pop_last(sl);
- test_eq(cp_alloc, NULL);
-
- /* Test uniq() */
- smartlist_split_string(sl,
- "50,noon,radar,a,man,a,plan,a,canal,panama,radar,noon,50",
- ",", 0, 0);
- smartlist_sort(sl, _compare_strs);
- smartlist_uniq(sl, _compare_strs, _tor_free);
- cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
- test_streq(cp_alloc, "50,a,canal,man,noon,panama,plan,radar");
- tor_free(cp_alloc);
-
- /* Test string_isin and isin_case and num_isin */
- test_assert(smartlist_string_isin(sl, "noon"));
- test_assert(!smartlist_string_isin(sl, "noonoon"));
- test_assert(smartlist_string_isin_case(sl, "nOOn"));
- test_assert(!smartlist_string_isin_case(sl, "nooNooN"));
- test_assert(smartlist_string_num_isin(sl, 50));
- test_assert(!smartlist_string_num_isin(sl, 60));
-
- /* Test smartlist_choose */
- {
- int i;
- int allsame = 1;
- int allin = 1;
- void *first = smartlist_choose(sl);
- test_assert(smartlist_isin(sl, first));
- for (i = 0; i < 100; ++i) {
- void *second = smartlist_choose(sl);
- if (second != first)
- allsame = 0;
- if (!smartlist_isin(sl, second))
- allin = 0;
- }
- test_assert(!allsame);
- test_assert(allin);
- }
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
-
- /* Test string_remove and remove and join_strings2 */
- smartlist_split_string(sl,
- "Some say the Earth will end in ice and some in fire",
- " ", 0, 0);
- cp = smartlist_get(sl, 4);
- test_streq(cp, "will");
- smartlist_add(sl, cp);
- smartlist_remove(sl, cp);
- tor_free(cp);
- cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
- test_streq(cp_alloc, "Some,say,the,Earth,fire,end,in,ice,and,some,in");
- tor_free(cp_alloc);
- smartlist_string_remove(sl, "in");
- cp_alloc = smartlist_join_strings2(sl, "+XX", 1, 0, &sz);
- test_streq(cp_alloc, "Some+say+the+Earth+fire+end+some+ice+and");
- test_eq((int)sz, 40);
-
- done:
-
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_free(sl);
- tor_free(cp_alloc);
-}
-
-/** Run unit tests for smartlist set manipulation functions. */
-static void
-test_util_smartlist_overlap(void)
-{
- smartlist_t *sl = smartlist_create();
- smartlist_t *ints = smartlist_create();
- smartlist_t *odds = smartlist_create();
- smartlist_t *evens = smartlist_create();
- smartlist_t *primes = smartlist_create();
- int i;
- for (i=1; i < 10; i += 2)
- smartlist_add(odds, (void*)(uintptr_t)i);
- for (i=0; i < 10; i += 2)
- smartlist_add(evens, (void*)(uintptr_t)i);
-
- /* add_all */
- smartlist_add_all(ints, odds);
- smartlist_add_all(ints, evens);
- test_eq(smartlist_len(ints), 10);
-
- smartlist_add(primes, (void*)2);
- smartlist_add(primes, (void*)3);
- smartlist_add(primes, (void*)5);
- smartlist_add(primes, (void*)7);
-
- /* overlap */
- test_assert(smartlist_overlap(ints, odds));
- test_assert(smartlist_overlap(odds, primes));
- test_assert(smartlist_overlap(evens, primes));
- test_assert(!smartlist_overlap(odds, evens));
-
- /* intersect */
- smartlist_add_all(sl, odds);
- smartlist_intersect(sl, primes);
- test_eq(smartlist_len(sl), 3);
- test_assert(smartlist_isin(sl, (void*)3));
- test_assert(smartlist_isin(sl, (void*)5));
- test_assert(smartlist_isin(sl, (void*)7));
-
- /* subtract */
- smartlist_add_all(sl, primes);
- smartlist_subtract(sl, odds);
- test_eq(smartlist_len(sl), 1);
- test_assert(smartlist_isin(sl, (void*)2));
-
- done:
- smartlist_free(odds);
- smartlist_free(evens);
- smartlist_free(ints);
- smartlist_free(primes);
- smartlist_free(sl);
-}
-
-/** Run unit tests for smartlist-of-digests functions. */
-static void
-test_util_smartlist_digests(void)
-{
- smartlist_t *sl = smartlist_create();
-
- /* digest_isin. */
- smartlist_add(sl, tor_memdup("AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN));
- smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN));
- smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN));
- test_eq(0, smartlist_digest_isin(NULL, "AAAAAAAAAAAAAAAAAAAA"));
- test_assert(smartlist_digest_isin(sl, "AAAAAAAAAAAAAAAAAAAA"));
- test_assert(smartlist_digest_isin(sl, "\00090AAB2AAAAaasdAAAAA"));
- test_eq(0, smartlist_digest_isin(sl, "\00090AAB2AAABaasdAAAAA"));
-
- /* sort digests */
- smartlist_sort_digests(sl);
- test_memeq(smartlist_get(sl, 0), "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
- test_memeq(smartlist_get(sl, 1), "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
- test_memeq(smartlist_get(sl, 2), "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN);
- test_eq(3, smartlist_len(sl));
-
- /* uniq_digests */
- smartlist_uniq_digests(sl);
- test_eq(2, smartlist_len(sl));
- test_memeq(smartlist_get(sl, 0), "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
- test_memeq(smartlist_get(sl, 1), "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN);
-
- done:
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_free(sl);
-}
-
-/** Run unit tests for concatenate-a-smartlist-of-strings functions. */
-static void
-test_util_smartlist_join(void)
-{
- smartlist_t *sl = smartlist_create();
- smartlist_t *sl2 = smartlist_create(), *sl3 = smartlist_create(),
- *sl4 = smartlist_create();
- char *joined=NULL;
- /* unique, sorted. */
- smartlist_split_string(sl,
- "Abashments Ambush Anchorman Bacon Banks Borscht "
- "Bunks Inhumane Insurance Knish Know Manners "
- "Maraschinos Stamina Sunbonnets Unicorns Wombats",
- " ", 0, 0);
- /* non-unique, sorted. */
- smartlist_split_string(sl2,
- "Ambush Anchorman Anchorman Anemias Anemias Bacon "
- "Crossbowmen Inhumane Insurance Knish Know Manners "
- "Manners Maraschinos Wombats Wombats Work",
- " ", 0, 0);
- SMARTLIST_FOREACH_JOIN(sl, char *, cp1,
- sl2, char *, cp2,
- strcmp(cp1,cp2),
- smartlist_add(sl3, cp2)) {
- test_streq(cp1, cp2);
- smartlist_add(sl4, cp1);
- } SMARTLIST_FOREACH_JOIN_END(cp1, cp2);
-
- SMARTLIST_FOREACH(sl3, const char *, cp,
- test_assert(smartlist_isin(sl2, cp) &&
- !smartlist_string_isin(sl, cp)));
- SMARTLIST_FOREACH(sl4, const char *, cp,
- test_assert(smartlist_isin(sl, cp) &&
- smartlist_string_isin(sl2, cp)));
- joined = smartlist_join_strings(sl3, ",", 0, NULL);
- test_streq(joined, "Anemias,Anemias,Crossbowmen,Work");
- tor_free(joined);
- joined = smartlist_join_strings(sl4, ",", 0, NULL);
- test_streq(joined, "Ambush,Anchorman,Anchorman,Bacon,Inhumane,Insurance,"
- "Knish,Know,Manners,Manners,Maraschinos,Wombats,Wombats");
- tor_free(joined);
-
- done:
- smartlist_free(sl4);
- smartlist_free(sl3);
- SMARTLIST_FOREACH(sl2, char *, cp, tor_free(cp));
- smartlist_free(sl2);
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_free(sl);
- tor_free(joined);
-}
-
-/** Run unit tests for bitarray code */
-static void
-test_util_bitarray(void)
-{
- bitarray_t *ba = NULL;
- int i, j, ok=1;
-
- ba = bitarray_init_zero(1);
- test_assert(ba);
- test_assert(! bitarray_is_set(ba, 0));
- bitarray_set(ba, 0);
- test_assert(bitarray_is_set(ba, 0));
- bitarray_clear(ba, 0);
- test_assert(! bitarray_is_set(ba, 0));
- bitarray_free(ba);
-
- ba = bitarray_init_zero(1023);
- for (i = 1; i < 64; ) {
- for (j = 0; j < 1023; ++j) {
- if (j % i)
- bitarray_set(ba, j);
- else
- bitarray_clear(ba, j);
- }
- for (j = 0; j < 1023; ++j) {
- if (!bool_eq(bitarray_is_set(ba, j), j%i))
- ok = 0;
- }
- test_assert(ok);
- if (i < 7)
- ++i;
- else if (i == 28)
- i = 32;
- else
- i += 7;
- }
-
- done:
- if (ba)
- bitarray_free(ba);
-}
-
-/** Run unit tests for digest set code (implemented as a hashtable or as a
- * bloom filter) */
-static void
-test_util_digestset(void)
-{
- smartlist_t *included = smartlist_create();
- char d[DIGEST_LEN];
- int i;
- int ok = 1;
- int false_positives = 0;
- digestset_t *set = NULL;
-
- for (i = 0; i < 1000; ++i) {
- crypto_rand(d, DIGEST_LEN);
- smartlist_add(included, tor_memdup(d, DIGEST_LEN));
- }
- set = digestset_new(1000);
- SMARTLIST_FOREACH(included, const char *, cp,
- if (digestset_isin(set, cp))
- ok = 0);
- test_assert(ok);
- SMARTLIST_FOREACH(included, const char *, cp,
- digestset_add(set, cp));
- SMARTLIST_FOREACH(included, const char *, cp,
- if (!digestset_isin(set, cp))
- ok = 0);
- test_assert(ok);
- for (i = 0; i < 1000; ++i) {
- crypto_rand(d, DIGEST_LEN);
- if (digestset_isin(set, d))
- ++false_positives;
- }
- test_assert(false_positives < 50); /* Should be far lower. */
-
- done:
- if (set)
- digestset_free(set);
- SMARTLIST_FOREACH(included, char *, cp, tor_free(cp));
- smartlist_free(included);
-}
-
-/** mutex for thread test to stop the threads hitting data at the same time. */
-static tor_mutex_t *_thread_test_mutex = NULL;
-/** mutexes for the thread test to make sure that the threads have to
- * interleave somewhat. */
-static tor_mutex_t *_thread_test_start1 = NULL,
- *_thread_test_start2 = NULL;
-/** Shared strmap for the thread test. */
-static strmap_t *_thread_test_strmap = NULL;
-/** The name of thread1 for the thread test */
-static char *_thread1_name = NULL;
-/** The name of thread2 for the thread test */
-static char *_thread2_name = NULL;
-
-static void _thread_test_func(void* _s) ATTR_NORETURN;
-
-/** How many iterations have the threads in the unit test run? */
-static int t1_count = 0, t2_count = 0;
-
-/** Helper function for threading unit tests: This function runs in a
- * subthread. It grabs its own mutex (start1 or start2) to make sure that it
- * should start, then it repeatedly alters _test_thread_strmap protected by
- * _thread_test_mutex. */
-static void
-_thread_test_func(void* _s)
-{
- char *s = _s;
- int i, *count;
- tor_mutex_t *m;
- char buf[64];
- char **cp;
- if (!strcmp(s, "thread 1")) {
- m = _thread_test_start1;
- cp = &_thread1_name;
- count = &t1_count;
- } else {
- m = _thread_test_start2;
- cp = &_thread2_name;
- count = &t2_count;
- }
- tor_mutex_acquire(m);
-
- tor_snprintf(buf, sizeof(buf), "%lu", tor_get_thread_id());
- *cp = tor_strdup(buf);
-
- for (i=0; i<10000; ++i) {
- tor_mutex_acquire(_thread_test_mutex);
- strmap_set(_thread_test_strmap, "last to run", *cp);
- ++*count;
- tor_mutex_release(_thread_test_mutex);
- }
- tor_mutex_acquire(_thread_test_mutex);
- strmap_set(_thread_test_strmap, s, *cp);
- tor_mutex_release(_thread_test_mutex);
-
- tor_mutex_release(m);
-
- spawn_exit();
-}
-
-/** Run unit tests for threading logic. */
-static void
-test_util_threads(void)
-{
- char *s1 = NULL, *s2 = NULL;
- int done = 0, timedout = 0;
- time_t started;
-#ifndef MS_WINDOWS
- struct timeval tv;
- tv.tv_sec=0;
- tv.tv_usec=10;
-#endif
-#ifndef TOR_IS_MULTITHREADED
- /* Skip this test if we aren't threading. We should be threading most
- * everywhere by now. */
- if (1)
- return;
-#endif
- _thread_test_mutex = tor_mutex_new();
- _thread_test_start1 = tor_mutex_new();
- _thread_test_start2 = tor_mutex_new();
- _thread_test_strmap = strmap_new();
- s1 = tor_strdup("thread 1");
- s2 = tor_strdup("thread 2");
- tor_mutex_acquire(_thread_test_start1);
- tor_mutex_acquire(_thread_test_start2);
- spawn_func(_thread_test_func, s1);
- spawn_func(_thread_test_func, s2);
- tor_mutex_release(_thread_test_start2);
- tor_mutex_release(_thread_test_start1);
- started = time(NULL);
- while (!done) {
- tor_mutex_acquire(_thread_test_mutex);
- strmap_assert_ok(_thread_test_strmap);
- if (strmap_get(_thread_test_strmap, "thread 1") &&
- strmap_get(_thread_test_strmap, "thread 2")) {
- done = 1;
- } else if (time(NULL) > started + 25) {
- timedout = done = 1;
- }
- tor_mutex_release(_thread_test_mutex);
-#ifndef MS_WINDOWS
- /* Prevent the main thread from starving the worker threads. */
- select(0, NULL, NULL, NULL, &tv);
-#endif
- }
-
- tor_mutex_acquire(_thread_test_start1);
- tor_mutex_release(_thread_test_start1);
- tor_mutex_acquire(_thread_test_start2);
- tor_mutex_release(_thread_test_start2);
-
- tor_mutex_free(_thread_test_mutex);
-
- if (timedout) {
- printf("\nTimed out: %d %d", t1_count, t2_count);
- test_assert(strmap_get(_thread_test_strmap, "thread 1"));
- test_assert(strmap_get(_thread_test_strmap, "thread 2"));
- test_assert(!timedout);
- }
-
- /* different thread IDs. */
- test_assert(strcmp(strmap_get(_thread_test_strmap, "thread 1"),
- strmap_get(_thread_test_strmap, "thread 2")));
- test_assert(!strcmp(strmap_get(_thread_test_strmap, "thread 1"),
- strmap_get(_thread_test_strmap, "last to run")) ||
- !strcmp(strmap_get(_thread_test_strmap, "thread 2"),
- strmap_get(_thread_test_strmap, "last to run")));
-
- done:
- tor_free(s1);
- tor_free(s2);
- tor_free(_thread1_name);
- tor_free(_thread2_name);
- if (_thread_test_strmap)
- strmap_free(_thread_test_strmap, NULL);
- if (_thread_test_start1)
- tor_mutex_free(_thread_test_start1);
- if (_thread_test_start2)
- tor_mutex_free(_thread_test_start2);
-}
-
-/** Helper: return a tristate based on comparing two strings. */
-static int
-_compare_strings_for_pqueue(const void *s1, const void *s2)
-{
- return strcmp((const char*)s1, (const char*)s2);
-}
-
-/** Run unit tests for heap-based priority queue functions. */
-static void
-test_util_pqueue(void)
-{
- smartlist_t *sl = smartlist_create();
- int (*cmp)(const void *, const void*);
-#define OK() smartlist_pqueue_assert_ok(sl, cmp)
-
- cmp = _compare_strings_for_pqueue;
-
- smartlist_pqueue_add(sl, cmp, (char*)"cows");
- smartlist_pqueue_add(sl, cmp, (char*)"zebras");
- smartlist_pqueue_add(sl, cmp, (char*)"fish");
- smartlist_pqueue_add(sl, cmp, (char*)"frogs");
- smartlist_pqueue_add(sl, cmp, (char*)"apples");
- smartlist_pqueue_add(sl, cmp, (char*)"squid");
- smartlist_pqueue_add(sl, cmp, (char*)"daschunds");
- smartlist_pqueue_add(sl, cmp, (char*)"eggplants");
- smartlist_pqueue_add(sl, cmp, (char*)"weissbier");
- smartlist_pqueue_add(sl, cmp, (char*)"lobsters");
- smartlist_pqueue_add(sl, cmp, (char*)"roquefort");
-
- OK();
-
- test_eq(smartlist_len(sl), 11);
- test_streq(smartlist_get(sl, 0), "apples");
- test_streq(smartlist_pqueue_pop(sl, cmp), "apples");
- test_eq(smartlist_len(sl), 10);
- OK();
- test_streq(smartlist_pqueue_pop(sl, cmp), "cows");
- test_streq(smartlist_pqueue_pop(sl, cmp), "daschunds");
- smartlist_pqueue_add(sl, cmp, (char*)"chinchillas");
- OK();
- smartlist_pqueue_add(sl, cmp, (char*)"fireflies");
- OK();
- test_streq(smartlist_pqueue_pop(sl, cmp), "chinchillas");
- test_streq(smartlist_pqueue_pop(sl, cmp), "eggplants");
- test_streq(smartlist_pqueue_pop(sl, cmp), "fireflies");
- OK();
- test_streq(smartlist_pqueue_pop(sl, cmp), "fish");
- test_streq(smartlist_pqueue_pop(sl, cmp), "frogs");
- test_streq(smartlist_pqueue_pop(sl, cmp), "lobsters");
- test_streq(smartlist_pqueue_pop(sl, cmp), "roquefort");
- OK();
- test_eq(smartlist_len(sl), 3);
- test_streq(smartlist_pqueue_pop(sl, cmp), "squid");
- test_streq(smartlist_pqueue_pop(sl, cmp), "weissbier");
- test_streq(smartlist_pqueue_pop(sl, cmp), "zebras");
- test_eq(smartlist_len(sl), 0);
- OK();
-#undef OK
-
- done:
-
- smartlist_free(sl);
-}
-
-/** Run unit tests for compression functions */
-static void
-test_util_gzip(void)
-{
- char *buf1=NULL, *buf2=NULL, *buf3=NULL, *cp1, *cp2;
- const char *ccp2;
- size_t len1, len2;
- tor_zlib_state_t *state = NULL;
-
- buf1 = tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
- test_assert(detect_compression_method(buf1, strlen(buf1)) == UNKNOWN_METHOD);
- if (is_gzip_supported()) {
- test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
- GZIP_METHOD));
- test_assert(buf2);
- test_assert(!memcmp(buf2, "\037\213", 2)); /* Gzip magic. */
- test_assert(detect_compression_method(buf2, len1) == GZIP_METHOD);
-
- test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
- GZIP_METHOD, 1, LOG_INFO));
- test_assert(buf3);
- test_streq(buf1,buf3);
-
- tor_free(buf2);
- tor_free(buf3);
- }
-
- test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
- ZLIB_METHOD));
- test_assert(buf2);
- test_assert(!memcmp(buf2, "\x78\xDA", 2)); /* deflate magic. */
- test_assert(detect_compression_method(buf2, len1) == ZLIB_METHOD);
-
- test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
- ZLIB_METHOD, 1, LOG_INFO));
- test_assert(buf3);
- test_streq(buf1,buf3);
-
- /* Check whether we can uncompress concatenated, compressed strings. */
- tor_free(buf3);
- buf2 = tor_realloc(buf2, len1*2);
- memcpy(buf2+len1, buf2, len1);
- test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1*2,
- ZLIB_METHOD, 1, LOG_INFO));
- test_eq(len2, (strlen(buf1)+1)*2);
- test_memeq(buf3,
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
- (strlen(buf1)+1)*2);
-
- tor_free(buf1);
- tor_free(buf2);
- tor_free(buf3);
-
- /* Check whether we can uncompress partial strings. */
- buf1 =
- tor_strdup("String with low redundancy that won't be compressed much.");
- test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
- ZLIB_METHOD));
- tor_assert(len1>16);
- /* when we allow an incomplete string, we should succeed.*/
- tor_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1-16,
- ZLIB_METHOD, 0, LOG_INFO));
- buf3[len2]='\0';
- tor_assert(len2 > 5);
- tor_assert(!strcmpstart(buf1, buf3));
-
- /* when we demand a complete string, this must fail. */
- tor_free(buf3);
- tor_assert(tor_gzip_uncompress(&buf3, &len2, buf2, len1-16,
- ZLIB_METHOD, 1, LOG_INFO));
- tor_assert(!buf3);
-
- /* Now, try streaming compression. */
- tor_free(buf1);
- tor_free(buf2);
- tor_free(buf3);
- state = tor_zlib_new(1, ZLIB_METHOD);
- tor_assert(state);
- cp1 = buf1 = tor_malloc(1024);
- len1 = 1024;
- ccp2 = "ABCDEFGHIJABCDEFGHIJ";
- len2 = 21;
- test_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 0)
- == TOR_ZLIB_OK);
- test_eq(len2, 0); /* Make sure we compressed it all. */
- test_assert(cp1 > buf1);
-
- len2 = 0;
- cp2 = cp1;
- test_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 1)
- == TOR_ZLIB_DONE);
- test_eq(len2, 0);
- test_assert(cp1 > cp2); /* Make sure we really added something. */
-
- tor_assert(!tor_gzip_uncompress(&buf3, &len2, buf1, 1024-len1,
- ZLIB_METHOD, 1, LOG_WARN));
- test_streq(buf3, "ABCDEFGHIJABCDEFGHIJ"); /*Make sure it compressed right.*/
-
- done:
- if (state)
- tor_zlib_free(state);
- tor_free(buf2);
- tor_free(buf3);
- tor_free(buf1);
-}
-
-/** Run unit tests for string-to-void* map functions */
-static void
-test_util_strmap(void)
-{
- strmap_t *map;
- strmap_iter_t *iter;
- const char *k;
- void *v;
- char *visited = NULL;
- smartlist_t *found_keys = NULL;
-
- map = strmap_new();
- test_assert(map);
- test_eq(strmap_size(map), 0);
- test_assert(strmap_isempty(map));
- v = strmap_set(map, "K1", (void*)99);
- test_eq(v, NULL);
- test_assert(!strmap_isempty(map));
- v = strmap_set(map, "K2", (void*)101);
- test_eq(v, NULL);
- v = strmap_set(map, "K1", (void*)100);
- test_eq(v, (void*)99);
- test_eq_ptr(strmap_get(map,"K1"), (void*)100);
- test_eq_ptr(strmap_get(map,"K2"), (void*)101);
- test_eq_ptr(strmap_get(map,"K-not-there"), NULL);
- strmap_assert_ok(map);
-
- v = strmap_remove(map,"K2");
- strmap_assert_ok(map);
- test_eq_ptr(v, (void*)101);
- test_eq_ptr(strmap_get(map,"K2"), NULL);
- test_eq_ptr(strmap_remove(map,"K2"), NULL);
-
- strmap_set(map, "K2", (void*)101);
- strmap_set(map, "K3", (void*)102);
- strmap_set(map, "K4", (void*)103);
- test_eq(strmap_size(map), 4);
- strmap_assert_ok(map);
- strmap_set(map, "K5", (void*)104);
- strmap_set(map, "K6", (void*)105);
- strmap_assert_ok(map);
-
- /* Test iterator. */
- iter = strmap_iter_init(map);
- found_keys = smartlist_create();
- while (!strmap_iter_done(iter)) {
- strmap_iter_get(iter,&k,&v);
- smartlist_add(found_keys, tor_strdup(k));
- test_eq_ptr(v, strmap_get(map, k));
-
- if (!strcmp(k, "K2")) {
- iter = strmap_iter_next_rmv(map,iter);
- } else {
- iter = strmap_iter_next(map,iter);
- }
- }
-
- /* Make sure we removed K2, but not the others. */
- test_eq_ptr(strmap_get(map, "K2"), NULL);
- test_eq_ptr(strmap_get(map, "K5"), (void*)104);
- /* Make sure we visited everyone once */
- smartlist_sort_strings(found_keys);
- visited = smartlist_join_strings(found_keys, ":", 0, NULL);
- test_streq(visited, "K1:K2:K3:K4:K5:K6");
-
- strmap_assert_ok(map);
- /* Clean up after ourselves. */
- strmap_free(map, NULL);
- map = NULL;
-
- /* Now try some lc functions. */
- map = strmap_new();
- strmap_set_lc(map,"Ab.C", (void*)1);
- test_eq_ptr(strmap_get(map,"ab.c"), (void*)1);
- strmap_assert_ok(map);
- test_eq_ptr(strmap_get_lc(map,"AB.C"), (void*)1);
- test_eq_ptr(strmap_get(map,"AB.C"), NULL);
- test_eq_ptr(strmap_remove_lc(map,"aB.C"), (void*)1);
- strmap_assert_ok(map);
- test_eq_ptr(strmap_get_lc(map,"AB.C"), NULL);
-
- done:
- if (map)
- strmap_free(map,NULL);
- if (found_keys) {
- SMARTLIST_FOREACH(found_keys, char *, cp, tor_free(cp));
- smartlist_free(found_keys);
- }
- tor_free(visited);
-}
-
-/** Run unit tests for mmap() wrapper functionality. */
-static void
-test_util_mmap(void)
-{
- char *fname1 = tor_strdup(get_fname("mapped_1"));
- char *fname2 = tor_strdup(get_fname("mapped_2"));
- char *fname3 = tor_strdup(get_fname("mapped_3"));
- const size_t buflen = 17000;
- char *buf = tor_malloc(17000);
- tor_mmap_t *mapping = NULL;
-
- crypto_rand(buf, buflen);
-
- mapping = tor_mmap_file(fname1);
- test_assert(! mapping);
-
- write_str_to_file(fname1, "Short file.", 1);
- write_bytes_to_file(fname2, buf, buflen, 1);
- write_bytes_to_file(fname3, buf, 16384, 1);
-
- mapping = tor_mmap_file(fname1);
- test_assert(mapping);
- test_eq(mapping->size, strlen("Short file."));
- test_streq(mapping->data, "Short file.");
-#ifdef MS_WINDOWS
- tor_munmap_file(mapping);
- mapping = NULL;
- test_assert(unlink(fname1) == 0);
-#else
- /* make sure we can unlink. */
- test_assert(unlink(fname1) == 0);
- test_streq(mapping->data, "Short file.");
- tor_munmap_file(mapping);
- mapping = NULL;
-#endif
-
- /* Now a zero-length file. */
- write_str_to_file(fname1, "", 1);
- mapping = tor_mmap_file(fname1);
- test_eq(mapping, NULL);
- test_eq(ERANGE, errno);
- unlink(fname1);
-
- /* Make sure that we fail to map a no-longer-existent file. */
- mapping = tor_mmap_file(fname1);
- test_assert(mapping == NULL);
-
- /* Now try a big file that stretches across a few pages and isn't aligned */
- mapping = tor_mmap_file(fname2);
- test_assert(mapping);
- test_eq(mapping->size, buflen);
- test_memeq(mapping->data, buf, buflen);
- tor_munmap_file(mapping);
- mapping = NULL;
-
- /* Now try a big aligned file. */
- mapping = tor_mmap_file(fname3);
- test_assert(mapping);
- test_eq(mapping->size, 16384);
- test_memeq(mapping->data, buf, 16384);
- tor_munmap_file(mapping);
- mapping = NULL;
-
- done:
- unlink(fname1);
- unlink(fname2);
- unlink(fname3);
-
- tor_free(fname1);
- tor_free(fname2);
- tor_free(fname3);
- tor_free(buf);
-
- if (mapping)
- tor_munmap_file(mapping);
-}
-
-/** Run unit tests for escaping/unescaping data for use by controllers. */
-static void
-test_util_control_formats(void)
-{
- char *out = NULL;
- const char *inp =
- "..This is a test\r\nof the emergency \nbroadcast\r\n..system.\r\nZ.\r\n";
- size_t sz;
-
- sz = read_escaped_data(inp, strlen(inp), &out);
- test_streq(out,
- ".This is a test\nof the emergency \nbroadcast\n.system.\nZ.\n");
- test_eq(sz, strlen(out));
-
- done:
- tor_free(out);
-}
-
-static void
-test_util_sscanf(void)
-{
- unsigned u1, u2, u3;
- char s1[10], s2[10], s3[10], ch;
- int r;
-
- r = tor_sscanf("hello world", "hello world"); /* String match: success */
- test_eq(r, 0);
- r = tor_sscanf("hello world 3", "hello worlb %u", &u1); /* String fail */
- test_eq(r, 0);
- r = tor_sscanf("12345", "%u", &u1); /* Simple number */
- test_eq(r, 1);
- test_eq(u1, 12345u);
- r = tor_sscanf("", "%u", &u1); /* absent number */
- test_eq(r, 0);
- r = tor_sscanf("A", "%u", &u1); /* bogus number */
- test_eq(r, 0);
- r = tor_sscanf("4294967295", "%u", &u1); /* UINT32_MAX should work. */
- test_eq(r, 1);
- test_eq(u1, 4294967295u);
- r = tor_sscanf("4294967296", "%u", &u1); /* Always say -1 at 32 bits. */
- test_eq(r, 0);
- r = tor_sscanf("123456", "%2u%u", &u1, &u2); /* Width */
- test_eq(r, 2);
- test_eq(u1, 12u);
- test_eq(u2, 3456u);
- r = tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1, &u2, &u3); /* separators */
- test_eq(r, 3);
- test_eq(u1, 12u);
- test_eq(u2, 3u);
- test_eq(u3, 456u);
- r = tor_sscanf("12:3:045", "%2u:%2u:%3u", &u1, &u2, &u3); /* 0s */
- test_eq(r, 3);
- test_eq(u1, 12u);
- test_eq(u2, 3u);
- test_eq(u3, 45u);
- /* %u does not match space.*/
- r = tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1, &u2, &u3);
- test_eq(r, 2);
- /* %u does not match negative numbers. */
- r = tor_sscanf("12:3:-4", "%2u:%2u:%3u", &u1, &u2, &u3);
- test_eq(r, 2);
- /* Arbitrary amounts of 0-padding are okay */
- r = tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u", &u1, &u2, &u3);
- test_eq(r, 3);
- test_eq(u1, 12u);
- test_eq(u2, 3u);
- test_eq(u3, 99u);
-
- r = tor_sscanf("99% fresh", "%3u%% fresh", &u1); /* percents are scannable.*/
- test_eq(r, 1);
- test_eq(u1, 99);
-
- r = tor_sscanf("hello", "%s", s1); /* %s needs a number. */
- test_eq(r, -1);
-
- r = tor_sscanf("hello", "%3s%7s", s1, s2); /* %s matches characters. */
- test_eq(r, 2);
- test_streq(s1, "hel");
- test_streq(s2, "lo");
- r = tor_sscanf("WD40", "%2s%u", s3, &u1); /* %s%u */
- test_eq(r, 2);
- test_streq(s3, "WD");
- test_eq(u1, 40);
- r = tor_sscanf("76trombones", "%6u%9s", &u1, s1); /* %u%s */
- test_eq(r, 2);
- test_eq(u1, 76);
- test_streq(s1, "trombones");
- r = tor_sscanf("hello world", "%9s %9s", s1, s2); /* %s doesn't eat space. */
- test_eq(r, 2);
- test_streq(s1, "hello");
- test_streq(s2, "world");
- r = tor_sscanf("hi", "%9s%9s%3s", s1, s2, s3); /* %s can be empty. */
- test_eq(r, 3);
- test_streq(s1, "hi");
- test_streq(s2, "");
- test_streq(s3, "");
-
- r = tor_sscanf("1.2.3", "%u.%u.%u%c", &u1, &u2, &u3, &ch);
- test_eq(r, 3);
- r = tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1, &u2, &u3, &ch);
- test_eq(r, 4);
-
- done:
- ;
-}
-
-/** Run unit tests for the onion handshake code. */
-static void
-test_onion_handshake(void)
-{
- /* client-side */
- crypto_dh_env_t *c_dh = NULL;
- char c_buf[ONIONSKIN_CHALLENGE_LEN];
- char c_keys[40];
-
- /* server-side */
- char s_buf[ONIONSKIN_REPLY_LEN];
- char s_keys[40];
-
- /* shared */
- crypto_pk_env_t *pk = NULL;
-
- pk = pk_generate(0);
-
- /* client handshake 1. */
- memset(c_buf, 0, ONIONSKIN_CHALLENGE_LEN);
- test_assert(! onion_skin_create(pk, &c_dh, c_buf));
-
- /* server handshake */
- memset(s_buf, 0, ONIONSKIN_REPLY_LEN);
- memset(s_keys, 0, 40);
- test_assert(! onion_skin_server_handshake(c_buf, pk, NULL,
- s_buf, s_keys, 40));
-
- /* client handshake 2 */
- memset(c_keys, 0, 40);
- test_assert(! onion_skin_client_handshake(c_dh, s_buf, c_keys, 40));
-
- if (memcmp(c_keys, s_keys, 40)) {
- puts("Aiiiie");
- exit(1);
- }
- test_memeq(c_keys, s_keys, 40);
- memset(s_buf, 0, 40);
- test_memneq(c_keys, s_buf, 40);
-
- done:
- if (c_dh)
- crypto_dh_free(c_dh);
- if (pk)
- crypto_free_pk_env(pk);
-}
-
-/** Run unit tests for router descriptor generation logic. */
-static void
-test_dir_format(void)
-{
- char buf[8192], buf2[8192];
- char platform[256];
- char fingerprint[FINGERPRINT_LEN+1];
- char *pk1_str = NULL, *pk2_str = NULL, *pk3_str = NULL, *cp;
- size_t pk1_str_len, pk2_str_len, pk3_str_len;
- routerinfo_t *r1=NULL, *r2=NULL;
- crypto_pk_env_t *pk1 = NULL, *pk2 = NULL, *pk3 = NULL;
- routerinfo_t *rp1 = NULL;
- addr_policy_t *ex1, *ex2;
- routerlist_t *dir1 = NULL, *dir2 = NULL;
- tor_version_t ver1;
-
- pk1 = pk_generate(0);
- pk2 = pk_generate(1);
- pk3 = pk_generate(2);
-
- test_assert( is_legal_nickname("a"));
- test_assert(!is_legal_nickname(""));
- test_assert(!is_legal_nickname("abcdefghijklmnopqrst")); /* 20 chars */
- test_assert(!is_legal_nickname("hyphen-")); /* bad char */
- test_assert( is_legal_nickname("abcdefghijklmnopqrs")); /* 19 chars */
- test_assert(!is_legal_nickname("$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
- /* valid */
- test_assert( is_legal_nickname_or_hexdigest(
- "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
- test_assert( is_legal_nickname_or_hexdigest(
- "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
- test_assert( is_legal_nickname_or_hexdigest(
- "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA~fred"));
- /* too short */
- test_assert(!is_legal_nickname_or_hexdigest(
- "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
- /* illegal char */
- test_assert(!is_legal_nickname_or_hexdigest(
- "$AAAAAAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
- /* hex part too long */
- test_assert(!is_legal_nickname_or_hexdigest(
- "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
- test_assert(!is_legal_nickname_or_hexdigest(
- "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
- /* Bad nickname */
- test_assert(!is_legal_nickname_or_hexdigest(
- "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="));
- test_assert(!is_legal_nickname_or_hexdigest(
- "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"));
- test_assert(!is_legal_nickname_or_hexdigest(
- "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~hyphen-"));
- test_assert(!is_legal_nickname_or_hexdigest(
- "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"
- "abcdefghijklmnoppqrst"));
- /* Bad extra char. */
- test_assert(!is_legal_nickname_or_hexdigest(
- "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!"));
- test_assert(is_legal_nickname_or_hexdigest("xyzzy"));
- test_assert(is_legal_nickname_or_hexdigest("abcdefghijklmnopqrs"));
- test_assert(!is_legal_nickname_or_hexdigest("abcdefghijklmnopqrst"));
-
- get_platform_str(platform, sizeof(platform));
- r1 = tor_malloc_zero(sizeof(routerinfo_t));
- r1->address = tor_strdup("18.244.0.1");
- r1->addr = 0xc0a80001u; /* 192.168.0.1 */
- r1->cache_info.published_on = 0;
- r1->or_port = 9000;
- r1->dir_port = 9003;
- r1->onion_pkey = crypto_pk_dup_key(pk1);
- r1->identity_pkey = crypto_pk_dup_key(pk2);
- r1->bandwidthrate = 1000;
- r1->bandwidthburst = 5000;
- r1->bandwidthcapacity = 10000;
- r1->exit_policy = NULL;
- r1->nickname = tor_strdup("Magri");
- r1->platform = tor_strdup(platform);
-
- ex1 = tor_malloc_zero(sizeof(addr_policy_t));
- ex2 = tor_malloc_zero(sizeof(addr_policy_t));
- ex1->policy_type = ADDR_POLICY_ACCEPT;
- tor_addr_from_ipv4h(&ex1->addr, 0);
- ex1->maskbits = 0;
- ex1->prt_min = ex1->prt_max = 80;
- ex2->policy_type = ADDR_POLICY_REJECT;
- tor_addr_from_ipv4h(&ex2->addr, 18<<24);
- ex2->maskbits = 8;
- ex2->prt_min = ex2->prt_max = 24;
- r2 = tor_malloc_zero(sizeof(routerinfo_t));
- r2->address = tor_strdup("1.1.1.1");
- r2->addr = 0x0a030201u; /* 10.3.2.1 */
- r2->platform = tor_strdup(platform);
- r2->cache_info.published_on = 5;
- r2->or_port = 9005;
- r2->dir_port = 0;
- r2->onion_pkey = crypto_pk_dup_key(pk2);
- r2->identity_pkey = crypto_pk_dup_key(pk1);
- r2->bandwidthrate = r2->bandwidthburst = r2->bandwidthcapacity = 3000;
- r2->exit_policy = smartlist_create();
- smartlist_add(r2->exit_policy, ex2);
- smartlist_add(r2->exit_policy, ex1);
- r2->nickname = tor_strdup("Fred");
-
- test_assert(!crypto_pk_write_public_key_to_string(pk1, &pk1_str,
- &pk1_str_len));
- test_assert(!crypto_pk_write_public_key_to_string(pk2 , &pk2_str,
- &pk2_str_len));
- test_assert(!crypto_pk_write_public_key_to_string(pk3 , &pk3_str,
- &pk3_str_len));
-
- memset(buf, 0, 2048);
- test_assert(router_dump_router_to_string(buf, 2048, r1, pk2)>0);
-
- strlcpy(buf2, "router Magri 18.244.0.1 9000 0 9003\n"
- "platform Tor "VERSION" on ", sizeof(buf2));
- strlcat(buf2, get_uname(), sizeof(buf2));
- strlcat(buf2, "\n"
- "opt protocols Link 1 2 Circuit 1\n"
- "published 1970-01-01 00:00:00\n"
- "opt fingerprint ", sizeof(buf2));
- test_assert(!crypto_pk_get_fingerprint(pk2, fingerprint, 1));
- strlcat(buf2, fingerprint, sizeof(buf2));
- strlcat(buf2, "\nuptime 0\n"
- /* XXX the "0" above is hard-coded, but even if we made it reflect
- * uptime, that still wouldn't make it right, because the two
- * descriptors might be made on different seconds... hm. */
- "bandwidth 1000 5000 10000\n"
- "opt extra-info-digest 0000000000000000000000000000000000000000\n"
- "onion-key\n", sizeof(buf2));
- strlcat(buf2, pk1_str, sizeof(buf2));
- strlcat(buf2, "signing-key\n", sizeof(buf2));
- strlcat(buf2, pk2_str, sizeof(buf2));
- strlcat(buf2, "opt hidden-service-dir\n", sizeof(buf2));
- strlcat(buf2, "reject *:*\nrouter-signature\n", sizeof(buf2));
- buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same
- * twice */
-
- test_streq(buf, buf2);
-
- test_assert(router_dump_router_to_string(buf, 2048, r1, pk2)>0);
- cp = buf;
- rp1 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL);
- test_assert(rp1);
- test_streq(rp1->address, r1->address);
- test_eq(rp1->or_port, r1->or_port);
- //test_eq(rp1->dir_port, r1->dir_port);
- test_eq(rp1->bandwidthrate, r1->bandwidthrate);
- test_eq(rp1->bandwidthburst, r1->bandwidthburst);
- test_eq(rp1->bandwidthcapacity, r1->bandwidthcapacity);
- test_assert(crypto_pk_cmp_keys(rp1->onion_pkey, pk1) == 0);
- test_assert(crypto_pk_cmp_keys(rp1->identity_pkey, pk2) == 0);
- //test_assert(rp1->exit_policy == NULL);
-
-#if 0
- /* XXX Once we have exit policies, test this again. XXX */
- strlcpy(buf2, "router tor.tor.tor 9005 0 0 3000\n", sizeof(buf2));
- strlcat(buf2, pk2_str, sizeof(buf2));
- strlcat(buf2, "signing-key\n", sizeof(buf2));
- strlcat(buf2, pk1_str, sizeof(buf2));
- strlcat(buf2, "accept *:80\nreject 18.*:24\n\n", sizeof(buf2));
- test_assert(router_dump_router_to_string(buf, 2048, &r2, pk2)>0);
- test_streq(buf, buf2);
-
- cp = buf;
- rp2 = router_parse_entry_from_string(&cp,1);
- test_assert(rp2);
- test_streq(rp2->address, r2.address);
- test_eq(rp2->or_port, r2.or_port);
- test_eq(rp2->dir_port, r2.dir_port);
- test_eq(rp2->bandwidth, r2.bandwidth);
- test_assert(crypto_pk_cmp_keys(rp2->onion_pkey, pk2) == 0);
- test_assert(crypto_pk_cmp_keys(rp2->identity_pkey, pk1) == 0);
- test_eq(rp2->exit_policy->policy_type, EXIT_POLICY_ACCEPT);
- test_streq(rp2->exit_policy->string, "accept *:80");
- test_streq(rp2->exit_policy->address, "*");
- test_streq(rp2->exit_policy->port, "80");
- test_eq(rp2->exit_policy->next->policy_type, EXIT_POLICY_REJECT);
- test_streq(rp2->exit_policy->next->string, "reject 18.*:24");
- test_streq(rp2->exit_policy->next->address, "18.*");
- test_streq(rp2->exit_policy->next->port, "24");
- test_assert(rp2->exit_policy->next->next == NULL);
-
- /* Okay, now for the directories. */
- {
- fingerprint_list = smartlist_create();
- crypto_pk_get_fingerprint(pk2, buf, 1);
- add_fingerprint_to_dir("Magri", buf, fingerprint_list);
- crypto_pk_get_fingerprint(pk1, buf, 1);
- add_fingerprint_to_dir("Fred", buf, fingerprint_list);
- }
-
- {
- char d[DIGEST_LEN];
- const char *m;
- /* XXXX NM re-enable. */
- /* Make sure routers aren't too far in the past any more. */
- r1->cache_info.published_on = time(NULL);
- r2->cache_info.published_on = time(NULL)-3*60*60;
- test_assert(router_dump_router_to_string(buf, 2048, r1, pk2)>0);
- test_eq(dirserv_add_descriptor(buf,&m,""), ROUTER_ADDED_NOTIFY_GENERATOR);
- test_assert(router_dump_router_to_string(buf, 2048, r2, pk1)>0);
- test_eq(dirserv_add_descriptor(buf,&m,""), ROUTER_ADDED_NOTIFY_GENERATOR);
- get_options()->Nickname = tor_strdup("DirServer");
- test_assert(!dirserv_dump_directory_to_string(&cp,pk3, 0));
- crypto_pk_get_digest(pk3, d);
- test_assert(!router_parse_directory(cp));
- test_eq(2, smartlist_len(dir1->routers));
- tor_free(cp);
- }
-#endif
- dirserv_free_fingerprint_list();
-
- /* Try out version parsing functionality */
- test_eq(0, tor_version_parse("0.3.4pre2-cvs", &ver1));
- test_eq(0, ver1.major);
- test_eq(3, ver1.minor);
- test_eq(4, ver1.micro);
- test_eq(VER_PRE, ver1.status);
- test_eq(2, ver1.patchlevel);
- test_eq(0, tor_version_parse("0.3.4rc1", &ver1));
- test_eq(0, ver1.major);
- test_eq(3, ver1.minor);
- test_eq(4, ver1.micro);
- test_eq(VER_RC, ver1.status);
- test_eq(1, ver1.patchlevel);
- test_eq(0, tor_version_parse("1.3.4", &ver1));
- test_eq(1, ver1.major);
- test_eq(3, ver1.minor);
- test_eq(4, ver1.micro);
- test_eq(VER_RELEASE, ver1.status);
- test_eq(0, ver1.patchlevel);
- test_eq(0, tor_version_parse("1.3.4.999", &ver1));
- test_eq(1, ver1.major);
- test_eq(3, ver1.minor);
- test_eq(4, ver1.micro);
- test_eq(VER_RELEASE, ver1.status);
- test_eq(999, ver1.patchlevel);
- test_eq(0, tor_version_parse("0.1.2.4-alpha", &ver1));
- test_eq(0, ver1.major);
- test_eq(1, ver1.minor);
- test_eq(2, ver1.micro);
- test_eq(4, ver1.patchlevel);
- test_eq(VER_RELEASE, ver1.status);
- test_streq("alpha", ver1.status_tag);
- test_eq(0, tor_version_parse("0.1.2.4", &ver1));
- test_eq(0, ver1.major);
- test_eq(1, ver1.minor);
- test_eq(2, ver1.micro);
- test_eq(4, ver1.patchlevel);
- test_eq(VER_RELEASE, ver1.status);
- test_streq("", ver1.status_tag);
-
-#define test_eq_vs(vs1, vs2) test_eq_type(version_status_t, "%d", (vs1), (vs2))
-#define test_v_i_o(val, ver, lst) \
- test_eq_vs(val, tor_version_is_obsolete(ver, lst))
-
- /* make sure tor_version_is_obsolete() works */
- test_v_i_o(VS_OLD, "0.0.1", "Tor 0.0.2");
- test_v_i_o(VS_OLD, "0.0.1", "0.0.2, Tor 0.0.3");
- test_v_i_o(VS_OLD, "0.0.1", "0.0.2,Tor 0.0.3");
- test_v_i_o(VS_OLD, "0.0.1","0.0.3,BetterTor 0.0.1");
- test_v_i_o(VS_RECOMMENDED, "0.0.2", "Tor 0.0.2,Tor 0.0.3");
- test_v_i_o(VS_NEW_IN_SERIES, "0.0.2", "Tor 0.0.2pre1,Tor 0.0.3");
- test_v_i_o(VS_OLD, "0.0.2", "Tor 0.0.2.1,Tor 0.0.3");
- test_v_i_o(VS_NEW, "0.1.0", "Tor 0.0.2,Tor 0.0.3");
- test_v_i_o(VS_RECOMMENDED, "0.0.7rc2", "0.0.7,Tor 0.0.7rc2,Tor 0.0.8");
- test_v_i_o(VS_OLD, "0.0.5.0", "0.0.5.1-cvs");
- test_v_i_o(VS_NEW_IN_SERIES, "0.0.5.1-cvs", "0.0.5, 0.0.6");
- /* Not on list, but newer than any in same series. */
- test_v_i_o(VS_NEW_IN_SERIES, "0.1.0.3",
- "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
- /* Series newer than any on list. */
- test_v_i_o(VS_NEW, "0.1.2.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
- /* Series older than any on list. */
- test_v_i_o(VS_OLD, "0.0.1.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
- /* Not on list, not newer than any on same series. */
- test_v_i_o(VS_UNRECOMMENDED, "0.1.0.1",
- "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
- /* On list, not newer than any on same series. */
- test_v_i_o(VS_UNRECOMMENDED,
- "0.1.0.1", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
- test_eq(0, tor_version_as_new_as("Tor 0.0.5", "0.0.9pre1-cvs"));
- test_eq(1, tor_version_as_new_as(
- "Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
- "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh",
- "0.0.8rc2"));
- test_eq(0, tor_version_as_new_as(
- "Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
- "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh", "0.0.8.2"));
-
- /* Now try svn revisions. */
- test_eq(1, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
- "Tor 0.2.1.0-dev (r99)"));
- test_eq(1, tor_version_as_new_as("Tor 0.2.1.0-dev (r100) on Banana Jr",
- "Tor 0.2.1.0-dev (r99) on Hal 9000"));
- test_eq(1, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
- "Tor 0.2.1.0-dev on Colossus"));
- test_eq(0, tor_version_as_new_as("Tor 0.2.1.0-dev (r99)",
- "Tor 0.2.1.0-dev (r100)"));
- test_eq(0, tor_version_as_new_as("Tor 0.2.1.0-dev (r99) on MCP",
- "Tor 0.2.1.0-dev (r100) on AM"));
- test_eq(0, tor_version_as_new_as("Tor 0.2.1.0-dev",
- "Tor 0.2.1.0-dev (r99)"));
- test_eq(1, tor_version_as_new_as("Tor 0.2.1.1",
- "Tor 0.2.1.0-dev (r99)"));
- done:
- if (r1)
- routerinfo_free(r1);
- if (r2)
- routerinfo_free(r2);
-
- tor_free(pk1_str);
- tor_free(pk2_str);
- tor_free(pk3_str);
- if (pk1) crypto_free_pk_env(pk1);
- if (pk2) crypto_free_pk_env(pk2);
- if (pk3) crypto_free_pk_env(pk3);
- if (rp1) routerinfo_free(rp1);
- tor_free(dir1); /* XXXX And more !*/
- tor_free(dir2); /* And more !*/
-}
-
-/** Run unit tests for misc directory functions. */
-static void
-test_dirutil(void)
-{
- smartlist_t *sl = smartlist_create();
- fp_pair_t *pair;
-
- dir_split_resource_into_fingerprint_pairs(
- /* Two pairs, out of order, with one duplicate. */
- "73656372657420646174612E0000000000FFFFFF-"
- "557365204145532d32353620696e73746561642e+"
- "73656372657420646174612E0000000000FFFFFF-"
- "557365204145532d32353620696e73746561642e+"
- "48657861646563696d616c2069736e277420736f-"
- "676f6f6420666f7220686964696e6720796f7572.z", sl);
-
- test_eq(smartlist_len(sl), 2);
- pair = smartlist_get(sl, 0);
- test_memeq(pair->first, "Hexadecimal isn't so", DIGEST_LEN);
- test_memeq(pair->second, "good for hiding your", DIGEST_LEN);
- pair = smartlist_get(sl, 1);
- test_memeq(pair->first, "secret data.\0\0\0\0\0\xff\xff\xff", DIGEST_LEN);
- test_memeq(pair->second, "Use AES-256 instead.", DIGEST_LEN);
-
- done:
- SMARTLIST_FOREACH(sl, fp_pair_t *, pair, tor_free(pair));
- smartlist_free(sl);
-}
-
-extern const char AUTHORITY_CERT_1[];
-extern const char AUTHORITY_SIGNKEY_1[];
-extern const char AUTHORITY_CERT_2[];
-extern const char AUTHORITY_SIGNKEY_2[];
-extern const char AUTHORITY_CERT_3[];
-extern const char AUTHORITY_SIGNKEY_3[];
-
-/** Helper: Test that two networkstatus_voter_info_t do in fact represent the
- * same voting authority, and that they do in fact have all the same
- * information. */
-static void
-test_same_voter(networkstatus_voter_info_t *v1,
- networkstatus_voter_info_t *v2)
-{
- test_streq(v1->nickname, v2->nickname);
- test_memeq(v1->identity_digest, v2->identity_digest, DIGEST_LEN);
- test_streq(v1->address, v2->address);
- test_eq(v1->addr, v2->addr);
- test_eq(v1->dir_port, v2->dir_port);
- test_eq(v1->or_port, v2->or_port);
- test_streq(v1->contact, v2->contact);
- test_memeq(v1->vote_digest, v2->vote_digest, DIGEST_LEN);
- done:
- ;
-}
-
-/** Run unit tests for getting the median of a list. */
-static void
-test_util_order_functions(void)
-{
- int lst[25], n = 0;
- // int a=12,b=24,c=25,d=60,e=77;
-
-#define median() median_int(lst, n)
-
- lst[n++] = 12;
- test_eq(12, median()); /* 12 */
- lst[n++] = 77;
- //smartlist_shuffle(sl);
- test_eq(12, median()); /* 12, 77 */
- lst[n++] = 77;
- //smartlist_shuffle(sl);
- test_eq(77, median()); /* 12, 77, 77 */
- lst[n++] = 24;
- test_eq(24, median()); /* 12,24,77,77 */
- lst[n++] = 60;
- lst[n++] = 12;
- lst[n++] = 25;
- //smartlist_shuffle(sl);
- test_eq(25, median()); /* 12,12,24,25,60,77,77 */
-#undef median
-
- done:
- ;
-}
-
-/** Helper: Make a new routerinfo containing the right information for a
- * given vote_routerstatus_t. */
-static routerinfo_t *
-generate_ri_from_rs(const vote_routerstatus_t *vrs)
-{
- routerinfo_t *r;
- const routerstatus_t *rs = &vrs->status;
- static time_t published = 0;
-
- r = tor_malloc_zero(sizeof(routerinfo_t));
- memcpy(r->cache_info.identity_digest, rs->identity_digest, DIGEST_LEN);
- memcpy(r->cache_info.signed_descriptor_digest, rs->descriptor_digest,
- DIGEST_LEN);
- r->cache_info.do_not_cache = 1;
- r->cache_info.routerlist_index = -1;
- r->cache_info.signed_descriptor_body =
- tor_strdup("123456789012345678901234567890123");
- r->cache_info.signed_descriptor_len =
- strlen(r->cache_info.signed_descriptor_body);
- r->exit_policy = smartlist_create();
- r->cache_info.published_on = ++published + time(NULL);
- return r;
-}
-
-/** Run unit tests for generating and parsing V3 consensus networkstatus
- * documents. */
-static void
-test_v3_networkstatus(void)
-{
- authority_cert_t *cert1=NULL, *cert2=NULL, *cert3=NULL;
- crypto_pk_env_t *sign_skey_1=NULL, *sign_skey_2=NULL, *sign_skey_3=NULL;
- crypto_pk_env_t *sign_skey_leg1=NULL;
- const char *msg=NULL;
-
- time_t now = time(NULL);
- networkstatus_voter_info_t *voter;
- networkstatus_t *vote=NULL, *v1=NULL, *v2=NULL, *v3=NULL, *con=NULL;
- vote_routerstatus_t *vrs;
- routerstatus_t *rs;
- char *v1_text=NULL, *v2_text=NULL, *v3_text=NULL, *consensus_text=NULL, *cp;
- smartlist_t *votes = smartlist_create();
-
- /* For generating the two other consensuses. */
- char *detached_text1=NULL, *detached_text2=NULL;
- char *consensus_text2=NULL, *consensus_text3=NULL;
- networkstatus_t *con2=NULL, *con3=NULL;
- ns_detached_signatures_t *dsig1=NULL, *dsig2=NULL;
-
- /* Parse certificates and keys. */
- cert1 = authority_cert_parse_from_string(AUTHORITY_CERT_1, NULL);
- test_assert(cert1);
- test_assert(cert1->is_cross_certified);
- cert2 = authority_cert_parse_from_string(AUTHORITY_CERT_2, NULL);
- test_assert(cert2);
- cert3 = authority_cert_parse_from_string(AUTHORITY_CERT_3, NULL);
- test_assert(cert3);
- sign_skey_1 = crypto_new_pk_env();
- sign_skey_2 = crypto_new_pk_env();
- sign_skey_3 = crypto_new_pk_env();
- sign_skey_leg1 = pk_generate(4);
-
- test_assert(!crypto_pk_read_private_key_from_string(sign_skey_1,
- AUTHORITY_SIGNKEY_1));
- test_assert(!crypto_pk_read_private_key_from_string(sign_skey_2,
- AUTHORITY_SIGNKEY_2));
- test_assert(!crypto_pk_read_private_key_from_string(sign_skey_3,
- AUTHORITY_SIGNKEY_3));
-
- test_assert(!crypto_pk_cmp_keys(sign_skey_1, cert1->signing_key));
- test_assert(!crypto_pk_cmp_keys(sign_skey_2, cert2->signing_key));
-
- /*
- * Set up a vote; generate it; try to parse it.
- */
- vote = tor_malloc_zero(sizeof(networkstatus_t));
- vote->type = NS_TYPE_VOTE;
- vote->published = now;
- vote->valid_after = now+1000;
- vote->fresh_until = now+2000;
- vote->valid_until = now+3000;
- vote->vote_seconds = 100;
- vote->dist_seconds = 200;
- vote->supported_methods = smartlist_create();
- smartlist_split_string(vote->supported_methods, "1 2 3", NULL, 0, -1);
- vote->client_versions = tor_strdup("0.1.2.14,0.1.2.15");
- vote->server_versions = tor_strdup("0.1.2.14,0.1.2.15,0.1.2.16");
- vote->known_flags = smartlist_create();
- smartlist_split_string(vote->known_flags,
- "Authority Exit Fast Guard Running Stable V2Dir Valid",
- 0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- vote->voters = smartlist_create();
- voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
- voter->nickname = tor_strdup("Voter1");
- voter->address = tor_strdup("1.2.3.4");
- voter->addr = 0x01020304;
- voter->dir_port = 80;
- voter->or_port = 9000;
- voter->contact = tor_strdup("voter@example.com");
- crypto_pk_get_digest(cert1->identity_key, voter->identity_digest);
- smartlist_add(vote->voters, voter);
- vote->cert = authority_cert_dup(cert1);
- vote->routerstatus_list = smartlist_create();
- /* add the first routerstatus. */
- vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
- rs = &vrs->status;
- vrs->version = tor_strdup("0.1.2.14");
- rs->published_on = now-1500;
- strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
- memset(rs->identity_digest, 3, DIGEST_LEN);
- memset(rs->descriptor_digest, 78, DIGEST_LEN);
- rs->addr = 0x99008801;
- rs->or_port = 443;
- rs->dir_port = 8000;
- /* all flags but running cleared */
- rs->is_running = 1;
- smartlist_add(vote->routerstatus_list, vrs);
- test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
-
- /* add the second routerstatus. */
- vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
- rs = &vrs->status;
- vrs->version = tor_strdup("0.2.0.5");
- rs->published_on = now-1000;
- strlcpy(rs->nickname, "router1", sizeof(rs->nickname));
- memset(rs->identity_digest, 5, DIGEST_LEN);
- memset(rs->descriptor_digest, 77, DIGEST_LEN);
- rs->addr = 0x99009901;
- rs->or_port = 443;
- rs->dir_port = 0;
- rs->is_exit = rs->is_stable = rs->is_fast = rs->is_running =
- rs->is_valid = rs->is_v2_dir = rs->is_possible_guard = 1;
- smartlist_add(vote->routerstatus_list, vrs);
- test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
-
- /* add the third routerstatus. */
- vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
- rs = &vrs->status;
- vrs->version = tor_strdup("0.1.0.3");
- rs->published_on = now-1000;
- strlcpy(rs->nickname, "router3", sizeof(rs->nickname));
- memset(rs->identity_digest, 33, DIGEST_LEN);
- memset(rs->descriptor_digest, 79, DIGEST_LEN);
- rs->addr = 0xAA009901;
- rs->or_port = 400;
- rs->dir_port = 9999;
- rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
- rs->is_running = rs->is_valid = rs->is_v2_dir = rs->is_possible_guard = 1;
- smartlist_add(vote->routerstatus_list, vrs);
- test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
-
- /* add a fourth routerstatus that is not running. */
- vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
- rs = &vrs->status;
- vrs->version = tor_strdup("0.1.6.3");
- rs->published_on = now-1000;
- strlcpy(rs->nickname, "router4", sizeof(rs->nickname));
- memset(rs->identity_digest, 34, DIGEST_LEN);
- memset(rs->descriptor_digest, 48, DIGEST_LEN);
- rs->addr = 0xC0000203;
- rs->or_port = 500;
- rs->dir_port = 1999;
- /* Running flag (and others) cleared */
- smartlist_add(vote->routerstatus_list, vrs);
- test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
-
- /* dump the vote and try to parse it. */
- v1_text = format_networkstatus_vote(sign_skey_1, vote);
- test_assert(v1_text);
- v1 = networkstatus_parse_vote_from_string(v1_text, NULL, NS_TYPE_VOTE);
- test_assert(v1);
-
- /* Make sure the parsed thing was right. */
- test_eq(v1->type, NS_TYPE_VOTE);
- test_eq(v1->published, vote->published);
- test_eq(v1->valid_after, vote->valid_after);
- test_eq(v1->fresh_until, vote->fresh_until);
- test_eq(v1->valid_until, vote->valid_until);
- test_eq(v1->vote_seconds, vote->vote_seconds);
- test_eq(v1->dist_seconds, vote->dist_seconds);
- test_streq(v1->client_versions, vote->client_versions);
- test_streq(v1->server_versions, vote->server_versions);
- test_assert(v1->voters && smartlist_len(v1->voters));
- voter = smartlist_get(v1->voters, 0);
- test_streq(voter->nickname, "Voter1");
- test_streq(voter->address, "1.2.3.4");
- test_eq(voter->addr, 0x01020304);
- test_eq(voter->dir_port, 80);
- test_eq(voter->or_port, 9000);
- test_streq(voter->contact, "voter@example.com");
- test_assert(v1->cert);
- test_assert(!crypto_pk_cmp_keys(sign_skey_1, v1->cert->signing_key));
- cp = smartlist_join_strings(v1->known_flags, ":", 0, NULL);
- test_streq(cp, "Authority:Exit:Fast:Guard:Running:Stable:V2Dir:Valid");
- tor_free(cp);
- test_eq(smartlist_len(v1->routerstatus_list), 4);
- /* Check the first routerstatus. */
- vrs = smartlist_get(v1->routerstatus_list, 0);
- rs = &vrs->status;
- test_streq(vrs->version, "0.1.2.14");
- test_eq(rs->published_on, now-1500);
- test_streq(rs->nickname, "router2");
- test_memeq(rs->identity_digest,
- "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
- DIGEST_LEN);
- test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
- test_eq(rs->addr, 0x99008801);
- test_eq(rs->or_port, 443);
- test_eq(rs->dir_port, 8000);
- test_eq(vrs->flags, U64_LITERAL(16)); // no flags except "running"
- /* Check the second routerstatus. */
- vrs = smartlist_get(v1->routerstatus_list, 1);
- rs = &vrs->status;
- test_streq(vrs->version, "0.2.0.5");
- test_eq(rs->published_on, now-1000);
- test_streq(rs->nickname, "router1");
- test_memeq(rs->identity_digest,
- "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
- DIGEST_LEN);
- test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
- test_eq(rs->addr, 0x99009901);
- test_eq(rs->or_port, 443);
- test_eq(rs->dir_port, 0);
- test_eq(vrs->flags, U64_LITERAL(254)); // all flags except "authority."
-
- /* Generate second vote. It disagrees on some of the times,
- * and doesn't list versions, and knows some crazy flags */
- vote->published = now+1;
- vote->fresh_until = now+3005;
- vote->dist_seconds = 300;
- authority_cert_free(vote->cert);
- vote->cert = authority_cert_dup(cert2);
- tor_free(vote->client_versions);
- tor_free(vote->server_versions);
- voter = smartlist_get(vote->voters, 0);
- tor_free(voter->nickname);
- tor_free(voter->address);
- voter->nickname = tor_strdup("Voter2");
- voter->address = tor_strdup("2.3.4.5");
- voter->addr = 0x02030405;
- crypto_pk_get_digest(cert2->identity_key, voter->identity_digest);
- smartlist_add(vote->known_flags, tor_strdup("MadeOfCheese"));
- smartlist_add(vote->known_flags, tor_strdup("MadeOfTin"));
- smartlist_sort_strings(vote->known_flags);
- vrs = smartlist_get(vote->routerstatus_list, 2);
- smartlist_del_keeporder(vote->routerstatus_list, 2);
- tor_free(vrs->version);
- tor_free(vrs);
- vrs = smartlist_get(vote->routerstatus_list, 0);
- vrs->status.is_fast = 1;
- /* generate and parse. */
- v2_text = format_networkstatus_vote(sign_skey_2, vote);
- test_assert(v2_text);
- v2 = networkstatus_parse_vote_from_string(v2_text, NULL, NS_TYPE_VOTE);
- test_assert(v2);
- /* Check that flags come out right.*/
- cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
- test_streq(cp, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
- "Running:Stable:V2Dir:Valid");
- tor_free(cp);
- vrs = smartlist_get(v2->routerstatus_list, 1);
- /* 1023 - authority(1) - madeofcheese(16) - madeoftin(32) */
- test_eq(vrs->flags, U64_LITERAL(974));
-
- /* Generate the third vote. */
- vote->published = now;
- vote->fresh_until = now+2003;
- vote->dist_seconds = 250;
- authority_cert_free(vote->cert);
- vote->cert = authority_cert_dup(cert3);
- smartlist_add(vote->supported_methods, tor_strdup("4"));
- vote->client_versions = tor_strdup("0.1.2.14,0.1.2.17");
- vote->server_versions = tor_strdup("0.1.2.10,0.1.2.15,0.1.2.16");
- voter = smartlist_get(vote->voters, 0);
- tor_free(voter->nickname);
- tor_free(voter->address);
- voter->nickname = tor_strdup("Voter3");
- voter->address = tor_strdup("3.4.5.6");
- voter->addr = 0x03040506;
- crypto_pk_get_digest(cert3->identity_key, voter->identity_digest);
- /* This one has a legacy id. */
- memset(voter->legacy_id_digest, (int)'A', DIGEST_LEN);
- vrs = smartlist_get(vote->routerstatus_list, 0);
- smartlist_del_keeporder(vote->routerstatus_list, 0);
- tor_free(vrs->version);
- tor_free(vrs);
- vrs = smartlist_get(vote->routerstatus_list, 0);
- memset(vrs->status.descriptor_digest, (int)'Z', DIGEST_LEN);
- test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
-
- v3_text = format_networkstatus_vote(sign_skey_3, vote);
- test_assert(v3_text);
-
- v3 = networkstatus_parse_vote_from_string(v3_text, NULL, NS_TYPE_VOTE);
- test_assert(v3);
-
- /* Compute a consensus as voter 3. */
- smartlist_add(votes, v3);
- smartlist_add(votes, v1);
- smartlist_add(votes, v2);
- consensus_text = networkstatus_compute_consensus(votes, 3,
- cert3->identity_key,
- sign_skey_3,
- "AAAAAAAAAAAAAAAAAAAA",
- sign_skey_leg1);
- test_assert(consensus_text);
- con = networkstatus_parse_vote_from_string(consensus_text, NULL,
- NS_TYPE_CONSENSUS);
- test_assert(con);
- //log_notice(LD_GENERAL, "<<%s>>\n<<%s>>\n<<%s>>\n",
- // v1_text, v2_text, v3_text);
-
- /* Check consensus contents. */
- test_assert(con->type == NS_TYPE_CONSENSUS);
- test_eq(con->published, 0); /* this field only appears in votes. */
- test_eq(con->valid_after, now+1000);
- test_eq(con->fresh_until, now+2003); /* median */
- test_eq(con->valid_until, now+3000);
- test_eq(con->vote_seconds, 100);
- test_eq(con->dist_seconds, 250); /* median */
- test_streq(con->client_versions, "0.1.2.14");
- test_streq(con->server_versions, "0.1.2.15,0.1.2.16");
- cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
- test_streq(cp, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
- "Running:Stable:V2Dir:Valid");
- tor_free(cp);
- test_eq(4, smartlist_len(con->voters)); /*3 voters, 1 legacy key.*/
- /* The voter id digests should be in this order. */
- test_assert(memcmp(cert2->cache_info.identity_digest,
- cert1->cache_info.identity_digest,DIGEST_LEN)<0);
- test_assert(memcmp(cert1->cache_info.identity_digest,
- cert3->cache_info.identity_digest,DIGEST_LEN)<0);
- test_same_voter(smartlist_get(con->voters, 1),
- smartlist_get(v2->voters, 0));
- test_same_voter(smartlist_get(con->voters, 2),
- smartlist_get(v1->voters, 0));
- test_same_voter(smartlist_get(con->voters, 3),
- smartlist_get(v3->voters, 0));
-
- test_assert(!con->cert);
- test_eq(2, smartlist_len(con->routerstatus_list));
- /* There should be two listed routers: one with identity 3, one with
- * identity 5. */
- /* This one showed up in 2 digests. */
- rs = smartlist_get(con->routerstatus_list, 0);
- test_memeq(rs->identity_digest,
- "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
- DIGEST_LEN);
- test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
- test_assert(!rs->is_authority);
- test_assert(!rs->is_exit);
- test_assert(!rs->is_fast);
- test_assert(!rs->is_possible_guard);
- test_assert(!rs->is_stable);
- test_assert(rs->is_running); /* If it wasn't running it wouldn't be here */
- test_assert(!rs->is_v2_dir);
- test_assert(!rs->is_valid);
- test_assert(!rs->is_named);
- /* XXXX check version */
-
- rs = smartlist_get(con->routerstatus_list, 1);
- /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */
- test_memeq(rs->identity_digest,
- "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
- DIGEST_LEN);
- test_streq(rs->nickname, "router1");
- test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
- test_eq(rs->published_on, now-1000);
- test_eq(rs->addr, 0x99009901);
- test_eq(rs->or_port, 443);
- test_eq(rs->dir_port, 0);
- test_assert(!rs->is_authority);
- test_assert(rs->is_exit);
- test_assert(rs->is_fast);
- test_assert(rs->is_possible_guard);
- test_assert(rs->is_stable);
- test_assert(rs->is_running);
- test_assert(rs->is_v2_dir);
- test_assert(rs->is_valid);
- test_assert(!rs->is_named);
- /* XXXX check version */
- // x231
- // x213
-
- /* Check signatures. the first voter is a pseudo-entry with a legacy key.
- * The second one hasn't signed. The fourth one has signed: validate it. */
- voter = smartlist_get(con->voters, 1);
- test_assert(!voter->signature);
- test_assert(!voter->good_signature);
- test_assert(!voter->bad_signature);
-
- voter = smartlist_get(con->voters, 3);
- test_assert(voter->signature);
- test_assert(!voter->good_signature);
- test_assert(!voter->bad_signature);
- test_assert(!networkstatus_check_voter_signature(con,
- smartlist_get(con->voters, 3),
- cert3));
- test_assert(voter->signature);
- test_assert(voter->good_signature);
- test_assert(!voter->bad_signature);
-
- {
- const char *msg=NULL;
- /* Compute the other two signed consensuses. */
- smartlist_shuffle(votes);
- consensus_text2 = networkstatus_compute_consensus(votes, 3,
- cert2->identity_key,
- sign_skey_2, NULL,NULL);
- smartlist_shuffle(votes);
- consensus_text3 = networkstatus_compute_consensus(votes, 3,
- cert1->identity_key,
- sign_skey_1, NULL,NULL);
- test_assert(consensus_text2);
- test_assert(consensus_text3);
- con2 = networkstatus_parse_vote_from_string(consensus_text2, NULL,
- NS_TYPE_CONSENSUS);
- con3 = networkstatus_parse_vote_from_string(consensus_text3, NULL,
- NS_TYPE_CONSENSUS);
- test_assert(con2);
- test_assert(con3);
-
- /* All three should have the same digest. */
- test_memeq(con->networkstatus_digest, con2->networkstatus_digest,
- DIGEST_LEN);
- test_memeq(con->networkstatus_digest, con3->networkstatus_digest,
- DIGEST_LEN);
-
- /* Extract a detached signature from con3. */
- detached_text1 = networkstatus_get_detached_signatures(con3);
- tor_assert(detached_text1);
- /* Try to parse it. */
- dsig1 = networkstatus_parse_detached_signatures(detached_text1, NULL);
- tor_assert(dsig1);
-
- /* Are parsed values as expected? */
- test_eq(dsig1->valid_after, con3->valid_after);
- test_eq(dsig1->fresh_until, con3->fresh_until);
- test_eq(dsig1->valid_until, con3->valid_until);
- test_memeq(dsig1->networkstatus_digest, con3->networkstatus_digest,
- DIGEST_LEN);
- test_eq(1, smartlist_len(dsig1->signatures));
- voter = smartlist_get(dsig1->signatures, 0);
- test_memeq(voter->identity_digest, cert1->cache_info.identity_digest,
- DIGEST_LEN);
-
- /* Try adding it to con2. */
- detached_text2 = networkstatus_get_detached_signatures(con2);
- test_eq(1, networkstatus_add_detached_signatures(con2, dsig1, &msg));
- tor_free(detached_text2);
- detached_text2 = networkstatus_get_detached_signatures(con2);
- //printf("\n<%s>\n", detached_text2);
- dsig2 = networkstatus_parse_detached_signatures(detached_text2, NULL);
- test_assert(dsig2);
- /*
- printf("\n");
- SMARTLIST_FOREACH(dsig2->signatures, networkstatus_voter_info_t *, vi, {
- char hd[64];
- base16_encode(hd, sizeof(hd), vi->identity_digest, DIGEST_LEN);
- printf("%s\n", hd);
- });
- */
- test_eq(2, smartlist_len(dsig2->signatures));
-
- /* Try adding to con2 twice; verify that nothing changes. */
- test_eq(0, networkstatus_add_detached_signatures(con2, dsig1, &msg));
-
- /* Add to con. */
- test_eq(2, networkstatus_add_detached_signatures(con, dsig2, &msg));
- /* Check signatures */
- test_assert(!networkstatus_check_voter_signature(con,
- smartlist_get(con->voters, 1),
- cert2));
- test_assert(!networkstatus_check_voter_signature(con,
- smartlist_get(con->voters, 2),
- cert1));
-
- }
-
- done:
- smartlist_free(votes);
- tor_free(v1_text);
- tor_free(v2_text);
- tor_free(v3_text);
- tor_free(consensus_text);
-
- if (vote)
- networkstatus_vote_free(vote);
- if (v1)
- networkstatus_vote_free(v1);
- if (v2)
- networkstatus_vote_free(v2);
- if (v3)
- networkstatus_vote_free(v3);
- if (con)
- networkstatus_vote_free(con);
- if (sign_skey_1)
- crypto_free_pk_env(sign_skey_1);
- if (sign_skey_2)
- crypto_free_pk_env(sign_skey_2);
- if (sign_skey_3)
- crypto_free_pk_env(sign_skey_3);
- if (sign_skey_leg1)
- crypto_free_pk_env(sign_skey_leg1);
- if (cert1)
- authority_cert_free(cert1);
- if (cert2)
- authority_cert_free(cert2);
- if (cert3)
- authority_cert_free(cert3);
-
- tor_free(consensus_text2);
- tor_free(consensus_text3);
- tor_free(detached_text1);
- tor_free(detached_text2);
- if (con2)
- networkstatus_vote_free(con2);
- if (con3)
- networkstatus_vote_free(con3);
- if (dsig1)
- ns_detached_signatures_free(dsig1);
- if (dsig2)
- ns_detached_signatures_free(dsig2);
-}
-
-/** Helper: Parse the exit policy string in <b>policy_str</b>, and make sure
- * that policies_summarize() produces the string <b>expected_summary</b> from
- * it. */
-static void
-test_policy_summary_helper(const char *policy_str,
- const char *expected_summary)
-{
- config_line_t line;
- smartlist_t *policy = smartlist_create();
- char *summary = NULL;
- int r;
-
- line.key = (char*)"foo";
- line.value = (char *)policy_str;
- line.next = NULL;
-
- r = policies_parse_exit_policy(&line, &policy, 0, NULL);
- test_eq(r, 0);
- summary = policy_summarize(policy);
-
- test_assert(summary != NULL);
- test_streq(summary, expected_summary);
-
- done:
- tor_free(summary);
- if (policy)
- addr_policy_list_free(policy);
-}
-
-/** Run unit tests for generating summary lines of exit policies */
-static void
-test_policies(void)
-{
- int i;
- smartlist_t *policy = NULL, *policy2 = NULL;
- addr_policy_t *p;
- tor_addr_t tar;
- config_line_t line;
- smartlist_t *sm = NULL;
- char *policy_str = NULL;
-
- policy = smartlist_create();
-
- p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1);
- test_assert(p != NULL);
- test_eq(ADDR_POLICY_REJECT, p->policy_type);
- tor_addr_from_ipv4h(&tar, 0xc0a80000u);
- test_eq(0, tor_addr_compare(&p->addr, &tar, CMP_EXACT));
- test_eq(16, p->maskbits);
- test_eq(1, p->prt_min);
- test_eq(65535, p->prt_max);
-
- smartlist_add(policy, p);
-
- test_assert(ADDR_POLICY_ACCEPTED ==
- compare_addr_to_addr_policy(0x01020304u, 2, policy));
- test_assert(ADDR_POLICY_PROBABLY_ACCEPTED ==
- compare_addr_to_addr_policy(0, 2, policy));
- test_assert(ADDR_POLICY_REJECTED ==
- compare_addr_to_addr_policy(0xc0a80102, 2, policy));
-
- policy2 = NULL;
- test_assert(0 == policies_parse_exit_policy(NULL, &policy2, 1, NULL));
- test_assert(policy2);
-
- test_assert(!exit_policy_is_general_exit(policy));
- test_assert(exit_policy_is_general_exit(policy2));
- test_assert(!exit_policy_is_general_exit(NULL));
-
- test_assert(cmp_addr_policies(policy, policy2));
- test_assert(cmp_addr_policies(policy, NULL));
- test_assert(!cmp_addr_policies(policy2, policy2));
- test_assert(!cmp_addr_policies(NULL, NULL));
-
- test_assert(!policy_is_reject_star(policy2));
- test_assert(policy_is_reject_star(policy));
- test_assert(policy_is_reject_star(NULL));
-
- addr_policy_list_free(policy);
- policy = NULL;
-
- /* make sure compacting logic works. */
- policy = NULL;
- line.key = (char*)"foo";
- line.value = (char*)"accept *:80,reject private:*,reject *:*";
- line.next = NULL;
- test_assert(0 == policies_parse_exit_policy(&line, &policy, 0, NULL));
- test_assert(policy);
- //test_streq(policy->string, "accept *:80");
- //test_streq(policy->next->string, "reject *:*");
- test_eq(smartlist_len(policy), 2);
-
- /* test policy summaries */
- /* check if we properly ignore private IP addresses */
- test_policy_summary_helper("reject 192.168.0.0/16:*,"
- "reject 0.0.0.0/8:*,"
- "reject 10.0.0.0/8:*,"
- "accept *:10-30,"
- "accept *:90,"
- "reject *:*",
- "accept 10-30,90");
- /* check all accept policies, and proper counting of rejects */
- test_policy_summary_helper("reject 11.0.0.0/9:80,"
- "reject 12.0.0.0/9:80,"
- "reject 13.0.0.0/9:80,"
- "reject 14.0.0.0/9:80,"
- "accept *:*", "accept 1-65535");
- test_policy_summary_helper("reject 11.0.0.0/9:80,"
- "reject 12.0.0.0/9:80,"
- "reject 13.0.0.0/9:80,"
- "reject 14.0.0.0/9:80,"
- "reject 15.0.0.0:81,"
- "accept *:*", "accept 1-65535");
- test_policy_summary_helper("reject 11.0.0.0/9:80,"
- "reject 12.0.0.0/9:80,"
- "reject 13.0.0.0/9:80,"
- "reject 14.0.0.0/9:80,"
- "reject 15.0.0.0:80,"
- "accept *:*",
- "reject 80");
- /* no exits */
- test_policy_summary_helper("accept 11.0.0.0/9:80,"
- "reject *:*",
- "reject 1-65535");
- /* port merging */
- test_policy_summary_helper("accept *:80,"
- "accept *:81,"
- "accept *:100-110,"
- "accept *:111,"
- "reject *:*",
- "accept 80-81,100-111");
- /* border ports */
- test_policy_summary_helper("accept *:1,"
- "accept *:3,"
- "accept *:65535,"
- "reject *:*",
- "accept 1,3,65535");
- /* holes */
- test_policy_summary_helper("accept *:1,"
- "accept *:3,"
- "accept *:5,"
- "accept *:7,"
- "reject *:*",
- "accept 1,3,5,7");
- test_policy_summary_helper("reject *:1,"
- "reject *:3,"
- "reject *:5,"
- "reject *:7,"
- "accept *:*",
- "reject 1,3,5,7");
-
- /* truncation ports */
- sm = smartlist_create();
- for (i=1; i<2000; i+=2) {
- char buf[POLICY_BUF_LEN];
- tor_snprintf(buf, sizeof(buf), "reject *:%d", i);
- smartlist_add(sm, tor_strdup(buf));
- }
- smartlist_add(sm, tor_strdup("accept *:*"));
- policy_str = smartlist_join_strings(sm, ",", 0, NULL);
- test_policy_summary_helper( policy_str,
- "accept 2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,"
- "46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,"
- "92,94,96,98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,"
- "130,132,134,136,138,140,142,144,146,148,150,152,154,156,158,160,162,164,"
- "166,168,170,172,174,176,178,180,182,184,186,188,190,192,194,196,198,200,"
- "202,204,206,208,210,212,214,216,218,220,222,224,226,228,230,232,234,236,"
- "238,240,242,244,246,248,250,252,254,256,258,260,262,264,266,268,270,272,"
- "274,276,278,280,282,284,286,288,290,292,294,296,298,300,302,304,306,308,"
- "310,312,314,316,318,320,322,324,326,328,330,332,334,336,338,340,342,344,"
- "346,348,350,352,354,356,358,360,362,364,366,368,370,372,374,376,378,380,"
- "382,384,386,388,390,392,394,396,398,400,402,404,406,408,410,412,414,416,"
- "418,420,422,424,426,428,430,432,434,436,438,440,442,444,446,448,450,452,"
- "454,456,458,460,462,464,466,468,470,472,474,476,478,480,482,484,486,488,"
- "490,492,494,496,498,500,502,504,506,508,510,512,514,516,518,520,522");
-
- done:
- if (policy)
- addr_policy_list_free(policy);
- if (policy2)
- addr_policy_list_free(policy2);
- tor_free(policy_str);
- if (sm) {
- SMARTLIST_FOREACH(sm, char *, s, tor_free(s));
- smartlist_free(sm);
- }
-}
-
-/** Run unit tests for basic rendezvous functions. */
-static void
-test_rend_fns(void)
-{
- char address1[] = "fooaddress.onion";
- char address2[] = "aaaaaaaaaaaaaaaa.onion";
- char address3[] = "fooaddress.exit";
- char address4[] = "www.torproject.org";
- rend_service_descriptor_t *d1 =
- tor_malloc_zero(sizeof(rend_service_descriptor_t));
- rend_service_descriptor_t *d2 = NULL;
- char *encoded = NULL;
- size_t len;
- time_t now;
- int i;
- crypto_pk_env_t *pk1 = pk_generate(0), *pk2 = pk_generate(1);
-
- /* Test unversioned (v0) descriptor */
- d1->pk = crypto_pk_dup_key(pk1);
- now = time(NULL);
- d1->timestamp = now;
- d1->version = 0;
- d1->intro_nodes = smartlist_create();
- for (i = 0; i < 3; i++) {
- rend_intro_point_t *intro = tor_malloc_zero(sizeof(rend_intro_point_t));
- intro->extend_info = tor_malloc_zero(sizeof(extend_info_t));
- crypto_rand(intro->extend_info->identity_digest, DIGEST_LEN);
- intro->extend_info->nickname[0] = '$';
- base16_encode(intro->extend_info->nickname+1, HEX_DIGEST_LEN+1,
- intro->extend_info->identity_digest, DIGEST_LEN);
- smartlist_add(d1->intro_nodes, intro);
- }
- test_assert(! rend_encode_service_descriptor(d1, pk1, &encoded, &len));
- d2 = rend_parse_service_descriptor(encoded, len);
- test_assert(d2);
-
- test_assert(!crypto_pk_cmp_keys(d1->pk, d2->pk));
- test_eq(d2->timestamp, now);
- test_eq(d2->version, 0);
- test_eq(d2->protocols, 1<<2);
- test_eq(smartlist_len(d2->intro_nodes), 3);
- for (i = 0; i < 3; i++) {
- rend_intro_point_t *intro1 = smartlist_get(d1->intro_nodes, i);
- rend_intro_point_t *intro2 = smartlist_get(d2->intro_nodes, i);
- test_streq(intro1->extend_info->nickname,
- intro2->extend_info->nickname);
- }
-
- test_assert(BAD_HOSTNAME == parse_extended_hostname(address1));
- test_assert(ONION_HOSTNAME == parse_extended_hostname(address2));
- test_assert(EXIT_HOSTNAME == parse_extended_hostname(address3));
- test_assert(NORMAL_HOSTNAME == parse_extended_hostname(address4));
-
- crypto_free_pk_env(pk1);
- crypto_free_pk_env(pk2);
- pk1 = pk2 = NULL;
- rend_service_descriptor_free(d1);
- rend_service_descriptor_free(d2);
- d1 = d2 = NULL;
-
- done:
- if (pk1)
- crypto_free_pk_env(pk1);
- if (pk2)
- crypto_free_pk_env(pk2);
- if (d1)
- rend_service_descriptor_free(d1);
- if (d2)
- rend_service_descriptor_free(d2);
- tor_free(encoded);
-}
-
-/** Run AES performance benchmarks. */
-static void
-bench_aes(void)
-{
- int len, i;
- char *b1, *b2;
- crypto_cipher_env_t *c;
- struct timeval start, end;
- const int iters = 100000;
- uint64_t nsec;
- c = crypto_new_cipher_env();
- crypto_cipher_generate_key(c);
- crypto_cipher_encrypt_init_cipher(c);
- for (len = 1; len <= 8192; len *= 2) {
- b1 = tor_malloc_zero(len);
- b2 = tor_malloc_zero(len);
- tor_gettimeofday(&start);
- for (i = 0; i < iters; ++i) {
- crypto_cipher_encrypt(c, b1, b2, len);
- }
- tor_gettimeofday(&end);
- tor_free(b1);
- tor_free(b2);
- nsec = (uint64_t) tv_udiff(&start,&end);
- nsec *= 1000;
- nsec /= (iters*len);
- printf("%d bytes: "U64_FORMAT" nsec per byte\n", len,
- U64_PRINTF_ARG(nsec));
- }
- crypto_free_cipher_env(c);
-}
-
-/** Run digestmap_t performance benchmarks. */
-static void
-bench_dmap(void)
-{
- smartlist_t *sl = smartlist_create();
- smartlist_t *sl2 = smartlist_create();
- struct timeval start, end, pt2, pt3, pt4;
- const int iters = 10000;
- const int elts = 4000;
- const int fpostests = 1000000;
- char d[20];
- int i,n=0, fp = 0;
- digestmap_t *dm = digestmap_new();
- digestset_t *ds = digestset_new(elts);
-
- for (i = 0; i < elts; ++i) {
- crypto_rand(d, 20);
- smartlist_add(sl, tor_memdup(d, 20));
- }
- for (i = 0; i < elts; ++i) {
- crypto_rand(d, 20);
- smartlist_add(sl2, tor_memdup(d, 20));
- }
- printf("nbits=%d\n", ds->mask+1);
-
- tor_gettimeofday(&start);
- for (i = 0; i < iters; ++i) {
- SMARTLIST_FOREACH(sl, const char *, cp, digestmap_set(dm, cp, (void*)1));
- }
- tor_gettimeofday(&pt2);
- for (i = 0; i < iters; ++i) {
- SMARTLIST_FOREACH(sl, const char *, cp, digestmap_get(dm, cp));
- SMARTLIST_FOREACH(sl2, const char *, cp, digestmap_get(dm, cp));
- }
- tor_gettimeofday(&pt3);
- for (i = 0; i < iters; ++i) {
- SMARTLIST_FOREACH(sl, const char *, cp, digestset_add(ds, cp));
- }
- tor_gettimeofday(&pt4);
- for (i = 0; i < iters; ++i) {
- SMARTLIST_FOREACH(sl, const char *, cp, n += digestset_isin(ds, cp));
- SMARTLIST_FOREACH(sl2, const char *, cp, n += digestset_isin(ds, cp));
- }
- tor_gettimeofday(&end);
-
- for (i = 0; i < fpostests; ++i) {
- crypto_rand(d, 20);
- if (digestset_isin(ds, d)) ++fp;
- }
-
- printf("%ld\n",(unsigned long)tv_udiff(&start, &pt2));
- printf("%ld\n",(unsigned long)tv_udiff(&pt2, &pt3));
- printf("%ld\n",(unsigned long)tv_udiff(&pt3, &pt4));
- printf("%ld\n",(unsigned long)tv_udiff(&pt4, &end));
- printf("-- %d\n", n);
- printf("++ %f\n", fp/(double)fpostests);
- digestmap_free(dm, NULL);
- digestset_free(ds);
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- SMARTLIST_FOREACH(sl2, char *, cp, tor_free(cp));
- smartlist_free(sl);
- smartlist_free(sl2);
-}
-
-/** Run unittests for memory pool allocator */
-static void
-test_util_mempool(void)
-{
- mp_pool_t *pool = NULL;
- smartlist_t *allocated = NULL;
- int i;
-
- pool = mp_pool_new(1, 100);
- test_assert(pool);
- test_assert(pool->new_chunk_capacity >= 100);
- test_assert(pool->item_alloc_size >= sizeof(void*)+1);
- mp_pool_destroy(pool);
- pool = NULL;
-
- pool = mp_pool_new(241, 2500);
- test_assert(pool);
- test_assert(pool->new_chunk_capacity >= 10);
- test_assert(pool->item_alloc_size >= sizeof(void*)+241);
- test_eq(pool->item_alloc_size & 0x03, 0);
- test_assert(pool->new_chunk_capacity < 60);
-
- allocated = smartlist_create();
- for (i = 0; i < 20000; ++i) {
- if (smartlist_len(allocated) < 20 || crypto_rand_int(2)) {
- void *m = mp_pool_get(pool);
- memset(m, 0x09, 241);
- smartlist_add(allocated, m);
- //printf("%d: %p\n", i, m);
- //mp_pool_assert_ok(pool);
- } else {
- int idx = crypto_rand_int(smartlist_len(allocated));
- void *m = smartlist_get(allocated, idx);
- //printf("%d: free %p\n", i, m);
- smartlist_del(allocated, idx);
- mp_pool_release(m);
- //mp_pool_assert_ok(pool);
- }
- if (crypto_rand_int(777)==0)
- mp_pool_clean(pool, 1, 1);
-
- if (i % 777)
- mp_pool_assert_ok(pool);
- }
-
- done:
- if (allocated) {
- SMARTLIST_FOREACH(allocated, void *, m, mp_pool_release(m));
- mp_pool_assert_ok(pool);
- mp_pool_clean(pool, 0, 0);
- mp_pool_assert_ok(pool);
- smartlist_free(allocated);
- }
-
- if (pool)
- mp_pool_destroy(pool);
-}
-
-/** Run unittests for memory area allocator */
-static void
-test_util_memarea(void)
-{
- memarea_t *area = memarea_new();
- char *p1, *p2, *p3, *p1_orig;
- void *malloced_ptr = NULL;
- int i;
-
- test_assert(area);
-
- p1_orig = p1 = memarea_alloc(area,64);
- p2 = memarea_alloc_zero(area,52);
- p3 = memarea_alloc(area,11);
-
- test_assert(memarea_owns_ptr(area, p1));
- test_assert(memarea_owns_ptr(area, p2));
- test_assert(memarea_owns_ptr(area, p3));
- /* Make sure we left enough space. */
- test_assert(p1+64 <= p2);
- test_assert(p2+52 <= p3);
- /* Make sure we aligned. */
- test_eq(((uintptr_t)p1) % sizeof(void*), 0);
- test_eq(((uintptr_t)p2) % sizeof(void*), 0);
- test_eq(((uintptr_t)p3) % sizeof(void*), 0);
- test_assert(!memarea_owns_ptr(area, p3+8192));
- test_assert(!memarea_owns_ptr(area, p3+30));
- test_assert(tor_mem_is_zero(p2, 52));
- /* Make sure we don't overalign. */
- p1 = memarea_alloc(area, 1);
- p2 = memarea_alloc(area, 1);
- test_eq(p1+sizeof(void*), p2);
- {
- malloced_ptr = tor_malloc(64);
- test_assert(!memarea_owns_ptr(area, malloced_ptr));
- tor_free(malloced_ptr);
- }
-
- /* memarea_memdup */
- {
- malloced_ptr = tor_malloc(64);
- crypto_rand((char*)malloced_ptr, 64);
- p1 = memarea_memdup(area, malloced_ptr, 64);
- test_assert(p1 != malloced_ptr);
- test_memeq(p1, malloced_ptr, 64);
- tor_free(malloced_ptr);
- }
-
- /* memarea_strdup. */
- p1 = memarea_strdup(area,"");
- p2 = memarea_strdup(area, "abcd");
- test_assert(p1);
- test_assert(p2);
- test_streq(p1, "");
- test_streq(p2, "abcd");
-
- /* memarea_strndup. */
- {
- const char *s = "Ad ogni porta batte la morte e grida: il nome!";
- /* (From Turandot, act 3.) */
- size_t len = strlen(s);
- p1 = memarea_strndup(area, s, 1000);
- p2 = memarea_strndup(area, s, 10);
- test_streq(p1, s);
- test_assert(p2 >= p1 + len + 1);
- test_memeq(s, p2, 10);
- test_eq(p2[10], '\0');
- p3 = memarea_strndup(area, s, len);
- test_streq(p3, s);
- p3 = memarea_strndup(area, s, len-1);
- test_memeq(s, p3, len-1);
- test_eq(p3[len-1], '\0');
- }
-
- memarea_clear(area);
- p1 = memarea_alloc(area, 1);
- test_eq(p1, p1_orig);
- memarea_clear(area);
-
- /* Check for running over an area's size. */
- for (i = 0; i < 512; ++i) {
- p1 = memarea_alloc(area, crypto_rand_int(5)+1);
- test_assert(memarea_owns_ptr(area, p1));
- }
- memarea_assert_ok(area);
- /* Make sure we can allocate a too-big object. */
- p1 = memarea_alloc_zero(area, 9000);
- p2 = memarea_alloc_zero(area, 16);
- test_assert(memarea_owns_ptr(area, p1));
- test_assert(memarea_owns_ptr(area, p2));
-
- done:
- memarea_drop_all(area);
- tor_free(malloced_ptr);
-}
-
-/** Run unit tests for utility functions to get file names relative to
- * the data directory. */
-static void
-test_util_datadir(void)
-{
- char buf[1024];
- char *f = NULL;
-
- f = get_datadir_fname(NULL);
- test_streq(f, temp_dir);
- tor_free(f);
- f = get_datadir_fname("state");
- tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"state", temp_dir);
- test_streq(f, buf);
- tor_free(f);
- f = get_datadir_fname2("cache", "thingy");
- tor_snprintf(buf, sizeof(buf),
- "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy", temp_dir);
- test_streq(f, buf);
- tor_free(f);
- f = get_datadir_fname2_suffix("cache", "thingy", ".foo");
- tor_snprintf(buf, sizeof(buf),
- "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy.foo", temp_dir);
- test_streq(f, buf);
- tor_free(f);
- f = get_datadir_fname_suffix("cache", ".foo");
- tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"cache.foo",
- temp_dir);
- test_streq(f, buf);
-
- done:
- tor_free(f);
-}
-
-/** Test AES-CTR encryption and decryption with IV. */
-static void
-test_crypto_aes_iv(void)
-{
- crypto_cipher_env_t *cipher;
- char *plain, *encrypted1, *encrypted2, *decrypted1, *decrypted2;
- char plain_1[1], plain_15[15], plain_16[16], plain_17[17];
- char key1[16], key2[16];
- ssize_t encrypted_size, decrypted_size;
-
- plain = tor_malloc(4095);
- encrypted1 = tor_malloc(4095 + 1 + 16);
- encrypted2 = tor_malloc(4095 + 1 + 16);
- decrypted1 = tor_malloc(4095 + 1);
- decrypted2 = tor_malloc(4095 + 1);
-
- crypto_rand(plain, 4095);
- crypto_rand(key1, 16);
- crypto_rand(key2, 16);
- crypto_rand(plain_1, 1);
- crypto_rand(plain_15, 15);
- crypto_rand(plain_16, 16);
- crypto_rand(plain_17, 17);
- key1[0] = key2[0] + 128; /* Make sure that contents are different. */
- /* Encrypt and decrypt with the same key. */
- cipher = crypto_create_init_cipher(key1, 1);
- encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 4095,
- plain, 4095);
- crypto_free_cipher_env(cipher);
- cipher = NULL;
- test_eq(encrypted_size, 16 + 4095);
- tor_assert(encrypted_size > 0); /* This is obviously true, since 4111 is
- * greater than 0, but its truth is not
- * obvious to all analysis tools. */
- cipher = crypto_create_init_cipher(key1, 0);
- decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 4095,
- encrypted1, encrypted_size);
- crypto_free_cipher_env(cipher);
- cipher = NULL;
- test_eq(decrypted_size, 4095);
- tor_assert(decrypted_size > 0);
- test_memeq(plain, decrypted1, 4095);
- /* Encrypt a second time (with a new random initialization vector). */
- cipher = crypto_create_init_cipher(key1, 1);
- encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted2, 16 + 4095,
- plain, 4095);
- crypto_free_cipher_env(cipher);
- cipher = NULL;
- test_eq(encrypted_size, 16 + 4095);
- tor_assert(encrypted_size > 0);
- cipher = crypto_create_init_cipher(key1, 0);
- decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted2, 4095,
- encrypted2, encrypted_size);
- crypto_free_cipher_env(cipher);
- cipher = NULL;
- test_eq(decrypted_size, 4095);
- tor_assert(decrypted_size > 0);
- test_memeq(plain, decrypted2, 4095);
- test_memneq(encrypted1, encrypted2, encrypted_size);
- /* Decrypt with the wrong key. */
- cipher = crypto_create_init_cipher(key2, 0);
- decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted2, 4095,
- encrypted1, encrypted_size);
- crypto_free_cipher_env(cipher);
- cipher = NULL;
- test_memneq(plain, decrypted2, encrypted_size);
- /* Alter the initialization vector. */
- encrypted1[0] += 42;
- cipher = crypto_create_init_cipher(key1, 0);
- decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 4095,
- encrypted1, encrypted_size);
- crypto_free_cipher_env(cipher);
- cipher = NULL;
- test_memneq(plain, decrypted2, 4095);
- /* Special length case: 1. */
- cipher = crypto_create_init_cipher(key1, 1);
- encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 1,
- plain_1, 1);
- crypto_free_cipher_env(cipher);
- cipher = NULL;
- test_eq(encrypted_size, 16 + 1);
- tor_assert(encrypted_size > 0);
- cipher = crypto_create_init_cipher(key1, 0);
- decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 1,
- encrypted1, encrypted_size);
- crypto_free_cipher_env(cipher);
- cipher = NULL;
- test_eq(decrypted_size, 1);
- tor_assert(decrypted_size > 0);
- test_memeq(plain_1, decrypted1, 1);
- /* Special length case: 15. */
- cipher = crypto_create_init_cipher(key1, 1);
- encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 15,
- plain_15, 15);
- crypto_free_cipher_env(cipher);
- cipher = NULL;
- test_eq(encrypted_size, 16 + 15);
- tor_assert(encrypted_size > 0);
- cipher = crypto_create_init_cipher(key1, 0);
- decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 15,
- encrypted1, encrypted_size);
- crypto_free_cipher_env(cipher);
- cipher = NULL;
- test_eq(decrypted_size, 15);
- tor_assert(decrypted_size > 0);
- test_memeq(plain_15, decrypted1, 15);
- /* Special length case: 16. */
- cipher = crypto_create_init_cipher(key1, 1);
- encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 16,
- plain_16, 16);
- crypto_free_cipher_env(cipher);
- cipher = NULL;
- test_eq(encrypted_size, 16 + 16);
- tor_assert(encrypted_size > 0);
- cipher = crypto_create_init_cipher(key1, 0);
- decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 16,
- encrypted1, encrypted_size);
- crypto_free_cipher_env(cipher);
- cipher = NULL;
- test_eq(decrypted_size, 16);
- tor_assert(decrypted_size > 0);
- test_memeq(plain_16, decrypted1, 16);
- /* Special length case: 17. */
- cipher = crypto_create_init_cipher(key1, 1);
- encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 17,
- plain_17, 17);
- crypto_free_cipher_env(cipher);
- cipher = NULL;
- test_eq(encrypted_size, 16 + 17);
- tor_assert(encrypted_size > 0);
- cipher = crypto_create_init_cipher(key1, 0);
- decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 17,
- encrypted1, encrypted_size);
- test_eq(decrypted_size, 17);
- tor_assert(decrypted_size > 0);
- test_memeq(plain_17, decrypted1, 17);
-
- done:
- /* Free memory. */
- tor_free(plain);
- tor_free(encrypted1);
- tor_free(encrypted2);
- tor_free(decrypted1);
- tor_free(decrypted2);
- if (cipher)
- crypto_free_cipher_env(cipher);
-}
-
-/** Test base32 decoding. */
-static void
-test_crypto_base32_decode(void)
-{
- char plain[60], encoded[96 + 1], decoded[60];
- int res;
- crypto_rand(plain, 60);
- /* Encode and decode a random string. */
- base32_encode(encoded, 96 + 1, plain, 60);
- res = base32_decode(decoded, 60, encoded, 96);
- test_eq(res, 0);
- test_memeq(plain, decoded, 60);
- /* Encode, uppercase, and decode a random string. */
- base32_encode(encoded, 96 + 1, plain, 60);
- tor_strupper(encoded);
- res = base32_decode(decoded, 60, encoded, 96);
- test_eq(res, 0);
- test_memeq(plain, decoded, 60);
- /* Change encoded string and decode. */
- if (encoded[0] == 'A' || encoded[0] == 'a')
- encoded[0] = 'B';
- else
- encoded[0] = 'A';
- res = base32_decode(decoded, 60, encoded, 96);
- test_eq(res, 0);
- test_memneq(plain, decoded, 60);
- /* Bad encodings. */
- encoded[0] = '!';
- res = base32_decode(decoded, 60, encoded, 96);
- test_assert(res < 0);
-
- done:
- ;
-}
-
-/** Test encoding and parsing of v2 rendezvous service descriptors. */
-static void
-test_rend_fns_v2(void)
-{
- rend_service_descriptor_t *generated = NULL, *parsed = NULL;
- char service_id[DIGEST_LEN];
- char service_id_base32[REND_SERVICE_ID_LEN_BASE32+1];
- const char *next_desc;
- smartlist_t *descs = smartlist_create();
- char computed_desc_id[DIGEST_LEN];
- char parsed_desc_id[DIGEST_LEN];
- crypto_pk_env_t *pk1 = NULL, *pk2 = NULL;
- time_t now;
- char *intro_points_encrypted = NULL;
- size_t intro_points_size;
- size_t encoded_size;
- int i;
- pk1 = pk_generate(0);
- pk2 = pk_generate(1);
- generated = tor_malloc_zero(sizeof(rend_service_descriptor_t));
- generated->pk = crypto_pk_dup_key(pk1);
- crypto_pk_get_digest(generated->pk, service_id);
- base32_encode(service_id_base32, REND_SERVICE_ID_LEN_BASE32+1,
- service_id, REND_SERVICE_ID_LEN);
- now = time(NULL);
- generated->timestamp = now;
- generated->version = 2;
- generated->protocols = 42;
- generated->intro_nodes = smartlist_create();
-
- for (i = 0; i < 3; i++) {
- rend_intro_point_t *intro = tor_malloc_zero(sizeof(rend_intro_point_t));
- crypto_pk_env_t *okey = pk_generate(2 + i);
- intro->extend_info = tor_malloc_zero(sizeof(extend_info_t));
- intro->extend_info->onion_key = okey;
- crypto_pk_get_digest(intro->extend_info->onion_key,
- intro->extend_info->identity_digest);
- //crypto_rand(info->identity_digest, DIGEST_LEN); /* Would this work? */
- intro->extend_info->nickname[0] = '$';
- base16_encode(intro->extend_info->nickname + 1,
- sizeof(intro->extend_info->nickname) - 1,
- intro->extend_info->identity_digest, DIGEST_LEN);
- /* Does not cover all IP addresses. */
- tor_addr_from_ipv4h(&intro->extend_info->addr, crypto_rand_int(65536));
- intro->extend_info->port = crypto_rand_int(65536);
- intro->intro_key = crypto_pk_dup_key(pk2);
- smartlist_add(generated->intro_nodes, intro);
- }
- test_assert(rend_encode_v2_descriptors(descs, generated, now, 0,
- REND_NO_AUTH, NULL, NULL) > 0);
- test_assert(rend_compute_v2_desc_id(computed_desc_id, service_id_base32,
- NULL, now, 0) == 0);
- test_memeq(((rend_encoded_v2_service_descriptor_t *)
- smartlist_get(descs, 0))->desc_id, computed_desc_id, DIGEST_LEN);
- test_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);
- test_assert(parsed);
- test_memeq(((rend_encoded_v2_service_descriptor_t *)
- smartlist_get(descs, 0))->desc_id, parsed_desc_id, DIGEST_LEN);
- test_eq(rend_parse_introduction_points(parsed, intro_points_encrypted,
- intro_points_size), 3);
- test_assert(!crypto_pk_cmp_keys(generated->pk, parsed->pk));
- test_eq(parsed->timestamp, now);
- test_eq(parsed->version, 2);
- test_eq(parsed->protocols, 42);
- test_eq(smartlist_len(parsed->intro_nodes), 3);
- for (i = 0; i < smartlist_len(parsed->intro_nodes); i++) {
- rend_intro_point_t *par_intro = smartlist_get(parsed->intro_nodes, i),
- *gen_intro = smartlist_get(generated->intro_nodes, i);
- extend_info_t *par_info = par_intro->extend_info;
- extend_info_t *gen_info = gen_intro->extend_info;
- test_assert(!crypto_pk_cmp_keys(gen_info->onion_key, par_info->onion_key));
- test_memeq(gen_info->identity_digest, par_info->identity_digest,
- DIGEST_LEN);
- test_streq(gen_info->nickname, par_info->nickname);
- test_assert(tor_addr_eq(&gen_info->addr, &par_info->addr));
- test_eq(gen_info->port, par_info->port);
- }
-
- rend_service_descriptor_free(parsed);
- rend_service_descriptor_free(generated);
- parsed = generated = NULL;
-
- done:
- if (descs) {
- for (i = 0; i < smartlist_len(descs); i++)
- rend_encoded_v2_service_descriptor_free(smartlist_get(descs, i));
- smartlist_free(descs);
- }
- if (parsed)
- rend_service_descriptor_free(parsed);
- if (generated)
- rend_service_descriptor_free(generated);
- if (pk1)
- crypto_free_pk_env(pk1);
- if (pk2)
- crypto_free_pk_env(pk2);
- tor_free(intro_points_encrypted);
-}
-
-/** Run unit tests for GeoIP code. */
-static void
-test_geoip(void)
-{
- int i, j;
- time_t now = time(NULL);
- char *s = NULL;
-
- /* Populate the DB a bit. Add these in order, since we can't do the final
- * 'sort' step. These aren't very good IP addresses, but they're perfectly
- * fine uint32_t values. */
- test_eq(0, geoip_parse_entry("10,50,AB"));
- test_eq(0, geoip_parse_entry("52,90,XY"));
- test_eq(0, geoip_parse_entry("95,100,AB"));
- test_eq(0, geoip_parse_entry("\"105\",\"140\",\"ZZ\""));
- test_eq(0, geoip_parse_entry("\"150\",\"190\",\"XY\""));
- test_eq(0, geoip_parse_entry("\"200\",\"250\",\"AB\""));
-
- /* We should have 3 countries: ab, xy, zz. */
- test_eq(3, geoip_get_n_countries());
- /* Make sure that country ID actually works. */
-#define NAMEFOR(x) geoip_get_country_name(geoip_get_country_by_ip(x))
- test_streq("ab", NAMEFOR(32));
- test_streq("??", NAMEFOR(5));
- test_streq("??", NAMEFOR(51));
- test_streq("xy", NAMEFOR(150));
- test_streq("xy", NAMEFOR(190));
- test_streq("??", NAMEFOR(2000));
-#undef NAMEFOR
-
- get_options()->BridgeRelay = 1;
- get_options()->BridgeRecordUsageByCountry = 1;
- /* Put 9 observations in AB... */
- for (i=32; i < 40; ++i)
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, i, now-7200);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, 225, now-7200);
- /* and 3 observations in XY, several times. */
- for (j=0; j < 10; ++j)
- for (i=52; i < 55; ++i)
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, i, now-3600);
- /* and 17 observations in ZZ... */
- for (i=110; i < 127; ++i)
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, i, now);
- s = geoip_get_client_history(now+5*24*60*60, GEOIP_CLIENT_CONNECT);
- test_assert(s);
- test_streq("zz=24,ab=16,xy=8", s);
- tor_free(s);
-
- /* Now clear out all the AB observations. */
- geoip_remove_old_clients(now-6000);
- s = geoip_get_client_history(now+5*24*60*60, GEOIP_CLIENT_CONNECT);
- test_assert(s);
- test_streq("zz=24,xy=8", s);
-
- done:
- tor_free(s);
-}
-
-/** For test_array. Declare an CLI-invocable off-by-default function in the
- * unit tests, with function name and user-visible name <b>x</b>*/
-#define DISABLED(x) { #x, x, 0, 0, 0 }
-/** For test_array. Declare an CLI-invocable unit test function, with function
- * name test_<b>x</b>(), and user-visible name <b>x</b> */
-#define ENT(x) { #x, test_ ## x, 0, 0, 1 }
-/** For test_array. Declare an CLI-invocable unit test function, with function
- * name test_<b>x</b>_<b>y</b>(), and user-visible name
- * <b>x</b>/<b>y</b>. This function will be treated as a subentry of <b>x</b>,
- * so that invoking <b>x</b> from the CLI invokes this test too. */
-#define SUBENT(x,y) { #x "/" #y, test_ ## x ## _ ## y, 1, 0, 1 }
-
-/** An array of functions and information for all the unit tests we can run. */
-static struct {
- const char *test_name; /**< How does the user refer to this test from the
- * command line? */
- void (*test_fn)(void); /**< What function is called to run this test? */
- int is_subent; /**< Is this a subentry of a bigger set of related tests? */
- int selected; /**< Are we planning to run this one? */
- int is_default; /**< If the user doesn't say what tests they want, do they
- * get this function by default? */
-} test_array[] = {
- ENT(buffers),
- ENT(crypto),
- SUBENT(crypto, rng),
- SUBENT(crypto, aes),
- SUBENT(crypto, sha),
- SUBENT(crypto, pk),
- SUBENT(crypto, dh),
- SUBENT(crypto, s2k),
- SUBENT(crypto, aes_iv),
- SUBENT(crypto, base32_decode),
- ENT(util),
- SUBENT(util, ip6_helpers),
- SUBENT(util, gzip),
- SUBENT(util, datadir),
- SUBENT(util, smartlist_basic),
- SUBENT(util, smartlist_strings),
- SUBENT(util, smartlist_overlap),
- SUBENT(util, smartlist_digests),
- SUBENT(util, smartlist_join),
- SUBENT(util, bitarray),
- SUBENT(util, digestset),
- SUBENT(util, mempool),
- SUBENT(util, memarea),
- SUBENT(util, strmap),
- SUBENT(util, control_formats),
- SUBENT(util, pqueue),
- SUBENT(util, mmap),
- SUBENT(util, threads),
- SUBENT(util, order_functions),
- SUBENT(util, sscanf),
- ENT(onion_handshake),
- ENT(dir_format),
- ENT(dirutil),
- ENT(v3_networkstatus),
- ENT(policies),
- ENT(rend_fns),
- SUBENT(rend_fns, v2),
- ENT(geoip),
-
- DISABLED(bench_aes),
- DISABLED(bench_dmap),
- { NULL, NULL, 0, 0, 0 },
-};
-
-static void syntax(void) ATTR_NORETURN;
-
-/** Print a syntax usage message, and exit.*/
-static void
-syntax(void)
-{
- int i;
- printf("Syntax:\n"
- " test [-v|--verbose] [--warn|--notice|--info|--debug]\n"
- " [testname...]\n"
- "Recognized tests are:\n");
- for (i = 0; test_array[i].test_name; ++i) {
- printf(" %s\n", test_array[i].test_name);
- }
-
- exit(0);
-}
-
-/** Main entry point for unit test code: parse the command line, and run
- * some unit tests. */
-int
-main(int c, char**v)
-{
- or_options_t *options;
- char *errmsg = NULL;
- int i;
- int verbose = 0, any_selected = 0;
- int loglevel = LOG_ERR;
-
-#ifdef USE_DMALLOC
- {
- int r = CRYPTO_set_mem_ex_functions(_tor_malloc, _tor_realloc, _tor_free);
- tor_assert(r);
- }
-#endif
-
- update_approx_time(time(NULL));
- options = options_new();
- tor_threads_init();
- init_logging();
-
- for (i = 1; i < c; ++i) {
- if (!strcmp(v[i], "-v") || !strcmp(v[i], "--verbose"))
- verbose++;
- else if (!strcmp(v[i], "--warn"))
- loglevel = LOG_WARN;
- else if (!strcmp(v[i], "--notice"))
- loglevel = LOG_NOTICE;
- else if (!strcmp(v[i], "--info"))
- loglevel = LOG_INFO;
- else if (!strcmp(v[i], "--debug"))
- loglevel = LOG_DEBUG;
- else if (!strcmp(v[i], "--help") || !strcmp(v[i], "-h") || v[i][0] == '-')
- syntax();
- else {
- int j, found=0;
- for (j = 0; test_array[j].test_name; ++j) {
- if (!strcmp(v[i], test_array[j].test_name) ||
- (test_array[j].is_subent &&
- !strcmpstart(test_array[j].test_name, v[i]) &&
- test_array[j].test_name[strlen(v[i])] == '/') ||
- (v[i][0] == '=' && !strcmp(v[i]+1, test_array[j].test_name))) {
- test_array[j].selected = 1;
- any_selected = 1;
- found = 1;
- }
- }
- if (!found) {
- printf("Unknown test: %s\n", v[i]);
- syntax();
- }
- }
- }
-
- if (!any_selected) {
- for (i = 0; test_array[i].test_name; ++i) {
- test_array[i].selected = test_array[i].is_default;
- }
- }
-
- {
- log_severity_list_t s;
- memset(&s, 0, sizeof(s));
- set_log_severity_config(loglevel, LOG_ERR, &s);
- add_stream_log(&s, "", fileno(stdout));
- }
-
- options->command = CMD_RUN_UNITTESTS;
- crypto_global_init(0);
- rep_hist_init();
- network_init();
- setup_directory();
- options_init(options);
- options->DataDirectory = tor_strdup(temp_dir);
- if (set_options(options, &errmsg) < 0) {
- printf("Failed to set initial options: %s\n", errmsg);
- tor_free(errmsg);
- return 1;
- }
-
- crypto_seed_rng(1);
-
- atexit(remove_directory);
-
- printf("Running Tor unit tests on %s\n", get_uname());
-
- for (i = 0; test_array[i].test_name; ++i) {
- if (!test_array[i].selected)
- continue;
- if (!test_array[i].is_subent) {
- printf("\n============================== %s\n",test_array[i].test_name);
- } else if (test_array[i].is_subent && verbose) {
- printf("\n%s", test_array[i].test_name);
- }
- test_array[i].test_fn();
- }
- puts("");
-
- free_pregenerated_keys();
-#ifdef USE_DMALLOC
- tor_free_all(0);
- dmalloc_log_unfreed();
-#endif
-
- if (have_failed)
- return 1;
- else
- return 0;
-}
-
diff --git a/src/or/tor_main.c b/src/or/tor_main.c
index bb1bf37b4d..117369c565 100644
--- a/src/or/tor_main.c
+++ b/src/or/tor_main.c
@@ -7,7 +7,7 @@
* built from. This string is generated by a bit of shell kludging int
* src/or/Makefile.am, and is usually right.
*/
-const char tor_svn_revision[] =
+const char tor_git_revision[] =
#ifndef _MSC_VER
#include "micro-revision.i"
#endif
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
new file mode 100644
index 0000000000..546fa2f4b7
--- /dev/null
+++ b/src/test/Makefile.am
@@ -0,0 +1,30 @@
+TESTS = test
+
+noinst_PROGRAMS = test
+
+AM_CPPFLAGS = -DSHARE_DATADIR="\"$(datadir)\"" \
+ -DLOCALSTATEDIR="\"$(localstatedir)\"" \
+ -DBINDIR="\"$(bindir)\"" \
+ -I"$(top_srcdir)/src/or"
+
+# -L flags need to go in LDFLAGS. -l flags need to go in LDADD.
+# This seems to matter nowhere but on windows, but I assure you that it
+# matters a lot there, and is quite hard to debug if you forget to do it.
+
+test_SOURCES = \
+ test_data.c \
+ test.c \
+ test_addr.c \
+ test_crypto.c \
+ test_dir.c \
+ test_containers.c \
+ test_util.c \
+ tinytest.c
+
+test_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
+ @TOR_LDFLAGS_libevent@
+test_LDADD = ../or/libtor.a ../common/libor.a ../common/libor-crypto.a \
+ ../common/libor-event.a \
+ @TOR_ZLIB_LIBS@ -lm @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@
+
+noinst_HEADERS = tinytest.h tinytest_macros.h test.h
diff --git a/src/test/test.c b/src/test/test.c
new file mode 100644
index 0000000000..8782ef5077
--- /dev/null
+++ b/src/test/test.c
@@ -0,0 +1,1286 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/* Ordinarily defined in tor_main.c; this bit is just here to provide one
+ * since we're not linking to tor_main.c */
+const char tor_git_revision[] = "";
+
+/**
+ * \file test.c
+ * \brief Unit tests for many pieces of the lower level Tor modules.
+ **/
+
+#include "orconfig.h"
+
+#include <stdio.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef MS_WINDOWS
+/* For mkdir() */
+#include <direct.h>
+#else
+#include <dirent.h>
+#endif
+
+/* These macros pull in declarations for some functions and structures that
+ * are typically file-private. */
+#define BUFFERS_PRIVATE
+#define CONFIG_PRIVATE
+#define GEOIP_PRIVATE
+#define ROUTER_PRIVATE
+#define CIRCUIT_PRIVATE
+
+/*
+ * Linux doesn't provide lround in math.h by default, but mac os does...
+ * It's best just to leave math.h out of the picture entirely.
+ */
+//#include <math.h>
+long int lround(double x);
+double fabs(double x);
+
+#include "or.h"
+#include "buffers.h"
+#include "circuitbuild.h"
+#include "config.h"
+#include "connection_edge.h"
+#include "geoip.h"
+#include "rendcommon.h"
+#include "test.h"
+#include "torgzip.h"
+#include "mempool.h"
+#include "memarea.h"
+#include "onion.h"
+#include "policies.h"
+#include "rephist.h"
+#include "routerparse.h"
+
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#include <openssl/crypto.h>
+#include "main.h"
+#endif
+
+/** Set to true if any unit test has failed. Mostly, this is set by the macros
+ * in test.h */
+int have_failed = 0;
+
+/** Temporary directory (set up by setup_directory) under which we store all
+ * our files during testing. */
+static char temp_dir[256];
+static pid_t temp_dir_setup_in_pid = 0;
+
+/** Select and create the temporary directory we'll use to run our unit tests.
+ * Store it in <b>temp_dir</b>. Exit immediately if we can't create it.
+ * idempotent. */
+static void
+setup_directory(void)
+{
+ static int is_setup = 0;
+ int r;
+ if (is_setup) return;
+
+#ifdef MS_WINDOWS
+ // XXXX
+ tor_snprintf(temp_dir, sizeof(temp_dir),
+ "c:\\windows\\temp\\tor_test_%d", (int)getpid());
+ r = mkdir(temp_dir);
+#else
+ tor_snprintf(temp_dir, sizeof(temp_dir), "/tmp/tor_test_%d", (int) getpid());
+ r = mkdir(temp_dir, 0700);
+#endif
+ if (r) {
+ fprintf(stderr, "Can't create directory %s:", temp_dir);
+ perror("");
+ exit(1);
+ }
+ is_setup = 1;
+ temp_dir_setup_in_pid = getpid();
+}
+
+/** Return a filename relative to our testing temporary directory */
+const char *
+get_fname(const char *name)
+{
+ static char buf[1024];
+ setup_directory();
+ if (!name)
+ return temp_dir;
+ tor_snprintf(buf,sizeof(buf),"%s/%s",temp_dir,name);
+ return buf;
+}
+
+/** Remove all files stored under the temporary directory, and the directory
+ * itself. Called by atexit(). */
+static void
+remove_directory(void)
+{
+ smartlist_t *elements;
+ if (getpid() != temp_dir_setup_in_pid) {
+ /* Only clean out the tempdir when the main process is exiting. */
+ return;
+ }
+ elements = tor_listdir(temp_dir);
+ if (elements) {
+ SMARTLIST_FOREACH(elements, const char *, cp,
+ {
+ size_t len = strlen(cp)+strlen(temp_dir)+16;
+ char *tmp = tor_malloc(len);
+ tor_snprintf(tmp, len, "%s"PATH_SEPARATOR"%s", temp_dir, cp);
+ unlink(tmp);
+ tor_free(tmp);
+ });
+ SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
+ smartlist_free(elements);
+ }
+ rmdir(temp_dir);
+}
+
+/** Define this if unit tests spend too much time generating public keys*/
+#undef CACHE_GENERATED_KEYS
+
+static crypto_pk_env_t *pregen_keys[5] = {NULL, NULL, NULL, NULL, NULL};
+#define N_PREGEN_KEYS ((int)(sizeof(pregen_keys)/sizeof(pregen_keys[0])))
+
+/** Generate and return a new keypair for use in unit tests. If we're using
+ * the key cache optimization, we might reuse keys: we only guarantee that
+ * keys made with distinct values for <b>idx</b> are different. The value of
+ * <b>idx</b> must be at least 0, and less than N_PREGEN_KEYS. */
+crypto_pk_env_t *
+pk_generate(int idx)
+{
+#ifdef CACHE_GENERATED_KEYS
+ tor_assert(idx < N_PREGEN_KEYS);
+ if (! pregen_keys[idx]) {
+ pregen_keys[idx] = crypto_new_pk_env();
+ tor_assert(!crypto_pk_generate_key(pregen_keys[idx]));
+ }
+ return crypto_pk_dup_key(pregen_keys[idx]);
+#else
+ crypto_pk_env_t *result;
+ (void) idx;
+ result = crypto_new_pk_env();
+ tor_assert(!crypto_pk_generate_key(result));
+ return result;
+#endif
+}
+
+/** Free all storage used for the cached key optimization. */
+static void
+free_pregenerated_keys(void)
+{
+ unsigned idx;
+ for (idx = 0; idx < N_PREGEN_KEYS; ++idx) {
+ if (pregen_keys[idx]) {
+ crypto_free_pk_env(pregen_keys[idx]);
+ pregen_keys[idx] = NULL;
+ }
+ }
+}
+
+/** Run unit tests for buffers.c */
+static void
+test_buffers(void)
+{
+ char str[256];
+ char str2[256];
+
+ buf_t *buf = NULL, *buf2 = NULL;
+ const char *cp;
+
+ int j;
+ size_t r;
+
+ /****
+ * buf_new
+ ****/
+ if (!(buf = buf_new()))
+ test_fail();
+
+ //test_eq(buf_capacity(buf), 4096);
+ test_eq(buf_datalen(buf), 0);
+
+ /****
+ * General pointer frobbing
+ */
+ for (j=0;j<256;++j) {
+ str[j] = (char)j;
+ }
+ write_to_buf(str, 256, buf);
+ write_to_buf(str, 256, buf);
+ test_eq(buf_datalen(buf), 512);
+ fetch_from_buf(str2, 200, buf);
+ test_memeq(str, str2, 200);
+ test_eq(buf_datalen(buf), 312);
+ memset(str2, 0, sizeof(str2));
+
+ fetch_from_buf(str2, 256, buf);
+ test_memeq(str+200, str2, 56);
+ test_memeq(str, str2+56, 200);
+ test_eq(buf_datalen(buf), 56);
+ memset(str2, 0, sizeof(str2));
+ /* Okay, now we should be 512 bytes into the 4096-byte buffer. If we add
+ * another 3584 bytes, we hit the end. */
+ for (j=0;j<15;++j) {
+ write_to_buf(str, 256, buf);
+ }
+ assert_buf_ok(buf);
+ test_eq(buf_datalen(buf), 3896);
+ fetch_from_buf(str2, 56, buf);
+ test_eq(buf_datalen(buf), 3840);
+ test_memeq(str+200, str2, 56);
+ for (j=0;j<15;++j) {
+ memset(str2, 0, sizeof(str2));
+ fetch_from_buf(str2, 256, buf);
+ test_memeq(str, str2, 256);
+ }
+ test_eq(buf_datalen(buf), 0);
+ buf_free(buf);
+ buf = NULL;
+
+ /* Okay, now make sure growing can work. */
+ buf = buf_new_with_capacity(16);
+ //test_eq(buf_capacity(buf), 16);
+ write_to_buf(str+1, 255, buf);
+ //test_eq(buf_capacity(buf), 256);
+ fetch_from_buf(str2, 254, buf);
+ test_memeq(str+1, str2, 254);
+ //test_eq(buf_capacity(buf), 256);
+ assert_buf_ok(buf);
+ write_to_buf(str, 32, buf);
+ //test_eq(buf_capacity(buf), 256);
+ assert_buf_ok(buf);
+ write_to_buf(str, 256, buf);
+ assert_buf_ok(buf);
+ //test_eq(buf_capacity(buf), 512);
+ test_eq(buf_datalen(buf), 33+256);
+ fetch_from_buf(str2, 33, buf);
+ test_eq(*str2, str[255]);
+
+ test_memeq(str2+1, str, 32);
+ //test_eq(buf_capacity(buf), 512);
+ test_eq(buf_datalen(buf), 256);
+ fetch_from_buf(str2, 256, buf);
+ test_memeq(str, str2, 256);
+
+ /* now try shrinking: case 1. */
+ buf_free(buf);
+ buf = buf_new_with_capacity(33668);
+ for (j=0;j<67;++j) {
+ write_to_buf(str,255, buf);
+ }
+ //test_eq(buf_capacity(buf), 33668);
+ test_eq(buf_datalen(buf), 17085);
+ for (j=0; j < 40; ++j) {
+ fetch_from_buf(str2, 255,buf);
+ test_memeq(str2, str, 255);
+ }
+
+ /* now try shrinking: case 2. */
+ buf_free(buf);
+ buf = buf_new_with_capacity(33668);
+ for (j=0;j<67;++j) {
+ write_to_buf(str,255, buf);
+ }
+ for (j=0; j < 20; ++j) {
+ fetch_from_buf(str2, 255,buf);
+ test_memeq(str2, str, 255);
+ }
+ for (j=0;j<80;++j) {
+ write_to_buf(str,255, buf);
+ }
+ //test_eq(buf_capacity(buf),33668);
+ for (j=0; j < 120; ++j) {
+ fetch_from_buf(str2, 255,buf);
+ test_memeq(str2, str, 255);
+ }
+
+ /* Move from buf to buf. */
+ buf_free(buf);
+ buf = buf_new_with_capacity(4096);
+ buf2 = buf_new_with_capacity(4096);
+ for (j=0;j<100;++j)
+ write_to_buf(str, 255, buf);
+ test_eq(buf_datalen(buf), 25500);
+ for (j=0;j<100;++j) {
+ r = 10;
+ move_buf_to_buf(buf2, buf, &r);
+ test_eq(r, 0);
+ }
+ test_eq(buf_datalen(buf), 24500);
+ test_eq(buf_datalen(buf2), 1000);
+ for (j=0;j<3;++j) {
+ fetch_from_buf(str2, 255, buf2);
+ test_memeq(str2, str, 255);
+ }
+ r = 8192; /*big move*/
+ move_buf_to_buf(buf2, buf, &r);
+ test_eq(r, 0);
+ r = 30000; /* incomplete move */
+ move_buf_to_buf(buf2, buf, &r);
+ test_eq(r, 13692);
+ for (j=0;j<97;++j) {
+ fetch_from_buf(str2, 255, buf2);
+ test_memeq(str2, str, 255);
+ }
+ buf_free(buf);
+ buf_free(buf2);
+ buf = buf2 = NULL;
+
+ buf = buf_new_with_capacity(5);
+ cp = "Testing. This is a moderately long Testing string.";
+ for (j = 0; cp[j]; j++)
+ write_to_buf(cp+j, 1, buf);
+ test_eq(0, buf_find_string_offset(buf, "Testing", 7));
+ test_eq(1, buf_find_string_offset(buf, "esting", 6));
+ test_eq(1, buf_find_string_offset(buf, "est", 3));
+ test_eq(39, buf_find_string_offset(buf, "ing str", 7));
+ test_eq(35, buf_find_string_offset(buf, "Testing str", 11));
+ test_eq(32, buf_find_string_offset(buf, "ng ", 3));
+ test_eq(43, buf_find_string_offset(buf, "string.", 7));
+ test_eq(-1, buf_find_string_offset(buf, "shrdlu", 6));
+ test_eq(-1, buf_find_string_offset(buf, "Testing thing", 13));
+ test_eq(-1, buf_find_string_offset(buf, "ngx", 3));
+ buf_free(buf);
+ buf = NULL;
+
+ done:
+ if (buf)
+ buf_free(buf);
+ if (buf2)
+ buf_free(buf2);
+}
+
+/** Run unit tests for the onion handshake code. */
+static void
+test_onion_handshake(void)
+{
+ /* client-side */
+ crypto_dh_env_t *c_dh = NULL;
+ char c_buf[ONIONSKIN_CHALLENGE_LEN];
+ char c_keys[40];
+
+ /* server-side */
+ char s_buf[ONIONSKIN_REPLY_LEN];
+ char s_keys[40];
+
+ /* shared */
+ crypto_pk_env_t *pk = NULL;
+
+ pk = pk_generate(0);
+
+ /* client handshake 1. */
+ memset(c_buf, 0, ONIONSKIN_CHALLENGE_LEN);
+ test_assert(! onion_skin_create(pk, &c_dh, c_buf));
+
+ /* server handshake */
+ memset(s_buf, 0, ONIONSKIN_REPLY_LEN);
+ memset(s_keys, 0, 40);
+ test_assert(! onion_skin_server_handshake(c_buf, pk, NULL,
+ s_buf, s_keys, 40));
+
+ /* client handshake 2 */
+ memset(c_keys, 0, 40);
+ test_assert(! onion_skin_client_handshake(c_dh, s_buf, c_keys, 40));
+
+ if (memcmp(c_keys, s_keys, 40)) {
+ puts("Aiiiie");
+ exit(1);
+ }
+ test_memeq(c_keys, s_keys, 40);
+ memset(s_buf, 0, 40);
+ test_memneq(c_keys, s_buf, 40);
+
+ done:
+ if (c_dh)
+ crypto_dh_free(c_dh);
+ if (pk)
+ crypto_free_pk_env(pk);
+}
+
+static void
+test_circuit_timeout(void)
+{
+ /* Plan:
+ * 1. Generate 1000 samples
+ * 2. Estimate parameters
+ * 3. If difference, repeat
+ * 4. Save state
+ * 5. load state
+ * 6. Estimate parameters
+ * 7. compare differences
+ */
+ circuit_build_times_t initial;
+ circuit_build_times_t estimate;
+ circuit_build_times_t final;
+ double timeout1, timeout2;
+ or_state_t state;
+ int i, runs;
+ double close_ms;
+ circuit_build_times_init(&initial);
+ circuit_build_times_init(&estimate);
+ circuit_build_times_init(&final);
+
+ memset(&state, 0, sizeof(or_state_t));
+
+ circuitbuild_running_unit_tests();
+#define timeout0 (build_time_t)(30*1000.0)
+ initial.Xm = 3000;
+ circuit_build_times_initial_alpha(&initial,
+ CBT_DEFAULT_QUANTILE_CUTOFF/100.0,
+ timeout0);
+ close_ms = MAX(circuit_build_times_calculate_timeout(&initial,
+ CBT_DEFAULT_CLOSE_QUANTILE/100.0),
+ CBT_DEFAULT_TIMEOUT_INITIAL_VALUE);
+ do {
+ for (i=0; i < CBT_DEFAULT_MIN_CIRCUITS_TO_OBSERVE; i++) {
+ build_time_t sample = circuit_build_times_generate_sample(&initial,0,1);
+
+ if (sample > close_ms) {
+ circuit_build_times_add_time(&estimate, CBT_BUILD_ABANDONED);
+ } else {
+ circuit_build_times_add_time(&estimate, sample);
+ }
+ }
+ circuit_build_times_update_alpha(&estimate);
+ timeout1 = circuit_build_times_calculate_timeout(&estimate,
+ CBT_DEFAULT_QUANTILE_CUTOFF/100.0);
+ circuit_build_times_set_timeout(&estimate);
+ log_notice(LD_CIRC, "Timeout1 is %lf, Xm is %d", timeout1, estimate.Xm);
+ /* 2% error */
+ } while (fabs(circuit_build_times_cdf(&initial, timeout0) -
+ circuit_build_times_cdf(&initial, timeout1)) > 0.02);
+
+ test_assert(estimate.total_build_times <= CBT_NCIRCUITS_TO_OBSERVE);
+
+ circuit_build_times_update_state(&estimate, &state);
+ test_assert(circuit_build_times_parse_state(&final, &state) == 0);
+
+ circuit_build_times_update_alpha(&final);
+ timeout2 = circuit_build_times_calculate_timeout(&final,
+ CBT_DEFAULT_QUANTILE_CUTOFF/100.0);
+
+ circuit_build_times_set_timeout(&final);
+ log_notice(LD_CIRC, "Timeout2 is %lf, Xm is %d", timeout2, final.Xm);
+
+ /* 5% here because some accuracy is lost due to histogram conversion */
+ test_assert(fabs(circuit_build_times_cdf(&initial, timeout0) -
+ circuit_build_times_cdf(&initial, timeout2)) < 0.05);
+
+ for (runs = 0; runs < 50; runs++) {
+ int build_times_idx = 0;
+ int total_build_times = 0;
+
+ final.close_ms = final.timeout_ms = CBT_DEFAULT_TIMEOUT_INITIAL_VALUE;
+ estimate.close_ms = estimate.timeout_ms
+ = CBT_DEFAULT_TIMEOUT_INITIAL_VALUE;
+
+ for (i = 0; i < CBT_DEFAULT_RECENT_CIRCUITS*2; i++) {
+ circuit_build_times_network_circ_success(&estimate);
+ circuit_build_times_add_time(&estimate,
+ circuit_build_times_generate_sample(&estimate, 0,
+ CBT_DEFAULT_QUANTILE_CUTOFF/100.0));
+
+ circuit_build_times_network_circ_success(&estimate);
+ circuit_build_times_add_time(&final,
+ circuit_build_times_generate_sample(&final, 0,
+ CBT_DEFAULT_QUANTILE_CUTOFF/100.0));
+ }
+
+ test_assert(!circuit_build_times_network_check_changed(&estimate));
+ test_assert(!circuit_build_times_network_check_changed(&final));
+
+ /* Reset liveness to be non-live */
+ final.liveness.network_last_live = 0;
+ estimate.liveness.network_last_live = 0;
+
+ build_times_idx = estimate.build_times_idx;
+ total_build_times = estimate.total_build_times;
+
+ test_assert(circuit_build_times_network_check_live(&estimate));
+ test_assert(circuit_build_times_network_check_live(&final));
+
+ circuit_build_times_count_close(&estimate, 0,
+ (time_t)(approx_time()-estimate.close_ms/1000.0-1));
+ circuit_build_times_count_close(&final, 0,
+ (time_t)(approx_time()-final.close_ms/1000.0-1));
+
+ test_assert(!circuit_build_times_network_check_live(&estimate));
+ test_assert(!circuit_build_times_network_check_live(&final));
+
+ log_info(LD_CIRC, "idx: %d %d, tot: %d %d",
+ build_times_idx, estimate.build_times_idx,
+ total_build_times, estimate.total_build_times);
+
+ /* Check rollback index. Should match top of loop. */
+ test_assert(build_times_idx == estimate.build_times_idx);
+ // This can fail if estimate.total_build_times == 1000, because
+ // in that case, rewind actually causes us to lose timeouts
+ if (total_build_times != CBT_NCIRCUITS_TO_OBSERVE)
+ test_assert(total_build_times == estimate.total_build_times);
+
+ /* Now simulate that the network has become live and we need
+ * a change */
+ circuit_build_times_network_is_live(&estimate);
+ circuit_build_times_network_is_live(&final);
+
+ for (i = 0; i < CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT; i++) {
+ circuit_build_times_count_timeout(&estimate, 1);
+
+ if (i < CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT-1) {
+ circuit_build_times_count_timeout(&final, 1);
+ }
+ }
+
+ test_assert(estimate.liveness.after_firsthop_idx == 0);
+ test_assert(final.liveness.after_firsthop_idx ==
+ CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT-1);
+
+ test_assert(circuit_build_times_network_check_live(&estimate));
+ test_assert(circuit_build_times_network_check_live(&final));
+
+ circuit_build_times_count_timeout(&final, 1);
+ }
+
+ done:
+ return;
+}
+
+/** Helper: Parse the exit policy string in <b>policy_str</b>, and make sure
+ * that policies_summarize() produces the string <b>expected_summary</b> from
+ * it. */
+static void
+test_policy_summary_helper(const char *policy_str,
+ const char *expected_summary)
+{
+ config_line_t line;
+ smartlist_t *policy = smartlist_create();
+ char *summary = NULL;
+ int r;
+
+ line.key = (char*)"foo";
+ line.value = (char *)policy_str;
+ line.next = NULL;
+
+ r = policies_parse_exit_policy(&line, &policy, 0, NULL, 1);
+ test_eq(r, 0);
+ summary = policy_summarize(policy);
+
+ test_assert(summary != NULL);
+ test_streq(summary, expected_summary);
+
+ done:
+ tor_free(summary);
+ if (policy)
+ addr_policy_list_free(policy);
+}
+
+/** Run unit tests for generating summary lines of exit policies */
+static void
+test_policies(void)
+{
+ int i;
+ smartlist_t *policy = NULL, *policy2 = NULL, *policy3 = NULL,
+ *policy4 = NULL, *policy5 = NULL, *policy6 = NULL,
+ *policy7 = NULL;
+ addr_policy_t *p;
+ tor_addr_t tar;
+ config_line_t line;
+ smartlist_t *sm = NULL;
+ char *policy_str = NULL;
+
+ policy = smartlist_create();
+
+ p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1);
+ test_assert(p != NULL);
+ test_eq(ADDR_POLICY_REJECT, p->policy_type);
+ tor_addr_from_ipv4h(&tar, 0xc0a80000u);
+ test_eq(0, tor_addr_compare(&p->addr, &tar, CMP_EXACT));
+ test_eq(16, p->maskbits);
+ test_eq(1, p->prt_min);
+ test_eq(65535, p->prt_max);
+
+ smartlist_add(policy, p);
+
+ test_assert(ADDR_POLICY_ACCEPTED ==
+ compare_addr_to_addr_policy(0x01020304u, 2, policy));
+ test_assert(ADDR_POLICY_PROBABLY_ACCEPTED ==
+ compare_addr_to_addr_policy(0, 2, policy));
+ test_assert(ADDR_POLICY_REJECTED ==
+ compare_addr_to_addr_policy(0xc0a80102, 2, policy));
+
+ test_assert(0 == policies_parse_exit_policy(NULL, &policy2, 1, NULL, 1));
+ test_assert(policy2);
+
+ policy3 = smartlist_create();
+ p = router_parse_addr_policy_item_from_string("reject *:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy3, p);
+ p = router_parse_addr_policy_item_from_string("accept *:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy3, p);
+
+ policy4 = smartlist_create();
+ p = router_parse_addr_policy_item_from_string("accept *:443",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy4, p);
+ p = router_parse_addr_policy_item_from_string("accept *:443",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy4, p);
+
+ policy5 = smartlist_create();
+ p = router_parse_addr_policy_item_from_string("reject 0.0.0.0/8:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject 169.254.0.0/16:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject 127.0.0.0/8:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject 10.0.0.0/8:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject 172.16.0.0/12:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject 80.190.250.90:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject *:1-65534",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject *:65535",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("accept *:1-65535",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+
+ policy6 = smartlist_create();
+ p = router_parse_addr_policy_item_from_string("accept 43.3.0.0/9:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy6, p);
+
+ policy7 = smartlist_create();
+ p = router_parse_addr_policy_item_from_string("accept 0.0.0.0/8:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy7, p);
+
+ test_assert(!exit_policy_is_general_exit(policy));
+ test_assert(exit_policy_is_general_exit(policy2));
+ test_assert(!exit_policy_is_general_exit(NULL));
+ test_assert(!exit_policy_is_general_exit(policy3));
+ test_assert(!exit_policy_is_general_exit(policy4));
+ test_assert(!exit_policy_is_general_exit(policy5));
+ test_assert(!exit_policy_is_general_exit(policy6));
+ test_assert(!exit_policy_is_general_exit(policy7));
+
+ test_assert(cmp_addr_policies(policy, policy2));
+ test_assert(cmp_addr_policies(policy, NULL));
+ test_assert(!cmp_addr_policies(policy2, policy2));
+ test_assert(!cmp_addr_policies(NULL, NULL));
+
+ test_assert(!policy_is_reject_star(policy2));
+ test_assert(policy_is_reject_star(policy));
+ test_assert(policy_is_reject_star(NULL));
+
+ addr_policy_list_free(policy);
+ policy = NULL;
+
+ /* make sure compacting logic works. */
+ policy = NULL;
+ line.key = (char*)"foo";
+ line.value = (char*)"accept *:80,reject private:*,reject *:*";
+ line.next = NULL;
+ test_assert(0 == policies_parse_exit_policy(&line, &policy, 0, NULL, 1));
+ test_assert(policy);
+ //test_streq(policy->string, "accept *:80");
+ //test_streq(policy->next->string, "reject *:*");
+ test_eq(smartlist_len(policy), 2);
+
+ /* test policy summaries */
+ /* check if we properly ignore private IP addresses */
+ test_policy_summary_helper("reject 192.168.0.0/16:*,"
+ "reject 0.0.0.0/8:*,"
+ "reject 10.0.0.0/8:*,"
+ "accept *:10-30,"
+ "accept *:90,"
+ "reject *:*",
+ "accept 10-30,90");
+ /* check all accept policies, and proper counting of rejects */
+ test_policy_summary_helper("reject 11.0.0.0/9:80,"
+ "reject 12.0.0.0/9:80,"
+ "reject 13.0.0.0/9:80,"
+ "reject 14.0.0.0/9:80,"
+ "accept *:*", "accept 1-65535");
+ test_policy_summary_helper("reject 11.0.0.0/9:80,"
+ "reject 12.0.0.0/9:80,"
+ "reject 13.0.0.0/9:80,"
+ "reject 14.0.0.0/9:80,"
+ "reject 15.0.0.0:81,"
+ "accept *:*", "accept 1-65535");
+ test_policy_summary_helper("reject 11.0.0.0/9:80,"
+ "reject 12.0.0.0/9:80,"
+ "reject 13.0.0.0/9:80,"
+ "reject 14.0.0.0/9:80,"
+ "reject 15.0.0.0:80,"
+ "accept *:*",
+ "reject 80");
+ /* no exits */
+ test_policy_summary_helper("accept 11.0.0.0/9:80,"
+ "reject *:*",
+ "reject 1-65535");
+ /* port merging */
+ test_policy_summary_helper("accept *:80,"
+ "accept *:81,"
+ "accept *:100-110,"
+ "accept *:111,"
+ "reject *:*",
+ "accept 80-81,100-111");
+ /* border ports */
+ test_policy_summary_helper("accept *:1,"
+ "accept *:3,"
+ "accept *:65535,"
+ "reject *:*",
+ "accept 1,3,65535");
+ /* holes */
+ test_policy_summary_helper("accept *:1,"
+ "accept *:3,"
+ "accept *:5,"
+ "accept *:7,"
+ "reject *:*",
+ "accept 1,3,5,7");
+ test_policy_summary_helper("reject *:1,"
+ "reject *:3,"
+ "reject *:5,"
+ "reject *:7,"
+ "accept *:*",
+ "reject 1,3,5,7");
+
+ /* truncation ports */
+ sm = smartlist_create();
+ for (i=1; i<2000; i+=2) {
+ char buf[POLICY_BUF_LEN];
+ tor_snprintf(buf, sizeof(buf), "reject *:%d", i);
+ smartlist_add(sm, tor_strdup(buf));
+ }
+ smartlist_add(sm, tor_strdup("accept *:*"));
+ policy_str = smartlist_join_strings(sm, ",", 0, NULL);
+ test_policy_summary_helper( policy_str,
+ "accept 2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,"
+ "46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,"
+ "92,94,96,98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,"
+ "130,132,134,136,138,140,142,144,146,148,150,152,154,156,158,160,162,164,"
+ "166,168,170,172,174,176,178,180,182,184,186,188,190,192,194,196,198,200,"
+ "202,204,206,208,210,212,214,216,218,220,222,224,226,228,230,232,234,236,"
+ "238,240,242,244,246,248,250,252,254,256,258,260,262,264,266,268,270,272,"
+ "274,276,278,280,282,284,286,288,290,292,294,296,298,300,302,304,306,308,"
+ "310,312,314,316,318,320,322,324,326,328,330,332,334,336,338,340,342,344,"
+ "346,348,350,352,354,356,358,360,362,364,366,368,370,372,374,376,378,380,"
+ "382,384,386,388,390,392,394,396,398,400,402,404,406,408,410,412,414,416,"
+ "418,420,422,424,426,428,430,432,434,436,438,440,442,444,446,448,450,452,"
+ "454,456,458,460,462,464,466,468,470,472,474,476,478,480,482,484,486,488,"
+ "490,492,494,496,498,500,502,504,506,508,510,512,514,516,518,520,522");
+
+ done:
+ addr_policy_list_free(policy);
+ addr_policy_list_free(policy2);
+ addr_policy_list_free(policy3);
+ addr_policy_list_free(policy4);
+ addr_policy_list_free(policy5);
+ addr_policy_list_free(policy6);
+ addr_policy_list_free(policy7);
+ tor_free(policy_str);
+ if (sm) {
+ SMARTLIST_FOREACH(sm, char *, s, tor_free(s));
+ smartlist_free(sm);
+ }
+}
+
+/** Run AES performance benchmarks. */
+static void
+bench_aes(void)
+{
+ int len, i;
+ char *b1, *b2;
+ crypto_cipher_env_t *c;
+ struct timeval start, end;
+ const int iters = 100000;
+ uint64_t nsec;
+ c = crypto_new_cipher_env();
+ crypto_cipher_generate_key(c);
+ crypto_cipher_encrypt_init_cipher(c);
+ for (len = 1; len <= 8192; len *= 2) {
+ b1 = tor_malloc_zero(len);
+ b2 = tor_malloc_zero(len);
+ tor_gettimeofday(&start);
+ for (i = 0; i < iters; ++i) {
+ crypto_cipher_encrypt(c, b1, b2, len);
+ }
+ tor_gettimeofday(&end);
+ tor_free(b1);
+ tor_free(b2);
+ nsec = (uint64_t) tv_udiff(&start,&end);
+ nsec *= 1000;
+ nsec /= (iters*len);
+ printf("%d bytes: "U64_FORMAT" nsec per byte\n", len,
+ U64_PRINTF_ARG(nsec));
+ }
+ crypto_free_cipher_env(c);
+}
+
+/** Run digestmap_t performance benchmarks. */
+static void
+bench_dmap(void)
+{
+ smartlist_t *sl = smartlist_create();
+ smartlist_t *sl2 = smartlist_create();
+ struct timeval start, end, pt2, pt3, pt4;
+ const int iters = 10000;
+ const int elts = 4000;
+ const int fpostests = 1000000;
+ char d[20];
+ int i,n=0, fp = 0;
+ digestmap_t *dm = digestmap_new();
+ digestset_t *ds = digestset_new(elts);
+
+ for (i = 0; i < elts; ++i) {
+ crypto_rand(d, 20);
+ smartlist_add(sl, tor_memdup(d, 20));
+ }
+ for (i = 0; i < elts; ++i) {
+ crypto_rand(d, 20);
+ smartlist_add(sl2, tor_memdup(d, 20));
+ }
+ printf("nbits=%d\n", ds->mask+1);
+
+ tor_gettimeofday(&start);
+ for (i = 0; i < iters; ++i) {
+ SMARTLIST_FOREACH(sl, const char *, cp, digestmap_set(dm, cp, (void*)1));
+ }
+ tor_gettimeofday(&pt2);
+ for (i = 0; i < iters; ++i) {
+ SMARTLIST_FOREACH(sl, const char *, cp, digestmap_get(dm, cp));
+ SMARTLIST_FOREACH(sl2, const char *, cp, digestmap_get(dm, cp));
+ }
+ tor_gettimeofday(&pt3);
+ for (i = 0; i < iters; ++i) {
+ SMARTLIST_FOREACH(sl, const char *, cp, digestset_add(ds, cp));
+ }
+ tor_gettimeofday(&pt4);
+ for (i = 0; i < iters; ++i) {
+ SMARTLIST_FOREACH(sl, const char *, cp, n += digestset_isin(ds, cp));
+ SMARTLIST_FOREACH(sl2, const char *, cp, n += digestset_isin(ds, cp));
+ }
+ tor_gettimeofday(&end);
+
+ for (i = 0; i < fpostests; ++i) {
+ crypto_rand(d, 20);
+ if (digestset_isin(ds, d)) ++fp;
+ }
+
+ printf("%ld\n",(unsigned long)tv_udiff(&start, &pt2));
+ printf("%ld\n",(unsigned long)tv_udiff(&pt2, &pt3));
+ printf("%ld\n",(unsigned long)tv_udiff(&pt3, &pt4));
+ printf("%ld\n",(unsigned long)tv_udiff(&pt4, &end));
+ printf("-- %d\n", n);
+ printf("++ %f\n", fp/(double)fpostests);
+ digestmap_free(dm, NULL);
+ digestset_free(ds);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ SMARTLIST_FOREACH(sl2, char *, cp, tor_free(cp));
+ smartlist_free(sl);
+ smartlist_free(sl2);
+}
+
+/** Test encoding and parsing of rendezvous service descriptors. */
+static void
+test_rend_fns(void)
+{
+ rend_service_descriptor_t *generated = NULL, *parsed = NULL;
+ char service_id[DIGEST_LEN];
+ char service_id_base32[REND_SERVICE_ID_LEN_BASE32+1];
+ const char *next_desc;
+ smartlist_t *descs = smartlist_create();
+ char computed_desc_id[DIGEST_LEN];
+ char parsed_desc_id[DIGEST_LEN];
+ crypto_pk_env_t *pk1 = NULL, *pk2 = NULL;
+ time_t now;
+ char *intro_points_encrypted = NULL;
+ size_t intro_points_size;
+ size_t encoded_size;
+ int i;
+ char address1[] = "fooaddress.onion";
+ char address2[] = "aaaaaaaaaaaaaaaa.onion";
+ char address3[] = "fooaddress.exit";
+ char address4[] = "www.torproject.org";
+
+ test_assert(BAD_HOSTNAME == parse_extended_hostname(address1, 1));
+ test_assert(ONION_HOSTNAME == parse_extended_hostname(address2, 1));
+ test_assert(EXIT_HOSTNAME == parse_extended_hostname(address3, 1));
+ test_assert(NORMAL_HOSTNAME == parse_extended_hostname(address4, 1));
+
+ pk1 = pk_generate(0);
+ pk2 = pk_generate(1);
+ generated = tor_malloc_zero(sizeof(rend_service_descriptor_t));
+ generated->pk = crypto_pk_dup_key(pk1);
+ crypto_pk_get_digest(generated->pk, service_id);
+ base32_encode(service_id_base32, REND_SERVICE_ID_LEN_BASE32+1,
+ service_id, REND_SERVICE_ID_LEN);
+ now = time(NULL);
+ generated->timestamp = now;
+ generated->version = 2;
+ generated->protocols = 42;
+ generated->intro_nodes = smartlist_create();
+
+ for (i = 0; i < 3; i++) {
+ rend_intro_point_t *intro = tor_malloc_zero(sizeof(rend_intro_point_t));
+ crypto_pk_env_t *okey = pk_generate(2 + i);
+ intro->extend_info = tor_malloc_zero(sizeof(extend_info_t));
+ intro->extend_info->onion_key = okey;
+ crypto_pk_get_digest(intro->extend_info->onion_key,
+ intro->extend_info->identity_digest);
+ //crypto_rand(info->identity_digest, DIGEST_LEN); /* Would this work? */
+ intro->extend_info->nickname[0] = '$';
+ base16_encode(intro->extend_info->nickname + 1,
+ sizeof(intro->extend_info->nickname) - 1,
+ intro->extend_info->identity_digest, DIGEST_LEN);
+ /* Does not cover all IP addresses. */
+ tor_addr_from_ipv4h(&intro->extend_info->addr, crypto_rand_int(65536));
+ intro->extend_info->port = 1 + crypto_rand_int(65535);
+ intro->intro_key = crypto_pk_dup_key(pk2);
+ smartlist_add(generated->intro_nodes, intro);
+ }
+ test_assert(rend_encode_v2_descriptors(descs, generated, now, 0,
+ REND_NO_AUTH, NULL, NULL) > 0);
+ test_assert(rend_compute_v2_desc_id(computed_desc_id, service_id_base32,
+ NULL, now, 0) == 0);
+ test_memeq(((rend_encoded_v2_service_descriptor_t *)
+ smartlist_get(descs, 0))->desc_id, computed_desc_id, DIGEST_LEN);
+ test_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);
+ test_assert(parsed);
+ test_memeq(((rend_encoded_v2_service_descriptor_t *)
+ smartlist_get(descs, 0))->desc_id, parsed_desc_id, DIGEST_LEN);
+ test_eq(rend_parse_introduction_points(parsed, intro_points_encrypted,
+ intro_points_size), 3);
+ test_assert(!crypto_pk_cmp_keys(generated->pk, parsed->pk));
+ test_eq(parsed->timestamp, now);
+ test_eq(parsed->version, 2);
+ test_eq(parsed->protocols, 42);
+ test_eq(smartlist_len(parsed->intro_nodes), 3);
+ for (i = 0; i < smartlist_len(parsed->intro_nodes); i++) {
+ rend_intro_point_t *par_intro = smartlist_get(parsed->intro_nodes, i),
+ *gen_intro = smartlist_get(generated->intro_nodes, i);
+ extend_info_t *par_info = par_intro->extend_info;
+ extend_info_t *gen_info = gen_intro->extend_info;
+ test_assert(!crypto_pk_cmp_keys(gen_info->onion_key, par_info->onion_key));
+ test_memeq(gen_info->identity_digest, par_info->identity_digest,
+ DIGEST_LEN);
+ test_streq(gen_info->nickname, par_info->nickname);
+ test_assert(tor_addr_eq(&gen_info->addr, &par_info->addr));
+ test_eq(gen_info->port, par_info->port);
+ }
+
+ rend_service_descriptor_free(parsed);
+ rend_service_descriptor_free(generated);
+ parsed = generated = NULL;
+
+ done:
+ if (descs) {
+ for (i = 0; i < smartlist_len(descs); i++)
+ rend_encoded_v2_service_descriptor_free(smartlist_get(descs, i));
+ smartlist_free(descs);
+ }
+ if (parsed)
+ rend_service_descriptor_free(parsed);
+ if (generated)
+ rend_service_descriptor_free(generated);
+ if (pk1)
+ crypto_free_pk_env(pk1);
+ if (pk2)
+ crypto_free_pk_env(pk2);
+ tor_free(intro_points_encrypted);
+}
+
+/** Run unit tests for GeoIP code. */
+static void
+test_geoip(void)
+{
+ int i, j;
+ time_t now = time(NULL);
+ char *s = NULL;
+
+ /* Populate the DB a bit. Add these in order, since we can't do the final
+ * 'sort' step. These aren't very good IP addresses, but they're perfectly
+ * fine uint32_t values. */
+ test_eq(0, geoip_parse_entry("10,50,AB"));
+ test_eq(0, geoip_parse_entry("52,90,XY"));
+ test_eq(0, geoip_parse_entry("95,100,AB"));
+ test_eq(0, geoip_parse_entry("\"105\",\"140\",\"ZZ\""));
+ test_eq(0, geoip_parse_entry("\"150\",\"190\",\"XY\""));
+ test_eq(0, geoip_parse_entry("\"200\",\"250\",\"AB\""));
+
+ /* We should have 4 countries: ??, ab, xy, zz. */
+ test_eq(4, geoip_get_n_countries());
+ /* Make sure that country ID actually works. */
+#define NAMEFOR(x) geoip_get_country_name(geoip_get_country_by_ip(x))
+ test_streq("??", NAMEFOR(3));
+ test_eq(0, geoip_get_country_by_ip(3));
+ test_streq("ab", NAMEFOR(32));
+ test_streq("??", NAMEFOR(5));
+ test_streq("??", NAMEFOR(51));
+ test_streq("xy", NAMEFOR(150));
+ test_streq("xy", NAMEFOR(190));
+ test_streq("??", NAMEFOR(2000));
+#undef NAMEFOR
+
+ get_options()->BridgeRelay = 1;
+ get_options()->BridgeRecordUsageByCountry = 1;
+ /* Put 9 observations in AB... */
+ for (i=32; i < 40; ++i)
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, i, now-7200);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, 225, now-7200);
+ /* and 3 observations in XY, several times. */
+ for (j=0; j < 10; ++j)
+ for (i=52; i < 55; ++i)
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, i, now-3600);
+ /* and 17 observations in ZZ... */
+ for (i=110; i < 127; ++i)
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, i, now);
+ s = geoip_get_client_history(GEOIP_CLIENT_CONNECT);
+ test_assert(s);
+ test_streq("zz=24,ab=16,xy=8", s);
+ tor_free(s);
+
+ /* Now clear out all the AB observations. */
+ geoip_remove_old_clients(now-6000);
+ s = geoip_get_client_history(GEOIP_CLIENT_CONNECT);
+ test_assert(s);
+ test_streq("zz=24,xy=8", s);
+
+ done:
+ tor_free(s);
+}
+
+/** Run unit tests for stats code. */
+static void
+test_stats(void)
+{
+ time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
+ char *s = NULL;
+ int i;
+
+ /* We shouldn't collect exit stats without initializing them. */
+ rep_hist_note_exit_stream_opened(80);
+ rep_hist_note_exit_bytes(80, 100, 10000);
+ s = rep_hist_format_exit_stats(now + 86400);
+ test_assert(!s);
+
+ /* Initialize stats, note some streams and bytes, and generate history
+ * string. */
+ rep_hist_exit_stats_init(now);
+ rep_hist_note_exit_stream_opened(80);
+ rep_hist_note_exit_bytes(80, 100, 10000);
+ rep_hist_note_exit_stream_opened(443);
+ rep_hist_note_exit_bytes(443, 100, 10000);
+ rep_hist_note_exit_bytes(443, 100, 10000);
+ s = rep_hist_format_exit_stats(now + 86400);
+ test_streq("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ "exit-kibibytes-written 80=1,443=1,other=0\n"
+ "exit-kibibytes-read 80=10,443=20,other=0\n"
+ "exit-streams-opened 80=4,443=4,other=0\n", s);
+ tor_free(s);
+
+ /* Add a few bytes on 10 more ports and ensure that only the top 10
+ * ports are contained in the history string. */
+ for (i = 50; i < 60; i++) {
+ rep_hist_note_exit_bytes(i, i, i);
+ rep_hist_note_exit_stream_opened(i);
+ }
+ s = rep_hist_format_exit_stats(now + 86400);
+ test_streq("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ "exit-kibibytes-written 52=1,53=1,54=1,55=1,56=1,57=1,58=1,"
+ "59=1,80=1,443=1,other=1\n"
+ "exit-kibibytes-read 52=1,53=1,54=1,55=1,56=1,57=1,58=1,"
+ "59=1,80=10,443=20,other=1\n"
+ "exit-streams-opened 52=4,53=4,54=4,55=4,56=4,57=4,58=4,"
+ "59=4,80=4,443=4,other=4\n", s);
+ tor_free(s);
+
+ /* Stop collecting stats, add some bytes, and ensure we don't generate
+ * a history string. */
+ rep_hist_exit_stats_term();
+ rep_hist_note_exit_bytes(80, 100, 10000);
+ s = rep_hist_format_exit_stats(now + 86400);
+ test_assert(!s);
+
+ /* Re-start stats, add some bytes, reset stats, and see what history we
+ * get when observing no streams or bytes at all. */
+ rep_hist_exit_stats_init(now);
+ rep_hist_note_exit_stream_opened(80);
+ rep_hist_note_exit_bytes(80, 100, 10000);
+ rep_hist_reset_exit_stats(now);
+ s = rep_hist_format_exit_stats(now + 86400);
+ test_streq("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ "exit-kibibytes-written other=0\n"
+ "exit-kibibytes-read other=0\n"
+ "exit-streams-opened other=0\n", s);
+
+ done:
+ tor_free(s);
+}
+
+static void *
+legacy_test_setup(const struct testcase_t *testcase)
+{
+ return testcase->setup_data;
+}
+
+void
+legacy_test_helper(void *data)
+{
+ void (*fn)(void) = data;
+ fn();
+}
+
+static int
+legacy_test_cleanup(const struct testcase_t *testcase, void *ptr)
+{
+ (void)ptr;
+ (void)testcase;
+ return 1;
+}
+
+const struct testcase_setup_t legacy_setup = {
+ legacy_test_setup, legacy_test_cleanup
+};
+
+#define ENT(name) \
+ { #name, legacy_test_helper, 0, &legacy_setup, test_ ## name }
+#define SUBENT(group, name) \
+ { #group "_" #name, legacy_test_helper, 0, &legacy_setup, \
+ test_ ## group ## _ ## name }
+#define DISABLED(name) \
+ { #name, legacy_test_helper, TT_SKIP, &legacy_setup, name }
+#define FORK(name) \
+ { #name, legacy_test_helper, TT_FORK, &legacy_setup, test_ ## name }
+
+static struct testcase_t test_array[] = {
+ ENT(buffers),
+ ENT(onion_handshake),
+ ENT(circuit_timeout),
+ ENT(policies),
+ ENT(rend_fns),
+ ENT(geoip),
+ FORK(stats),
+
+ DISABLED(bench_aes),
+ DISABLED(bench_dmap),
+ END_OF_TESTCASES
+};
+
+extern struct testcase_t addr_tests[];
+extern struct testcase_t crypto_tests[];
+extern struct testcase_t container_tests[];
+extern struct testcase_t util_tests[];
+extern struct testcase_t dir_tests[];
+
+static struct testgroup_t testgroups[] = {
+ { "", test_array },
+ { "addr/", addr_tests },
+ { "crypto/", crypto_tests },
+ { "container/", container_tests },
+ { "util/", util_tests },
+ { "dir/", dir_tests },
+ END_OF_GROUPS
+};
+
+/** Main entry point for unit test code: parse the command line, and run
+ * some unit tests. */
+int
+main(int c, const char **v)
+{
+ or_options_t *options;
+ char *errmsg = NULL;
+ int i, i_out;
+ int loglevel = LOG_ERR;
+
+#ifdef USE_DMALLOC
+ {
+ int r = CRYPTO_set_mem_ex_functions(_tor_malloc, _tor_realloc, _tor_free);
+ tor_assert(r);
+ }
+#endif
+
+ update_approx_time(time(NULL));
+ options = options_new();
+ tor_threads_init();
+ init_logging();
+
+ for (i_out = i = 1; i < c; ++i) {
+ if (!strcmp(v[i], "--warn")) {
+ loglevel = LOG_WARN;
+ } else if (!strcmp(v[i], "--notice")) {
+ loglevel = LOG_NOTICE;
+ } else if (!strcmp(v[i], "--info")) {
+ loglevel = LOG_INFO;
+ } else if (!strcmp(v[i], "--debug")) {
+ loglevel = LOG_DEBUG;
+ } else {
+ v[i_out++] = v[i];
+ }
+ }
+ c = i_out;
+
+ {
+ log_severity_list_t s;
+ memset(&s, 0, sizeof(s));
+ set_log_severity_config(loglevel, LOG_ERR, &s);
+ add_stream_log(&s, "", fileno(stdout));
+ }
+
+ options->command = CMD_RUN_UNITTESTS;
+ crypto_global_init(0, NULL, NULL);
+ rep_hist_init();
+ network_init();
+ setup_directory();
+ options_init(options);
+ options->DataDirectory = tor_strdup(temp_dir);
+ options->EntryStatistics = 1;
+ if (set_options(options, &errmsg) < 0) {
+ printf("Failed to set initial options: %s\n", errmsg);
+ tor_free(errmsg);
+ return 1;
+ }
+
+ crypto_seed_rng(1);
+
+ atexit(remove_directory);
+
+ have_failed = (tinytest_main(c, v, testgroups) != 0);
+
+ free_pregenerated_keys();
+#ifdef USE_DMALLOC
+ tor_free_all(0);
+ dmalloc_log_unfreed();
+#endif
+
+ if (have_failed)
+ return 1;
+ else
+ return 0;
+}
+
diff --git a/src/test/test.h b/src/test/test.h
new file mode 100644
index 0000000000..550c57a812
--- /dev/null
+++ b/src/test/test.h
@@ -0,0 +1,75 @@
+/* Copyright (c) 2001-2003, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef _TOR_TEST_H
+#define _TOR_TEST_H
+
+/**
+ * \file test.h
+ * \brief Macros and functions used by unit tests.
+ */
+
+#include "compat.h"
+#include "tinytest.h"
+#define TT_EXIT_TEST_FUNCTION STMT_BEGIN goto done; STMT_END
+#include "tinytest_macros.h"
+
+#ifdef __GNUC__
+#define PRETTY_FUNCTION __PRETTY_FUNCTION__
+#else
+#define PRETTY_FUNCTION ""
+#endif
+
+#define test_fail_msg(msg) TT_DIE((msg))
+
+#define test_fail() test_fail_msg("Assertion failed.")
+
+#define test_assert(expr) tt_assert(expr)
+
+#define test_eq(expr1, expr2) tt_int_op((expr1), ==, (expr2))
+#define test_eq_ptr(expr1, expr2) tt_ptr_op((expr1), ==, (expr2))
+#define test_neq(expr1, expr2) tt_int_op((expr1), !=, (expr2))
+#define test_neq_ptr(expr1, expr2) tt_ptr_op((expr1), !=, (expr2))
+#define test_streq(expr1, expr2) tt_str_op((expr1), ==, (expr2))
+#define test_strneq(expr1, expr2) tt_str_op((expr1), !=, (expr2))
+#define test_streq(expr1, expr2) tt_str_op((expr1), ==, (expr2))
+
+#define test_mem_op(expr1, op, expr2, len) \
+ tt_assert_test_fmt_type(expr1,expr2,#expr1" "#op" "#expr2, \
+ const char *, \
+ (memcmp(_val1, _val2, len) op 0), \
+ char *, "%s", \
+ { size_t printlen = (len)*2+1; \
+ _print = tor_malloc(printlen); \
+ base16_encode(_print, printlen, _value, \
+ (len)); }, \
+ { tor_free(_print); } \
+ );
+
+#define test_memeq(expr1, expr2, len) test_mem_op((expr1), ==, (expr2), len)
+#define test_memneq(expr1, expr2, len) test_mem_op((expr1), !=, (expr2), len)
+
+/* As test_mem_op, but decodes 'hex' before comparing. There must be a
+ * local char* variable called mem_op_hex_tmp for this to work. */
+#define test_mem_op_hex(expr1, op, hex) \
+ STMT_BEGIN \
+ size_t length = strlen(hex); \
+ tor_free(mem_op_hex_tmp); \
+ mem_op_hex_tmp = tor_malloc(length/2); \
+ tor_assert((length&1)==0); \
+ base16_decode(mem_op_hex_tmp, length/2, hex, length); \
+ test_mem_op(expr1, op, mem_op_hex_tmp, length/2); \
+ STMT_END
+
+#define test_memeq_hex(expr1, hex) test_mem_op_hex(expr1, ==, hex)
+
+const char *get_fname(const char *name);
+crypto_pk_env_t *pk_generate(int idx);
+
+void legacy_test_helper(void *data);
+extern const struct testcase_setup_t legacy_setup;
+
+#endif
+
diff --git a/src/test/test_addr.c b/src/test/test_addr.c
new file mode 100644
index 0000000000..bafc0a968e
--- /dev/null
+++ b/src/test/test_addr.c
@@ -0,0 +1,497 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#include "or.h"
+#include "test.h"
+
+static void
+test_addr_basic(void)
+{
+ uint32_t u32;
+ uint16_t u16;
+ char *cp;
+
+ /* Test parse_addr_port */
+ cp = NULL; u32 = 3; u16 = 3;
+ test_assert(!parse_addr_port(LOG_WARN, "1.2.3.4", &cp, &u32, &u16));
+ test_streq(cp, "1.2.3.4");
+ test_eq(u32, 0x01020304u);
+ test_eq(u16, 0);
+ tor_free(cp);
+ test_assert(!parse_addr_port(LOG_WARN, "4.3.2.1:99", &cp, &u32, &u16));
+ test_streq(cp, "4.3.2.1");
+ test_eq(u32, 0x04030201u);
+ test_eq(u16, 99);
+ tor_free(cp);
+ test_assert(!parse_addr_port(LOG_WARN, "nonexistent.address:4040",
+ &cp, NULL, &u16));
+ test_streq(cp, "nonexistent.address");
+ test_eq(u16, 4040);
+ tor_free(cp);
+ test_assert(!parse_addr_port(LOG_WARN, "localhost:9999", &cp, &u32, &u16));
+ test_streq(cp, "localhost");
+ test_eq(u32, 0x7f000001u);
+ test_eq(u16, 9999);
+ tor_free(cp);
+ u32 = 3;
+ test_assert(!parse_addr_port(LOG_WARN, "localhost", NULL, &u32, &u16));
+ test_eq(cp, NULL);
+ test_eq(u32, 0x7f000001u);
+ test_eq(u16, 0);
+ tor_free(cp);
+ test_eq(0, addr_mask_get_bits(0x0u));
+ test_eq(32, addr_mask_get_bits(0xFFFFFFFFu));
+ test_eq(16, addr_mask_get_bits(0xFFFF0000u));
+ test_eq(31, addr_mask_get_bits(0xFFFFFFFEu));
+ test_eq(1, addr_mask_get_bits(0x80000000u));
+
+ /* Test inet_ntop */
+ {
+ char tmpbuf[TOR_ADDR_BUF_LEN];
+ const char *ip = "176.192.208.224";
+ struct in_addr in;
+ tor_inet_pton(AF_INET, ip, &in);
+ tor_inet_ntop(AF_INET, &in, tmpbuf, sizeof(tmpbuf));
+ test_streq(tmpbuf, ip);
+ }
+
+ done:
+ ;
+}
+
+#define _test_op_ip6(a,op,b,e1,e2) \
+ STMT_BEGIN \
+ tt_assert_test_fmt_type(a,b,e1" "#op" "e2,struct in6_addr*, \
+ (memcmp(_val1->s6_addr, _val2->s6_addr, 16) op 0), \
+ char *, "%s", \
+ { int i; char *cp; \
+ cp = _print = tor_malloc(64); \
+ for (i=0;i<16;++i) { \
+ tor_snprintf(cp, 3,"%02x", (unsigned)_value->s6_addr[i]);\
+ cp += 2; \
+ if (i != 15) *cp++ = ':'; \
+ } \
+ }, { tor_free(_print); } \
+ ); \
+ STMT_END
+
+/** Helper: Assert that two strings both decode as IPv6 addresses with
+ * tor_inet_pton(), and both decode to the same address. */
+#define test_pton6_same(a,b) STMT_BEGIN \
+ test_eq(tor_inet_pton(AF_INET6, a, &a1), 1); \
+ test_eq(tor_inet_pton(AF_INET6, b, &a2), 1); \
+ _test_op_ip6(&a1,==,&a2,#a,#b); \
+ STMT_END
+
+/** Helper: Assert that <b>a</b> is recognized as a bad IPv6 address by
+ * tor_inet_pton(). */
+#define test_pton6_bad(a) \
+ test_eq(0, tor_inet_pton(AF_INET6, a, &a1))
+
+/** Helper: assert that <b>a</b>, when parsed by tor_inet_pton() and displayed
+ * with tor_inet_ntop(), yields <b>b</b>. Also assert that <b>b</b> parses to
+ * the same value as <b>a</b>. */
+#define test_ntop6_reduces(a,b) STMT_BEGIN \
+ test_eq(tor_inet_pton(AF_INET6, a, &a1), 1); \
+ test_streq(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)), b); \
+ test_eq(tor_inet_pton(AF_INET6, b, &a2), 1); \
+ _test_op_ip6(&a1, ==, &a2, a, b); \
+ STMT_END
+
+/** Helper: assert that <b>a</b> parses by tor_inet_pton() into a address that
+ * passes tor_addr_is_internal() with <b>for_listening</b>. */
+#define test_internal_ip(a,for_listening) STMT_BEGIN \
+ test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
+ t1.family = AF_INET6; \
+ if (!tor_addr_is_internal(&t1, for_listening)) \
+ test_fail_msg( a "was not internal."); \
+ STMT_END
+
+/** Helper: assert that <b>a</b> parses by tor_inet_pton() into a address that
+ * does not pass tor_addr_is_internal() with <b>for_listening</b>. */
+#define test_external_ip(a,for_listening) STMT_BEGIN \
+ test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
+ t1.family = AF_INET6; \
+ if (tor_addr_is_internal(&t1, for_listening)) \
+ test_fail_msg(a "was not external."); \
+ STMT_END
+
+/** Helper: Assert that <b>a</b> and <b>b</b>, when parsed by
+ * tor_inet_pton(), give addresses that compare in the order defined by
+ * <b>op</b> with tor_addr_compare(). */
+#define test_addr_compare(a, op, b) STMT_BEGIN \
+ test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
+ test_eq(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), 1); \
+ t1.family = t2.family = AF_INET6; \
+ r = tor_addr_compare(&t1,&t2,CMP_SEMANTIC); \
+ if (!(r op 0)) \
+ test_fail_msg("failed: tor_addr_compare("a","b") "#op" 0"); \
+ STMT_END
+
+/** Helper: Assert that <b>a</b> and <b>b</b>, when parsed by
+ * tor_inet_pton(), give addresses that compare in the order defined by
+ * <b>op</b> with tor_addr_compare_masked() with <b>m</b> masked. */
+#define test_addr_compare_masked(a, op, b, m) STMT_BEGIN \
+ test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
+ test_eq(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), 1); \
+ t1.family = t2.family = AF_INET6; \
+ r = tor_addr_compare_masked(&t1,&t2,m,CMP_SEMANTIC); \
+ if (!(r op 0)) \
+ test_fail_msg("failed: tor_addr_compare_masked("a","b","#m") "#op" 0"); \
+ STMT_END
+
+/** Helper: assert that <b>xx</b> is parseable as a masked IPv6 address with
+ * ports by tor_parse_mask_addr_ports(), with family <b>f</b>, IP address
+ * as 4 32-bit words <b>ip1...ip4</b>, mask bits as <b>mm</b>, and port range
+ * as <b>pt1..pt2</b>. */
+#define test_addr_mask_ports_parse(xx, f, ip1, ip2, ip3, ip4, mm, pt1, pt2) \
+ STMT_BEGIN \
+ test_eq(tor_addr_parse_mask_ports(xx, &t1, &mask, &port1, &port2), f); \
+ p1=tor_inet_ntop(AF_INET6, &t1.addr.in6_addr, bug, sizeof(bug)); \
+ test_eq(htonl(ip1), tor_addr_to_in6_addr32(&t1)[0]); \
+ test_eq(htonl(ip2), tor_addr_to_in6_addr32(&t1)[1]); \
+ test_eq(htonl(ip3), tor_addr_to_in6_addr32(&t1)[2]); \
+ test_eq(htonl(ip4), tor_addr_to_in6_addr32(&t1)[3]); \
+ test_eq(mask, mm); \
+ test_eq(port1, pt1); \
+ test_eq(port2, pt2); \
+ STMT_END
+
+/** Run unit tests for IPv6 encoding/decoding/manipulation functions. */
+static void
+test_addr_ip6_helpers(void)
+{
+ char buf[TOR_ADDR_BUF_LEN], bug[TOR_ADDR_BUF_LEN];
+ struct in6_addr a1, a2;
+ tor_addr_t t1, t2;
+ int r, i;
+ uint16_t port1, port2;
+ maskbits_t mask;
+ const char *p1;
+ struct sockaddr_storage sa_storage;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+
+ // struct in_addr b1, b2;
+ /* Test tor_inet_ntop and tor_inet_pton: IPv6 */
+
+ /* ==== Converting to and from sockaddr_t. */
+ sin = (struct sockaddr_in *)&sa_storage;
+ sin->sin_family = AF_INET;
+ sin->sin_port = 9090;
+ sin->sin_addr.s_addr = htonl(0x7f7f0102); /*127.127.1.2*/
+ tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, NULL);
+ test_eq(tor_addr_family(&t1), AF_INET);
+ test_eq(tor_addr_to_ipv4h(&t1), 0x7f7f0102);
+
+ memset(&sa_storage, 0, sizeof(sa_storage));
+ test_eq(sizeof(struct sockaddr_in),
+ tor_addr_to_sockaddr(&t1, 1234, (struct sockaddr *)&sa_storage,
+ sizeof(sa_storage)));
+ test_eq(1234, ntohs(sin->sin_port));
+ test_eq(0x7f7f0102, ntohl(sin->sin_addr.s_addr));
+
+ memset(&sa_storage, 0, sizeof(sa_storage));
+ sin6 = (struct sockaddr_in6 *)&sa_storage;
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = htons(7070);
+ sin6->sin6_addr.s6_addr[0] = 128;
+ tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, NULL);
+ test_eq(tor_addr_family(&t1), AF_INET6);
+ p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0);
+ test_streq(p1, "8000::");
+
+ memset(&sa_storage, 0, sizeof(sa_storage));
+ test_eq(sizeof(struct sockaddr_in6),
+ tor_addr_to_sockaddr(&t1, 9999, (struct sockaddr *)&sa_storage,
+ sizeof(sa_storage)));
+ test_eq(AF_INET6, sin6->sin6_family);
+ test_eq(9999, ntohs(sin6->sin6_port));
+ test_eq(0x80000000, ntohl(S6_ADDR32(sin6->sin6_addr)[0]));
+
+ /* ==== tor_addr_lookup: static cases. (Can't test dns without knowing we
+ * have a good resolver. */
+ test_eq(0, tor_addr_lookup("127.128.129.130", AF_UNSPEC, &t1));
+ test_eq(AF_INET, tor_addr_family(&t1));
+ test_eq(tor_addr_to_ipv4h(&t1), 0x7f808182);
+
+ test_eq(0, tor_addr_lookup("9000::5", AF_UNSPEC, &t1));
+ test_eq(AF_INET6, tor_addr_family(&t1));
+ test_eq(0x90, tor_addr_to_in6_addr8(&t1)[0]);
+ test_assert(tor_mem_is_zero((char*)tor_addr_to_in6_addr8(&t1)+1, 14));
+ test_eq(0x05, tor_addr_to_in6_addr8(&t1)[15]);
+
+ /* === Test pton: valid af_inet6 */
+ /* Simple, valid parsing. */
+ r = tor_inet_pton(AF_INET6,
+ "0102:0304:0506:0708:090A:0B0C:0D0E:0F10", &a1);
+ test_assert(r==1);
+ for (i=0;i<16;++i) { test_eq(i+1, (int)a1.s6_addr[i]); }
+ /* ipv4 ending. */
+ test_pton6_same("0102:0304:0506:0708:090A:0B0C:0D0E:0F10",
+ "0102:0304:0506:0708:090A:0B0C:13.14.15.16");
+ /* shortened words. */
+ test_pton6_same("0001:0099:BEEF:0000:0123:FFFF:0001:0001",
+ "1:99:BEEF:0:0123:FFFF:1:1");
+ /* zeros at the beginning */
+ test_pton6_same("0000:0000:0000:0000:0009:C0A8:0001:0001",
+ "::9:c0a8:1:1");
+ test_pton6_same("0000:0000:0000:0000:0009:C0A8:0001:0001",
+ "::9:c0a8:0.1.0.1");
+ /* zeros in the middle. */
+ test_pton6_same("fe80:0000:0000:0000:0202:1111:0001:0001",
+ "fe80::202:1111:1:1");
+ /* zeros at the end. */
+ test_pton6_same("1000:0001:0000:0007:0000:0000:0000:0000",
+ "1000:1:0:7::");
+
+ /* === Test ntop: af_inet6 */
+ test_ntop6_reduces("0:0:0:0:0:0:0:0", "::");
+
+ test_ntop6_reduces("0001:0099:BEEF:0006:0123:FFFF:0001:0001",
+ "1:99:beef:6:123:ffff:1:1");
+
+ //test_ntop6_reduces("0:0:0:0:0:0:c0a8:0101", "::192.168.1.1");
+ test_ntop6_reduces("0:0:0:0:0:ffff:c0a8:0101", "::ffff:192.168.1.1");
+ test_ntop6_reduces("002:0:0000:0:3::4", "2::3:0:0:4");
+ test_ntop6_reduces("0:0::1:0:3", "::1:0:3");
+ test_ntop6_reduces("008:0::0", "8::");
+ test_ntop6_reduces("0:0:0:0:0:ffff::1", "::ffff:0.0.0.1");
+ test_ntop6_reduces("abcd:0:0:0:0:0:7f00::", "abcd::7f00:0");
+ test_ntop6_reduces("0000:0000:0000:0000:0009:C0A8:0001:0001",
+ "::9:c0a8:1:1");
+ test_ntop6_reduces("fe80:0000:0000:0000:0202:1111:0001:0001",
+ "fe80::202:1111:1:1");
+ test_ntop6_reduces("1000:0001:0000:0007:0000:0000:0000:0000",
+ "1000:1:0:7::");
+
+ /* === Test pton: invalid in6. */
+ test_pton6_bad("foobar.");
+ test_pton6_bad("55555::");
+ test_pton6_bad("9:-60::");
+ test_pton6_bad("1:2:33333:4:0002:3::");
+ //test_pton6_bad("1:2:3333:4:00002:3::");// BAD, but glibc doesn't say so.
+ test_pton6_bad("1:2:3333:4:fish:3::");
+ test_pton6_bad("1:2:3:4:5:6:7:8:9");
+ test_pton6_bad("1:2:3:4:5:6:7");
+ test_pton6_bad("1:2:3:4:5:6:1.2.3.4.5");
+ test_pton6_bad("1:2:3:4:5:6:1.2.3");
+ test_pton6_bad("::1.2.3");
+ test_pton6_bad("::1.2.3.4.5");
+ test_pton6_bad("99");
+ test_pton6_bad("");
+ test_pton6_bad("1::2::3:4");
+ test_pton6_bad("a:::b:c");
+ test_pton6_bad(":::a:b:c");
+ test_pton6_bad("a:b:c:::");
+
+ /* test internal checking */
+ test_external_ip("fbff:ffff::2:7", 0);
+ test_internal_ip("fc01::2:7", 0);
+ test_internal_ip("fdff:ffff::f:f", 0);
+ test_external_ip("fe00::3:f", 0);
+
+ test_external_ip("fe7f:ffff::2:7", 0);
+ test_internal_ip("fe80::2:7", 0);
+ test_internal_ip("febf:ffff::f:f", 0);
+
+ test_internal_ip("fec0::2:7:7", 0);
+ test_internal_ip("feff:ffff::e:7:7", 0);
+ test_external_ip("ff00::e:7:7", 0);
+
+ test_internal_ip("::", 0);
+ test_internal_ip("::1", 0);
+ test_internal_ip("::1", 1);
+ test_internal_ip("::", 0);
+ test_external_ip("::", 1);
+ test_external_ip("::2", 0);
+ test_external_ip("2001::", 0);
+ test_external_ip("ffff::", 0);
+
+ test_external_ip("::ffff:0.0.0.0", 1);
+ test_internal_ip("::ffff:0.0.0.0", 0);
+ test_internal_ip("::ffff:0.255.255.255", 0);
+ test_external_ip("::ffff:1.0.0.0", 0);
+
+ test_external_ip("::ffff:9.255.255.255", 0);
+ test_internal_ip("::ffff:10.0.0.0", 0);
+ test_internal_ip("::ffff:10.255.255.255", 0);
+ test_external_ip("::ffff:11.0.0.0", 0);
+
+ test_external_ip("::ffff:126.255.255.255", 0);
+ test_internal_ip("::ffff:127.0.0.0", 0);
+ test_internal_ip("::ffff:127.255.255.255", 0);
+ test_external_ip("::ffff:128.0.0.0", 0);
+
+ test_external_ip("::ffff:172.15.255.255", 0);
+ test_internal_ip("::ffff:172.16.0.0", 0);
+ test_internal_ip("::ffff:172.31.255.255", 0);
+ test_external_ip("::ffff:172.32.0.0", 0);
+
+ test_external_ip("::ffff:192.167.255.255", 0);
+ test_internal_ip("::ffff:192.168.0.0", 0);
+ test_internal_ip("::ffff:192.168.255.255", 0);
+ test_external_ip("::ffff:192.169.0.0", 0);
+
+ test_external_ip("::ffff:169.253.255.255", 0);
+ test_internal_ip("::ffff:169.254.0.0", 0);
+ test_internal_ip("::ffff:169.254.255.255", 0);
+ test_external_ip("::ffff:169.255.0.0", 0);
+ test_assert(is_internal_IP(0x7f000001, 0));
+
+ /* tor_addr_compare(tor_addr_t x2) */
+ test_addr_compare("ffff::", ==, "ffff::0");
+ test_addr_compare("0::3:2:1", <, "0::ffff:0.3.2.1");
+ test_addr_compare("0::2:2:1", <, "0::ffff:0.3.2.1");
+ test_addr_compare("0::ffff:0.3.2.1", >, "0::0:0:0");
+ test_addr_compare("0::ffff:5.2.2.1", <, "::ffff:6.0.0.0"); /* XXXX wrong. */
+ tor_addr_parse_mask_ports("[::ffff:2.3.4.5]", &t1, NULL, NULL, NULL);
+ tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL);
+ test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) == 0);
+ tor_addr_parse_mask_ports("[::ffff:2.3.4.4]", &t1, NULL, NULL, NULL);
+ tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL);
+ test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) < 0);
+
+ /* test compare_masked */
+ test_addr_compare_masked("ffff::", ==, "ffff::0", 128);
+ test_addr_compare_masked("ffff::", ==, "ffff::0", 64);
+ test_addr_compare_masked("0::2:2:1", <, "0::8000:2:1", 81);
+ test_addr_compare_masked("0::2:2:1", ==, "0::8000:2:1", 80);
+
+ /* Test decorated addr_to_string. */
+ test_eq(AF_INET6, tor_addr_from_str(&t1, "[123:45:6789::5005:11]"));
+ p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
+ test_streq(p1, "[123:45:6789::5005:11]");
+ test_eq(AF_INET, tor_addr_from_str(&t1, "18.0.0.1"));
+ p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
+ test_streq(p1, "18.0.0.1");
+
+ /* Test tor_addr_parse_reverse_lookup_name */
+ i = tor_addr_parse_reverse_lookup_name(&t1, "Foobar.baz", AF_UNSPEC, 0);
+ test_eq(0, i);
+ i = tor_addr_parse_reverse_lookup_name(&t1, "Foobar.baz", AF_UNSPEC, 1);
+ test_eq(0, i);
+ i = tor_addr_parse_reverse_lookup_name(&t1, "1.0.168.192.in-addr.arpa",
+ AF_UNSPEC, 1);
+ test_eq(1, i);
+ test_eq(tor_addr_family(&t1), AF_INET);
+ p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
+ test_streq(p1, "192.168.0.1");
+ i = tor_addr_parse_reverse_lookup_name(&t1, "192.168.0.99", AF_UNSPEC, 0);
+ test_eq(0, i);
+ i = tor_addr_parse_reverse_lookup_name(&t1, "192.168.0.99", AF_UNSPEC, 1);
+ test_eq(1, i);
+ p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
+ test_streq(p1, "192.168.0.99");
+ memset(&t1, 0, sizeof(t1));
+ i = tor_addr_parse_reverse_lookup_name(&t1,
+ "0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f."
+ "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
+ "ip6.ARPA",
+ AF_UNSPEC, 0);
+ test_eq(1, i);
+ p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
+ test_streq(p1, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]");
+ /* Failing cases. */
+ i = tor_addr_parse_reverse_lookup_name(&t1,
+ "6.7.8.9.a.b.c.d.e.f."
+ "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
+ "ip6.ARPA",
+ AF_UNSPEC, 0);
+ test_eq(i, -1);
+ i = tor_addr_parse_reverse_lookup_name(&t1,
+ "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.f.0."
+ "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
+ "ip6.ARPA",
+ AF_UNSPEC, 0);
+ test_eq(i, -1);
+ i = tor_addr_parse_reverse_lookup_name(&t1,
+ "6.7.8.9.a.b.c.d.e.f.X.0.0.0.0.9."
+ "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
+ "ip6.ARPA",
+ AF_UNSPEC, 0);
+ test_eq(i, -1);
+ i = tor_addr_parse_reverse_lookup_name(&t1, "32.1.1.in-addr.arpa",
+ AF_UNSPEC, 0);
+ test_eq(i, -1);
+ i = tor_addr_parse_reverse_lookup_name(&t1, ".in-addr.arpa",
+ AF_UNSPEC, 0);
+ test_eq(i, -1);
+ i = tor_addr_parse_reverse_lookup_name(&t1, "1.2.3.4.5.in-addr.arpa",
+ AF_UNSPEC, 0);
+ test_eq(i, -1);
+ i = tor_addr_parse_reverse_lookup_name(&t1, "1.2.3.4.5.in-addr.arpa",
+ AF_INET6, 0);
+ test_eq(i, -1);
+ i = tor_addr_parse_reverse_lookup_name(&t1,
+ "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.0."
+ "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
+ "ip6.ARPA",
+ AF_INET, 0);
+ test_eq(i, -1);
+
+ /* test tor_addr_parse_mask_ports */
+ test_addr_mask_ports_parse("[::f]/17:47-95", AF_INET6,
+ 0, 0, 0, 0x0000000f, 17, 47, 95);
+ //test_addr_parse("[::fefe:4.1.1.7/120]:999-1000");
+ //test_addr_parse_check("::fefe:401:107", 120, 999, 1000);
+ test_addr_mask_ports_parse("[::ffff:4.1.1.7]/120:443", AF_INET6,
+ 0, 0, 0x0000ffff, 0x04010107, 120, 443, 443);
+ test_addr_mask_ports_parse("[abcd:2::44a:0]:2-65000", AF_INET6,
+ 0xabcd0002, 0, 0, 0x044a0000, 128, 2, 65000);
+
+ r=tor_addr_parse_mask_ports("[fefef::]/112", &t1, NULL, NULL, NULL);
+ test_assert(r == -1);
+ r=tor_addr_parse_mask_ports("efef::/112", &t1, NULL, NULL, NULL);
+ test_assert(r == -1);
+ r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f::]", &t1, NULL, NULL, NULL);
+ test_assert(r == -1);
+ r=tor_addr_parse_mask_ports("[::f:f:f:f:f:f:f:f]", &t1, NULL, NULL, NULL);
+ test_assert(r == -1);
+ r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f:f]", &t1, NULL, NULL, NULL);
+ test_assert(r == -1);
+ /* Test for V4-mapped address with mask < 96. (arguably not valid) */
+ r=tor_addr_parse_mask_ports("[::ffff:1.1.2.2/33]", &t1, &mask, NULL, NULL);
+ test_assert(r == -1);
+ r=tor_addr_parse_mask_ports("1.1.2.2/33", &t1, &mask, NULL, NULL);
+ test_assert(r == -1);
+ r=tor_addr_parse_mask_ports("1.1.2.2/31", &t1, &mask, NULL, NULL);
+ test_assert(r == AF_INET);
+ r=tor_addr_parse_mask_ports("[efef::]/112", &t1, &mask, &port1, &port2);
+ test_assert(r == AF_INET6);
+ test_assert(port1 == 1);
+ test_assert(port2 == 65535);
+
+ /* make sure inet address lengths >= max */
+ test_assert(INET_NTOA_BUF_LEN >= sizeof("255.255.255.255"));
+ test_assert(TOR_ADDR_BUF_LEN >=
+ sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"));
+
+ test_assert(sizeof(tor_addr_t) >= sizeof(struct in6_addr));
+
+ /* get interface addresses */
+ r = get_interface_address6(LOG_DEBUG, AF_INET, &t1);
+ i = get_interface_address6(LOG_DEBUG, AF_INET6, &t2);
+#if 0
+ tor_inet_ntop(AF_INET, &t1.sa.sin_addr, buf, sizeof(buf));
+ printf("\nv4 address: %s (family=%i)", buf, IN_FAMILY(&t1));
+ tor_inet_ntop(AF_INET6, &t2.sa6.sin6_addr, buf, sizeof(buf));
+ printf("\nv6 address: %s (family=%i)", buf, IN_FAMILY(&t2));
+#endif
+
+ done:
+ ;
+}
+
+#define ADDR_LEGACY(name) \
+ { #name, legacy_test_helper, 0, &legacy_setup, test_addr_ ## name }
+
+struct testcase_t addr_tests[] = {
+ ADDR_LEGACY(basic),
+ ADDR_LEGACY(ip6_helpers),
+ END_OF_TESTCASES
+};
+
diff --git a/src/test/test_containers.c b/src/test/test_containers.c
new file mode 100644
index 0000000000..1fc248cb46
--- /dev/null
+++ b/src/test/test_containers.c
@@ -0,0 +1,765 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#include "or.h"
+#include "test.h"
+
+/** Helper: return a tristate based on comparing the strings in *<b>a</b> and
+ * *<b>b</b>. */
+static int
+_compare_strs(const void **a, const void **b)
+{
+ const char *s1 = *a, *s2 = *b;
+ return strcmp(s1, s2);
+}
+
+/** Helper: return a tristate based on comparing the strings in *<b>a</b> and
+ * *<b>b</b>, excluding a's first character, and ignoring case. */
+static int
+_compare_without_first_ch(const void *a, const void **b)
+{
+ const char *s1 = a, *s2 = *b;
+ return strcasecmp(s1+1, s2);
+}
+
+/** Run unit tests for basic dynamic-sized array functionality. */
+static void
+test_container_smartlist_basic(void)
+{
+ smartlist_t *sl;
+
+ /* XXXX test sort_digests, uniq_strings, uniq_digests */
+
+ /* Test smartlist add, del_keeporder, insert, get. */
+ sl = smartlist_create();
+ smartlist_add(sl, (void*)1);
+ smartlist_add(sl, (void*)2);
+ smartlist_add(sl, (void*)3);
+ smartlist_add(sl, (void*)4);
+ smartlist_del_keeporder(sl, 1);
+ smartlist_insert(sl, 1, (void*)22);
+ smartlist_insert(sl, 0, (void*)0);
+ smartlist_insert(sl, 5, (void*)555);
+ test_eq_ptr((void*)0, smartlist_get(sl,0));
+ test_eq_ptr((void*)1, smartlist_get(sl,1));
+ test_eq_ptr((void*)22, smartlist_get(sl,2));
+ test_eq_ptr((void*)3, smartlist_get(sl,3));
+ test_eq_ptr((void*)4, smartlist_get(sl,4));
+ test_eq_ptr((void*)555, smartlist_get(sl,5));
+ /* Try deleting in the middle. */
+ smartlist_del(sl, 1);
+ test_eq_ptr((void*)555, smartlist_get(sl, 1));
+ /* Try deleting at the end. */
+ smartlist_del(sl, 4);
+ test_eq(4, smartlist_len(sl));
+
+ /* test isin. */
+ test_assert(smartlist_isin(sl, (void*)3));
+ test_assert(!smartlist_isin(sl, (void*)99));
+
+ done:
+ smartlist_free(sl);
+}
+
+/** Run unit tests for smartlist-of-strings functionality. */
+static void
+test_container_smartlist_strings(void)
+{
+ smartlist_t *sl = smartlist_create();
+ char *cp=NULL, *cp_alloc=NULL;
+ size_t sz;
+
+ /* Test split and join */
+ test_eq(0, smartlist_len(sl));
+ smartlist_split_string(sl, "abc", ":", 0, 0);
+ test_eq(1, smartlist_len(sl));
+ test_streq("abc", smartlist_get(sl, 0));
+ smartlist_split_string(sl, "a::bc::", "::", 0, 0);
+ test_eq(4, smartlist_len(sl));
+ test_streq("a", smartlist_get(sl, 1));
+ test_streq("bc", smartlist_get(sl, 2));
+ test_streq("", smartlist_get(sl, 3));
+ cp_alloc = smartlist_join_strings(sl, "", 0, NULL);
+ test_streq(cp_alloc, "abcabc");
+ tor_free(cp_alloc);
+ cp_alloc = smartlist_join_strings(sl, "!", 0, NULL);
+ test_streq(cp_alloc, "abc!a!bc!");
+ tor_free(cp_alloc);
+ cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
+ test_streq(cp_alloc, "abcXYaXYbcXY");
+ tor_free(cp_alloc);
+ cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
+ test_streq(cp_alloc, "abcXYaXYbcXYXY");
+ tor_free(cp_alloc);
+ cp_alloc = smartlist_join_strings(sl, "", 1, NULL);
+ test_streq(cp_alloc, "abcabc");
+ tor_free(cp_alloc);
+
+ smartlist_split_string(sl, "/def/ /ghijk", "/", 0, 0);
+ test_eq(8, smartlist_len(sl));
+ test_streq("", smartlist_get(sl, 4));
+ test_streq("def", smartlist_get(sl, 5));
+ test_streq(" ", smartlist_get(sl, 6));
+ test_streq("ghijk", smartlist_get(sl, 7));
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ smartlist_split_string(sl, "a,bbd,cdef", ",", SPLIT_SKIP_SPACE, 0);
+ test_eq(3, smartlist_len(sl));
+ test_streq("a", smartlist_get(sl,0));
+ test_streq("bbd", smartlist_get(sl,1));
+ test_streq("cdef", smartlist_get(sl,2));
+ smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>",
+ SPLIT_SKIP_SPACE, 0);
+ test_eq(8, smartlist_len(sl));
+ test_streq("z", smartlist_get(sl,3));
+ test_streq("zhasd", smartlist_get(sl,4));
+ test_streq("", smartlist_get(sl,5));
+ test_streq("bnud", smartlist_get(sl,6));
+ test_streq("", smartlist_get(sl,7));
+
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ smartlist_split_string(sl, " ab\tc \td ef ", NULL,
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ test_eq(4, smartlist_len(sl));
+ test_streq("ab", smartlist_get(sl,0));
+ test_streq("c", smartlist_get(sl,1));
+ test_streq("d", smartlist_get(sl,2));
+ test_streq("ef", smartlist_get(sl,3));
+ smartlist_split_string(sl, "ghi\tj", NULL,
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ test_eq(6, smartlist_len(sl));
+ test_streq("ghi", smartlist_get(sl,4));
+ test_streq("j", smartlist_get(sl,5));
+
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
+ test_streq(cp_alloc, "");
+ tor_free(cp_alloc);
+ cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
+ test_streq(cp_alloc, "XY");
+ tor_free(cp_alloc);
+
+ smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>",
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ test_eq(3, smartlist_len(sl));
+ test_streq("z", smartlist_get(sl, 0));
+ test_streq("zhasd", smartlist_get(sl, 1));
+ test_streq("bnud", smartlist_get(sl, 2));
+ smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>",
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
+ test_eq(5, smartlist_len(sl));
+ test_streq("z", smartlist_get(sl, 3));
+ test_streq("zhasd <> <> bnud<>", smartlist_get(sl, 4));
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ smartlist_split_string(sl, "abcd\n", "\n",
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ test_eq(1, smartlist_len(sl));
+ test_streq("abcd", smartlist_get(sl, 0));
+ smartlist_split_string(sl, "efgh", "\n",
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ test_eq(2, smartlist_len(sl));
+ test_streq("efgh", smartlist_get(sl, 1));
+
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ /* Test swapping, shuffling, and sorting. */
+ smartlist_split_string(sl, "the,onion,router,by,arma,and,nickm", ",", 0, 0);
+ test_eq(7, smartlist_len(sl));
+ smartlist_sort(sl, _compare_strs);
+ cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
+ test_streq(cp_alloc,"and,arma,by,nickm,onion,router,the");
+ tor_free(cp_alloc);
+ smartlist_swap(sl, 1, 5);
+ cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
+ test_streq(cp_alloc,"and,router,by,nickm,onion,arma,the");
+ tor_free(cp_alloc);
+ smartlist_shuffle(sl);
+ test_eq(7, smartlist_len(sl));
+ test_assert(smartlist_string_isin(sl, "and"));
+ test_assert(smartlist_string_isin(sl, "router"));
+ test_assert(smartlist_string_isin(sl, "by"));
+ test_assert(smartlist_string_isin(sl, "nickm"));
+ test_assert(smartlist_string_isin(sl, "onion"));
+ test_assert(smartlist_string_isin(sl, "arma"));
+ test_assert(smartlist_string_isin(sl, "the"));
+
+ /* Test bsearch. */
+ smartlist_sort(sl, _compare_strs);
+ test_streq("nickm", smartlist_bsearch(sl, "zNicKM",
+ _compare_without_first_ch));
+ test_streq("and", smartlist_bsearch(sl, " AND", _compare_without_first_ch));
+ test_eq_ptr(NULL, smartlist_bsearch(sl, " ANz", _compare_without_first_ch));
+
+ /* Test bsearch_idx */
+ {
+ int f;
+ test_eq(0, smartlist_bsearch_idx(sl," aaa",_compare_without_first_ch,&f));
+ test_eq(f, 0);
+ test_eq(0, smartlist_bsearch_idx(sl," and",_compare_without_first_ch,&f));
+ test_eq(f, 1);
+ test_eq(1, smartlist_bsearch_idx(sl," arm",_compare_without_first_ch,&f));
+ test_eq(f, 0);
+ test_eq(1, smartlist_bsearch_idx(sl," arma",_compare_without_first_ch,&f));
+ test_eq(f, 1);
+ test_eq(2, smartlist_bsearch_idx(sl," armb",_compare_without_first_ch,&f));
+ test_eq(f, 0);
+ test_eq(7, smartlist_bsearch_idx(sl," zzzz",_compare_without_first_ch,&f));
+ test_eq(f, 0);
+ }
+
+ /* Test reverse() and pop_last() */
+ smartlist_reverse(sl);
+ cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
+ test_streq(cp_alloc,"the,router,onion,nickm,by,arma,and");
+ tor_free(cp_alloc);
+ cp_alloc = smartlist_pop_last(sl);
+ test_streq(cp_alloc, "and");
+ tor_free(cp_alloc);
+ test_eq(smartlist_len(sl), 6);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+ cp_alloc = smartlist_pop_last(sl);
+ test_eq(cp_alloc, NULL);
+
+ /* Test uniq() */
+ smartlist_split_string(sl,
+ "50,noon,radar,a,man,a,plan,a,canal,panama,radar,noon,50",
+ ",", 0, 0);
+ smartlist_sort(sl, _compare_strs);
+ smartlist_uniq(sl, _compare_strs, _tor_free);
+ cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
+ test_streq(cp_alloc, "50,a,canal,man,noon,panama,plan,radar");
+ tor_free(cp_alloc);
+
+ /* Test string_isin and isin_case and num_isin */
+ test_assert(smartlist_string_isin(sl, "noon"));
+ test_assert(!smartlist_string_isin(sl, "noonoon"));
+ test_assert(smartlist_string_isin_case(sl, "nOOn"));
+ test_assert(!smartlist_string_isin_case(sl, "nooNooN"));
+ test_assert(smartlist_string_num_isin(sl, 50));
+ test_assert(!smartlist_string_num_isin(sl, 60));
+
+ /* Test smartlist_choose */
+ {
+ int i;
+ int allsame = 1;
+ int allin = 1;
+ void *first = smartlist_choose(sl);
+ test_assert(smartlist_isin(sl, first));
+ for (i = 0; i < 100; ++i) {
+ void *second = smartlist_choose(sl);
+ if (second != first)
+ allsame = 0;
+ if (!smartlist_isin(sl, second))
+ allin = 0;
+ }
+ test_assert(!allsame);
+ test_assert(allin);
+ }
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ /* Test string_remove and remove and join_strings2 */
+ smartlist_split_string(sl,
+ "Some say the Earth will end in ice and some in fire",
+ " ", 0, 0);
+ cp = smartlist_get(sl, 4);
+ test_streq(cp, "will");
+ smartlist_add(sl, cp);
+ smartlist_remove(sl, cp);
+ tor_free(cp);
+ cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
+ test_streq(cp_alloc, "Some,say,the,Earth,fire,end,in,ice,and,some,in");
+ tor_free(cp_alloc);
+ smartlist_string_remove(sl, "in");
+ cp_alloc = smartlist_join_strings2(sl, "+XX", 1, 0, &sz);
+ test_streq(cp_alloc, "Some+say+the+Earth+fire+end+some+ice+and");
+ test_eq((int)sz, 40);
+
+ done:
+
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_free(sl);
+ tor_free(cp_alloc);
+}
+
+/** Run unit tests for smartlist set manipulation functions. */
+static void
+test_container_smartlist_overlap(void)
+{
+ smartlist_t *sl = smartlist_create();
+ smartlist_t *ints = smartlist_create();
+ smartlist_t *odds = smartlist_create();
+ smartlist_t *evens = smartlist_create();
+ smartlist_t *primes = smartlist_create();
+ int i;
+ for (i=1; i < 10; i += 2)
+ smartlist_add(odds, (void*)(uintptr_t)i);
+ for (i=0; i < 10; i += 2)
+ smartlist_add(evens, (void*)(uintptr_t)i);
+
+ /* add_all */
+ smartlist_add_all(ints, odds);
+ smartlist_add_all(ints, evens);
+ test_eq(smartlist_len(ints), 10);
+
+ smartlist_add(primes, (void*)2);
+ smartlist_add(primes, (void*)3);
+ smartlist_add(primes, (void*)5);
+ smartlist_add(primes, (void*)7);
+
+ /* overlap */
+ test_assert(smartlist_overlap(ints, odds));
+ test_assert(smartlist_overlap(odds, primes));
+ test_assert(smartlist_overlap(evens, primes));
+ test_assert(!smartlist_overlap(odds, evens));
+
+ /* intersect */
+ smartlist_add_all(sl, odds);
+ smartlist_intersect(sl, primes);
+ test_eq(smartlist_len(sl), 3);
+ test_assert(smartlist_isin(sl, (void*)3));
+ test_assert(smartlist_isin(sl, (void*)5));
+ test_assert(smartlist_isin(sl, (void*)7));
+
+ /* subtract */
+ smartlist_add_all(sl, primes);
+ smartlist_subtract(sl, odds);
+ test_eq(smartlist_len(sl), 1);
+ test_assert(smartlist_isin(sl, (void*)2));
+
+ done:
+ smartlist_free(odds);
+ smartlist_free(evens);
+ smartlist_free(ints);
+ smartlist_free(primes);
+ smartlist_free(sl);
+}
+
+/** Run unit tests for smartlist-of-digests functions. */
+static void
+test_container_smartlist_digests(void)
+{
+ smartlist_t *sl = smartlist_create();
+
+ /* digest_isin. */
+ smartlist_add(sl, tor_memdup("AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN));
+ smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN));
+ smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN));
+ test_eq(0, smartlist_digest_isin(NULL, "AAAAAAAAAAAAAAAAAAAA"));
+ test_assert(smartlist_digest_isin(sl, "AAAAAAAAAAAAAAAAAAAA"));
+ test_assert(smartlist_digest_isin(sl, "\00090AAB2AAAAaasdAAAAA"));
+ test_eq(0, smartlist_digest_isin(sl, "\00090AAB2AAABaasdAAAAA"));
+
+ /* sort digests */
+ smartlist_sort_digests(sl);
+ test_memeq(smartlist_get(sl, 0), "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
+ test_memeq(smartlist_get(sl, 1), "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
+ test_memeq(smartlist_get(sl, 2), "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN);
+ test_eq(3, smartlist_len(sl));
+
+ /* uniq_digests */
+ smartlist_uniq_digests(sl);
+ test_eq(2, smartlist_len(sl));
+ test_memeq(smartlist_get(sl, 0), "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
+ test_memeq(smartlist_get(sl, 1), "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN);
+
+ done:
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_free(sl);
+}
+
+/** Run unit tests for concatenate-a-smartlist-of-strings functions. */
+static void
+test_container_smartlist_join(void)
+{
+ smartlist_t *sl = smartlist_create();
+ smartlist_t *sl2 = smartlist_create(), *sl3 = smartlist_create(),
+ *sl4 = smartlist_create();
+ char *joined=NULL;
+ /* unique, sorted. */
+ smartlist_split_string(sl,
+ "Abashments Ambush Anchorman Bacon Banks Borscht "
+ "Bunks Inhumane Insurance Knish Know Manners "
+ "Maraschinos Stamina Sunbonnets Unicorns Wombats",
+ " ", 0, 0);
+ /* non-unique, sorted. */
+ smartlist_split_string(sl2,
+ "Ambush Anchorman Anchorman Anemias Anemias Bacon "
+ "Crossbowmen Inhumane Insurance Knish Know Manners "
+ "Manners Maraschinos Wombats Wombats Work",
+ " ", 0, 0);
+ SMARTLIST_FOREACH_JOIN(sl, char *, cp1,
+ sl2, char *, cp2,
+ strcmp(cp1,cp2),
+ smartlist_add(sl3, cp2)) {
+ test_streq(cp1, cp2);
+ smartlist_add(sl4, cp1);
+ } SMARTLIST_FOREACH_JOIN_END(cp1, cp2);
+
+ SMARTLIST_FOREACH(sl3, const char *, cp,
+ test_assert(smartlist_isin(sl2, cp) &&
+ !smartlist_string_isin(sl, cp)));
+ SMARTLIST_FOREACH(sl4, const char *, cp,
+ test_assert(smartlist_isin(sl, cp) &&
+ smartlist_string_isin(sl2, cp)));
+ joined = smartlist_join_strings(sl3, ",", 0, NULL);
+ test_streq(joined, "Anemias,Anemias,Crossbowmen,Work");
+ tor_free(joined);
+ joined = smartlist_join_strings(sl4, ",", 0, NULL);
+ test_streq(joined, "Ambush,Anchorman,Anchorman,Bacon,Inhumane,Insurance,"
+ "Knish,Know,Manners,Manners,Maraschinos,Wombats,Wombats");
+ tor_free(joined);
+
+ done:
+ smartlist_free(sl4);
+ smartlist_free(sl3);
+ SMARTLIST_FOREACH(sl2, char *, cp, tor_free(cp));
+ smartlist_free(sl2);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_free(sl);
+ tor_free(joined);
+}
+
+/** Run unit tests for bitarray code */
+static void
+test_container_bitarray(void)
+{
+ bitarray_t *ba = NULL;
+ int i, j, ok=1;
+
+ ba = bitarray_init_zero(1);
+ test_assert(ba);
+ test_assert(! bitarray_is_set(ba, 0));
+ bitarray_set(ba, 0);
+ test_assert(bitarray_is_set(ba, 0));
+ bitarray_clear(ba, 0);
+ test_assert(! bitarray_is_set(ba, 0));
+ bitarray_free(ba);
+
+ ba = bitarray_init_zero(1023);
+ for (i = 1; i < 64; ) {
+ for (j = 0; j < 1023; ++j) {
+ if (j % i)
+ bitarray_set(ba, j);
+ else
+ bitarray_clear(ba, j);
+ }
+ for (j = 0; j < 1023; ++j) {
+ if (!bool_eq(bitarray_is_set(ba, j), j%i))
+ ok = 0;
+ }
+ test_assert(ok);
+ if (i < 7)
+ ++i;
+ else if (i == 28)
+ i = 32;
+ else
+ i += 7;
+ }
+
+ done:
+ if (ba)
+ bitarray_free(ba);
+}
+
+/** Run unit tests for digest set code (implemented as a hashtable or as a
+ * bloom filter) */
+static void
+test_container_digestset(void)
+{
+ smartlist_t *included = smartlist_create();
+ char d[DIGEST_LEN];
+ int i;
+ int ok = 1;
+ int false_positives = 0;
+ digestset_t *set = NULL;
+
+ for (i = 0; i < 1000; ++i) {
+ crypto_rand(d, DIGEST_LEN);
+ smartlist_add(included, tor_memdup(d, DIGEST_LEN));
+ }
+ set = digestset_new(1000);
+ SMARTLIST_FOREACH(included, const char *, cp,
+ if (digestset_isin(set, cp))
+ ok = 0);
+ test_assert(ok);
+ SMARTLIST_FOREACH(included, const char *, cp,
+ digestset_add(set, cp));
+ SMARTLIST_FOREACH(included, const char *, cp,
+ if (!digestset_isin(set, cp))
+ ok = 0);
+ test_assert(ok);
+ for (i = 0; i < 1000; ++i) {
+ crypto_rand(d, DIGEST_LEN);
+ if (digestset_isin(set, d))
+ ++false_positives;
+ }
+ test_assert(false_positives < 50); /* Should be far lower. */
+
+ done:
+ if (set)
+ digestset_free(set);
+ SMARTLIST_FOREACH(included, char *, cp, tor_free(cp));
+ smartlist_free(included);
+}
+
+typedef struct pq_entry_t {
+ const char *val;
+ int idx;
+} pq_entry_t;
+
+/** Helper: return a tristate based on comparing two pq_entry_t values. */
+static int
+_compare_strings_for_pqueue(const void *p1, const void *p2)
+{
+ const pq_entry_t *e1=p1, *e2=p2;
+ return strcmp(e1->val, e2->val);
+}
+
+/** Run unit tests for heap-based priority queue functions. */
+static void
+test_container_pqueue(void)
+{
+ smartlist_t *sl = smartlist_create();
+ int (*cmp)(const void *, const void*);
+ const int offset = STRUCT_OFFSET(pq_entry_t, idx);
+#define ENTRY(s) pq_entry_t s = { #s, -1 }
+ ENTRY(cows);
+ ENTRY(zebras);
+ ENTRY(fish);
+ ENTRY(frogs);
+ ENTRY(apples);
+ ENTRY(squid);
+ ENTRY(daschunds);
+ ENTRY(eggplants);
+ ENTRY(weissbier);
+ ENTRY(lobsters);
+ ENTRY(roquefort);
+ ENTRY(chinchillas);
+ ENTRY(fireflies);
+
+#define OK() smartlist_pqueue_assert_ok(sl, cmp, offset)
+
+ cmp = _compare_strings_for_pqueue;
+ smartlist_pqueue_add(sl, cmp, offset, &cows);
+ smartlist_pqueue_add(sl, cmp, offset, &zebras);
+ smartlist_pqueue_add(sl, cmp, offset, &fish);
+ smartlist_pqueue_add(sl, cmp, offset, &frogs);
+ smartlist_pqueue_add(sl, cmp, offset, &apples);
+ smartlist_pqueue_add(sl, cmp, offset, &squid);
+ smartlist_pqueue_add(sl, cmp, offset, &daschunds);
+ smartlist_pqueue_add(sl, cmp, offset, &eggplants);
+ smartlist_pqueue_add(sl, cmp, offset, &weissbier);
+ smartlist_pqueue_add(sl, cmp, offset, &lobsters);
+ smartlist_pqueue_add(sl, cmp, offset, &roquefort);
+
+ OK();
+
+ test_eq(smartlist_len(sl), 11);
+ test_eq_ptr(smartlist_get(sl, 0), &apples);
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &apples);
+ test_eq(smartlist_len(sl), 10);
+ OK();
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &cows);
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &daschunds);
+ smartlist_pqueue_add(sl, cmp, offset, &chinchillas);
+ OK();
+ smartlist_pqueue_add(sl, cmp, offset, &fireflies);
+ OK();
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &chinchillas);
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &eggplants);
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &fireflies);
+ OK();
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &fish);
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &frogs);
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &lobsters);
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &roquefort);
+ OK();
+ test_eq(smartlist_len(sl), 3);
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &squid);
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &weissbier);
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &zebras);
+ test_eq(smartlist_len(sl), 0);
+ OK();
+
+ /* Now test remove. */
+ smartlist_pqueue_add(sl, cmp, offset, &cows);
+ smartlist_pqueue_add(sl, cmp, offset, &fish);
+ smartlist_pqueue_add(sl, cmp, offset, &frogs);
+ smartlist_pqueue_add(sl, cmp, offset, &apples);
+ smartlist_pqueue_add(sl, cmp, offset, &squid);
+ smartlist_pqueue_add(sl, cmp, offset, &zebras);
+ test_eq(smartlist_len(sl), 6);
+ OK();
+ smartlist_pqueue_remove(sl, cmp, offset, &zebras);
+ test_eq(smartlist_len(sl), 5);
+ OK();
+ smartlist_pqueue_remove(sl, cmp, offset, &cows);
+ test_eq(smartlist_len(sl), 4);
+ OK();
+ smartlist_pqueue_remove(sl, cmp, offset, &apples);
+ test_eq(smartlist_len(sl), 3);
+ OK();
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &fish);
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &frogs);
+ test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &squid);
+ test_eq(smartlist_len(sl), 0);
+ OK();
+
+#undef OK
+
+ done:
+
+ smartlist_free(sl);
+}
+
+/** Run unit tests for string-to-void* map functions */
+static void
+test_container_strmap(void)
+{
+ strmap_t *map;
+ strmap_iter_t *iter;
+ const char *k;
+ void *v;
+ char *visited = NULL;
+ smartlist_t *found_keys = NULL;
+
+ map = strmap_new();
+ test_assert(map);
+ test_eq(strmap_size(map), 0);
+ test_assert(strmap_isempty(map));
+ v = strmap_set(map, "K1", (void*)99);
+ test_eq(v, NULL);
+ test_assert(!strmap_isempty(map));
+ v = strmap_set(map, "K2", (void*)101);
+ test_eq(v, NULL);
+ v = strmap_set(map, "K1", (void*)100);
+ test_eq(v, (void*)99);
+ test_eq_ptr(strmap_get(map,"K1"), (void*)100);
+ test_eq_ptr(strmap_get(map,"K2"), (void*)101);
+ test_eq_ptr(strmap_get(map,"K-not-there"), NULL);
+ strmap_assert_ok(map);
+
+ v = strmap_remove(map,"K2");
+ strmap_assert_ok(map);
+ test_eq_ptr(v, (void*)101);
+ test_eq_ptr(strmap_get(map,"K2"), NULL);
+ test_eq_ptr(strmap_remove(map,"K2"), NULL);
+
+ strmap_set(map, "K2", (void*)101);
+ strmap_set(map, "K3", (void*)102);
+ strmap_set(map, "K4", (void*)103);
+ test_eq(strmap_size(map), 4);
+ strmap_assert_ok(map);
+ strmap_set(map, "K5", (void*)104);
+ strmap_set(map, "K6", (void*)105);
+ strmap_assert_ok(map);
+
+ /* Test iterator. */
+ iter = strmap_iter_init(map);
+ found_keys = smartlist_create();
+ while (!strmap_iter_done(iter)) {
+ strmap_iter_get(iter,&k,&v);
+ smartlist_add(found_keys, tor_strdup(k));
+ test_eq_ptr(v, strmap_get(map, k));
+
+ if (!strcmp(k, "K2")) {
+ iter = strmap_iter_next_rmv(map,iter);
+ } else {
+ iter = strmap_iter_next(map,iter);
+ }
+ }
+
+ /* Make sure we removed K2, but not the others. */
+ test_eq_ptr(strmap_get(map, "K2"), NULL);
+ test_eq_ptr(strmap_get(map, "K5"), (void*)104);
+ /* Make sure we visited everyone once */
+ smartlist_sort_strings(found_keys);
+ visited = smartlist_join_strings(found_keys, ":", 0, NULL);
+ test_streq(visited, "K1:K2:K3:K4:K5:K6");
+
+ strmap_assert_ok(map);
+ /* Clean up after ourselves. */
+ strmap_free(map, NULL);
+ map = NULL;
+
+ /* Now try some lc functions. */
+ map = strmap_new();
+ strmap_set_lc(map,"Ab.C", (void*)1);
+ test_eq_ptr(strmap_get(map,"ab.c"), (void*)1);
+ strmap_assert_ok(map);
+ test_eq_ptr(strmap_get_lc(map,"AB.C"), (void*)1);
+ test_eq_ptr(strmap_get(map,"AB.C"), NULL);
+ test_eq_ptr(strmap_remove_lc(map,"aB.C"), (void*)1);
+ strmap_assert_ok(map);
+ test_eq_ptr(strmap_get_lc(map,"AB.C"), NULL);
+
+ done:
+ if (map)
+ strmap_free(map,NULL);
+ if (found_keys) {
+ SMARTLIST_FOREACH(found_keys, char *, cp, tor_free(cp));
+ smartlist_free(found_keys);
+ }
+ tor_free(visited);
+}
+
+/** Run unit tests for getting the median of a list. */
+static void
+test_container_order_functions(void)
+{
+ int lst[25], n = 0;
+ // int a=12,b=24,c=25,d=60,e=77;
+
+#define median() median_int(lst, n)
+
+ lst[n++] = 12;
+ test_eq(12, median()); /* 12 */
+ lst[n++] = 77;
+ //smartlist_shuffle(sl);
+ test_eq(12, median()); /* 12, 77 */
+ lst[n++] = 77;
+ //smartlist_shuffle(sl);
+ test_eq(77, median()); /* 12, 77, 77 */
+ lst[n++] = 24;
+ test_eq(24, median()); /* 12,24,77,77 */
+ lst[n++] = 60;
+ lst[n++] = 12;
+ lst[n++] = 25;
+ //smartlist_shuffle(sl);
+ test_eq(25, median()); /* 12,12,24,25,60,77,77 */
+#undef median
+
+ done:
+ ;
+}
+
+#define CONTAINER_LEGACY(name) \
+ { #name, legacy_test_helper, 0, &legacy_setup, test_container_ ## name }
+
+struct testcase_t container_tests[] = {
+ CONTAINER_LEGACY(smartlist_basic),
+ CONTAINER_LEGACY(smartlist_strings),
+ CONTAINER_LEGACY(smartlist_overlap),
+ CONTAINER_LEGACY(smartlist_digests),
+ CONTAINER_LEGACY(smartlist_join),
+ CONTAINER_LEGACY(bitarray),
+ CONTAINER_LEGACY(digestset),
+ CONTAINER_LEGACY(strmap),
+ CONTAINER_LEGACY(pqueue),
+ CONTAINER_LEGACY(order_functions),
+ END_OF_TESTCASES
+};
+
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
new file mode 100644
index 0000000000..b475914b1b
--- /dev/null
+++ b/src/test/test_crypto.c
@@ -0,0 +1,788 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#define CRYPTO_PRIVATE
+#include "or.h"
+#include "test.h"
+
+/** Run unit tests for Diffie-Hellman functionality. */
+static void
+test_crypto_dh(void)
+{
+ crypto_dh_env_t *dh1 = crypto_dh_new();
+ crypto_dh_env_t *dh2 = crypto_dh_new();
+ char p1[DH_BYTES];
+ char p2[DH_BYTES];
+ char s1[DH_BYTES];
+ char s2[DH_BYTES];
+ ssize_t s1len, s2len;
+
+ test_eq(crypto_dh_get_bytes(dh1), DH_BYTES);
+ test_eq(crypto_dh_get_bytes(dh2), DH_BYTES);
+
+ memset(p1, 0, DH_BYTES);
+ memset(p2, 0, DH_BYTES);
+ test_memeq(p1, p2, DH_BYTES);
+ test_assert(! crypto_dh_get_public(dh1, p1, DH_BYTES));
+ test_memneq(p1, p2, DH_BYTES);
+ test_assert(! crypto_dh_get_public(dh2, p2, DH_BYTES));
+ test_memneq(p1, p2, DH_BYTES);
+
+ memset(s1, 0, DH_BYTES);
+ memset(s2, 0xFF, DH_BYTES);
+ s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p2, DH_BYTES, s1, 50);
+ s2len = crypto_dh_compute_secret(LOG_WARN, dh2, p1, DH_BYTES, s2, 50);
+ test_assert(s1len > 0);
+ test_eq(s1len, s2len);
+ test_memeq(s1, s2, s1len);
+
+ {
+ /* XXXX Now fabricate some bad values and make sure they get caught,
+ * Check 0, 1, N-1, >= N, etc.
+ */
+ }
+
+ done:
+ crypto_dh_free(dh1);
+ crypto_dh_free(dh2);
+}
+
+/** Run unit tests for our random number generation function and its wrappers.
+ */
+static void
+test_crypto_rng(void)
+{
+ int i, j, allok;
+ char data1[100], data2[100];
+ double d;
+
+ /* Try out RNG. */
+ test_assert(! crypto_seed_rng(0));
+ crypto_rand(data1, 100);
+ crypto_rand(data2, 100);
+ test_memneq(data1,data2,100);
+ allok = 1;
+ for (i = 0; i < 100; ++i) {
+ uint64_t big;
+ char *host;
+ j = crypto_rand_int(100);
+ if (i < 0 || i >= 100)
+ allok = 0;
+ big = crypto_rand_uint64(U64_LITERAL(1)<<40);
+ if (big >= (U64_LITERAL(1)<<40))
+ allok = 0;
+ big = crypto_rand_uint64(U64_LITERAL(5));
+ if (big >= 5)
+ allok = 0;
+ d = crypto_rand_double();
+ test_assert(d >= 0);
+ test_assert(d < 1.0);
+ host = crypto_random_hostname(3,8,"www.",".onion");
+ if (strcmpstart(host,"www.") ||
+ strcmpend(host,".onion") ||
+ strlen(host) < 13 ||
+ strlen(host) > 18)
+ allok = 0;
+ tor_free(host);
+ }
+ test_assert(allok);
+ done:
+ ;
+}
+
+/** Run unit tests for our AES functionality */
+static void
+test_crypto_aes(void)
+{
+ char *data1 = NULL, *data2 = NULL, *data3 = NULL;
+ crypto_cipher_env_t *env1 = NULL, *env2 = NULL;
+ int i, j;
+ char *mem_op_hex_tmp=NULL;
+
+ data1 = tor_malloc(1024);
+ data2 = tor_malloc(1024);
+ data3 = tor_malloc(1024);
+
+ /* Now, test encryption and decryption with stream cipher. */
+ data1[0]='\0';
+ for (i = 1023; i>0; i -= 35)
+ strncat(data1, "Now is the time for all good onions", i);
+
+ memset(data2, 0, 1024);
+ memset(data3, 0, 1024);
+ env1 = crypto_new_cipher_env();
+ test_neq(env1, 0);
+ env2 = crypto_new_cipher_env();
+ test_neq(env2, 0);
+ j = crypto_cipher_generate_key(env1);
+ crypto_cipher_set_key(env2, crypto_cipher_get_key(env1));
+ crypto_cipher_encrypt_init_cipher(env1);
+ crypto_cipher_decrypt_init_cipher(env2);
+
+ /* Try encrypting 512 chars. */
+ crypto_cipher_encrypt(env1, data2, data1, 512);
+ crypto_cipher_decrypt(env2, data3, data2, 512);
+ test_memeq(data1, data3, 512);
+ test_memneq(data1, data2, 512);
+
+ /* Now encrypt 1 at a time, and get 1 at a time. */
+ for (j = 512; j < 560; ++j) {
+ crypto_cipher_encrypt(env1, data2+j, data1+j, 1);
+ }
+ for (j = 512; j < 560; ++j) {
+ crypto_cipher_decrypt(env2, data3+j, data2+j, 1);
+ }
+ test_memeq(data1, data3, 560);
+ /* Now encrypt 3 at a time, and get 5 at a time. */
+ for (j = 560; j < 1024-5; j += 3) {
+ crypto_cipher_encrypt(env1, data2+j, data1+j, 3);
+ }
+ for (j = 560; j < 1024-5; j += 5) {
+ crypto_cipher_decrypt(env2, data3+j, data2+j, 5);
+ }
+ test_memeq(data1, data3, 1024-5);
+ /* Now make sure that when we encrypt with different chunk sizes, we get
+ the same results. */
+ crypto_free_cipher_env(env2);
+ env2 = NULL;
+
+ memset(data3, 0, 1024);
+ env2 = crypto_new_cipher_env();
+ test_neq(env2, 0);
+ crypto_cipher_set_key(env2, crypto_cipher_get_key(env1));
+ crypto_cipher_encrypt_init_cipher(env2);
+ for (j = 0; j < 1024-16; j += 17) {
+ crypto_cipher_encrypt(env2, data3+j, data1+j, 17);
+ }
+ for (j= 0; j < 1024-16; ++j) {
+ if (data2[j] != data3[j]) {
+ printf("%d: %d\t%d\n", j, (int) data2[j], (int) data3[j]);
+ }
+ }
+ test_memeq(data2, data3, 1024-16);
+ crypto_free_cipher_env(env1);
+ env1 = NULL;
+ crypto_free_cipher_env(env2);
+ env2 = NULL;
+
+ /* NIST test vector for aes. */
+ env1 = crypto_new_cipher_env(); /* IV starts at 0 */
+ crypto_cipher_set_key(env1, "\x80\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00");
+ crypto_cipher_encrypt_init_cipher(env1);
+ crypto_cipher_encrypt(env1, data1,
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00", 16);
+ test_memeq_hex(data1, "0EDD33D3C621E546455BD8BA1418BEC8");
+
+ /* Now test rollover. All these values are originally from a python
+ * script. */
+ crypto_cipher_set_iv(env1, "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\xff\xff\xff\xff\xff\xff\xff\xff");
+ memset(data2, 0, 1024);
+ crypto_cipher_encrypt(env1, data1, data2, 32);
+ test_memeq_hex(data1, "335fe6da56f843199066c14a00a40231"
+ "cdd0b917dbc7186908a6bfb5ffd574d3");
+
+ crypto_cipher_set_iv(env1, "\x00\x00\x00\x00\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff");
+ memset(data2, 0, 1024);
+ crypto_cipher_encrypt(env1, data1, data2, 32);
+ test_memeq_hex(data1, "e627c6423fa2d77832a02b2794094b73"
+ "3e63c721df790d2c6469cc1953a3ffac");
+
+ crypto_cipher_set_iv(env1, "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff");
+ memset(data2, 0, 1024);
+ crypto_cipher_encrypt(env1, data1, data2, 32);
+ test_memeq_hex(data1, "2aed2bff0de54f9328efd070bf48f70a"
+ "0EDD33D3C621E546455BD8BA1418BEC8");
+
+ /* Now check rollover on inplace cipher. */
+ crypto_cipher_set_iv(env1, "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff");
+ crypto_cipher_crypt_inplace(env1, data2, 64);
+ test_memeq_hex(data2, "2aed2bff0de54f9328efd070bf48f70a"
+ "0EDD33D3C621E546455BD8BA1418BEC8"
+ "93e2c5243d6839eac58503919192f7ae"
+ "1908e67cafa08d508816659c2e693191");
+ crypto_cipher_set_iv(env1, "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff");
+ crypto_cipher_crypt_inplace(env1, data2, 64);
+ test_assert(tor_mem_is_zero(data2, 64));
+
+ done:
+ tor_free(mem_op_hex_tmp);
+ if (env1)
+ crypto_free_cipher_env(env1);
+ if (env2)
+ crypto_free_cipher_env(env2);
+ tor_free(data1);
+ tor_free(data2);
+ tor_free(data3);
+}
+
+/** Run unit tests for our SHA-1 functionality */
+static void
+test_crypto_sha(void)
+{
+ crypto_digest_env_t *d1 = NULL, *d2 = NULL;
+ int i;
+ char key[80];
+ char digest[32];
+ char data[50];
+ char d_out1[DIGEST_LEN], d_out2[DIGEST256_LEN];
+ char *mem_op_hex_tmp=NULL;
+
+ /* Test SHA-1 with a test vector from the specification. */
+ i = crypto_digest(data, "abc", 3);
+ test_memeq_hex(data, "A9993E364706816ABA3E25717850C26C9CD0D89D");
+
+ /* Test SHA-256 with a test vector from the specification. */
+ i = crypto_digest256(data, "abc", 3, DIGEST_SHA256);
+ test_memeq_hex(data, "BA7816BF8F01CFEA414140DE5DAE2223B00361A3"
+ "96177A9CB410FF61F20015AD");
+
+ /* Test HMAC-SHA-1 with test cases from RFC2202. */
+
+ /* Case 1. */
+ memset(key, 0x0b, 20);
+ crypto_hmac_sha1(digest, key, 20, "Hi There", 8);
+ test_streq(hex_str(digest, 20),
+ "B617318655057264E28BC0B6FB378C8EF146BE00");
+ /* Case 2. */
+ crypto_hmac_sha1(digest, "Jefe", 4, "what do ya want for nothing?", 28);
+ test_streq(hex_str(digest, 20),
+ "EFFCDF6AE5EB2FA2D27416D5F184DF9C259A7C79");
+
+ /* Case 4. */
+ base16_decode(key, 25,
+ "0102030405060708090a0b0c0d0e0f10111213141516171819", 50);
+ memset(data, 0xcd, 50);
+ crypto_hmac_sha1(digest, key, 25, data, 50);
+ test_streq(hex_str(digest, 20),
+ "4C9007F4026250C6BC8414F9BF50C86C2D7235DA");
+
+ /* Case 5. */
+ memset(key, 0xaa, 80);
+ crypto_hmac_sha1(digest, key, 80,
+ "Test Using Larger Than Block-Size Key - Hash Key First",
+ 54);
+ test_streq(hex_str(digest, 20),
+ "AA4AE5E15272D00E95705637CE8A3B55ED402112");
+
+ /* Incremental digest code. */
+ d1 = crypto_new_digest_env();
+ test_assert(d1);
+ crypto_digest_add_bytes(d1, "abcdef", 6);
+ d2 = crypto_digest_dup(d1);
+ test_assert(d2);
+ crypto_digest_add_bytes(d2, "ghijkl", 6);
+ crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
+ crypto_digest(d_out2, "abcdefghijkl", 12);
+ test_memeq(d_out1, d_out2, DIGEST_LEN);
+ crypto_digest_assign(d2, d1);
+ crypto_digest_add_bytes(d2, "mno", 3);
+ crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
+ crypto_digest(d_out2, "abcdefmno", 9);
+ test_memeq(d_out1, d_out2, DIGEST_LEN);
+ crypto_digest_get_digest(d1, d_out1, sizeof(d_out1));
+ crypto_digest(d_out2, "abcdef", 6);
+ test_memeq(d_out1, d_out2, DIGEST_LEN);
+ crypto_free_digest_env(d1);
+ crypto_free_digest_env(d2);
+
+ /* Incremental digest code with sha256 */
+ d1 = crypto_new_digest256_env(DIGEST_SHA256);
+ test_assert(d1);
+ crypto_digest_add_bytes(d1, "abcdef", 6);
+ d2 = crypto_digest_dup(d1);
+ test_assert(d2);
+ crypto_digest_add_bytes(d2, "ghijkl", 6);
+ crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
+ crypto_digest256(d_out2, "abcdefghijkl", 12, DIGEST_SHA256);
+ test_memeq(d_out1, d_out2, DIGEST_LEN);
+ crypto_digest_assign(d2, d1);
+ crypto_digest_add_bytes(d2, "mno", 3);
+ crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
+ crypto_digest256(d_out2, "abcdefmno", 9, DIGEST_SHA256);
+ test_memeq(d_out1, d_out2, DIGEST_LEN);
+ crypto_digest_get_digest(d1, d_out1, sizeof(d_out1));
+ crypto_digest256(d_out2, "abcdef", 6, DIGEST_SHA256);
+ test_memeq(d_out1, d_out2, DIGEST_LEN);
+
+ done:
+ if (d1)
+ crypto_free_digest_env(d1);
+ if (d2)
+ crypto_free_digest_env(d2);
+ tor_free(mem_op_hex_tmp);
+}
+
+/** Run unit tests for our public key crypto functions */
+static void
+test_crypto_pk(void)
+{
+ crypto_pk_env_t *pk1 = NULL, *pk2 = NULL;
+ char *encoded = NULL;
+ char data1[1024], data2[1024], data3[1024];
+ size_t size;
+ int i, j, p, len;
+
+ /* Public-key ciphers */
+ pk1 = pk_generate(0);
+ pk2 = crypto_new_pk_env();
+ test_assert(pk1 && pk2);
+ test_assert(! crypto_pk_write_public_key_to_string(pk1, &encoded, &size));
+ test_assert(! crypto_pk_read_public_key_from_string(pk2, encoded, size));
+ test_eq(0, crypto_pk_cmp_keys(pk1, pk2));
+
+ test_eq(128, crypto_pk_keysize(pk1));
+ test_eq(128, crypto_pk_keysize(pk2));
+
+ test_eq(128, crypto_pk_public_encrypt(pk2, data1, "Hello whirled.", 15,
+ PK_PKCS1_OAEP_PADDING));
+ test_eq(128, crypto_pk_public_encrypt(pk1, data2, "Hello whirled.", 15,
+ PK_PKCS1_OAEP_PADDING));
+ /* oaep padding should make encryption not match */
+ test_memneq(data1, data2, 128);
+ test_eq(15, crypto_pk_private_decrypt(pk1, data3, data1, 128,
+ PK_PKCS1_OAEP_PADDING,1));
+ test_streq(data3, "Hello whirled.");
+ memset(data3, 0, 1024);
+ test_eq(15, crypto_pk_private_decrypt(pk1, data3, data2, 128,
+ PK_PKCS1_OAEP_PADDING,1));
+ test_streq(data3, "Hello whirled.");
+ /* Can't decrypt with public key. */
+ test_eq(-1, crypto_pk_private_decrypt(pk2, data3, data2, 128,
+ PK_PKCS1_OAEP_PADDING,1));
+ /* Try again with bad padding */
+ memcpy(data2+1, "XYZZY", 5); /* This has fails ~ once-in-2^40 */
+ test_eq(-1, crypto_pk_private_decrypt(pk1, data3, data2, 128,
+ PK_PKCS1_OAEP_PADDING,1));
+
+ /* File operations: save and load private key */
+ test_assert(! crypto_pk_write_private_key_to_filename(pk1,
+ get_fname("pkey1")));
+ /* failing case for read: can't read. */
+ test_assert(crypto_pk_read_private_key_from_filename(pk2,
+ get_fname("xyzzy")) < 0);
+ write_str_to_file(get_fname("xyzzy"), "foobar", 6);
+ /* Failing case for read: no key. */
+ test_assert(crypto_pk_read_private_key_from_filename(pk2,
+ get_fname("xyzzy")) < 0);
+ test_assert(! crypto_pk_read_private_key_from_filename(pk2,
+ get_fname("pkey1")));
+ test_eq(15, crypto_pk_private_decrypt(pk2, data3, data1, 128,
+ PK_PKCS1_OAEP_PADDING,1));
+
+ /* Now try signing. */
+ strlcpy(data1, "Ossifrage", 1024);
+ test_eq(128, crypto_pk_private_sign(pk1, data2, data1, 10));
+ test_eq(10, crypto_pk_public_checksig(pk1, data3, data2, 128));
+ test_streq(data3, "Ossifrage");
+ /* Try signing digests. */
+ test_eq(128, crypto_pk_private_sign_digest(pk1, data2, data1, 10));
+ test_eq(20, crypto_pk_public_checksig(pk1, data3, data2, 128));
+ test_eq(0, crypto_pk_public_checksig_digest(pk1, data1, 10, data2, 128));
+ test_eq(-1, crypto_pk_public_checksig_digest(pk1, data1, 11, data2, 128));
+ /*XXXX test failed signing*/
+
+ /* Try encoding */
+ crypto_free_pk_env(pk2);
+ pk2 = NULL;
+ i = crypto_pk_asn1_encode(pk1, data1, 1024);
+ test_assert(i>0);
+ pk2 = crypto_pk_asn1_decode(data1, i);
+ test_assert(crypto_pk_cmp_keys(pk1,pk2) == 0);
+
+ /* Try with hybrid encryption wrappers. */
+ crypto_rand(data1, 1024);
+ for (i = 0; i < 3; ++i) {
+ for (j = 85; j < 140; ++j) {
+ memset(data2,0,1024);
+ memset(data3,0,1024);
+ if (i == 0 && j < 129)
+ continue;
+ p = (i==0)?PK_NO_PADDING:
+ (i==1)?PK_PKCS1_PADDING:PK_PKCS1_OAEP_PADDING;
+ len = crypto_pk_public_hybrid_encrypt(pk1,data2,data1,j,p,0);
+ test_assert(len>=0);
+ len = crypto_pk_private_hybrid_decrypt(pk1,data3,data2,len,p,1);
+ test_eq(len,j);
+ test_memeq(data1,data3,j);
+ }
+ }
+
+ /* Try copy_full */
+ crypto_free_pk_env(pk2);
+ pk2 = crypto_pk_copy_full(pk1);
+ test_assert(pk2 != NULL);
+ test_neq_ptr(pk1, pk2);
+ test_assert(crypto_pk_cmp_keys(pk1,pk2) == 0);
+
+ done:
+ if (pk1)
+ crypto_free_pk_env(pk1);
+ if (pk2)
+ crypto_free_pk_env(pk2);
+ tor_free(encoded);
+}
+
+/** Run unit tests for misc crypto formatting functionality (base64, base32,
+ * fingerprints, etc) */
+static void
+test_crypto_formats(void)
+{
+ char *data1 = NULL, *data2 = NULL, *data3 = NULL;
+ int i, j, idx;
+
+ data1 = tor_malloc(1024);
+ data2 = tor_malloc(1024);
+ data3 = tor_malloc(1024);
+ test_assert(data1 && data2 && data3);
+
+ /* Base64 tests */
+ memset(data1, 6, 1024);
+ for (idx = 0; idx < 10; ++idx) {
+ i = base64_encode(data2, 1024, data1, idx);
+ test_assert(i >= 0);
+ j = base64_decode(data3, 1024, data2, i);
+ test_eq(j,idx);
+ test_memeq(data3, data1, idx);
+ }
+
+ strlcpy(data1, "Test string that contains 35 chars.", 1024);
+ strlcat(data1, " 2nd string that contains 35 chars.", 1024);
+
+ i = base64_encode(data2, 1024, data1, 71);
+ test_assert(i >= 0);
+ j = base64_decode(data3, 1024, data2, i);
+ test_eq(j, 71);
+ test_streq(data3, data1);
+ test_assert(data2[i] == '\0');
+
+ crypto_rand(data1, DIGEST_LEN);
+ memset(data2, 100, 1024);
+ digest_to_base64(data2, data1);
+ test_eq(BASE64_DIGEST_LEN, strlen(data2));
+ test_eq(100, data2[BASE64_DIGEST_LEN+2]);
+ memset(data3, 99, 1024);
+ test_eq(digest_from_base64(data3, data2), 0);
+ test_memeq(data1, data3, DIGEST_LEN);
+ test_eq(99, data3[DIGEST_LEN+1]);
+
+ test_assert(digest_from_base64(data3, "###") < 0);
+
+ /* Encoding SHA256 */
+ crypto_rand(data2, DIGEST256_LEN);
+ memset(data2, 100, 1024);
+ digest256_to_base64(data2, data1);
+ test_eq(BASE64_DIGEST256_LEN, strlen(data2));
+ test_eq(100, data2[BASE64_DIGEST256_LEN+2]);
+ memset(data3, 99, 1024);
+ test_eq(digest256_from_base64(data3, data2), 0);
+ test_memeq(data1, data3, DIGEST256_LEN);
+ test_eq(99, data3[DIGEST256_LEN+1]);
+
+ /* Base32 tests */
+ strlcpy(data1, "5chrs", 1024);
+ /* bit pattern is: [35 63 68 72 73] ->
+ * [00110101 01100011 01101000 01110010 01110011]
+ * By 5s: [00110 10101 10001 10110 10000 11100 10011 10011]
+ */
+ base32_encode(data2, 9, data1, 5);
+ test_streq(data2, "gvrwq4tt");
+
+ strlcpy(data1, "\xFF\xF5\x6D\x44\xAE\x0D\x5C\xC9\x62\xC4", 1024);
+ base32_encode(data2, 30, data1, 10);
+ test_streq(data2, "772w2rfobvomsywe");
+
+ /* Base16 tests */
+ strlcpy(data1, "6chrs\xff", 1024);
+ base16_encode(data2, 13, data1, 6);
+ test_streq(data2, "3663687273FF");
+
+ strlcpy(data1, "f0d678affc000100", 1024);
+ i = base16_decode(data2, 8, data1, 16);
+ test_eq(i,0);
+ test_memeq(data2, "\xf0\xd6\x78\xaf\xfc\x00\x01\x00",8);
+
+ /* now try some failing base16 decodes */
+ test_eq(-1, base16_decode(data2, 8, data1, 15)); /* odd input len */
+ test_eq(-1, base16_decode(data2, 7, data1, 16)); /* dest too short */
+ strlcpy(data1, "f0dz!8affc000100", 1024);
+ test_eq(-1, base16_decode(data2, 8, data1, 16));
+
+ tor_free(data1);
+ tor_free(data2);
+ tor_free(data3);
+
+ /* Add spaces to fingerprint */
+ {
+ data1 = tor_strdup("ABCD1234ABCD56780000ABCD1234ABCD56780000");
+ test_eq(strlen(data1), 40);
+ data2 = tor_malloc(FINGERPRINT_LEN+1);
+ add_spaces_to_fp(data2, FINGERPRINT_LEN+1, data1);
+ test_streq(data2, "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 0000");
+ tor_free(data1);
+ tor_free(data2);
+ }
+
+ /* Check fingerprint */
+ {
+ test_assert(crypto_pk_check_fingerprint_syntax(
+ "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 0000"));
+ test_assert(!crypto_pk_check_fingerprint_syntax(
+ "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 000"));
+ test_assert(!crypto_pk_check_fingerprint_syntax(
+ "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 00000"));
+ test_assert(!crypto_pk_check_fingerprint_syntax(
+ "ABCD 1234 ABCD 5678 0000 ABCD1234 ABCD 5678 0000"));
+ test_assert(!crypto_pk_check_fingerprint_syntax(
+ "ABCD 1234 ABCD 5678 0000 ABCD1234 ABCD 5678 00000"));
+ test_assert(!crypto_pk_check_fingerprint_syntax(
+ "ACD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 00000"));
+ }
+
+ done:
+ tor_free(data1);
+ tor_free(data2);
+ tor_free(data3);
+}
+
+/** Run unit tests for our secret-to-key passphrase hashing functionality. */
+static void
+test_crypto_s2k(void)
+{
+ char buf[29];
+ char buf2[29];
+ char *buf3 = NULL;
+ int i;
+
+ memset(buf, 0, sizeof(buf));
+ memset(buf2, 0, sizeof(buf2));
+ buf3 = tor_malloc(65536);
+ memset(buf3, 0, 65536);
+
+ secret_to_key(buf+9, 20, "", 0, buf);
+ crypto_digest(buf2+9, buf3, 1024);
+ test_memeq(buf, buf2, 29);
+
+ memcpy(buf,"vrbacrda",8);
+ memcpy(buf2,"vrbacrda",8);
+ buf[8] = 96;
+ buf2[8] = 96;
+ secret_to_key(buf+9, 20, "12345678", 8, buf);
+ for (i = 0; i < 65536; i += 16) {
+ memcpy(buf3+i, "vrbacrda12345678", 16);
+ }
+ crypto_digest(buf2+9, buf3, 65536);
+ test_memeq(buf, buf2, 29);
+
+ done:
+ tor_free(buf3);
+}
+
+/** Test AES-CTR encryption and decryption with IV. */
+static void
+test_crypto_aes_iv(void)
+{
+ crypto_cipher_env_t *cipher;
+ char *plain, *encrypted1, *encrypted2, *decrypted1, *decrypted2;
+ char plain_1[1], plain_15[15], plain_16[16], plain_17[17];
+ char key1[16], key2[16];
+ ssize_t encrypted_size, decrypted_size;
+
+ plain = tor_malloc(4095);
+ encrypted1 = tor_malloc(4095 + 1 + 16);
+ encrypted2 = tor_malloc(4095 + 1 + 16);
+ decrypted1 = tor_malloc(4095 + 1);
+ decrypted2 = tor_malloc(4095 + 1);
+
+ crypto_rand(plain, 4095);
+ crypto_rand(key1, 16);
+ crypto_rand(key2, 16);
+ crypto_rand(plain_1, 1);
+ crypto_rand(plain_15, 15);
+ crypto_rand(plain_16, 16);
+ crypto_rand(plain_17, 17);
+ key1[0] = key2[0] + 128; /* Make sure that contents are different. */
+ /* Encrypt and decrypt with the same key. */
+ cipher = crypto_create_init_cipher(key1, 1);
+ encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 4095,
+ plain, 4095);
+ crypto_free_cipher_env(cipher);
+ cipher = NULL;
+ test_eq(encrypted_size, 16 + 4095);
+ tor_assert(encrypted_size > 0); /* This is obviously true, since 4111 is
+ * greater than 0, but its truth is not
+ * obvious to all analysis tools. */
+ cipher = crypto_create_init_cipher(key1, 0);
+ decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 4095,
+ encrypted1, encrypted_size);
+ crypto_free_cipher_env(cipher);
+ cipher = NULL;
+ test_eq(decrypted_size, 4095);
+ tor_assert(decrypted_size > 0);
+ test_memeq(plain, decrypted1, 4095);
+ /* Encrypt a second time (with a new random initialization vector). */
+ cipher = crypto_create_init_cipher(key1, 1);
+ encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted2, 16 + 4095,
+ plain, 4095);
+ crypto_free_cipher_env(cipher);
+ cipher = NULL;
+ test_eq(encrypted_size, 16 + 4095);
+ tor_assert(encrypted_size > 0);
+ cipher = crypto_create_init_cipher(key1, 0);
+ decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted2, 4095,
+ encrypted2, encrypted_size);
+ crypto_free_cipher_env(cipher);
+ cipher = NULL;
+ test_eq(decrypted_size, 4095);
+ tor_assert(decrypted_size > 0);
+ test_memeq(plain, decrypted2, 4095);
+ test_memneq(encrypted1, encrypted2, encrypted_size);
+ /* Decrypt with the wrong key. */
+ cipher = crypto_create_init_cipher(key2, 0);
+ decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted2, 4095,
+ encrypted1, encrypted_size);
+ crypto_free_cipher_env(cipher);
+ cipher = NULL;
+ test_memneq(plain, decrypted2, encrypted_size);
+ /* Alter the initialization vector. */
+ encrypted1[0] += 42;
+ cipher = crypto_create_init_cipher(key1, 0);
+ decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 4095,
+ encrypted1, encrypted_size);
+ crypto_free_cipher_env(cipher);
+ cipher = NULL;
+ test_memneq(plain, decrypted2, 4095);
+ /* Special length case: 1. */
+ cipher = crypto_create_init_cipher(key1, 1);
+ encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 1,
+ plain_1, 1);
+ crypto_free_cipher_env(cipher);
+ cipher = NULL;
+ test_eq(encrypted_size, 16 + 1);
+ tor_assert(encrypted_size > 0);
+ cipher = crypto_create_init_cipher(key1, 0);
+ decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 1,
+ encrypted1, encrypted_size);
+ crypto_free_cipher_env(cipher);
+ cipher = NULL;
+ test_eq(decrypted_size, 1);
+ tor_assert(decrypted_size > 0);
+ test_memeq(plain_1, decrypted1, 1);
+ /* Special length case: 15. */
+ cipher = crypto_create_init_cipher(key1, 1);
+ encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 15,
+ plain_15, 15);
+ crypto_free_cipher_env(cipher);
+ cipher = NULL;
+ test_eq(encrypted_size, 16 + 15);
+ tor_assert(encrypted_size > 0);
+ cipher = crypto_create_init_cipher(key1, 0);
+ decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 15,
+ encrypted1, encrypted_size);
+ crypto_free_cipher_env(cipher);
+ cipher = NULL;
+ test_eq(decrypted_size, 15);
+ tor_assert(decrypted_size > 0);
+ test_memeq(plain_15, decrypted1, 15);
+ /* Special length case: 16. */
+ cipher = crypto_create_init_cipher(key1, 1);
+ encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 16,
+ plain_16, 16);
+ crypto_free_cipher_env(cipher);
+ cipher = NULL;
+ test_eq(encrypted_size, 16 + 16);
+ tor_assert(encrypted_size > 0);
+ cipher = crypto_create_init_cipher(key1, 0);
+ decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 16,
+ encrypted1, encrypted_size);
+ crypto_free_cipher_env(cipher);
+ cipher = NULL;
+ test_eq(decrypted_size, 16);
+ tor_assert(decrypted_size > 0);
+ test_memeq(plain_16, decrypted1, 16);
+ /* Special length case: 17. */
+ cipher = crypto_create_init_cipher(key1, 1);
+ encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 17,
+ plain_17, 17);
+ crypto_free_cipher_env(cipher);
+ cipher = NULL;
+ test_eq(encrypted_size, 16 + 17);
+ tor_assert(encrypted_size > 0);
+ cipher = crypto_create_init_cipher(key1, 0);
+ decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 17,
+ encrypted1, encrypted_size);
+ test_eq(decrypted_size, 17);
+ tor_assert(decrypted_size > 0);
+ test_memeq(plain_17, decrypted1, 17);
+
+ done:
+ /* Free memory. */
+ tor_free(plain);
+ tor_free(encrypted1);
+ tor_free(encrypted2);
+ tor_free(decrypted1);
+ tor_free(decrypted2);
+ if (cipher)
+ crypto_free_cipher_env(cipher);
+}
+
+/** Test base32 decoding. */
+static void
+test_crypto_base32_decode(void)
+{
+ char plain[60], encoded[96 + 1], decoded[60];
+ int res;
+ crypto_rand(plain, 60);
+ /* Encode and decode a random string. */
+ base32_encode(encoded, 96 + 1, plain, 60);
+ res = base32_decode(decoded, 60, encoded, 96);
+ test_eq(res, 0);
+ test_memeq(plain, decoded, 60);
+ /* Encode, uppercase, and decode a random string. */
+ base32_encode(encoded, 96 + 1, plain, 60);
+ tor_strupper(encoded);
+ res = base32_decode(decoded, 60, encoded, 96);
+ test_eq(res, 0);
+ test_memeq(plain, decoded, 60);
+ /* Change encoded string and decode. */
+ if (encoded[0] == 'A' || encoded[0] == 'a')
+ encoded[0] = 'B';
+ else
+ encoded[0] = 'A';
+ res = base32_decode(decoded, 60, encoded, 96);
+ test_eq(res, 0);
+ test_memneq(plain, decoded, 60);
+ /* Bad encodings. */
+ encoded[0] = '!';
+ res = base32_decode(decoded, 60, encoded, 96);
+ test_assert(res < 0);
+
+ done:
+ ;
+}
+
+#define CRYPTO_LEGACY(name) \
+ { #name, legacy_test_helper, 0, &legacy_setup, test_crypto_ ## name }
+
+struct testcase_t crypto_tests[] = {
+ CRYPTO_LEGACY(formats),
+ CRYPTO_LEGACY(rng),
+ CRYPTO_LEGACY(aes),
+ CRYPTO_LEGACY(sha),
+ CRYPTO_LEGACY(pk),
+ CRYPTO_LEGACY(dh),
+ CRYPTO_LEGACY(s2k),
+ CRYPTO_LEGACY(aes_iv),
+ CRYPTO_LEGACY(base32_decode),
+ END_OF_TESTCASES
+};
+
diff --git a/src/or/test_data.c b/src/test/test_data.c
index f926ee17dd..f926ee17dd 100644
--- a/src/or/test_data.c
+++ b/src/test/test_data.c
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
new file mode 100644
index 0000000000..a0ad1914cc
--- /dev/null
+++ b/src/test/test_dir.c
@@ -0,0 +1,1317 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#define DIRSERV_PRIVATE
+#define DIRVOTE_PRIVATE
+#define ROUTER_PRIVATE
+#include "or.h"
+#include "directory.h"
+#include "dirserv.h"
+#include "dirvote.h"
+#include "networkstatus.h"
+#include "router.h"
+#include "routerlist.h"
+#include "routerparse.h"
+#include "test.h"
+
+static void
+test_dir_nicknames(void)
+{
+ test_assert( is_legal_nickname("a"));
+ test_assert(!is_legal_nickname(""));
+ test_assert(!is_legal_nickname("abcdefghijklmnopqrst")); /* 20 chars */
+ test_assert(!is_legal_nickname("hyphen-")); /* bad char */
+ test_assert( is_legal_nickname("abcdefghijklmnopqrs")); /* 19 chars */
+ test_assert(!is_legal_nickname("$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
+ /* valid */
+ test_assert( is_legal_nickname_or_hexdigest(
+ "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
+ test_assert( is_legal_nickname_or_hexdigest(
+ "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
+ test_assert( is_legal_nickname_or_hexdigest(
+ "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA~fred"));
+ /* too short */
+ test_assert(!is_legal_nickname_or_hexdigest(
+ "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
+ /* illegal char */
+ test_assert(!is_legal_nickname_or_hexdigest(
+ "$AAAAAAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
+ /* hex part too long */
+ test_assert(!is_legal_nickname_or_hexdigest(
+ "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
+ test_assert(!is_legal_nickname_or_hexdigest(
+ "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
+ /* Bad nickname */
+ test_assert(!is_legal_nickname_or_hexdigest(
+ "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="));
+ test_assert(!is_legal_nickname_or_hexdigest(
+ "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"));
+ test_assert(!is_legal_nickname_or_hexdigest(
+ "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~hyphen-"));
+ test_assert(!is_legal_nickname_or_hexdigest(
+ "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"
+ "abcdefghijklmnoppqrst"));
+ /* Bad extra char. */
+ test_assert(!is_legal_nickname_or_hexdigest(
+ "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!"));
+ test_assert(is_legal_nickname_or_hexdigest("xyzzy"));
+ test_assert(is_legal_nickname_or_hexdigest("abcdefghijklmnopqrs"));
+ test_assert(!is_legal_nickname_or_hexdigest("abcdefghijklmnopqrst"));
+ done:
+ ;
+}
+
+/** Run unit tests for router descriptor generation logic. */
+static void
+test_dir_formats(void)
+{
+ char buf[8192], buf2[8192];
+ char platform[256];
+ char fingerprint[FINGERPRINT_LEN+1];
+ char *pk1_str = NULL, *pk2_str = NULL, *pk3_str = NULL, *cp;
+ size_t pk1_str_len, pk2_str_len, pk3_str_len;
+ routerinfo_t *r1=NULL, *r2=NULL;
+ crypto_pk_env_t *pk1 = NULL, *pk2 = NULL, *pk3 = NULL;
+ routerinfo_t *rp1 = NULL;
+ addr_policy_t *ex1, *ex2;
+ routerlist_t *dir1 = NULL, *dir2 = NULL;
+
+ pk1 = pk_generate(0);
+ pk2 = pk_generate(1);
+ pk3 = pk_generate(2);
+
+ test_assert(pk1 && pk2 && pk3);
+
+ get_platform_str(platform, sizeof(platform));
+ r1 = tor_malloc_zero(sizeof(routerinfo_t));
+ r1->address = tor_strdup("18.244.0.1");
+ r1->addr = 0xc0a80001u; /* 192.168.0.1 */
+ r1->cache_info.published_on = 0;
+ r1->or_port = 9000;
+ r1->dir_port = 9003;
+ r1->onion_pkey = crypto_pk_dup_key(pk1);
+ r1->identity_pkey = crypto_pk_dup_key(pk2);
+ r1->bandwidthrate = 1000;
+ r1->bandwidthburst = 5000;
+ r1->bandwidthcapacity = 10000;
+ r1->exit_policy = NULL;
+ r1->nickname = tor_strdup("Magri");
+ r1->platform = tor_strdup(platform);
+
+ ex1 = tor_malloc_zero(sizeof(addr_policy_t));
+ ex2 = tor_malloc_zero(sizeof(addr_policy_t));
+ ex1->policy_type = ADDR_POLICY_ACCEPT;
+ tor_addr_from_ipv4h(&ex1->addr, 0);
+ ex1->maskbits = 0;
+ ex1->prt_min = ex1->prt_max = 80;
+ ex2->policy_type = ADDR_POLICY_REJECT;
+ tor_addr_from_ipv4h(&ex2->addr, 18<<24);
+ ex2->maskbits = 8;
+ ex2->prt_min = ex2->prt_max = 24;
+ r2 = tor_malloc_zero(sizeof(routerinfo_t));
+ r2->address = tor_strdup("1.1.1.1");
+ r2->addr = 0x0a030201u; /* 10.3.2.1 */
+ r2->platform = tor_strdup(platform);
+ r2->cache_info.published_on = 5;
+ r2->or_port = 9005;
+ r2->dir_port = 0;
+ r2->onion_pkey = crypto_pk_dup_key(pk2);
+ r2->identity_pkey = crypto_pk_dup_key(pk1);
+ r2->bandwidthrate = r2->bandwidthburst = r2->bandwidthcapacity = 3000;
+ r2->exit_policy = smartlist_create();
+ smartlist_add(r2->exit_policy, ex2);
+ smartlist_add(r2->exit_policy, ex1);
+ r2->nickname = tor_strdup("Fred");
+
+ test_assert(!crypto_pk_write_public_key_to_string(pk1, &pk1_str,
+ &pk1_str_len));
+ test_assert(!crypto_pk_write_public_key_to_string(pk2 , &pk2_str,
+ &pk2_str_len));
+ test_assert(!crypto_pk_write_public_key_to_string(pk3 , &pk3_str,
+ &pk3_str_len));
+
+ memset(buf, 0, 2048);
+ test_assert(router_dump_router_to_string(buf, 2048, r1, pk2)>0);
+
+ strlcpy(buf2, "router Magri 18.244.0.1 9000 0 9003\n"
+ "platform Tor "VERSION" on ", sizeof(buf2));
+ strlcat(buf2, get_uname(), sizeof(buf2));
+ strlcat(buf2, "\n"
+ "opt protocols Link 1 2 Circuit 1\n"
+ "published 1970-01-01 00:00:00\n"
+ "opt fingerprint ", sizeof(buf2));
+ test_assert(!crypto_pk_get_fingerprint(pk2, fingerprint, 1));
+ strlcat(buf2, fingerprint, sizeof(buf2));
+ strlcat(buf2, "\nuptime 0\n"
+ /* XXX the "0" above is hard-coded, but even if we made it reflect
+ * uptime, that still wouldn't make it right, because the two
+ * descriptors might be made on different seconds... hm. */
+ "bandwidth 1000 5000 10000\n"
+ "onion-key\n", sizeof(buf2));
+ strlcat(buf2, pk1_str, sizeof(buf2));
+ strlcat(buf2, "signing-key\n", sizeof(buf2));
+ strlcat(buf2, pk2_str, sizeof(buf2));
+ strlcat(buf2, "opt hidden-service-dir\n", sizeof(buf2));
+ strlcat(buf2, "reject *:*\nrouter-signature\n", sizeof(buf2));
+ buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same
+ * twice */
+
+ test_streq(buf, buf2);
+
+ test_assert(router_dump_router_to_string(buf, 2048, r1, pk2)>0);
+ cp = buf;
+ rp1 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL);
+ test_assert(rp1);
+ test_streq(rp1->address, r1->address);
+ test_eq(rp1->or_port, r1->or_port);
+ //test_eq(rp1->dir_port, r1->dir_port);
+ test_eq(rp1->bandwidthrate, r1->bandwidthrate);
+ test_eq(rp1->bandwidthburst, r1->bandwidthburst);
+ test_eq(rp1->bandwidthcapacity, r1->bandwidthcapacity);
+ test_assert(crypto_pk_cmp_keys(rp1->onion_pkey, pk1) == 0);
+ test_assert(crypto_pk_cmp_keys(rp1->identity_pkey, pk2) == 0);
+ //test_assert(rp1->exit_policy == NULL);
+
+#if 0
+ /* XXX Once we have exit policies, test this again. XXX */
+ strlcpy(buf2, "router tor.tor.tor 9005 0 0 3000\n", sizeof(buf2));
+ strlcat(buf2, pk2_str, sizeof(buf2));
+ strlcat(buf2, "signing-key\n", sizeof(buf2));
+ strlcat(buf2, pk1_str, sizeof(buf2));
+ strlcat(buf2, "accept *:80\nreject 18.*:24\n\n", sizeof(buf2));
+ test_assert(router_dump_router_to_string(buf, 2048, &r2, pk2)>0);
+ test_streq(buf, buf2);
+
+ cp = buf;
+ rp2 = router_parse_entry_from_string(&cp,1);
+ test_assert(rp2);
+ test_streq(rp2->address, r2.address);
+ test_eq(rp2->or_port, r2.or_port);
+ test_eq(rp2->dir_port, r2.dir_port);
+ test_eq(rp2->bandwidth, r2.bandwidth);
+ test_assert(crypto_pk_cmp_keys(rp2->onion_pkey, pk2) == 0);
+ test_assert(crypto_pk_cmp_keys(rp2->identity_pkey, pk1) == 0);
+ test_eq(rp2->exit_policy->policy_type, EXIT_POLICY_ACCEPT);
+ test_streq(rp2->exit_policy->string, "accept *:80");
+ test_streq(rp2->exit_policy->address, "*");
+ test_streq(rp2->exit_policy->port, "80");
+ test_eq(rp2->exit_policy->next->policy_type, EXIT_POLICY_REJECT);
+ test_streq(rp2->exit_policy->next->string, "reject 18.*:24");
+ test_streq(rp2->exit_policy->next->address, "18.*");
+ test_streq(rp2->exit_policy->next->port, "24");
+ test_assert(rp2->exit_policy->next->next == NULL);
+
+ /* Okay, now for the directories. */
+ {
+ fingerprint_list = smartlist_create();
+ crypto_pk_get_fingerprint(pk2, buf, 1);
+ add_fingerprint_to_dir("Magri", buf, fingerprint_list);
+ crypto_pk_get_fingerprint(pk1, buf, 1);
+ add_fingerprint_to_dir("Fred", buf, fingerprint_list);
+ }
+
+ {
+ char d[DIGEST_LEN];
+ const char *m;
+ /* XXXX NM re-enable. */
+ /* Make sure routers aren't too far in the past any more. */
+ r1->cache_info.published_on = time(NULL);
+ r2->cache_info.published_on = time(NULL)-3*60*60;
+ test_assert(router_dump_router_to_string(buf, 2048, r1, pk2)>0);
+ test_eq(dirserv_add_descriptor(buf,&m,""), ROUTER_ADDED_NOTIFY_GENERATOR);
+ test_assert(router_dump_router_to_string(buf, 2048, r2, pk1)>0);
+ test_eq(dirserv_add_descriptor(buf,&m,""), ROUTER_ADDED_NOTIFY_GENERATOR);
+ get_options()->Nickname = tor_strdup("DirServer");
+ test_assert(!dirserv_dump_directory_to_string(&cp,pk3, 0));
+ crypto_pk_get_digest(pk3, d);
+ test_assert(!router_parse_directory(cp));
+ test_eq(2, smartlist_len(dir1->routers));
+ tor_free(cp);
+ }
+#endif
+ dirserv_free_fingerprint_list();
+
+ done:
+ if (r1)
+ routerinfo_free(r1);
+ if (r2)
+ routerinfo_free(r2);
+
+ tor_free(pk1_str);
+ tor_free(pk2_str);
+ tor_free(pk3_str);
+ if (pk1) crypto_free_pk_env(pk1);
+ if (pk2) crypto_free_pk_env(pk2);
+ if (pk3) crypto_free_pk_env(pk3);
+ if (rp1) routerinfo_free(rp1);
+ tor_free(dir1); /* XXXX And more !*/
+ tor_free(dir2); /* And more !*/
+}
+
+static void
+test_dir_versions(void)
+{
+ tor_version_t ver1;
+
+ /* Try out version parsing functionality */
+ test_eq(0, tor_version_parse("0.3.4pre2-cvs", &ver1));
+ test_eq(0, ver1.major);
+ test_eq(3, ver1.minor);
+ test_eq(4, ver1.micro);
+ test_eq(VER_PRE, ver1.status);
+ test_eq(2, ver1.patchlevel);
+ test_eq(0, tor_version_parse("0.3.4rc1", &ver1));
+ test_eq(0, ver1.major);
+ test_eq(3, ver1.minor);
+ test_eq(4, ver1.micro);
+ test_eq(VER_RC, ver1.status);
+ test_eq(1, ver1.patchlevel);
+ test_eq(0, tor_version_parse("1.3.4", &ver1));
+ test_eq(1, ver1.major);
+ test_eq(3, ver1.minor);
+ test_eq(4, ver1.micro);
+ test_eq(VER_RELEASE, ver1.status);
+ test_eq(0, ver1.patchlevel);
+ test_eq(0, tor_version_parse("1.3.4.999", &ver1));
+ test_eq(1, ver1.major);
+ test_eq(3, ver1.minor);
+ test_eq(4, ver1.micro);
+ test_eq(VER_RELEASE, ver1.status);
+ test_eq(999, ver1.patchlevel);
+ test_eq(0, tor_version_parse("0.1.2.4-alpha", &ver1));
+ test_eq(0, ver1.major);
+ test_eq(1, ver1.minor);
+ test_eq(2, ver1.micro);
+ test_eq(4, ver1.patchlevel);
+ test_eq(VER_RELEASE, ver1.status);
+ test_streq("alpha", ver1.status_tag);
+ test_eq(0, tor_version_parse("0.1.2.4", &ver1));
+ test_eq(0, ver1.major);
+ test_eq(1, ver1.minor);
+ test_eq(2, ver1.micro);
+ test_eq(4, ver1.patchlevel);
+ test_eq(VER_RELEASE, ver1.status);
+ test_streq("", 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")
+#define test_v_i_o(val, ver, lst) \
+ tt_versionstatus_op(val, ==, tor_version_is_obsolete(ver, lst))
+
+ /* make sure tor_version_is_obsolete() works */
+ test_v_i_o(VS_OLD, "0.0.1", "Tor 0.0.2");
+ test_v_i_o(VS_OLD, "0.0.1", "0.0.2, Tor 0.0.3");
+ test_v_i_o(VS_OLD, "0.0.1", "0.0.2,Tor 0.0.3");
+ test_v_i_o(VS_OLD, "0.0.1","0.0.3,BetterTor 0.0.1");
+ test_v_i_o(VS_RECOMMENDED, "0.0.2", "Tor 0.0.2,Tor 0.0.3");
+ test_v_i_o(VS_NEW_IN_SERIES, "0.0.2", "Tor 0.0.2pre1,Tor 0.0.3");
+ test_v_i_o(VS_OLD, "0.0.2", "Tor 0.0.2.1,Tor 0.0.3");
+ test_v_i_o(VS_NEW, "0.1.0", "Tor 0.0.2,Tor 0.0.3");
+ test_v_i_o(VS_RECOMMENDED, "0.0.7rc2", "0.0.7,Tor 0.0.7rc2,Tor 0.0.8");
+ test_v_i_o(VS_OLD, "0.0.5.0", "0.0.5.1-cvs");
+ test_v_i_o(VS_NEW_IN_SERIES, "0.0.5.1-cvs", "0.0.5, 0.0.6");
+ /* Not on list, but newer than any in same series. */
+ test_v_i_o(VS_NEW_IN_SERIES, "0.1.0.3",
+ "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
+ /* Series newer than any on list. */
+ test_v_i_o(VS_NEW, "0.1.2.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
+ /* Series older than any on list. */
+ test_v_i_o(VS_OLD, "0.0.1.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
+ /* Not on list, not newer than any on same series. */
+ test_v_i_o(VS_UNRECOMMENDED, "0.1.0.1",
+ "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
+ /* On list, not newer than any on same series. */
+ test_v_i_o(VS_UNRECOMMENDED,
+ "0.1.0.1", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
+ test_eq(0, tor_version_as_new_as("Tor 0.0.5", "0.0.9pre1-cvs"));
+ test_eq(1, tor_version_as_new_as(
+ "Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
+ "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh",
+ "0.0.8rc2"));
+ test_eq(0, tor_version_as_new_as(
+ "Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
+ "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh", "0.0.8.2"));
+
+ /* Now try svn revisions. */
+ test_eq(1, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
+ "Tor 0.2.1.0-dev (r99)"));
+ test_eq(1, tor_version_as_new_as("Tor 0.2.1.0-dev (r100) on Banana Jr",
+ "Tor 0.2.1.0-dev (r99) on Hal 9000"));
+ test_eq(1, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
+ "Tor 0.2.1.0-dev on Colossus"));
+ test_eq(0, tor_version_as_new_as("Tor 0.2.1.0-dev (r99)",
+ "Tor 0.2.1.0-dev (r100)"));
+ test_eq(0, tor_version_as_new_as("Tor 0.2.1.0-dev (r99) on MCP",
+ "Tor 0.2.1.0-dev (r100) on AM"));
+ test_eq(0, tor_version_as_new_as("Tor 0.2.1.0-dev",
+ "Tor 0.2.1.0-dev (r99)"));
+ test_eq(1, tor_version_as_new_as("Tor 0.2.1.1",
+ "Tor 0.2.1.0-dev (r99)"));
+
+ /* Now try git revisions */
+ test_eq(0, tor_version_parse("0.5.6.7 (git-ff00ff)", &ver1));
+ test_eq(0, ver1.major);
+ test_eq(5, ver1.minor);
+ test_eq(6, ver1.micro);
+ test_eq(7, ver1.patchlevel);
+ test_eq(3, ver1.git_tag_len);
+ test_memeq(ver1.git_tag, "\xff\x00\xff", 3);
+ test_eq(-1, tor_version_parse("0.5.6.7 (git-ff00xx)", &ver1));
+ test_eq(-1, tor_version_parse("0.5.6.7 (git-ff00fff)", &ver1));
+ test_eq(0, tor_version_parse("0.5.6.7 (git ff00fff)", &ver1));
+ done:
+ ;
+}
+
+/** Run unit tests for directory fp_pair functions. */
+static void
+test_dir_fp_pairs(void)
+{
+ smartlist_t *sl = smartlist_create();
+ fp_pair_t *pair;
+
+ dir_split_resource_into_fingerprint_pairs(
+ /* Two pairs, out of order, with one duplicate. */
+ "73656372657420646174612E0000000000FFFFFF-"
+ "557365204145532d32353620696e73746561642e+"
+ "73656372657420646174612E0000000000FFFFFF-"
+ "557365204145532d32353620696e73746561642e+"
+ "48657861646563696d616c2069736e277420736f-"
+ "676f6f6420666f7220686964696e6720796f7572.z", sl);
+
+ test_eq(smartlist_len(sl), 2);
+ pair = smartlist_get(sl, 0);
+ test_memeq(pair->first, "Hexadecimal isn't so", DIGEST_LEN);
+ test_memeq(pair->second, "good for hiding your", DIGEST_LEN);
+ pair = smartlist_get(sl, 1);
+ test_memeq(pair->first, "secret data.\0\0\0\0\0\xff\xff\xff", DIGEST_LEN);
+ test_memeq(pair->second, "Use AES-256 instead.", DIGEST_LEN);
+
+ done:
+ SMARTLIST_FOREACH(sl, fp_pair_t *, pair, tor_free(pair));
+ smartlist_free(sl);
+}
+
+static void
+test_dir_split_fps(void *testdata)
+{
+ smartlist_t *sl = smartlist_create();
+ char *mem_op_hex_tmp = NULL;
+ (void)testdata;
+
+ /* Some example hex fingerprints and their base64 equivalents */
+#define HEX1 "Fe0daff89127389bc67558691231234551193EEE"
+#define HEX2 "Deadbeef99999991111119999911111111f00ba4"
+#define HEX3 "b33ff00db33ff00db33ff00db33ff00db33ff00d"
+#define HEX256_1 \
+ "f3f3f3f3fbbbbf3f3f3f3fbbbf3f3f3f3fbbbbf3f3f3f3fbbbf3f3f3f3fbbbbf"
+#define HEX256_2 \
+ "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccCCc"
+#define HEX256_3 \
+ "0123456789ABCdef0123456789ABCdef0123456789ABCdef0123456789ABCdef"
+#define B64_1 "/g2v+JEnOJvGdVhpEjEjRVEZPu4"
+#define B64_2 "3q2+75mZmZERERmZmRERERHwC6Q"
+#define B64_3 "sz/wDbM/8A2zP/ANsz/wDbM/8A0"
+#define B64_256_1 "8/Pz8/u7vz8/Pz+7vz8/Pz+7u/Pz8/P7u/Pz8/P7u78"
+#define B64_256_2 "zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMw"
+#define B64_256_3 "ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8"
+
+ /* no flags set */
+ dir_split_resource_into_fingerprints("A+C+B", sl, NULL, 0);
+ tt_int_op(smartlist_len(sl), ==, 3);
+ tt_str_op(smartlist_get(sl, 0), ==, "A");
+ tt_str_op(smartlist_get(sl, 1), ==, "C");
+ tt_str_op(smartlist_get(sl, 2), ==, "B");
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ /* uniq strings. */
+ dir_split_resource_into_fingerprints("A+C+B+A+B+B", sl, NULL, DSR_SORT_UNIQ);
+ tt_int_op(smartlist_len(sl), ==, 3);
+ tt_str_op(smartlist_get(sl, 0), ==, "A");
+ tt_str_op(smartlist_get(sl, 1), ==, "B");
+ tt_str_op(smartlist_get(sl, 2), ==, "C");
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ /* Decode hex. */
+ dir_split_resource_into_fingerprints(HEX1"+"HEX2, sl, NULL, DSR_HEX);
+ tt_int_op(smartlist_len(sl), ==, 2);
+ test_mem_op_hex(smartlist_get(sl, 0), ==, HEX1);
+ test_mem_op_hex(smartlist_get(sl, 1), ==, HEX2);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ /* decode hex and drop weirdness. */
+ dir_split_resource_into_fingerprints(HEX1"+bogus+"HEX2"+"HEX256_1,
+ sl, NULL, DSR_HEX);
+ tt_int_op(smartlist_len(sl), ==, 2);
+ test_mem_op_hex(smartlist_get(sl, 0), ==, HEX1);
+ test_mem_op_hex(smartlist_get(sl, 1), ==, HEX2);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ /* Decode long hex */
+ dir_split_resource_into_fingerprints(HEX256_1"+"HEX256_2"+"HEX2"+"HEX256_3,
+ sl, NULL, DSR_HEX|DSR_DIGEST256);
+ tt_int_op(smartlist_len(sl), ==, 3);
+ test_mem_op_hex(smartlist_get(sl, 0), ==, HEX256_1);
+ test_mem_op_hex(smartlist_get(sl, 1), ==, HEX256_2);
+ test_mem_op_hex(smartlist_get(sl, 2), ==, HEX256_3);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ /* Decode hex and sort. */
+ dir_split_resource_into_fingerprints(HEX1"+"HEX2"+"HEX3"+"HEX2,
+ sl, NULL, DSR_HEX|DSR_SORT_UNIQ);
+ tt_int_op(smartlist_len(sl), ==, 3);
+ test_mem_op_hex(smartlist_get(sl, 0), ==, HEX3);
+ test_mem_op_hex(smartlist_get(sl, 1), ==, HEX2);
+ test_mem_op_hex(smartlist_get(sl, 2), ==, HEX1);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ /* Decode long hex and sort */
+ dir_split_resource_into_fingerprints(HEX256_1"+"HEX256_2"+"HEX256_3
+ "+"HEX256_1,
+ sl, NULL,
+ DSR_HEX|DSR_DIGEST256|DSR_SORT_UNIQ);
+ tt_int_op(smartlist_len(sl), ==, 3);
+ test_mem_op_hex(smartlist_get(sl, 0), ==, HEX256_3);
+ test_mem_op_hex(smartlist_get(sl, 1), ==, HEX256_2);
+ test_mem_op_hex(smartlist_get(sl, 2), ==, HEX256_1);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ /* Decode base64 */
+ dir_split_resource_into_fingerprints(B64_1"-"B64_2, sl, NULL, DSR_BASE64);
+ tt_int_op(smartlist_len(sl), ==, 2);
+ test_mem_op_hex(smartlist_get(sl, 0), ==, HEX1);
+ test_mem_op_hex(smartlist_get(sl, 1), ==, HEX2);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ /* Decode long base64 */
+ dir_split_resource_into_fingerprints(B64_256_1"-"B64_256_2,
+ sl, NULL, DSR_BASE64|DSR_DIGEST256);
+ tt_int_op(smartlist_len(sl), ==, 2);
+ test_mem_op_hex(smartlist_get(sl, 0), ==, HEX256_1);
+ test_mem_op_hex(smartlist_get(sl, 1), ==, HEX256_2);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ dir_split_resource_into_fingerprints(B64_256_1,
+ sl, NULL, DSR_BASE64|DSR_DIGEST256);
+ tt_int_op(smartlist_len(sl), ==, 1);
+ test_mem_op_hex(smartlist_get(sl, 0), ==, HEX256_1);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ done:
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_free(sl);
+ tor_free(mem_op_hex_tmp);
+}
+
+static void
+test_dir_measured_bw(void)
+{
+ measured_bw_line_t mbwl;
+ int i;
+ const char *lines_pass[] = {
+ "node_id=$557365204145532d32353620696e73746561642e bw=1024\n",
+ "node_id=$557365204145532d32353620696e73746561642e\t bw=1024 \n",
+ " node_id=$557365204145532d32353620696e73746561642e bw=1024\n",
+ "\tnoise\tnode_id=$557365204145532d32353620696e73746561642e "
+ "bw=1024 junk=007\n",
+ "misc=junk node_id=$557365204145532d32353620696e73746561642e "
+ "bw=1024 junk=007\n",
+ "end"
+ };
+ const char *lines_fail[] = {
+ /* Test possible python stupidity on input */
+ "node_id=None bw=1024\n",
+ "node_id=$None bw=1024\n",
+ "node_id=$557365204145532d32353620696e73746561642e bw=None\n",
+ "node_id=$557365204145532d32353620696e73746561642e bw=1024.0\n",
+ "node_id=$557365204145532d32353620696e73746561642e bw=.1024\n",
+ "node_id=$557365204145532d32353620696e73746561642e bw=1.024\n",
+ "node_id=$557365204145532d32353620696e73746561642e bw=1024 bw=0\n",
+ "node_id=$557365204145532d32353620696e73746561642e bw=1024 bw=None\n",
+ "node_id=$557365204145532d32353620696e73746561642e bw=-1024\n",
+ /* Test incomplete writes due to race conditions, partial copies, etc */
+ "node_i",
+ "node_i\n",
+ "node_id=",
+ "node_id=\n",
+ "node_id=$557365204145532d32353620696e73746561642e bw=",
+ "node_id=$557365204145532d32353620696e73746561642e bw=1024",
+ "node_id=$557365204145532d32353620696e73746561642e bw=\n",
+ "node_id=$557365204145532d32353620696e7374",
+ "node_id=$557365204145532d32353620696e7374\n",
+ "",
+ "\n",
+ " \n ",
+ " \n\n",
+ /* Test assorted noise */
+ " node_id= ",
+ "node_id==$557365204145532d32353620696e73746561642e bw==1024\n",
+ "node_id=$55736520414552d32353620696e73746561642e bw=1024\n",
+ "node_id=557365204145532d32353620696e73746561642e bw=1024\n",
+ "node_id= $557365204145532d32353620696e73746561642e bw=0.23\n",
+ "end"
+ };
+
+ for (i = 0; strcmp(lines_fail[i], "end"); i++) {
+ //fprintf(stderr, "Testing: %s\n", lines_fail[i]);
+ test_assert(measured_bw_line_parse(&mbwl, lines_fail[i]) == -1);
+ }
+
+ for (i = 0; strcmp(lines_pass[i], "end"); i++) {
+ //fprintf(stderr, "Testing: %s %d\n", lines_pass[i], TOR_ISSPACE('\n'));
+ test_assert(measured_bw_line_parse(&mbwl, lines_pass[i]) == 0);
+ test_assert(mbwl.bw == 1024);
+ test_assert(strcmp(mbwl.node_hex,
+ "557365204145532d32353620696e73746561642e") == 0);
+ }
+
+ done:
+ return;
+}
+
+static void
+test_dir_param_voting(void)
+{
+ networkstatus_t vote1, vote2, vote3, vote4;
+ smartlist_t *votes = smartlist_create();
+ char *res = NULL;
+
+ /* dirvote_compute_params only looks at the net_params field of the votes,
+ so that's all we need to set.
+ */
+ memset(&vote1, 0, sizeof(vote1));
+ memset(&vote2, 0, sizeof(vote2));
+ memset(&vote3, 0, sizeof(vote3));
+ memset(&vote4, 0, sizeof(vote4));
+ vote1.net_params = smartlist_create();
+ vote2.net_params = smartlist_create();
+ vote3.net_params = smartlist_create();
+ vote4.net_params = smartlist_create();
+ smartlist_split_string(vote1.net_params,
+ "ab=90 abcd=20 cw=50 x-yz=-99", NULL, 0, 0);
+ smartlist_split_string(vote2.net_params,
+ "ab=27 cw=5 x-yz=88", NULL, 0, 0);
+ smartlist_split_string(vote3.net_params,
+ "abcd=20 c=60 cw=500 x-yz=-9 zzzzz=101", NULL, 0, 0);
+ smartlist_split_string(vote4.net_params,
+ "ab=900 abcd=200 c=1 cw=51 x-yz=100", NULL, 0, 0);
+ test_eq(100, networkstatus_get_param(&vote4, "x-yz", 50));
+ test_eq(222, networkstatus_get_param(&vote4, "foobar", 222));
+
+ smartlist_add(votes, &vote1);
+ smartlist_add(votes, &vote2);
+ smartlist_add(votes, &vote3);
+ smartlist_add(votes, &vote4);
+
+ res = dirvote_compute_params(votes);
+ test_streq(res,
+ "ab=90 abcd=20 c=1 cw=50 x-yz=-9 zzzzz=101");
+
+ done:
+ tor_free(res);
+ SMARTLIST_FOREACH(vote1.net_params, char *, cp, tor_free(cp));
+ SMARTLIST_FOREACH(vote2.net_params, char *, cp, tor_free(cp));
+ SMARTLIST_FOREACH(vote3.net_params, char *, cp, tor_free(cp));
+ SMARTLIST_FOREACH(vote4.net_params, char *, cp, tor_free(cp));
+ smartlist_free(vote1.net_params);
+ smartlist_free(vote2.net_params);
+ smartlist_free(vote3.net_params);
+ smartlist_free(vote4.net_params);
+ smartlist_free(votes);
+
+ return;
+}
+
+extern const char AUTHORITY_CERT_1[];
+extern const char AUTHORITY_SIGNKEY_1[];
+extern const char AUTHORITY_CERT_2[];
+extern const char AUTHORITY_SIGNKEY_2[];
+extern const char AUTHORITY_CERT_3[];
+extern const char AUTHORITY_SIGNKEY_3[];
+
+/** Helper: Test that two networkstatus_voter_info_t do in fact represent the
+ * same voting authority, and that they do in fact have all the same
+ * information. */
+static void
+test_same_voter(networkstatus_voter_info_t *v1,
+ networkstatus_voter_info_t *v2)
+{
+ test_streq(v1->nickname, v2->nickname);
+ test_memeq(v1->identity_digest, v2->identity_digest, DIGEST_LEN);
+ test_streq(v1->address, v2->address);
+ test_eq(v1->addr, v2->addr);
+ test_eq(v1->dir_port, v2->dir_port);
+ test_eq(v1->or_port, v2->or_port);
+ test_streq(v1->contact, v2->contact);
+ test_memeq(v1->vote_digest, v2->vote_digest, DIGEST_LEN);
+ done:
+ ;
+}
+
+/** Helper: Make a new routerinfo containing the right information for a
+ * given vote_routerstatus_t. */
+static routerinfo_t *
+generate_ri_from_rs(const vote_routerstatus_t *vrs)
+{
+ routerinfo_t *r;
+ const routerstatus_t *rs = &vrs->status;
+ static time_t published = 0;
+
+ r = tor_malloc_zero(sizeof(routerinfo_t));
+ memcpy(r->cache_info.identity_digest, rs->identity_digest, DIGEST_LEN);
+ memcpy(r->cache_info.signed_descriptor_digest, rs->descriptor_digest,
+ DIGEST_LEN);
+ r->cache_info.do_not_cache = 1;
+ r->cache_info.routerlist_index = -1;
+ r->cache_info.signed_descriptor_body =
+ tor_strdup("123456789012345678901234567890123");
+ r->cache_info.signed_descriptor_len =
+ strlen(r->cache_info.signed_descriptor_body);
+ r->exit_policy = smartlist_create();
+ r->cache_info.published_on = ++published + time(NULL);
+ return r;
+}
+
+/** Helper: get a detached signatures document for one or two
+ * consensuses. */
+static char *
+get_detached_sigs(networkstatus_t *ns, networkstatus_t *ns2)
+{
+ char *r;
+ smartlist_t *sl;
+ tor_assert(ns && ns->flavor == FLAV_NS);
+ sl = smartlist_create();
+ smartlist_add(sl,ns);
+ if (ns2)
+ smartlist_add(sl,ns2);
+ r = networkstatus_get_detached_signatures(sl);
+ smartlist_free(sl);
+ return r;
+}
+
+/** Run unit tests for generating and parsing V3 consensus networkstatus
+ * documents. */
+static void
+test_dir_v3_networkstatus(void)
+{
+ authority_cert_t *cert1=NULL, *cert2=NULL, *cert3=NULL;
+ crypto_pk_env_t *sign_skey_1=NULL, *sign_skey_2=NULL, *sign_skey_3=NULL;
+ crypto_pk_env_t *sign_skey_leg1=NULL;
+ const char *msg=NULL;
+
+ time_t now = time(NULL);
+ networkstatus_voter_info_t *voter;
+ document_signature_t *sig;
+ networkstatus_t *vote=NULL, *v1=NULL, *v2=NULL, *v3=NULL, *con=NULL,
+ *con_md=NULL;
+ vote_routerstatus_t *vrs;
+ routerstatus_t *rs;
+ char *v1_text=NULL, *v2_text=NULL, *v3_text=NULL, *consensus_text=NULL, *cp;
+ smartlist_t *votes = smartlist_create();
+
+ /* For generating the two other consensuses. */
+ char *detached_text1=NULL, *detached_text2=NULL;
+ char *consensus_text2=NULL, *consensus_text3=NULL;
+ char *consensus_text_md2=NULL, *consensus_text_md3=NULL;
+ char *consensus_text_md=NULL;
+ networkstatus_t *con2=NULL, *con_md2=NULL, *con3=NULL, *con_md3=NULL;
+ ns_detached_signatures_t *dsig1=NULL, *dsig2=NULL;
+
+ /* Parse certificates and keys. */
+ cert1 = authority_cert_parse_from_string(AUTHORITY_CERT_1, NULL);
+ test_assert(cert1);
+ test_assert(cert1->is_cross_certified);
+ cert2 = authority_cert_parse_from_string(AUTHORITY_CERT_2, NULL);
+ test_assert(cert2);
+ cert3 = authority_cert_parse_from_string(AUTHORITY_CERT_3, NULL);
+ test_assert(cert3);
+ sign_skey_1 = crypto_new_pk_env();
+ sign_skey_2 = crypto_new_pk_env();
+ sign_skey_3 = crypto_new_pk_env();
+ sign_skey_leg1 = pk_generate(4);
+
+ test_assert(!crypto_pk_read_private_key_from_string(sign_skey_1,
+ AUTHORITY_SIGNKEY_1));
+ test_assert(!crypto_pk_read_private_key_from_string(sign_skey_2,
+ AUTHORITY_SIGNKEY_2));
+ test_assert(!crypto_pk_read_private_key_from_string(sign_skey_3,
+ AUTHORITY_SIGNKEY_3));
+
+ test_assert(!crypto_pk_cmp_keys(sign_skey_1, cert1->signing_key));
+ test_assert(!crypto_pk_cmp_keys(sign_skey_2, cert2->signing_key));
+
+ /*
+ * Set up a vote; generate it; try to parse it.
+ */
+ vote = tor_malloc_zero(sizeof(networkstatus_t));
+ vote->type = NS_TYPE_VOTE;
+ vote->published = now;
+ vote->valid_after = now+1000;
+ vote->fresh_until = now+2000;
+ vote->valid_until = now+3000;
+ vote->vote_seconds = 100;
+ vote->dist_seconds = 200;
+ vote->supported_methods = smartlist_create();
+ smartlist_split_string(vote->supported_methods, "1 2 3", NULL, 0, -1);
+ vote->client_versions = tor_strdup("0.1.2.14,0.1.2.15");
+ vote->server_versions = tor_strdup("0.1.2.14,0.1.2.15,0.1.2.16");
+ vote->known_flags = smartlist_create();
+ smartlist_split_string(vote->known_flags,
+ "Authority Exit Fast Guard Running Stable V2Dir Valid",
+ 0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ vote->voters = smartlist_create();
+ voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
+ voter->nickname = tor_strdup("Voter1");
+ voter->address = tor_strdup("1.2.3.4");
+ voter->addr = 0x01020304;
+ voter->dir_port = 80;
+ voter->or_port = 9000;
+ voter->contact = tor_strdup("voter@example.com");
+ crypto_pk_get_digest(cert1->identity_key, voter->identity_digest);
+ smartlist_add(vote->voters, voter);
+ vote->cert = authority_cert_dup(cert1);
+ vote->net_params = smartlist_create();
+ smartlist_split_string(vote->net_params, "circuitwindow=101 foo=990",
+ NULL, 0, 0);
+ vote->routerstatus_list = smartlist_create();
+ /* add the first routerstatus. */
+ vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
+ rs = &vrs->status;
+ vrs->version = tor_strdup("0.1.2.14");
+ rs->published_on = now-1500;
+ strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
+ memset(rs->identity_digest, 3, DIGEST_LEN);
+ memset(rs->descriptor_digest, 78, DIGEST_LEN);
+ rs->addr = 0x99008801;
+ rs->or_port = 443;
+ rs->dir_port = 8000;
+ /* all flags but running cleared */
+ rs->is_running = 1;
+ smartlist_add(vote->routerstatus_list, vrs);
+ test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
+
+ /* add the second routerstatus. */
+ vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
+ rs = &vrs->status;
+ vrs->version = tor_strdup("0.2.0.5");
+ rs->published_on = now-1000;
+ strlcpy(rs->nickname, "router1", sizeof(rs->nickname));
+ memset(rs->identity_digest, 5, DIGEST_LEN);
+ memset(rs->descriptor_digest, 77, DIGEST_LEN);
+ rs->addr = 0x99009901;
+ rs->or_port = 443;
+ rs->dir_port = 0;
+ rs->is_exit = rs->is_stable = rs->is_fast = rs->is_running =
+ rs->is_valid = rs->is_v2_dir = rs->is_possible_guard = 1;
+ smartlist_add(vote->routerstatus_list, vrs);
+ test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
+
+ /* add the third routerstatus. */
+ vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
+ rs = &vrs->status;
+ vrs->version = tor_strdup("0.1.0.3");
+ rs->published_on = now-1000;
+ strlcpy(rs->nickname, "router3", sizeof(rs->nickname));
+ memset(rs->identity_digest, 33, DIGEST_LEN);
+ memset(rs->descriptor_digest, 79, DIGEST_LEN);
+ rs->addr = 0xAA009901;
+ rs->or_port = 400;
+ rs->dir_port = 9999;
+ rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
+ rs->is_running = rs->is_valid = rs->is_v2_dir = rs->is_possible_guard = 1;
+ smartlist_add(vote->routerstatus_list, vrs);
+ test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
+
+ /* add a fourth routerstatus that is not running. */
+ vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
+ rs = &vrs->status;
+ vrs->version = tor_strdup("0.1.6.3");
+ rs->published_on = now-1000;
+ strlcpy(rs->nickname, "router4", sizeof(rs->nickname));
+ memset(rs->identity_digest, 34, DIGEST_LEN);
+ memset(rs->descriptor_digest, 47, DIGEST_LEN);
+ rs->addr = 0xC0000203;
+ rs->or_port = 500;
+ rs->dir_port = 1999;
+ /* Running flag (and others) cleared */
+ smartlist_add(vote->routerstatus_list, vrs);
+ test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
+
+ /* dump the vote and try to parse it. */
+ v1_text = format_networkstatus_vote(sign_skey_1, vote);
+ test_assert(v1_text);
+ v1 = networkstatus_parse_vote_from_string(v1_text, NULL, NS_TYPE_VOTE);
+ test_assert(v1);
+
+ /* Make sure the parsed thing was right. */
+ test_eq(v1->type, NS_TYPE_VOTE);
+ test_eq(v1->published, vote->published);
+ test_eq(v1->valid_after, vote->valid_after);
+ test_eq(v1->fresh_until, vote->fresh_until);
+ test_eq(v1->valid_until, vote->valid_until);
+ test_eq(v1->vote_seconds, vote->vote_seconds);
+ test_eq(v1->dist_seconds, vote->dist_seconds);
+ test_streq(v1->client_versions, vote->client_versions);
+ test_streq(v1->server_versions, vote->server_versions);
+ test_assert(v1->voters && smartlist_len(v1->voters));
+ voter = smartlist_get(v1->voters, 0);
+ test_streq(voter->nickname, "Voter1");
+ test_streq(voter->address, "1.2.3.4");
+ test_eq(voter->addr, 0x01020304);
+ test_eq(voter->dir_port, 80);
+ test_eq(voter->or_port, 9000);
+ test_streq(voter->contact, "voter@example.com");
+ test_assert(v1->cert);
+ test_assert(!crypto_pk_cmp_keys(sign_skey_1, v1->cert->signing_key));
+ cp = smartlist_join_strings(v1->known_flags, ":", 0, NULL);
+ test_streq(cp, "Authority:Exit:Fast:Guard:Running:Stable:V2Dir:Valid");
+ tor_free(cp);
+ test_eq(smartlist_len(v1->routerstatus_list), 4);
+ /* Check the first routerstatus. */
+ vrs = smartlist_get(v1->routerstatus_list, 0);
+ rs = &vrs->status;
+ test_streq(vrs->version, "0.1.2.14");
+ test_eq(rs->published_on, now-1500);
+ test_streq(rs->nickname, "router2");
+ test_memeq(rs->identity_digest,
+ "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
+ DIGEST_LEN);
+ test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
+ test_eq(rs->addr, 0x99008801);
+ test_eq(rs->or_port, 443);
+ test_eq(rs->dir_port, 8000);
+ test_eq(vrs->flags, U64_LITERAL(16)); // no flags except "running"
+ /* Check the second routerstatus. */
+ vrs = smartlist_get(v1->routerstatus_list, 1);
+ rs = &vrs->status;
+ test_streq(vrs->version, "0.2.0.5");
+ test_eq(rs->published_on, now-1000);
+ test_streq(rs->nickname, "router1");
+ test_memeq(rs->identity_digest,
+ "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
+ DIGEST_LEN);
+ test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
+ test_eq(rs->addr, 0x99009901);
+ test_eq(rs->or_port, 443);
+ test_eq(rs->dir_port, 0);
+ test_eq(vrs->flags, U64_LITERAL(254)); // all flags except "authority."
+
+ {
+ measured_bw_line_t mbw;
+ memset(mbw.node_id, 33, sizeof(mbw.node_id));
+ mbw.bw = 1024;
+ test_assert(measured_bw_line_apply(&mbw,
+ v1->routerstatus_list) == 1);
+ vrs = smartlist_get(v1->routerstatus_list, 2);
+ test_assert(vrs->status.has_measured_bw &&
+ vrs->status.measured_bw == 1024);
+ }
+
+ /* Generate second vote. It disagrees on some of the times,
+ * and doesn't list versions, and knows some crazy flags */
+ vote->published = now+1;
+ vote->fresh_until = now+3005;
+ vote->dist_seconds = 300;
+ authority_cert_free(vote->cert);
+ vote->cert = authority_cert_dup(cert2);
+ vote->net_params = smartlist_create();
+ smartlist_split_string(vote->net_params, "bar=2000000000 circuitwindow=20",
+ NULL, 0, 0);
+ tor_free(vote->client_versions);
+ tor_free(vote->server_versions);
+ voter = smartlist_get(vote->voters, 0);
+ tor_free(voter->nickname);
+ tor_free(voter->address);
+ voter->nickname = tor_strdup("Voter2");
+ voter->address = tor_strdup("2.3.4.5");
+ voter->addr = 0x02030405;
+ crypto_pk_get_digest(cert2->identity_key, voter->identity_digest);
+ smartlist_add(vote->known_flags, tor_strdup("MadeOfCheese"));
+ smartlist_add(vote->known_flags, tor_strdup("MadeOfTin"));
+ smartlist_sort_strings(vote->known_flags);
+ vrs = smartlist_get(vote->routerstatus_list, 2);
+ smartlist_del_keeporder(vote->routerstatus_list, 2);
+ tor_free(vrs->version);
+ tor_free(vrs);
+ vrs = smartlist_get(vote->routerstatus_list, 0);
+ vrs->status.is_fast = 1;
+ /* generate and parse. */
+ v2_text = format_networkstatus_vote(sign_skey_2, vote);
+ test_assert(v2_text);
+ v2 = networkstatus_parse_vote_from_string(v2_text, NULL, NS_TYPE_VOTE);
+ test_assert(v2);
+ /* Check that flags come out right.*/
+ cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
+ test_streq(cp, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
+ "Running:Stable:V2Dir:Valid");
+ tor_free(cp);
+ vrs = smartlist_get(v2->routerstatus_list, 1);
+ /* 1023 - authority(1) - madeofcheese(16) - madeoftin(32) */
+ test_eq(vrs->flags, U64_LITERAL(974));
+
+ /* Generate the third vote. */
+ vote->published = now;
+ vote->fresh_until = now+2003;
+ vote->dist_seconds = 250;
+ authority_cert_free(vote->cert);
+ vote->cert = authority_cert_dup(cert3);
+ vote->net_params = smartlist_create();
+ smartlist_split_string(vote->net_params, "circuitwindow=80 foo=660",
+ NULL, 0, 0);
+ smartlist_add(vote->supported_methods, tor_strdup("4"));
+ vote->client_versions = tor_strdup("0.1.2.14,0.1.2.17");
+ vote->server_versions = tor_strdup("0.1.2.10,0.1.2.15,0.1.2.16");
+ voter = smartlist_get(vote->voters, 0);
+ tor_free(voter->nickname);
+ tor_free(voter->address);
+ voter->nickname = tor_strdup("Voter3");
+ voter->address = tor_strdup("3.4.5.6");
+ voter->addr = 0x03040506;
+ crypto_pk_get_digest(cert3->identity_key, voter->identity_digest);
+ /* This one has a legacy id. */
+ memset(voter->legacy_id_digest, (int)'A', DIGEST_LEN);
+ vrs = smartlist_get(vote->routerstatus_list, 0);
+ smartlist_del_keeporder(vote->routerstatus_list, 0);
+ tor_free(vrs->version);
+ tor_free(vrs);
+ vrs = smartlist_get(vote->routerstatus_list, 0);
+ memset(vrs->status.descriptor_digest, (int)'Z', DIGEST_LEN);
+ test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
+
+ v3_text = format_networkstatus_vote(sign_skey_3, vote);
+ test_assert(v3_text);
+
+ v3 = networkstatus_parse_vote_from_string(v3_text, NULL, NS_TYPE_VOTE);
+ test_assert(v3);
+
+ /* Compute a consensus as voter 3. */
+ smartlist_add(votes, v3);
+ smartlist_add(votes, v1);
+ smartlist_add(votes, v2);
+ consensus_text = networkstatus_compute_consensus(votes, 3,
+ cert3->identity_key,
+ sign_skey_3,
+ "AAAAAAAAAAAAAAAAAAAA",
+ sign_skey_leg1,
+ FLAV_NS);
+ test_assert(consensus_text);
+ con = networkstatus_parse_vote_from_string(consensus_text, NULL,
+ NS_TYPE_CONSENSUS);
+ test_assert(con);
+ //log_notice(LD_GENERAL, "<<%s>>\n<<%s>>\n<<%s>>\n",
+ // v1_text, v2_text, v3_text);
+ consensus_text_md = networkstatus_compute_consensus(votes, 3,
+ cert3->identity_key,
+ sign_skey_3,
+ "AAAAAAAAAAAAAAAAAAAA",
+ sign_skey_leg1,
+ FLAV_MICRODESC);
+ test_assert(consensus_text_md);
+ con_md = networkstatus_parse_vote_from_string(consensus_text_md, NULL,
+ NS_TYPE_CONSENSUS);
+ test_assert(con_md);
+ test_eq(con_md->flavor, FLAV_MICRODESC);
+
+ /* Check consensus contents. */
+ test_assert(con->type == NS_TYPE_CONSENSUS);
+ test_eq(con->published, 0); /* this field only appears in votes. */
+ test_eq(con->valid_after, now+1000);
+ test_eq(con->fresh_until, now+2003); /* median */
+ test_eq(con->valid_until, now+3000);
+ test_eq(con->vote_seconds, 100);
+ test_eq(con->dist_seconds, 250); /* median */
+ test_streq(con->client_versions, "0.1.2.14");
+ test_streq(con->server_versions, "0.1.2.15,0.1.2.16");
+ cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
+ test_streq(cp, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
+ "Running:Stable:V2Dir:Valid");
+ tor_free(cp);
+ cp = smartlist_join_strings(con->net_params, ":", 0, NULL);
+ test_streq(cp, "bar=2000000000:circuitwindow=80:foo=660");
+ tor_free(cp);
+
+ test_eq(4, smartlist_len(con->voters)); /*3 voters, 1 legacy key.*/
+ /* The voter id digests should be in this order. */
+ test_assert(memcmp(cert2->cache_info.identity_digest,
+ cert1->cache_info.identity_digest,DIGEST_LEN)<0);
+ test_assert(memcmp(cert1->cache_info.identity_digest,
+ cert3->cache_info.identity_digest,DIGEST_LEN)<0);
+ test_same_voter(smartlist_get(con->voters, 1),
+ smartlist_get(v2->voters, 0));
+ test_same_voter(smartlist_get(con->voters, 2),
+ smartlist_get(v1->voters, 0));
+ test_same_voter(smartlist_get(con->voters, 3),
+ smartlist_get(v3->voters, 0));
+
+ test_assert(!con->cert);
+ test_eq(2, smartlist_len(con->routerstatus_list));
+ /* There should be two listed routers: one with identity 3, one with
+ * identity 5. */
+ /* This one showed up in 2 digests. */
+ rs = smartlist_get(con->routerstatus_list, 0);
+ test_memeq(rs->identity_digest,
+ "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
+ DIGEST_LEN);
+ test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
+ test_assert(!rs->is_authority);
+ test_assert(!rs->is_exit);
+ test_assert(!rs->is_fast);
+ test_assert(!rs->is_possible_guard);
+ test_assert(!rs->is_stable);
+ test_assert(rs->is_running); /* If it wasn't running it wouldn't be here */
+ test_assert(!rs->is_v2_dir);
+ test_assert(!rs->is_valid);
+ test_assert(!rs->is_named);
+ /* XXXX check version */
+
+ rs = smartlist_get(con->routerstatus_list, 1);
+ /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */
+ test_memeq(rs->identity_digest,
+ "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
+ DIGEST_LEN);
+ test_streq(rs->nickname, "router1");
+ test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
+ test_eq(rs->published_on, now-1000);
+ test_eq(rs->addr, 0x99009901);
+ test_eq(rs->or_port, 443);
+ test_eq(rs->dir_port, 0);
+ test_assert(!rs->is_authority);
+ test_assert(rs->is_exit);
+ test_assert(rs->is_fast);
+ test_assert(rs->is_possible_guard);
+ test_assert(rs->is_stable);
+ test_assert(rs->is_running);
+ test_assert(rs->is_v2_dir);
+ test_assert(rs->is_valid);
+ test_assert(!rs->is_named);
+ /* XXXX check version */
+
+ /* Check signatures. the first voter is a pseudo-entry with a legacy key.
+ * The second one hasn't signed. The fourth one has signed: validate it. */
+ voter = smartlist_get(con->voters, 1);
+ test_eq(smartlist_len(voter->sigs), 0);
+
+ voter = smartlist_get(con->voters, 3);
+ test_eq(smartlist_len(voter->sigs), 1);
+ sig = smartlist_get(voter->sigs, 0);
+ test_assert(sig->signature);
+ test_assert(!sig->good_signature);
+ test_assert(!sig->bad_signature);
+
+ test_assert(!networkstatus_check_document_signature(con, sig, cert3));
+ test_assert(sig->signature);
+ test_assert(sig->good_signature);
+ test_assert(!sig->bad_signature);
+
+ {
+ const char *msg=NULL;
+ /* Compute the other two signed consensuses. */
+ smartlist_shuffle(votes);
+ consensus_text2 = networkstatus_compute_consensus(votes, 3,
+ cert2->identity_key,
+ sign_skey_2, NULL,NULL,
+ FLAV_NS);
+ consensus_text_md2 = networkstatus_compute_consensus(votes, 3,
+ cert2->identity_key,
+ sign_skey_2, NULL,NULL,
+ FLAV_MICRODESC);
+ smartlist_shuffle(votes);
+ consensus_text3 = networkstatus_compute_consensus(votes, 3,
+ cert1->identity_key,
+ sign_skey_1, NULL,NULL,
+ FLAV_NS);
+ consensus_text_md3 = networkstatus_compute_consensus(votes, 3,
+ cert1->identity_key,
+ sign_skey_1, NULL,NULL,
+ FLAV_MICRODESC);
+ test_assert(consensus_text2);
+ test_assert(consensus_text3);
+ test_assert(consensus_text_md2);
+ test_assert(consensus_text_md3);
+ con2 = networkstatus_parse_vote_from_string(consensus_text2, NULL,
+ NS_TYPE_CONSENSUS);
+ con3 = networkstatus_parse_vote_from_string(consensus_text3, NULL,
+ NS_TYPE_CONSENSUS);
+ con_md2 = networkstatus_parse_vote_from_string(consensus_text_md2, NULL,
+ NS_TYPE_CONSENSUS);
+ con_md3 = networkstatus_parse_vote_from_string(consensus_text_md3, NULL,
+ NS_TYPE_CONSENSUS);
+ test_assert(con2);
+ test_assert(con3);
+ test_assert(con_md2);
+ test_assert(con_md3);
+
+ /* All three should have the same digest. */
+ test_memeq(&con->digests, &con2->digests, sizeof(digests_t));
+ test_memeq(&con->digests, &con3->digests, sizeof(digests_t));
+
+ test_memeq(&con_md->digests, &con_md2->digests, sizeof(digests_t));
+ test_memeq(&con_md->digests, &con_md3->digests, sizeof(digests_t));
+
+ /* Extract a detached signature from con3. */
+ detached_text1 = get_detached_sigs(con3, con_md3);
+ tor_assert(detached_text1);
+ /* Try to parse it. */
+ dsig1 = networkstatus_parse_detached_signatures(detached_text1, NULL);
+ tor_assert(dsig1);
+
+ /* Are parsed values as expected? */
+ test_eq(dsig1->valid_after, con3->valid_after);
+ test_eq(dsig1->fresh_until, con3->fresh_until);
+ test_eq(dsig1->valid_until, con3->valid_until);
+ {
+ digests_t *dsig_digests = strmap_get(dsig1->digests, "ns");
+ test_assert(dsig_digests);
+ test_memeq(dsig_digests->d[DIGEST_SHA1], con3->digests.d[DIGEST_SHA1],
+ DIGEST_LEN);
+ dsig_digests = strmap_get(dsig1->digests, "microdesc");
+ test_assert(dsig_digests);
+ test_memeq(dsig_digests->d[DIGEST_SHA256],
+ con_md3->digests.d[DIGEST_SHA256],
+ DIGEST256_LEN);
+ }
+ {
+ smartlist_t *dsig_signatures = strmap_get(dsig1->signatures, "ns");
+ test_assert(dsig_signatures);
+ test_eq(1, smartlist_len(dsig_signatures));
+ sig = smartlist_get(dsig_signatures, 0);
+ test_memeq(sig->identity_digest, cert1->cache_info.identity_digest,
+ DIGEST_LEN);
+ test_eq(sig->alg, DIGEST_SHA1);
+
+ dsig_signatures = strmap_get(dsig1->signatures, "microdesc");
+ test_assert(dsig_signatures);
+ test_eq(1, smartlist_len(dsig_signatures));
+ sig = smartlist_get(dsig_signatures, 0);
+ test_memeq(sig->identity_digest, cert1->cache_info.identity_digest,
+ DIGEST_LEN);
+ test_eq(sig->alg, DIGEST_SHA256);
+ }
+
+ /* Try adding it to con2. */
+ detached_text2 = get_detached_sigs(con2,con_md2);
+ test_eq(1, networkstatus_add_detached_signatures(con2, dsig1, &msg));
+ tor_free(detached_text2);
+ test_eq(1, networkstatus_add_detached_signatures(con_md2, dsig1, &msg));
+ tor_free(detached_text2);
+ detached_text2 = get_detached_sigs(con2,con_md2);
+ //printf("\n<%s>\n", detached_text2);
+ dsig2 = networkstatus_parse_detached_signatures(detached_text2, NULL);
+ test_assert(dsig2);
+ /*
+ printf("\n");
+ SMARTLIST_FOREACH(dsig2->signatures, networkstatus_voter_info_t *, vi, {
+ char hd[64];
+ base16_encode(hd, sizeof(hd), vi->identity_digest, DIGEST_LEN);
+ printf("%s\n", hd);
+ });
+ */
+ test_eq(2,
+ smartlist_len((smartlist_t*)strmap_get(dsig2->signatures, "ns")));
+ test_eq(2,
+ smartlist_len((smartlist_t*)strmap_get(dsig2->signatures,
+ "microdesc")));
+
+ /* Try adding to con2 twice; verify that nothing changes. */
+ test_eq(0, networkstatus_add_detached_signatures(con2, dsig1, &msg));
+
+ /* Add to con. */
+ test_eq(2, networkstatus_add_detached_signatures(con, dsig2, &msg));
+ /* Check signatures */
+ voter = smartlist_get(con->voters, 1);
+ sig = smartlist_get(voter->sigs, 0);
+ test_assert(sig);
+ test_assert(!networkstatus_check_document_signature(con, sig, cert2));
+ voter = smartlist_get(con->voters, 2);
+ sig = smartlist_get(voter->sigs, 0);
+ test_assert(sig);
+ test_assert(!networkstatus_check_document_signature(con, sig, cert1));
+ }
+
+ done:
+ smartlist_free(votes);
+ tor_free(v1_text);
+ tor_free(v2_text);
+ tor_free(v3_text);
+ tor_free(consensus_text);
+ tor_free(consensus_text_md);
+
+ if (vote)
+ networkstatus_vote_free(vote);
+ if (v1)
+ networkstatus_vote_free(v1);
+ if (v2)
+ networkstatus_vote_free(v2);
+ if (v3)
+ networkstatus_vote_free(v3);
+ if (con)
+ networkstatus_vote_free(con);
+ if (con_md)
+ networkstatus_vote_free(con_md);
+ if (sign_skey_1)
+ crypto_free_pk_env(sign_skey_1);
+ if (sign_skey_2)
+ crypto_free_pk_env(sign_skey_2);
+ if (sign_skey_3)
+ crypto_free_pk_env(sign_skey_3);
+ if (sign_skey_leg1)
+ crypto_free_pk_env(sign_skey_leg1);
+ if (cert1)
+ authority_cert_free(cert1);
+ if (cert2)
+ authority_cert_free(cert2);
+ if (cert3)
+ authority_cert_free(cert3);
+
+ tor_free(consensus_text2);
+ tor_free(consensus_text3);
+ tor_free(consensus_text_md2);
+ tor_free(consensus_text_md3);
+ tor_free(detached_text1);
+ tor_free(detached_text2);
+ if (con2)
+ networkstatus_vote_free(con2);
+ if (con3)
+ networkstatus_vote_free(con3);
+ if (con_md2)
+ networkstatus_vote_free(con_md2);
+ if (con_md3)
+ networkstatus_vote_free(con_md3);
+ if (dsig1)
+ ns_detached_signatures_free(dsig1);
+ if (dsig2)
+ ns_detached_signatures_free(dsig2);
+}
+
+#define DIR_LEGACY(name) \
+ { #name, legacy_test_helper, 0, &legacy_setup, test_dir_ ## name }
+
+#define DIR(name) \
+ { #name, test_dir_##name, 0, NULL, NULL }
+
+struct testcase_t dir_tests[] = {
+ DIR_LEGACY(nicknames),
+ DIR_LEGACY(formats),
+ DIR_LEGACY(versions),
+ DIR_LEGACY(fp_pairs),
+ DIR(split_fps),
+ DIR_LEGACY(measured_bw),
+ DIR_LEGACY(param_voting),
+ DIR_LEGACY(v3_networkstatus),
+ END_OF_TESTCASES
+};
+
diff --git a/src/test/test_util.c b/src/test/test_util.c
new file mode 100644
index 0000000000..a14d548b8e
--- /dev/null
+++ b/src/test/test_util.c
@@ -0,0 +1,1239 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#define CONTROL_PRIVATE
+#define MEMPOOL_PRIVATE
+#include "or.h"
+#include "config.h"
+#include "control.h"
+#include "test.h"
+#include "mempool.h"
+#include "memarea.h"
+
+static void
+test_util_time(void)
+{
+ struct timeval start, end;
+ struct tm a_time;
+ char timestr[RFC1123_TIME_LEN+1];
+ time_t t_res;
+ int i;
+
+ start.tv_sec = 5;
+ start.tv_usec = 5000;
+
+ end.tv_sec = 5;
+ end.tv_usec = 5000;
+
+ test_eq(0L, tv_udiff(&start, &end));
+
+ end.tv_usec = 7000;
+
+ test_eq(2000L, tv_udiff(&start, &end));
+
+ end.tv_sec = 6;
+
+ test_eq(1002000L, tv_udiff(&start, &end));
+
+ end.tv_usec = 0;
+
+ test_eq(995000L, tv_udiff(&start, &end));
+
+ end.tv_sec = 4;
+
+ test_eq(-1005000L, tv_udiff(&start, &end));
+
+ end.tv_usec = 999990;
+ start.tv_sec = 1;
+ start.tv_usec = 500;
+
+ /* The test values here are confirmed to be correct on a platform
+ * with a working timegm. */
+ a_time.tm_year = 2003-1900;
+ a_time.tm_mon = 7;
+ a_time.tm_mday = 30;
+ a_time.tm_hour = 6;
+ a_time.tm_min = 14;
+ a_time.tm_sec = 55;
+ test_eq((time_t) 1062224095UL, tor_timegm(&a_time));
+ a_time.tm_year = 2004-1900; /* Try a leap year, after feb. */
+ test_eq((time_t) 1093846495UL, tor_timegm(&a_time));
+ a_time.tm_mon = 1; /* Try a leap year, in feb. */
+ a_time.tm_mday = 10;
+ test_eq((time_t) 1076393695UL, tor_timegm(&a_time));
+
+ format_rfc1123_time(timestr, 0);
+ test_streq("Thu, 01 Jan 1970 00:00:00 GMT", timestr);
+ format_rfc1123_time(timestr, (time_t)1091580502UL);
+ test_streq("Wed, 04 Aug 2004 00:48:22 GMT", timestr);
+
+ t_res = 0;
+ i = parse_rfc1123_time(timestr, &t_res);
+ test_eq(i,0);
+ test_eq(t_res, (time_t)1091580502UL);
+ test_eq(-1, parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res));
+
+ tor_gettimeofday(&start);
+ /* now make sure time works. */
+ tor_gettimeofday(&end);
+ /* We might've timewarped a little. */
+ tt_int_op(tv_udiff(&start, &end), >=, -5000);
+
+ done:
+ ;
+}
+
+static void
+test_util_config_line(void)
+{
+ char buf[1024];
+ char *k=NULL, *v=NULL;
+ const char *str;
+
+ /* Test parse_config_line_from_str */
+ strlcpy(buf, "k v\n" " key value with spaces \n" "keykey val\n"
+ "k2\n"
+ "k3 \n" "\n" " \n" "#comment\n"
+ "k4#a\n" "k5#abc\n" "k6 val #with comment\n"
+ "kseven \"a quoted 'string\"\n"
+ "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n"
+ "k9 a line that\\\n spans two lines.\n\n"
+ "k10 more than\\\n one contin\\\nuation\n"
+ "k11 \\\ncontinuation at the start\n"
+ "k12 line with a\\\n#comment\n embedded\n"
+ "k13\\\ncontinuation at the very start\n"
+ "k14 a line that has a comment and # ends with a slash \\\n"
+ "k15 this should be the next new line\n"
+ "k16 a line that has a comment and # ends without a slash \n"
+ "k17 this should be the next new line\n"
+ , sizeof(buf));
+ str = buf;
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k");
+ test_streq(v, "v");
+ tor_free(k); tor_free(v);
+ test_assert(!strcmpstart(str, "key value with"));
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "key");
+ test_streq(v, "value with spaces");
+ tor_free(k); tor_free(v);
+ test_assert(!strcmpstart(str, "keykey"));
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "keykey");
+ test_streq(v, "val");
+ tor_free(k); tor_free(v);
+ test_assert(!strcmpstart(str, "k2\n"));
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k2");
+ test_streq(v, "");
+ tor_free(k); tor_free(v);
+ test_assert(!strcmpstart(str, "k3 \n"));
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k3");
+ test_streq(v, "");
+ tor_free(k); tor_free(v);
+ test_assert(!strcmpstart(str, "#comment"));
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k4");
+ test_streq(v, "");
+ tor_free(k); tor_free(v);
+ test_assert(!strcmpstart(str, "k5#abc"));
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k5");
+ test_streq(v, "");
+ tor_free(k); tor_free(v);
+ test_assert(!strcmpstart(str, "k6"));
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k6");
+ test_streq(v, "val");
+ tor_free(k); tor_free(v);
+ test_assert(!strcmpstart(str, "kseven"));
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "kseven");
+ test_streq(v, "a quoted \'string");
+ tor_free(k); tor_free(v);
+ test_assert(!strcmpstart(str, "k8 "));
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k8");
+ test_streq(v, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k9");
+ test_streq(v, "a line that spans two lines.");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k10");
+ test_streq(v, "more than one continuation");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k11");
+ test_streq(v, "continuation at the start");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k12");
+ test_streq(v, "line with a embedded");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k13");
+ test_streq(v, "continuation at the very start");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k14");
+ test_streq(v, "a line that has a comment and" );
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k15");
+ test_streq(v, "this should be the next new line");
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k16");
+ test_streq(v, "a line that has a comment and" );
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str(str, &k, &v);
+ test_streq(k, "k17");
+ test_streq(v, "this should be the next new line");
+ tor_free(k); tor_free(v);
+
+ test_streq(str, "");
+
+ done:
+ tor_free(k);
+ tor_free(v);
+}
+
+/** Test basic string functionality. */
+static void
+test_util_strmisc(void)
+{
+ char buf[1024];
+ int i;
+ char *cp;
+
+ /* Tests for corner cases of strl operations */
+ test_eq(5, strlcpy(buf, "Hello", 0));
+ strlcpy(buf, "Hello", sizeof(buf));
+ test_eq(10, strlcat(buf, "Hello", 5));
+
+ /* Test tor_strstrip() */
+ strlcpy(buf, "Testing 1 2 3", sizeof(buf));
+ tor_strstrip(buf, ",!");
+ test_streq(buf, "Testing 1 2 3");
+ strlcpy(buf, "!Testing 1 2 3?", sizeof(buf));
+ tor_strstrip(buf, "!? ");
+ test_streq(buf, "Testing123");
+
+ /* Test tor_parse_long. */
+ test_eq(10L, tor_parse_long("10",10,0,100,NULL,NULL));
+ test_eq(0L, tor_parse_long("10",10,50,100,NULL,NULL));
+ test_eq(-50L, tor_parse_long("-50",10,-100,100,NULL,NULL));
+
+ /* Test tor_parse_ulong */
+ test_eq(10UL, tor_parse_ulong("10",10,0,100,NULL,NULL));
+ test_eq(0UL, tor_parse_ulong("10",10,50,100,NULL,NULL));
+
+ /* Test tor_parse_uint64. */
+ test_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
+ test_assert(i == 1);
+ test_streq(cp, " x");
+ test_assert(U64_LITERAL(12345678901) ==
+ tor_parse_uint64("12345678901",10,0,UINT64_MAX, &i, &cp));
+ test_assert(i == 1);
+ test_streq(cp, "");
+ test_assert(U64_LITERAL(0) ==
+ tor_parse_uint64("12345678901",10,500,INT32_MAX, &i, &cp));
+ test_assert(i == 0);
+
+ {
+ /* Test tor_parse_double. */
+ double d = tor_parse_double("10", 0, UINT64_MAX,&i,NULL);
+ test_assert(i == 1);
+ test_assert(DBL_TO_U64(d) == 10);
+ d = tor_parse_double("0", 0, UINT64_MAX,&i,NULL);
+ test_assert(i == 1);
+ test_assert(DBL_TO_U64(d) == 0);
+ d = tor_parse_double(" ", 0, UINT64_MAX,&i,NULL);
+ test_assert(i == 0);
+ d = tor_parse_double(".0a", 0, UINT64_MAX,&i,NULL);
+ test_assert(i == 0);
+ d = tor_parse_double(".0a", 0, UINT64_MAX,&i,&cp);
+ test_assert(i == 1);
+ d = tor_parse_double("-.0", 0, UINT64_MAX,&i,NULL);
+ test_assert(i == 1);
+ }
+
+ /* Test failing snprintf cases */
+ test_eq(-1, tor_snprintf(buf, 0, "Foo"));
+ test_eq(-1, tor_snprintf(buf, 2, "Foo"));
+
+ /* Test printf with uint64 */
+ tor_snprintf(buf, sizeof(buf), "x!"U64_FORMAT"!x",
+ U64_PRINTF_ARG(U64_LITERAL(12345678901)));
+ test_streq(buf, "x!12345678901!x");
+
+ /* Test for strcmpstart and strcmpend. */
+ test_assert(strcmpstart("abcdef", "abcdef")==0);
+ test_assert(strcmpstart("abcdef", "abc")==0);
+ test_assert(strcmpstart("abcdef", "abd")<0);
+ test_assert(strcmpstart("abcdef", "abb")>0);
+ test_assert(strcmpstart("ab", "abb")<0);
+
+ test_assert(strcmpend("abcdef", "abcdef")==0);
+ test_assert(strcmpend("abcdef", "def")==0);
+ test_assert(strcmpend("abcdef", "deg")<0);
+ test_assert(strcmpend("abcdef", "dee")>0);
+ test_assert(strcmpend("ab", "abb")<0);
+
+ test_assert(strcasecmpend("AbcDEF", "abcdef")==0);
+ test_assert(strcasecmpend("abcdef", "dEF")==0);
+ test_assert(strcasecmpend("abcDEf", "deg")<0);
+ test_assert(strcasecmpend("abcdef", "DEE")>0);
+ test_assert(strcasecmpend("ab", "abB")<0);
+
+ /* Test mem_is_zero */
+ memset(buf,0,128);
+ buf[128] = 'x';
+ test_assert(tor_digest_is_zero(buf));
+ test_assert(tor_mem_is_zero(buf, 10));
+ test_assert(tor_mem_is_zero(buf, 20));
+ test_assert(tor_mem_is_zero(buf, 128));
+ test_assert(!tor_mem_is_zero(buf, 129));
+ buf[60] = (char)255;
+ test_assert(!tor_mem_is_zero(buf, 128));
+ buf[0] = (char)1;
+ test_assert(!tor_mem_is_zero(buf, 10));
+
+ /* Test 'escaped' */
+ test_streq("\"\"", escaped(""));
+ test_streq("\"abcd\"", escaped("abcd"));
+ test_streq("\"\\\\\\n\\r\\t\\\"\\'\"", escaped("\\\n\r\t\"\'"));
+ test_streq("\"z\\001abc\\277d\"", escaped("z\001abc\277d"));
+ test_assert(NULL == escaped(NULL));
+
+ /* Test strndup and memdup */
+ {
+ const char *s = "abcdefghijklmnopqrstuvwxyz";
+ cp = tor_strndup(s, 30);
+ test_streq(cp, s); /* same string, */
+ test_neq(cp, s); /* but different pointers. */
+ tor_free(cp);
+
+ cp = tor_strndup(s, 5);
+ test_streq(cp, "abcde");
+ tor_free(cp);
+
+ s = "a\0b\0c\0d\0e\0";
+ cp = tor_memdup(s,10);
+ test_memeq(cp, s, 10); /* same ram, */
+ test_neq(cp, s); /* but different pointers. */
+ tor_free(cp);
+ }
+
+ /* Test str-foo functions */
+ cp = tor_strdup("abcdef");
+ test_assert(tor_strisnonupper(cp));
+ cp[3] = 'D';
+ test_assert(!tor_strisnonupper(cp));
+ tor_strupper(cp);
+ test_streq(cp, "ABCDEF");
+ test_assert(tor_strisprint(cp));
+ cp[3] = 3;
+ test_assert(!tor_strisprint(cp));
+ tor_free(cp);
+
+ /* Test eat_whitespace. */
+ {
+ const char *s = " \n a";
+ test_eq_ptr(eat_whitespace(s), s+4);
+ s = "abcd";
+ test_eq_ptr(eat_whitespace(s), s);
+ s = "#xyz\nab";
+ test_eq_ptr(eat_whitespace(s), s+5);
+ }
+
+ /* Test memmem and memstr */
+ {
+ const char *haystack = "abcde";
+ tor_assert(!tor_memmem(haystack, 5, "ef", 2));
+ test_eq_ptr(tor_memmem(haystack, 5, "cd", 2), haystack + 2);
+ test_eq_ptr(tor_memmem(haystack, 5, "cde", 3), haystack + 2);
+ haystack = "ababcad";
+ test_eq_ptr(tor_memmem(haystack, 7, "abc", 3), haystack + 2);
+ test_eq_ptr(tor_memstr(haystack, 7, "abc"), haystack + 2);
+ test_assert(!tor_memstr(haystack, 7, "fe"));
+ test_assert(!tor_memstr(haystack, 7, "longerthantheoriginal"));
+ }
+
+ /* Test wrap_string */
+ {
+ smartlist_t *sl = smartlist_create();
+ wrap_string(sl, "This is a test of string wrapping functionality: woot.",
+ 10, "", "");
+ cp = smartlist_join_strings(sl, "", 0, NULL);
+ test_streq(cp,
+ "This is a\ntest of\nstring\nwrapping\nfunctional\nity: woot.\n");
+ tor_free(cp);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_clear(sl);
+
+ wrap_string(sl, "This is a test of string wrapping functionality: woot.",
+ 16, "### ", "# ");
+ cp = smartlist_join_strings(sl, "", 0, NULL);
+ test_streq(cp,
+ "### This is a\n# test of string\n# wrapping\n# functionality:\n"
+ "# woot.\n");
+
+ tor_free(cp);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_free(sl);
+ }
+ done:
+ ;
+}
+
+static void
+test_util_pow2(void)
+{
+ /* Test tor_log2(). */
+ test_eq(tor_log2(64), 6);
+ test_eq(tor_log2(65), 6);
+ test_eq(tor_log2(63), 5);
+ test_eq(tor_log2(1), 0);
+ test_eq(tor_log2(2), 1);
+ test_eq(tor_log2(3), 1);
+ test_eq(tor_log2(4), 2);
+ test_eq(tor_log2(5), 2);
+ test_eq(tor_log2(U64_LITERAL(40000000000000000)), 55);
+ test_eq(tor_log2(UINT64_MAX), 63);
+
+ /* Test round_to_power_of_2 */
+ test_eq(round_to_power_of_2(120), 128);
+ test_eq(round_to_power_of_2(128), 128);
+ test_eq(round_to_power_of_2(130), 128);
+ test_eq(round_to_power_of_2(U64_LITERAL(40000000000000000)),
+ U64_LITERAL(1)<<55);
+ test_eq(round_to_power_of_2(0), 2);
+
+ done:
+ ;
+}
+
+/** mutex for thread test to stop the threads hitting data at the same time. */
+static tor_mutex_t *_thread_test_mutex = NULL;
+/** mutexes for the thread test to make sure that the threads have to
+ * interleave somewhat. */
+static tor_mutex_t *_thread_test_start1 = NULL,
+ *_thread_test_start2 = NULL;
+/** Shared strmap for the thread test. */
+static strmap_t *_thread_test_strmap = NULL;
+/** The name of thread1 for the thread test */
+static char *_thread1_name = NULL;
+/** The name of thread2 for the thread test */
+static char *_thread2_name = NULL;
+
+static void _thread_test_func(void* _s) ATTR_NORETURN;
+
+/** How many iterations have the threads in the unit test run? */
+static int t1_count = 0, t2_count = 0;
+
+/** Helper function for threading unit tests: This function runs in a
+ * subthread. It grabs its own mutex (start1 or start2) to make sure that it
+ * should start, then it repeatedly alters _test_thread_strmap protected by
+ * _thread_test_mutex. */
+static void
+_thread_test_func(void* _s)
+{
+ char *s = _s;
+ int i, *count;
+ tor_mutex_t *m;
+ char buf[64];
+ char **cp;
+ if (!strcmp(s, "thread 1")) {
+ m = _thread_test_start1;
+ cp = &_thread1_name;
+ count = &t1_count;
+ } else {
+ m = _thread_test_start2;
+ cp = &_thread2_name;
+ count = &t2_count;
+ }
+
+ tor_snprintf(buf, sizeof(buf), "%lu", tor_get_thread_id());
+ *cp = tor_strdup(buf);
+
+ tor_mutex_acquire(m);
+
+ for (i=0; i<10000; ++i) {
+ tor_mutex_acquire(_thread_test_mutex);
+ strmap_set(_thread_test_strmap, "last to run", *cp);
+ ++*count;
+ tor_mutex_release(_thread_test_mutex);
+ }
+ tor_mutex_acquire(_thread_test_mutex);
+ strmap_set(_thread_test_strmap, s, *cp);
+ tor_mutex_release(_thread_test_mutex);
+
+ tor_mutex_release(m);
+
+ spawn_exit();
+}
+
+/** Run unit tests for threading logic. */
+static void
+test_util_threads(void)
+{
+ char *s1 = NULL, *s2 = NULL;
+ int done = 0, timedout = 0;
+ time_t started;
+#ifndef MS_WINDOWS
+ struct timeval tv;
+ tv.tv_sec=0;
+ tv.tv_usec=10;
+#endif
+#ifndef TOR_IS_MULTITHREADED
+ /* Skip this test if we aren't threading. We should be threading most
+ * everywhere by now. */
+ if (1)
+ return;
+#endif
+ _thread_test_mutex = tor_mutex_new();
+ _thread_test_start1 = tor_mutex_new();
+ _thread_test_start2 = tor_mutex_new();
+ _thread_test_strmap = strmap_new();
+ s1 = tor_strdup("thread 1");
+ s2 = tor_strdup("thread 2");
+ tor_mutex_acquire(_thread_test_start1);
+ tor_mutex_acquire(_thread_test_start2);
+ spawn_func(_thread_test_func, s1);
+ spawn_func(_thread_test_func, s2);
+ tor_mutex_release(_thread_test_start2);
+ tor_mutex_release(_thread_test_start1);
+ started = time(NULL);
+ while (!done) {
+ tor_mutex_acquire(_thread_test_mutex);
+ strmap_assert_ok(_thread_test_strmap);
+ if (strmap_get(_thread_test_strmap, "thread 1") &&
+ strmap_get(_thread_test_strmap, "thread 2")) {
+ done = 1;
+ } else if (time(NULL) > started + 25) {
+ timedout = done = 1;
+ }
+ tor_mutex_release(_thread_test_mutex);
+#ifndef MS_WINDOWS
+ /* Prevent the main thread from starving the worker threads. */
+ select(0, NULL, NULL, NULL, &tv);
+#endif
+ }
+ tor_mutex_acquire(_thread_test_start1);
+ tor_mutex_release(_thread_test_start1);
+ tor_mutex_acquire(_thread_test_start2);
+ tor_mutex_release(_thread_test_start2);
+
+ tor_mutex_free(_thread_test_mutex);
+
+ if (timedout) {
+ printf("\nTimed out: %d %d", t1_count, t2_count);
+ test_assert(strmap_get(_thread_test_strmap, "thread 1"));
+ test_assert(strmap_get(_thread_test_strmap, "thread 2"));
+ test_assert(!timedout);
+ }
+
+ /* different thread IDs. */
+ test_assert(strcmp(strmap_get(_thread_test_strmap, "thread 1"),
+ strmap_get(_thread_test_strmap, "thread 2")));
+ test_assert(!strcmp(strmap_get(_thread_test_strmap, "thread 1"),
+ strmap_get(_thread_test_strmap, "last to run")) ||
+ !strcmp(strmap_get(_thread_test_strmap, "thread 2"),
+ strmap_get(_thread_test_strmap, "last to run")));
+
+ done:
+ tor_free(s1);
+ tor_free(s2);
+ tor_free(_thread1_name);
+ tor_free(_thread2_name);
+ if (_thread_test_strmap)
+ strmap_free(_thread_test_strmap, NULL);
+ if (_thread_test_start1)
+ tor_mutex_free(_thread_test_start1);
+ if (_thread_test_start2)
+ tor_mutex_free(_thread_test_start2);
+}
+
+/** Run unit tests for compression functions */
+static void
+test_util_gzip(void)
+{
+ char *buf1=NULL, *buf2=NULL, *buf3=NULL, *cp1, *cp2;
+ const char *ccp2;
+ size_t len1, len2;
+ tor_zlib_state_t *state = NULL;
+
+ buf1 = tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
+ test_assert(detect_compression_method(buf1, strlen(buf1)) == UNKNOWN_METHOD);
+ if (is_gzip_supported()) {
+ test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
+ GZIP_METHOD));
+ test_assert(buf2);
+ test_assert(!memcmp(buf2, "\037\213", 2)); /* Gzip magic. */
+ test_assert(detect_compression_method(buf2, len1) == GZIP_METHOD);
+
+ test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
+ GZIP_METHOD, 1, LOG_INFO));
+ test_assert(buf3);
+ test_streq(buf1,buf3);
+
+ tor_free(buf2);
+ tor_free(buf3);
+ }
+
+ test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
+ ZLIB_METHOD));
+ test_assert(buf2);
+ test_assert(!memcmp(buf2, "\x78\xDA", 2)); /* deflate magic. */
+ test_assert(detect_compression_method(buf2, len1) == ZLIB_METHOD);
+
+ test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
+ ZLIB_METHOD, 1, LOG_INFO));
+ test_assert(buf3);
+ test_streq(buf1,buf3);
+
+ /* Check whether we can uncompress concatenated, compressed strings. */
+ tor_free(buf3);
+ buf2 = tor_realloc(buf2, len1*2);
+ memcpy(buf2+len1, buf2, len1);
+ test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1*2,
+ ZLIB_METHOD, 1, LOG_INFO));
+ test_eq(len2, (strlen(buf1)+1)*2);
+ test_memeq(buf3,
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
+ (strlen(buf1)+1)*2);
+
+ tor_free(buf1);
+ tor_free(buf2);
+ tor_free(buf3);
+
+ /* Check whether we can uncompress partial strings. */
+ buf1 =
+ tor_strdup("String with low redundancy that won't be compressed much.");
+ test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
+ ZLIB_METHOD));
+ tor_assert(len1>16);
+ /* when we allow an incomplete string, we should succeed.*/
+ tor_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1-16,
+ ZLIB_METHOD, 0, LOG_INFO));
+ buf3[len2]='\0';
+ tor_assert(len2 > 5);
+ tor_assert(!strcmpstart(buf1, buf3));
+
+ /* when we demand a complete string, this must fail. */
+ tor_free(buf3);
+ tor_assert(tor_gzip_uncompress(&buf3, &len2, buf2, len1-16,
+ ZLIB_METHOD, 1, LOG_INFO));
+ tor_assert(!buf3);
+
+ /* Now, try streaming compression. */
+ tor_free(buf1);
+ tor_free(buf2);
+ tor_free(buf3);
+ state = tor_zlib_new(1, ZLIB_METHOD);
+ tor_assert(state);
+ cp1 = buf1 = tor_malloc(1024);
+ len1 = 1024;
+ ccp2 = "ABCDEFGHIJABCDEFGHIJ";
+ len2 = 21;
+ test_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 0)
+ == TOR_ZLIB_OK);
+ test_eq(len2, 0); /* Make sure we compressed it all. */
+ test_assert(cp1 > buf1);
+
+ len2 = 0;
+ cp2 = cp1;
+ test_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 1)
+ == TOR_ZLIB_DONE);
+ test_eq(len2, 0);
+ test_assert(cp1 > cp2); /* Make sure we really added something. */
+
+ tor_assert(!tor_gzip_uncompress(&buf3, &len2, buf1, 1024-len1,
+ ZLIB_METHOD, 1, LOG_WARN));
+ test_streq(buf3, "ABCDEFGHIJABCDEFGHIJ"); /*Make sure it compressed right.*/
+
+ done:
+ if (state)
+ tor_zlib_free(state);
+ tor_free(buf2);
+ tor_free(buf3);
+ tor_free(buf1);
+}
+
+/** Run unit tests for mmap() wrapper functionality. */
+static void
+test_util_mmap(void)
+{
+ char *fname1 = tor_strdup(get_fname("mapped_1"));
+ char *fname2 = tor_strdup(get_fname("mapped_2"));
+ char *fname3 = tor_strdup(get_fname("mapped_3"));
+ const size_t buflen = 17000;
+ char *buf = tor_malloc(17000);
+ tor_mmap_t *mapping = NULL;
+
+ crypto_rand(buf, buflen);
+
+ mapping = tor_mmap_file(fname1);
+ test_assert(! mapping);
+
+ write_str_to_file(fname1, "Short file.", 1);
+ write_bytes_to_file(fname2, buf, buflen, 1);
+ write_bytes_to_file(fname3, buf, 16384, 1);
+
+ mapping = tor_mmap_file(fname1);
+ test_assert(mapping);
+ test_eq(mapping->size, strlen("Short file."));
+ test_streq(mapping->data, "Short file.");
+#ifdef MS_WINDOWS
+ tor_munmap_file(mapping);
+ mapping = NULL;
+ test_assert(unlink(fname1) == 0);
+#else
+ /* make sure we can unlink. */
+ test_assert(unlink(fname1) == 0);
+ test_streq(mapping->data, "Short file.");
+ tor_munmap_file(mapping);
+ mapping = NULL;
+#endif
+
+ /* Now a zero-length file. */
+ write_str_to_file(fname1, "", 1);
+ mapping = tor_mmap_file(fname1);
+ test_eq(mapping, NULL);
+ test_eq(ERANGE, errno);
+ unlink(fname1);
+
+ /* Make sure that we fail to map a no-longer-existent file. */
+ mapping = tor_mmap_file(fname1);
+ test_assert(mapping == NULL);
+
+ /* Now try a big file that stretches across a few pages and isn't aligned */
+ mapping = tor_mmap_file(fname2);
+ test_assert(mapping);
+ test_eq(mapping->size, buflen);
+ test_memeq(mapping->data, buf, buflen);
+ tor_munmap_file(mapping);
+ mapping = NULL;
+
+ /* Now try a big aligned file. */
+ mapping = tor_mmap_file(fname3);
+ test_assert(mapping);
+ test_eq(mapping->size, 16384);
+ test_memeq(mapping->data, buf, 16384);
+ tor_munmap_file(mapping);
+ mapping = NULL;
+
+ done:
+ unlink(fname1);
+ unlink(fname2);
+ unlink(fname3);
+
+ tor_free(fname1);
+ tor_free(fname2);
+ tor_free(fname3);
+ tor_free(buf);
+
+ if (mapping)
+ tor_munmap_file(mapping);
+}
+
+/** Run unit tests for escaping/unescaping data for use by controllers. */
+static void
+test_util_control_formats(void)
+{
+ char *out = NULL;
+ const char *inp =
+ "..This is a test\r\nof the emergency \nbroadcast\r\n..system.\r\nZ.\r\n";
+ size_t sz;
+
+ sz = read_escaped_data(inp, strlen(inp), &out);
+ test_streq(out,
+ ".This is a test\nof the emergency \nbroadcast\n.system.\nZ.\n");
+ test_eq(sz, strlen(out));
+
+ done:
+ tor_free(out);
+}
+
+static void
+test_util_sscanf(void)
+{
+ unsigned u1, u2, u3;
+ char s1[10], s2[10], s3[10], ch;
+ int r;
+
+ r = tor_sscanf("hello world", "hello world"); /* String match: success */
+ test_eq(r, 0);
+ r = tor_sscanf("hello world 3", "hello worlb %u", &u1); /* String fail */
+ test_eq(r, 0);
+ r = tor_sscanf("12345", "%u", &u1); /* Simple number */
+ test_eq(r, 1);
+ test_eq(u1, 12345u);
+ r = tor_sscanf("", "%u", &u1); /* absent number */
+ test_eq(r, 0);
+ r = tor_sscanf("A", "%u", &u1); /* bogus number */
+ test_eq(r, 0);
+ r = tor_sscanf("4294967295", "%u", &u1); /* UINT32_MAX should work. */
+ test_eq(r, 1);
+ test_eq(u1, 4294967295u);
+ r = tor_sscanf("4294967296", "%u", &u1); /* Always say -1 at 32 bits. */
+ test_eq(r, 0);
+ r = tor_sscanf("123456", "%2u%u", &u1, &u2); /* Width */
+ test_eq(r, 2);
+ test_eq(u1, 12u);
+ test_eq(u2, 3456u);
+ r = tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1, &u2, &u3); /* separators */
+ test_eq(r, 3);
+ test_eq(u1, 12u);
+ test_eq(u2, 3u);
+ test_eq(u3, 456u);
+ r = tor_sscanf("12:3:045", "%2u:%2u:%3u", &u1, &u2, &u3); /* 0s */
+ test_eq(r, 3);
+ test_eq(u1, 12u);
+ test_eq(u2, 3u);
+ test_eq(u3, 45u);
+ /* %u does not match space.*/
+ r = tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1, &u2, &u3);
+ test_eq(r, 2);
+ /* %u does not match negative numbers. */
+ r = tor_sscanf("12:3:-4", "%2u:%2u:%3u", &u1, &u2, &u3);
+ test_eq(r, 2);
+ /* Arbitrary amounts of 0-padding are okay */
+ r = tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u", &u1, &u2, &u3);
+ test_eq(r, 3);
+ test_eq(u1, 12u);
+ test_eq(u2, 3u);
+ test_eq(u3, 99u);
+
+ r = tor_sscanf("99% fresh", "%3u%% fresh", &u1); /* percents are scannable.*/
+ test_eq(r, 1);
+ test_eq(u1, 99);
+
+ r = tor_sscanf("hello", "%s", s1); /* %s needs a number. */
+ test_eq(r, -1);
+
+ r = tor_sscanf("hello", "%3s%7s", s1, s2); /* %s matches characters. */
+ test_eq(r, 2);
+ test_streq(s1, "hel");
+ test_streq(s2, "lo");
+ r = tor_sscanf("WD40", "%2s%u", s3, &u1); /* %s%u */
+ test_eq(r, 2);
+ test_streq(s3, "WD");
+ test_eq(u1, 40);
+ r = tor_sscanf("76trombones", "%6u%9s", &u1, s1); /* %u%s */
+ test_eq(r, 2);
+ test_eq(u1, 76);
+ test_streq(s1, "trombones");
+ r = tor_sscanf("hello world", "%9s %9s", s1, s2); /* %s doesn't eat space. */
+ test_eq(r, 2);
+ test_streq(s1, "hello");
+ test_streq(s2, "world");
+ r = tor_sscanf("hi", "%9s%9s%3s", s1, s2, s3); /* %s can be empty. */
+ test_eq(r, 3);
+ test_streq(s1, "hi");
+ test_streq(s2, "");
+ test_streq(s3, "");
+
+ r = tor_sscanf("1.2.3", "%u.%u.%u%c", &u1, &u2, &u3, &ch);
+ test_eq(r, 3);
+ r = tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1, &u2, &u3, &ch);
+ test_eq(r, 4);
+
+ done:
+ ;
+}
+
+/** Run unittests for memory pool allocator */
+static void
+test_util_mempool(void)
+{
+ mp_pool_t *pool = NULL;
+ smartlist_t *allocated = NULL;
+ int i;
+
+ pool = mp_pool_new(1, 100);
+ test_assert(pool);
+ test_assert(pool->new_chunk_capacity >= 100);
+ test_assert(pool->item_alloc_size >= sizeof(void*)+1);
+ mp_pool_destroy(pool);
+ pool = NULL;
+
+ pool = mp_pool_new(241, 2500);
+ test_assert(pool);
+ test_assert(pool->new_chunk_capacity >= 10);
+ test_assert(pool->item_alloc_size >= sizeof(void*)+241);
+ test_eq(pool->item_alloc_size & 0x03, 0);
+ test_assert(pool->new_chunk_capacity < 60);
+
+ allocated = smartlist_create();
+ for (i = 0; i < 20000; ++i) {
+ if (smartlist_len(allocated) < 20 || crypto_rand_int(2)) {
+ void *m = mp_pool_get(pool);
+ memset(m, 0x09, 241);
+ smartlist_add(allocated, m);
+ //printf("%d: %p\n", i, m);
+ //mp_pool_assert_ok(pool);
+ } else {
+ int idx = crypto_rand_int(smartlist_len(allocated));
+ void *m = smartlist_get(allocated, idx);
+ //printf("%d: free %p\n", i, m);
+ smartlist_del(allocated, idx);
+ mp_pool_release(m);
+ //mp_pool_assert_ok(pool);
+ }
+ if (crypto_rand_int(777)==0)
+ mp_pool_clean(pool, 1, 1);
+
+ if (i % 777)
+ mp_pool_assert_ok(pool);
+ }
+
+ done:
+ if (allocated) {
+ SMARTLIST_FOREACH(allocated, void *, m, mp_pool_release(m));
+ mp_pool_assert_ok(pool);
+ mp_pool_clean(pool, 0, 0);
+ mp_pool_assert_ok(pool);
+ smartlist_free(allocated);
+ }
+
+ if (pool)
+ mp_pool_destroy(pool);
+}
+
+/** Run unittests for memory area allocator */
+static void
+test_util_memarea(void)
+{
+ memarea_t *area = memarea_new();
+ char *p1, *p2, *p3, *p1_orig;
+ void *malloced_ptr = NULL;
+ int i;
+
+ test_assert(area);
+
+ p1_orig = p1 = memarea_alloc(area,64);
+ p2 = memarea_alloc_zero(area,52);
+ p3 = memarea_alloc(area,11);
+
+ test_assert(memarea_owns_ptr(area, p1));
+ test_assert(memarea_owns_ptr(area, p2));
+ test_assert(memarea_owns_ptr(area, p3));
+ /* Make sure we left enough space. */
+ test_assert(p1+64 <= p2);
+ test_assert(p2+52 <= p3);
+ /* Make sure we aligned. */
+ test_eq(((uintptr_t)p1) % sizeof(void*), 0);
+ test_eq(((uintptr_t)p2) % sizeof(void*), 0);
+ test_eq(((uintptr_t)p3) % sizeof(void*), 0);
+ test_assert(!memarea_owns_ptr(area, p3+8192));
+ test_assert(!memarea_owns_ptr(area, p3+30));
+ test_assert(tor_mem_is_zero(p2, 52));
+ /* Make sure we don't overalign. */
+ p1 = memarea_alloc(area, 1);
+ p2 = memarea_alloc(area, 1);
+ test_eq(p1+sizeof(void*), p2);
+ {
+ malloced_ptr = tor_malloc(64);
+ test_assert(!memarea_owns_ptr(area, malloced_ptr));
+ tor_free(malloced_ptr);
+ }
+
+ /* memarea_memdup */
+ {
+ malloced_ptr = tor_malloc(64);
+ crypto_rand((char*)malloced_ptr, 64);
+ p1 = memarea_memdup(area, malloced_ptr, 64);
+ test_assert(p1 != malloced_ptr);
+ test_memeq(p1, malloced_ptr, 64);
+ tor_free(malloced_ptr);
+ }
+
+ /* memarea_strdup. */
+ p1 = memarea_strdup(area,"");
+ p2 = memarea_strdup(area, "abcd");
+ test_assert(p1);
+ test_assert(p2);
+ test_streq(p1, "");
+ test_streq(p2, "abcd");
+
+ /* memarea_strndup. */
+ {
+ const char *s = "Ad ogni porta batte la morte e grida: il nome!";
+ /* (From Turandot, act 3.) */
+ size_t len = strlen(s);
+ p1 = memarea_strndup(area, s, 1000);
+ p2 = memarea_strndup(area, s, 10);
+ test_streq(p1, s);
+ test_assert(p2 >= p1 + len + 1);
+ test_memeq(s, p2, 10);
+ test_eq(p2[10], '\0');
+ p3 = memarea_strndup(area, s, len);
+ test_streq(p3, s);
+ p3 = memarea_strndup(area, s, len-1);
+ test_memeq(s, p3, len-1);
+ test_eq(p3[len-1], '\0');
+ }
+
+ memarea_clear(area);
+ p1 = memarea_alloc(area, 1);
+ test_eq(p1, p1_orig);
+ memarea_clear(area);
+
+ /* Check for running over an area's size. */
+ for (i = 0; i < 512; ++i) {
+ p1 = memarea_alloc(area, crypto_rand_int(5)+1);
+ test_assert(memarea_owns_ptr(area, p1));
+ }
+ memarea_assert_ok(area);
+ /* Make sure we can allocate a too-big object. */
+ p1 = memarea_alloc_zero(area, 9000);
+ p2 = memarea_alloc_zero(area, 16);
+ test_assert(memarea_owns_ptr(area, p1));
+ test_assert(memarea_owns_ptr(area, p2));
+
+ done:
+ memarea_drop_all(area);
+ tor_free(malloced_ptr);
+}
+
+/** Run unit tests for utility functions to get file names relative to
+ * the data directory. */
+static void
+test_util_datadir(void)
+{
+ char buf[1024];
+ char *f = NULL;
+ char *temp_dir = NULL;
+
+ temp_dir = get_datadir_fname(NULL);
+ f = get_datadir_fname("state");
+ tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"state", temp_dir);
+ test_streq(f, buf);
+ tor_free(f);
+ f = get_datadir_fname2("cache", "thingy");
+ tor_snprintf(buf, sizeof(buf),
+ "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy", temp_dir);
+ test_streq(f, buf);
+ tor_free(f);
+ f = get_datadir_fname2_suffix("cache", "thingy", ".foo");
+ tor_snprintf(buf, sizeof(buf),
+ "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy.foo", temp_dir);
+ test_streq(f, buf);
+ tor_free(f);
+ f = get_datadir_fname_suffix("cache", ".foo");
+ tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"cache.foo",
+ temp_dir);
+ test_streq(f, buf);
+
+ done:
+ tor_free(f);
+ tor_free(temp_dir);
+}
+
+static void
+test_util_strtok(void)
+{
+ char buf[128];
+ char buf2[128];
+ char *cp1, *cp2;
+ strlcpy(buf, "Graved on the dark in gestures of descent", sizeof(buf));
+ strlcpy(buf2, "they.seemed;their!own;most.perfect;monument", sizeof(buf2));
+ /* -- "Year's End", Richard Wilbur */
+
+ test_streq("Graved", tor_strtok_r_impl(buf, " ", &cp1));
+ test_streq("they", tor_strtok_r_impl(buf2, ".!..;!", &cp2));
+#define S1() tor_strtok_r_impl(NULL, " ", &cp1)
+#define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
+ test_streq("on", S1());
+ test_streq("the", S1());
+ test_streq("dark", S1());
+ test_streq("seemed", S2());
+ test_streq("their", S2());
+ test_streq("own", S2());
+ test_streq("in", S1());
+ test_streq("gestures", S1());
+ test_streq("of", S1());
+ test_streq("most", S2());
+ test_streq("perfect", S2());
+ test_streq("descent", S1());
+ test_streq("monument", S2());
+ test_assert(NULL == S1());
+ test_assert(NULL == S2());
+ done:
+ ;
+}
+
+static void
+test_util_find_str_at_start_of_line(void *ptr)
+{
+ const char *long_string =
+ "hello world. hello world. hello hello. howdy.\n"
+ "hello hello world\n";
+
+ (void)ptr;
+
+ /* not-found case. */
+ tt_assert(! find_str_at_start_of_line(long_string, "fred"));
+
+ /* not-found case where haystack doesn't end with \n */
+ tt_assert(! find_str_at_start_of_line("foobar\nbaz", "fred"));
+
+ /* start-of-string case */
+ tt_assert(long_string ==
+ find_str_at_start_of_line(long_string, "hello world."));
+
+ /* start-of-line case */
+ tt_assert(strchr(long_string,'\n')+1 ==
+ find_str_at_start_of_line(long_string, "hello hello"));
+ done:
+ ;
+}
+
+static void
+test_util_asprintf(void *ptr)
+{
+#define LOREMIPSUM \
+ "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
+ char *cp=NULL, *cp2=NULL;
+ int r;
+ (void)ptr;
+
+ /* empty string. */
+ r = tor_asprintf(&cp, "%s", "");
+ tt_assert(cp);
+ tt_int_op(r, ==, strlen(cp));
+ tt_str_op(cp, ==, "");
+
+ /* Short string with some printing in it. */
+ r = tor_asprintf(&cp2, "First=%d, Second=%d", 101, 202);
+ tt_assert(cp2);
+ tt_int_op(r, ==, strlen(cp2));
+ tt_str_op(cp2, ==, "First=101, Second=202");
+ tt_assert(cp != cp2);
+ tor_free(cp);
+ tor_free(cp2);
+
+ /* Glass-box test: a string exactly 128 characters long. */
+ r = tor_asprintf(&cp, "Lorem1: %sLorem2: %s", LOREMIPSUM, LOREMIPSUM);
+ tt_assert(cp);
+ tt_int_op(r, ==, 128);
+ tt_assert(cp[128] == '\0');
+ tt_str_op(cp, ==,
+ "Lorem1: "LOREMIPSUM"Lorem2: "LOREMIPSUM);
+ tor_free(cp);
+
+ /* String longer than 128 characters */
+ r = tor_asprintf(&cp, "1: %s 2: %s 3: %s",
+ LOREMIPSUM, LOREMIPSUM, LOREMIPSUM);
+ tt_assert(cp);
+ tt_int_op(r, ==, strlen(cp));
+ tt_str_op(cp, ==, "1: "LOREMIPSUM" 2: "LOREMIPSUM" 3: "LOREMIPSUM);
+
+ done:
+ tor_free(cp);
+ tor_free(cp2);
+}
+
+static void
+test_util_listdir(void *ptr)
+{
+ smartlist_t *dir_contents = NULL;
+ char *fname1=NULL, *fname2=NULL, *dirname=NULL;
+ (void)ptr;
+
+ fname1 = tor_strdup(get_fname("hopscotch"));
+ fname2 = tor_strdup(get_fname("mumblety-peg"));
+ dirname = tor_strdup(get_fname(NULL));
+
+ tt_int_op(write_str_to_file(fname1, "X\n", 0), ==, 0);
+ tt_int_op(write_str_to_file(fname2, "Y\n", 0), ==, 0);
+
+ dir_contents = tor_listdir(dirname);
+ tt_assert(dir_contents);
+ /* make sure that each filename is listed. */
+ tt_assert(smartlist_string_isin_case(dir_contents, "hopscotch"));
+ tt_assert(smartlist_string_isin_case(dir_contents, "mumblety-peg"));
+
+ tt_assert(!smartlist_string_isin(dir_contents, "."));
+ tt_assert(!smartlist_string_isin(dir_contents, ".."));
+
+ done:
+ tor_free(fname1);
+ tor_free(fname2);
+ tor_free(dirname);
+ if (dir_contents) {
+ SMARTLIST_FOREACH(dir_contents, char *, cp, tor_free(cp));
+ smartlist_free(dir_contents);
+ }
+}
+
+#ifdef MS_WINDOWS
+static void
+test_util_load_win_lib(void *ptr)
+{
+ HANDLE h = load_windows_system_library("advapi32.dll");
+
+ tt_assert(h);
+ done:
+ if (h)
+ CloseHandle(h);
+}
+#endif
+
+#define UTIL_LEGACY(name) \
+ { #name, legacy_test_helper, 0, &legacy_setup, test_util_ ## name }
+
+#define UTIL_TEST(name, flags) \
+ { #name, test_util_ ## name, flags, NULL, NULL }
+
+struct testcase_t util_tests[] = {
+ UTIL_LEGACY(time),
+ UTIL_LEGACY(config_line),
+ UTIL_LEGACY(strmisc),
+ UTIL_LEGACY(pow2),
+ UTIL_LEGACY(gzip),
+ UTIL_LEGACY(datadir),
+ UTIL_LEGACY(mempool),
+ UTIL_LEGACY(memarea),
+ UTIL_LEGACY(control_formats),
+ UTIL_LEGACY(mmap),
+ UTIL_LEGACY(threads),
+ UTIL_LEGACY(sscanf),
+ UTIL_LEGACY(strtok),
+ UTIL_TEST(find_str_at_start_of_line, 0),
+ UTIL_TEST(asprintf, 0),
+ UTIL_TEST(listdir, 0),
+#ifdef MS_WINDOWS
+ UTIL_TEST(load_win_lib, 0),
+#endif
+ END_OF_TESTCASES
+};
+
diff --git a/src/test/tinytest.c b/src/test/tinytest.c
new file mode 100644
index 0000000000..11ffc2fe56
--- /dev/null
+++ b/src/test/tinytest.c
@@ -0,0 +1,380 @@
+/* tinytest.c -- Copyright 2009-2010 Nick Mathewson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#endif
+
+#ifndef __GNUC__
+#define __attribute__(x)
+#endif
+
+#ifdef TINYTEST_LOCAL
+#include "tinytest_local.h"
+#endif
+#include "tinytest.h"
+#include "tinytest_macros.h"
+
+#define LONGEST_TEST_NAME 16384
+
+static int in_tinytest_main = 0; /**< true if we're in tinytest_main().*/
+static int n_ok = 0; /**< Number of tests that have passed */
+static int n_bad = 0; /**< Number of tests that have failed. */
+static int n_skipped = 0; /**< Number of tests that have been skipped. */
+
+static int opt_forked = 0; /**< True iff we're called from inside a win32 fork*/
+static int opt_nofork = 0; /**< Suppress calls to fork() for debugging. */
+static int opt_verbosity = 1; /**< -==quiet,0==terse,1==normal,2==verbose */
+const char *verbosity_flag = "";
+
+enum outcome { SKIP=2, OK=1, FAIL=0 };
+static enum outcome cur_test_outcome = 0;
+const char *cur_test_prefix = NULL; /**< prefix of the current test group */
+/** Name of the current test, if we haven't logged is yet. Used for --quiet */
+const char *cur_test_name = NULL;
+
+#ifdef WIN32
+/** Pointer to argv[0] for win32. */
+static const char *commandname = NULL;
+#endif
+
+static void usage(struct testgroup_t *groups, int list_groups)
+ __attribute__((noreturn));
+
+static enum outcome
+_testcase_run_bare(const struct testcase_t *testcase)
+{
+ void *env = NULL;
+ int outcome;
+ if (testcase->setup) {
+ env = testcase->setup->setup_fn(testcase);
+ if (!env)
+ return FAIL;
+ else if (env == (void*)TT_SKIP)
+ return SKIP;
+ }
+
+ cur_test_outcome = OK;
+ testcase->fn(env);
+ outcome = cur_test_outcome;
+
+ if (testcase->setup) {
+ if (testcase->setup->cleanup_fn(testcase, env) == 0)
+ outcome = FAIL;
+ }
+
+ return outcome;
+}
+
+#define MAGIC_EXITCODE 42
+
+static enum outcome
+_testcase_run_forked(const struct testgroup_t *group,
+ const struct testcase_t *testcase)
+{
+#ifdef WIN32
+ /* Fork? On Win32? How primitive! We'll do what the smart kids do:
+ we'll invoke our own exe (whose name we recall from the command
+ line) with a command line that tells it to run just the test we
+ want, and this time without forking.
+
+ (No, threads aren't an option. The whole point of forking is to
+ share no state between tests.)
+ */
+ int ok;
+ char buffer[LONGEST_TEST_NAME+256];
+ STARTUPINFOA si;
+ PROCESS_INFORMATION info;
+ DWORD exitcode;
+
+ if (!in_tinytest_main) {
+ printf("\nERROR. On Windows, _testcase_run_forked must be"
+ " called from within tinytest_main.\n");
+ abort();
+ }
+ if (opt_verbosity>0)
+ printf("[forking] ");
+
+ snprintf(buffer, sizeof(buffer), "%s --RUNNING-FORKED %s %s%s",
+ commandname, verbosity_flag, group->prefix, testcase->name);
+
+ memset(&si, 0, sizeof(si));
+ memset(&info, 0, sizeof(info));
+ si.cb = sizeof(si);
+
+ ok = CreateProcessA(commandname, buffer, NULL, NULL, 0,
+ 0, NULL, NULL, &si, &info);
+ if (!ok) {
+ printf("CreateProcess failed!\n");
+ return 0;
+ }
+ WaitForSingleObject(info.hProcess, INFINITE);
+ GetExitCodeProcess(info.hProcess, &exitcode);
+ CloseHandle(info.hProcess);
+ CloseHandle(info.hThread);
+ if (exitcode == 0)
+ return OK;
+ else if (exitcode == MAGIC_EXITCODE)
+ return SKIP;
+ else
+ return FAIL;
+#else
+ int outcome_pipe[2];
+ pid_t pid;
+ (void)group;
+
+ if (pipe(outcome_pipe))
+ perror("opening pipe");
+
+ if (opt_verbosity>0)
+ printf("[forking] ");
+ pid = fork();
+ if (!pid) {
+ /* child. */
+ int test_r, write_r;
+ char b[1];
+ close(outcome_pipe[0]);
+ test_r = _testcase_run_bare(testcase);
+ assert(0<=(int)test_r && (int)test_r<=2);
+ b[0] = "NYS"[test_r];
+ write_r = (int)write(outcome_pipe[1], b, 1);
+ if (write_r != 1) {
+ perror("write outcome to pipe");
+ exit(1);
+ }
+ exit(0);
+ } else {
+ /* parent */
+ int status, r;
+ char b[1];
+ /* Close this now, so that if the other side closes it,
+ * our read fails. */
+ close(outcome_pipe[1]);
+ r = (int)read(outcome_pipe[0], b, 1);
+ if (r == 0) {
+ printf("[Lost connection!] ");
+ return 0;
+ } else if (r != 1) {
+ perror("read outcome from pipe");
+ }
+ waitpid(pid, &status, 0);
+ close(outcome_pipe[0]);
+ return b[0]=='Y' ? OK : (b[0]=='S' ? SKIP : FAIL);
+ }
+#endif
+}
+
+int
+testcase_run_one(const struct testgroup_t *group,
+ const struct testcase_t *testcase)
+{
+ enum outcome outcome;
+
+ if (testcase->flags & TT_SKIP) {
+ if (opt_verbosity>0)
+ printf("%s%s: SKIPPED\n",
+ group->prefix, testcase->name);
+ ++n_skipped;
+ return SKIP;
+ }
+
+ if (opt_verbosity>0 && !opt_forked) {
+ printf("%s%s: ", group->prefix, testcase->name);
+ } else {
+ if (opt_verbosity==0) printf(".");
+ cur_test_prefix = group->prefix;
+ cur_test_name = testcase->name;
+ }
+
+ if ((testcase->flags & TT_FORK) && !(opt_forked||opt_nofork)) {
+ outcome = _testcase_run_forked(group, testcase);
+ } else {
+ outcome = _testcase_run_bare(testcase);
+ }
+
+ if (outcome == OK) {
+ ++n_ok;
+ if (opt_verbosity>0 && !opt_forked)
+ puts(opt_verbosity==1?"OK":"");
+ } else if (outcome == SKIP) {
+ ++n_skipped;
+ if (opt_verbosity>0 && !opt_forked)
+ puts("SKIPPED");
+ } else {
+ ++n_bad;
+ if (!opt_forked)
+ printf("\n [%s FAILED]\n", testcase->name);
+ }
+
+ if (opt_forked) {
+ exit(outcome==OK ? 0 : (outcome==SKIP?MAGIC_EXITCODE : 1));
+ } else {
+ return (int)outcome;
+ }
+}
+
+int
+_tinytest_set_flag(struct testgroup_t *groups, const char *arg, unsigned long flag)
+{
+ int i, j;
+ size_t length = LONGEST_TEST_NAME;
+ char fullname[LONGEST_TEST_NAME];
+ int found=0;
+ if (strstr(arg, ".."))
+ length = strstr(arg,"..")-arg;
+ for (i=0; groups[i].prefix; ++i) {
+ for (j=0; groups[i].cases[j].name; ++j) {
+ snprintf(fullname, sizeof(fullname), "%s%s",
+ groups[i].prefix, groups[i].cases[j].name);
+ if (!flag) /* Hack! */
+ printf(" %s\n", fullname);
+ if (!strncmp(fullname, arg, length)) {
+ groups[i].cases[j].flags |= flag;
+ ++found;
+ }
+ }
+ }
+ return found;
+}
+
+static void
+usage(struct testgroup_t *groups, int list_groups)
+{
+ puts("Options are: [--verbose|--quiet|--terse] [--no-fork]");
+ puts(" Specify tests by name, or using a prefix ending with '..'");
+ puts(" To skip a test, list give its name prefixed with a colon.");
+ puts(" Use --list-tests for a list of tests.");
+ if (list_groups) {
+ puts("Known tests are:");
+ _tinytest_set_flag(groups, "..", 0);
+ }
+ exit(0);
+}
+
+int
+tinytest_main(int c, const char **v, struct testgroup_t *groups)
+{
+ int i, j, n=0;
+
+#ifdef WIN32
+ commandname = v[0];
+#endif
+ for (i=1; i<c; ++i) {
+ if (v[i][0] == '-') {
+ if (!strcmp(v[i], "--RUNNING-FORKED")) {
+ opt_forked = 1;
+ } else if (!strcmp(v[i], "--no-fork")) {
+ opt_nofork = 1;
+ } else if (!strcmp(v[i], "--quiet")) {
+ opt_verbosity = -1;
+ verbosity_flag = "--quiet";
+ } else if (!strcmp(v[i], "--verbose")) {
+ opt_verbosity = 2;
+ verbosity_flag = "--verbose";
+ } else if (!strcmp(v[i], "--terse")) {
+ opt_verbosity = 0;
+ verbosity_flag = "--terse";
+ } else if (!strcmp(v[i], "--help")) {
+ usage(groups, 0);
+ } else if (!strcmp(v[i], "--list-tests")) {
+ usage(groups, 1);
+ } else {
+ printf("Unknown option %s. Try --help\n",v[i]);
+ return -1;
+ }
+ } else {
+ const char *test = v[i];
+ int flag = _TT_ENABLED;
+ if (test[0] == ':') {
+ ++test;
+ flag = TT_SKIP;
+ } else {
+ ++n;
+ }
+ if (!_tinytest_set_flag(groups, test, flag)) {
+ printf("No such test as %s!\n", v[i]);
+ return -1;
+ }
+ }
+ }
+ if (!n)
+ _tinytest_set_flag(groups, "..", _TT_ENABLED);
+
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ ++in_tinytest_main;
+ for (i=0; groups[i].prefix; ++i)
+ for (j=0; groups[i].cases[j].name; ++j)
+ if (groups[i].cases[j].flags & _TT_ENABLED)
+ testcase_run_one(&groups[i],
+ &groups[i].cases[j]);
+
+ --in_tinytest_main;
+
+ if (opt_verbosity==0)
+ puts("");
+
+ if (n_bad)
+ printf("%d/%d TESTS FAILED. (%d skipped)\n", n_bad,
+ n_bad+n_ok,n_skipped);
+ else if (opt_verbosity >= 1)
+ printf("%d tests ok. (%d skipped)\n", n_ok, n_skipped);
+
+ return (n_bad == 0) ? 0 : 1;
+}
+
+int
+_tinytest_get_verbosity(void)
+{
+ return opt_verbosity;
+}
+
+void
+_tinytest_set_test_failed(void)
+{
+ if (opt_verbosity <= 0 && cur_test_name) {
+ if (opt_verbosity==0) puts("");
+ printf("%s%s: ", cur_test_prefix, cur_test_name);
+ cur_test_name = NULL;
+ }
+ cur_test_outcome = 0;
+}
+
+void
+_tinytest_set_test_skipped(void)
+{
+ if (cur_test_outcome==OK)
+ cur_test_outcome = SKIP;
+}
+
diff --git a/src/test/tinytest.h b/src/test/tinytest.h
new file mode 100644
index 0000000000..cbe28b7f51
--- /dev/null
+++ b/src/test/tinytest.h
@@ -0,0 +1,87 @@
+/* tinytest.h -- Copyright 2009-2010 Nick Mathewson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _TINYTEST_H
+#define _TINYTEST_H
+
+/** Flag for a test that needs to run in a subprocess. */
+#define TT_FORK (1<<0)
+/** Runtime flag for a test we've decided to skip. */
+#define TT_SKIP (1<<1)
+/** Internal runtime flag for a test we've decided to run. */
+#define _TT_ENABLED (1<<2)
+/** If you add your own flags, make them start at this point. */
+#define TT_FIRST_USER_FLAG (1<<3)
+
+typedef void (*testcase_fn)(void *);
+
+struct testcase_t;
+
+/** Functions to initialize/teardown a structure for a testcase. */
+struct testcase_setup_t {
+ /** Return a new structure for use by a given testcase. */
+ void *(*setup_fn)(const struct testcase_t *);
+ /** Clean/free a structure from setup_fn. Return 1 if ok, 0 on err. */
+ int (*cleanup_fn)(const struct testcase_t *, void *);
+};
+
+/** A single test-case that you can run. */
+struct testcase_t {
+ const char *name; /**< An identifier for this case. */
+ testcase_fn fn; /**< The function to run to implement this case. */
+ unsigned long flags; /**< Bitfield of TT_* flags. */
+ const struct testcase_setup_t *setup; /**< Optional setup/cleanup fns*/
+ void *setup_data; /**< Extra data usable by setup function */
+};
+#define END_OF_TESTCASES { NULL, NULL, 0, NULL, NULL }
+
+/** A group of tests that are selectable together. */
+struct testgroup_t {
+ const char *prefix; /**< Prefix to prepend to testnames. */
+ struct testcase_t *cases; /** Array, ending with END_OF_TESTCASES */
+};
+#define END_OF_GROUPS { NULL, NULL}
+
+/** Implementation: called from a test to indicate failure, before logging. */
+void _tinytest_set_test_failed(void);
+/** Implementation: called from a test to indicate that we're skipping. */
+void _tinytest_set_test_skipped(void);
+/** Implementation: return 0 for quiet, 1 for normal, 2 for loud. */
+int _tinytest_get_verbosity(void);
+/** Implementation: Set a flag on tests matching a name; returns number
+ * of tests that matched. */
+int _tinytest_set_flag(struct testgroup_t *, const char *, unsigned long);
+
+/** Set all tests in 'groups' matching the name 'named' to be skipped. */
+#define tinytest_skip(groups, named) \
+ _tinytest_set_flag(groups, named, TT_SKIP)
+
+/** Run a single testcase in a single group. */
+int testcase_run_one(const struct testgroup_t *,const struct testcase_t *);
+/** Run a set of testcases from an END_OF_GROUPS-terminated array of groups,
+ as selected from the command line. */
+int tinytest_main(int argc, const char **argv, struct testgroup_t *groups);
+
+#endif
diff --git a/src/test/tinytest_demo.c b/src/test/tinytest_demo.c
new file mode 100644
index 0000000000..bd33cc37fa
--- /dev/null
+++ b/src/test/tinytest_demo.c
@@ -0,0 +1,215 @@
+/* tinytest_demo.c -- Copyright 2009 Nick Mathewson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/* Welcome to the example file for tinytest! I'll show you how to set up
+ * some simple and not-so-simple testcases. */
+
+/* Make sure you include these headers. */
+#include "tinytest.h"
+#include "tinytest_macros.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+/* ============================================================ */
+
+/* First, let's see if strcmp is working. (All your test cases should be
+ * functions declared to take a single void * as) an argument. */
+void
+test_strcmp(void *data)
+{
+ (void)data; /* This testcase takes no data. */
+
+ /* Let's make sure the empty string is equal to itself */
+ if (strcmp("","")) {
+ /* This macro tells tinytest to stop the current test
+ * and go straight to the "end" label. */
+ tt_abort_msg("The empty string was not equal to itself");
+ }
+
+ /* Pretty often, calling tt_abort_msg to indicate failure is more
+ heavy-weight than you want. Instead, just say: */
+ tt_assert(strcmp("testcase", "testcase") == 0);
+
+ /* Occasionally, you don't want to stop the current testcase just
+ because a single assertion has failed. In that case, use
+ tt_want: */
+ tt_want(strcmp("tinytest", "testcase") > 0);
+
+ /* You can use the tt_*_op family of macros to compare values and to
+ fail unless they have the relationship you want. They produce
+ more useful output than tt_assert, since they display the actual
+ values of the failing things.
+
+ Fail unless strcmp("abc, "abc") == 0 */
+ tt_int_op(strcmp("abc", "abc"), ==, 0);
+
+ /* Fail unless strcmp("abc, "abcd") is less than 0 */
+ tt_int_op(strcmp("abc", "abcd"), < , 0);
+
+ /* Incidentally, there's a test_str_op that uses strcmp internally. */
+ tt_str_op("abc", <, "abcd");
+
+
+ /* Every test-case function needs to finish with an "end:"
+ label and (optionally) code to clean up local variables. */
+ end:
+ ;
+}
+
+/* ============================================================ */
+
+/* Now let's mess with setup and teardown functions! These are handy if
+ you have a bunch of tests that all need a similar environment, and you
+ want to reconstruct that environment freshly for each one. */
+
+/* First you declare a type to hold the environment info, and functions to
+ set it up and tear it down. */
+struct data_buffer {
+ /* We're just going to have couple of character buffer. Using
+ setup/teardown functions is probably overkill for this case.
+
+ You could also do file descriptors, complicated handles, temporary
+ files, etc. */
+ char buffer1[512];
+ char buffer2[512];
+};
+/* The setup function needs to take a const struct testcase_t and return
+ void* */
+void *
+setup_data_buffer(const struct testcase_t *testcase)
+{
+ struct data_buffer *db = malloc(sizeof(struct data_buffer));
+
+ /* If you had a complicated set of setup rules, you might behave
+ differently here depending on testcase->flags or
+ testcase->setup_data or even or testcase->name. */
+
+ /* Returning a NULL here would mean that we couldn't set up for this
+ test, so we don't need to test db for null. */
+ return db;
+}
+/* The clean function deallocates storage carefully and returns true on
+ success. */
+int
+clean_data_buffer(const struct testcase_t *testcase, void *ptr)
+{
+ struct data_buffer *db = ptr;
+
+ if (db) {
+ free(db);
+ return 1;
+ }
+ return 0;
+}
+/* Finally, declare a testcase_setup_t with these functions. */
+struct testcase_setup_t data_buffer_setup = {
+ setup_data_buffer, clean_data_buffer
+};
+
+
+/* Now let's write our test. */
+void
+test_memcpy(void *ptr)
+{
+ /* This time, we use the argument. */
+ struct data_buffer *db = ptr;
+
+ /* We'll also introduce a local variable that might need cleaning up. */
+ char *mem = NULL;
+
+ /* Let's make sure that memcpy does what we'd like. */
+ strcpy(db->buffer1, "String 0");
+ memcpy(db->buffer2, db->buffer1, sizeof(db->buffer1));
+ tt_str_op(db->buffer1, ==, db->buffer2);
+
+ /* Now we've allocated memory that's referenced by a local variable.
+ The end block of the function will clean it up. */
+ mem = strdup("Hello world.");
+ tt_assert(mem);
+
+ /* Another rather trivial test. */
+ tt_str_op(db->buffer1, !=, mem);
+
+ end:
+ /* This time our end block has something to do. */
+ if (mem)
+ free(mem);
+}
+
+/* ============================================================ */
+
+/* Now we need to make sure that our tests get invoked. First, you take
+ a bunch of related tests and put them into an array of struct testcase_t.
+*/
+
+struct testcase_t demo_tests[] = {
+ /* Here's a really simple test: it has a name you can refer to it
+ with, and a function to invoke it. */
+ { "strcmp", test_strcmp, },
+
+ /* The second test has a flag, "TT_FORK", to make it run in a
+ subprocess, and a pointer to the testcase_setup_t that configures
+ its environment. */
+ { "memcpy", test_memcpy, TT_FORK, &data_buffer_setup },
+
+ /* The array has to end with END_OF_TESTCASES. */
+ END_OF_TESTCASES
+};
+
+/* Next, we make an array of testgroups. This is mandatory. Unlike more
+ heavy-duty testing frameworks, groups can't nest. */
+struct testgroup_t groups[] = {
+
+ /* Every group has a 'prefix', and an array of tests. That's it. */
+ { "demo/", demo_tests },
+
+ END_OF_GROUPS
+};
+
+
+int
+main(int c, const char **v)
+{
+ /* Finally, just call tinytest_main(). It lets you specify verbose
+ or quiet output with --verbose and --quiet. You can list
+ specific tests:
+
+ tinytest-demo demo/memcpy
+
+ or use a ..-wildcard to select multiple tests with a common
+ prefix:
+
+ tinytest-demo demo/..
+
+ If you list no tests, you get them all by default, so that
+ "tinytest-demo" and "tinytest-demo .." mean the same thing.
+
+ */
+ return tinytest_main(c, v, groups);
+}
diff --git a/src/test/tinytest_macros.h b/src/test/tinytest_macros.h
new file mode 100644
index 0000000000..a7fa64a824
--- /dev/null
+++ b/src/test/tinytest_macros.h
@@ -0,0 +1,167 @@
+/* tinytest_macros.h -- Copyright 2009-2010 Nick Mathewson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _TINYTEST_MACROS_H
+#define _TINYTEST_MACROS_H
+
+/* Helpers for defining statement-like macros */
+#define TT_STMT_BEGIN do {
+#define TT_STMT_END } while (0)
+
+/* Redefine this if your test functions want to abort with something besides
+ * "goto end;" */
+#ifndef TT_EXIT_TEST_FUNCTION
+#define TT_EXIT_TEST_FUNCTION TT_STMT_BEGIN goto end; TT_STMT_END
+#endif
+
+/* Redefine this if you want to note success/failure in some different way. */
+#ifndef TT_DECLARE
+#define TT_DECLARE(prefix, args) \
+ TT_STMT_BEGIN \
+ printf("\n %s %s:%d: ",prefix,__FILE__,__LINE__); \
+ printf args ; \
+ TT_STMT_END
+#endif
+
+/* Announce a failure. Args are parenthesized printf args. */
+#define TT_GRIPE(args) TT_DECLARE("FAIL", args)
+
+/* Announce a non-failure if we're verbose. */
+#define TT_BLATHER(args) \
+ TT_STMT_BEGIN \
+ if (_tinytest_get_verbosity()>1) TT_DECLARE(" OK", args); \
+ TT_STMT_END
+
+#define TT_DIE(args) \
+ TT_STMT_BEGIN \
+ _tinytest_set_test_failed(); \
+ TT_GRIPE(args); \
+ TT_EXIT_TEST_FUNCTION; \
+ TT_STMT_END
+
+#define TT_FAIL(args) \
+ TT_STMT_BEGIN \
+ _tinytest_set_test_failed(); \
+ TT_GRIPE(args); \
+ TT_STMT_END
+
+/* Fail and abort the current test for the reason in msg */
+#define tt_abort_printf(msg) TT_DIE(msg)
+#define tt_abort_perror(op) TT_DIE(("%s: %s [%d]",(op),strerror(errno), errno))
+#define tt_abort_msg(msg) TT_DIE(("%s", msg))
+#define tt_abort() TT_DIE(("%s", "(Failed.)"))
+
+/* Fail but do not abort the current test for the reason in msg. */
+#define tt_fail_printf(msg) TT_FAIL(msg)
+#define tt_fail_perror(op) TT_FAIL(("%s: %s [%d]",(op),strerror(errno), errno))
+#define tt_fail_msg(msg) TT_FAIL(("%s", msg))
+#define tt_fail() TT_FAIL(("%s", "(Failed.)"))
+
+/* End the current test, and indicate we are skipping it. */
+#define tt_skip() \
+ TT_STMT_BEGIN \
+ _tinytest_set_test_skipped(); \
+ TT_EXIT_TEST_FUNCTION; \
+ TT_STMT_END
+
+#define _tt_want(b, msg, fail) \
+ TT_STMT_BEGIN \
+ if (!(b)) { \
+ _tinytest_set_test_failed(); \
+ TT_GRIPE((msg)); \
+ fail; \
+ } else { \
+ TT_BLATHER((msg)); \
+ } \
+ TT_STMT_END
+
+/* Assert b, but do not stop the test if b fails. Log msg on failure. */
+#define tt_want_msg(b, msg) \
+ _tt_want(b, msg, );
+
+/* Assert b and stop the test if b fails. Log msg on failure. */
+#define tt_assert_msg(b, msg) \
+ _tt_want(b, msg, TT_EXIT_TEST_FUNCTION);
+
+/* Assert b, but do not stop the test if b fails. */
+#define tt_want(b) tt_want_msg( (b), "want("#b")")
+/* Assert b, and stop the test if b fails. */
+#define tt_assert(b) tt_assert_msg((b), "assert("#b")")
+
+#define tt_assert_test_fmt_type(a,b,str_test,type,test,printf_type,printf_fmt, \
+ setup_block,cleanup_block) \
+ TT_STMT_BEGIN \
+ type _val1 = (type)(a); \
+ type _val2 = (type)(b); \
+ int _tt_status = (test); \
+ if (!_tt_status || _tinytest_get_verbosity()>1) { \
+ printf_type _print; \
+ printf_type _print1; \
+ printf_type _print2; \
+ type _value = _val1; \
+ setup_block; \
+ _print1 = _print; \
+ _value = _val2; \
+ setup_block; \
+ _print2 = _print; \
+ TT_DECLARE(_tt_status?" OK":"FAIL", \
+ ("assert(%s): "printf_fmt" vs "printf_fmt, \
+ str_test, _print1, _print2)); \
+ _print = _print1; \
+ cleanup_block; \
+ _print = _print2; \
+ cleanup_block; \
+ if (!_tt_status) { \
+ _tinytest_set_test_failed(); \
+ TT_EXIT_TEST_FUNCTION; \
+ } \
+ } \
+ TT_STMT_END
+
+#define tt_assert_test_type(a,b,str_test,type,test,fmt) \
+ tt_assert_test_fmt_type(a,b,str_test,type,test,type,fmt, \
+ {_print=_value;},{})
+
+/* Helper: assert that a op b, when cast to type. Format the values with
+ * printf format fmt on failure. */
+#define tt_assert_op_type(a,op,b,type,fmt) \
+ tt_assert_test_type(a,b,#a" "#op" "#b,type,(_val1 op _val2),fmt)
+
+#define tt_int_op(a,op,b) \
+ tt_assert_test_type(a,b,#a" "#op" "#b,long,(_val1 op _val2),"%ld")
+
+#define tt_uint_op(a,op,b) \
+ tt_assert_test_type(a,b,#a" "#op" "#b,unsigned long, \
+ (_val1 op _val2),"%lu")
+
+#define tt_ptr_op(a,op,b) \
+ tt_assert_test_type(a,b,#a" "#op" "#b,void*, \
+ (_val1 op _val2),"%p")
+
+#define tt_str_op(a,op,b) \
+ tt_assert_test_type(a,b,#a" "#op" "#b,const char *, \
+ (strcmp(_val1,_val2) op 0),"<%s>")
+
+#endif
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
index 41786e4378..1bb5076849 100644
--- a/src/tools/Makefile.am
+++ b/src/tools/Makefile.am
@@ -3,16 +3,16 @@ noinst_PROGRAMS = tor-checkkey
tor_resolve_SOURCES = tor-resolve.c
tor_resolve_LDFLAGS = @TOR_LDFLAGS_libevent@
-tor_resolve_LDADD = ../common/libor.a @TOR_LIBEVENT_LIBS@ @TOR_LIB_WS32@
+tor_resolve_LDADD = ../common/libor.a -lm @TOR_LIBEVENT_LIBS@ @TOR_LIB_WS32@
tor_gencert_SOURCES = tor-gencert.c
tor_gencert_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
@TOR_LDFLAGS_libevent@
tor_gencert_LDADD = ../common/libor.a ../common/libor-crypto.a \
- -lz @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@
+ -lm @TOR_ZLIB_LIBS@ @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@
tor_checkkey_SOURCES = tor-checkkey.c
tor_checkkey_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
@TOR_LDFLAGS_libevent@
tor_checkkey_LDADD = ../common/libor.a ../common/libor-crypto.a \
- -lz @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@
+ -lm @TOR_ZLIB_LIBS@ @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@
diff --git a/src/tools/tor-checkkey.c b/src/tools/tor-checkkey.c
index b29b52d8db..94c8cbd44c 100644
--- a/src/tools/tor-checkkey.c
+++ b/src/tools/tor-checkkey.c
@@ -6,19 +6,21 @@
#include <stdio.h>
#include <stdlib.h>
#include "crypto.h"
-#include "log.h"
-#include "util.h"
+#include "torlog.h"
+#include "../common/util.h"
#include "compat.h"
#include <openssl/bn.h>
#include <openssl/rsa.h>
-int main(int c, char **v)
+int
+main(int c, char **v)
{
crypto_pk_env_t *env;
char *str;
RSA *rsa;
int wantdigest=0;
int fname_idx;
+ char *fname=NULL;
init_logging();
if (c < 2) {
@@ -29,7 +31,7 @@ int main(int c, char **v)
return 1;
}
- if (crypto_global_init(0)) {
+ if (crypto_global_init(0, NULL, NULL)) {
fprintf(stderr, "Couldn't initialize crypto library.\n");
return 1;
}
@@ -46,7 +48,9 @@ int main(int c, char **v)
fname_idx = 1;
}
- str = read_file_to_str(v[fname_idx], 0, NULL);
+ fname = expand_filename(v[fname_idx]);
+ str = read_file_to_str(fname, 0, NULL);
+ tor_free(fname);
if (!str) {
fprintf(stderr, "Couldn't read %s\n", v[fname_idx]);
return 1;
diff --git a/src/tools/tor-gencert.c b/src/tools/tor-gencert.c
index 3f449dc66e..bc99c24bd7 100644
--- a/src/tools/tor-gencert.c
+++ b/src/tools/tor-gencert.c
@@ -13,6 +13,7 @@
#include <openssl/evp.h>
#include <openssl/pem.h>
+#include <openssl/rsa.h>
#include <openssl/objects.h>
#include <openssl/obj_mac.h>
#include <openssl/err.h>
@@ -27,8 +28,8 @@
#define CRYPTO_PRIVATE
#include "compat.h"
-#include "util.h"
-#include "log.h"
+#include "../common/util.h"
+#include "../common/torlog.h"
#include "crypto.h"
#include "address.h"
@@ -63,7 +64,6 @@ show_help(void)
"[-c certificate_file]\n"
" [-m lifetime_in_months] [-a address:port] "
"[--passphrase-fd <fd>]\n");
-
}
/* XXXX copied from crypto.c */
@@ -218,6 +218,20 @@ parse_commandline(int argc, char **argv)
return 0;
}
+static RSA *
+generate_key(int bits)
+{
+ RSA *rsa = NULL;
+ crypto_pk_env_t *env = crypto_new_pk_env();
+ if (crypto_pk_generate_key_with_bits(env,bits)<0)
+ goto done;
+ rsa = _crypto_pk_env_get_rsa(env);
+ rsa = RSAPrivateKey_dup(rsa);
+ done:
+ crypto_free_pk_env(env);
+ return rsa;
+}
+
/** Try to read the identity key from <b>identity_key_file</b>. If no such
* file exists and create_identity_key is set, make a new identity key and
* store it. Return 0 on success, nonzero on failure.
@@ -238,7 +252,7 @@ load_identity_key(void)
}
log_notice(LD_GENERAL, "Generating %d-bit RSA identity key.",
IDENTITY_KEY_BITS);
- if (!(key = RSA_generate_key(IDENTITY_KEY_BITS, 65537, NULL, NULL))) {
+ if (!(key = generate_key(IDENTITY_KEY_BITS))) {
log_err(LD_GENERAL, "Couldn't generate identity key.");
crypto_log_errors(LOG_ERR, "Generating identity key");
return 1;
@@ -323,7 +337,7 @@ generate_signing_key(void)
RSA *key;
log_notice(LD_GENERAL, "Generating %d-bit RSA signing key.",
SIGNING_KEY_BITS);
- if (!(key = RSA_generate_key(SIGNING_KEY_BITS, 65537, NULL, NULL))) {
+ if (!(key = generate_key(SIGNING_KEY_BITS))) {
log_err(LD_GENERAL, "Couldn't generate signing key.");
crypto_log_errors(LOG_ERR, "Generating signing key");
return 1;
@@ -393,7 +407,6 @@ get_fingerprint(EVP_PKEY *pkey, char *out)
return r;
}
-
/** Set <b>out</b> to the hex-encoded fingerprint of <b>pkey</b>. */
static int
get_digest(EVP_PKEY *pkey, char *out)
@@ -487,7 +500,6 @@ generate_certificate(void)
return 0;
}
-
/** Entry point to tor-gencert */
int
main(int argc, char **argv)
@@ -496,7 +508,7 @@ main(int argc, char **argv)
init_logging();
/* Don't bother using acceleration. */
- if (crypto_global_init(0)) {
+ if (crypto_global_init(0, NULL, NULL)) {
fprintf(stderr, "Couldn't initialize crypto library.\n");
return 1;
}
diff --git a/src/tools/tor-resolve.c b/src/tools/tor-resolve.c
index 24c8a6406a..f5b0becaff 100644
--- a/src/tools/tor-resolve.c
+++ b/src/tools/tor-resolve.c
@@ -6,9 +6,9 @@
#include "orconfig.h"
#include "compat.h"
-#include "util.h"
+#include "../common/util.h"
#include "address.h"
-#include "log.h"
+#include "../common/torlog.h"
#include <stdio.h>
#include <stdlib.h>
@@ -148,7 +148,7 @@ parse_socks4a_resolve_response(const char *hostname,
static const char *
socks5_reason_to_string(char reason)
{
- switch(reason) {
+ switch (reason) {
case SOCKS5_SUCCEEDED:
return "succeeded";
case SOCKS5_GENERAL_ERROR:
@@ -251,7 +251,7 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
}
if (parse_socks4a_resolve_response(hostname,
reply_buf, RESPONSE_LEN_4,
- result_addr)<0){
+ result_addr)<0) {
return -1;
}
} else {
diff --git a/src/win32/orconfig.h b/src/win32/orconfig.h
index 65804fe19d..b3cd1db50b 100644
--- a/src/win32/orconfig.h
+++ b/src/win32/orconfig.h
@@ -88,11 +88,18 @@
#define HAVE_STRING_H
/* Define to 1 if you have the `strlcat' function. */
+#if defined (WINCE)
+#define HAVE_STRLCAT
+#else
#undef HAVE_STRLCAT
+#endif
/* Define to 1 if you have the `strlcpy' function. */
+#if defined (WINCE)
+#define HAVE_STRLCPY
+#else
#undef HAVE_STRLCPY
-
+#endif
/* Define to 1 if you have the `strptime' function. */
#undef HAVE_STRPTIME
@@ -226,6 +233,5 @@
#define USING_TWOS_COMPLEMENT
/* Version number of package */
-#define VERSION "0.2.1.25"
-
+#define VERSION "0.2.2.19-alpha"