aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/compat.c126
-rw-r--r--src/common/compat.h5
-rwxr-xr-xsrc/common/gen_linux_syscalls.pl37
-rwxr-xr-xsrc/common/gen_server_ciphers.py115
-rw-r--r--src/common/get_mozilla_ciphers.py210
-rw-r--r--src/common/linux_syscalls.inc2
-rw-r--r--src/common/log.c21
-rw-r--r--src/common/sandbox.c10
-rw-r--r--src/common/sandbox.h2
-rw-r--r--src/common/torlog.h5
-rw-r--r--src/common/util.c81
-rw-r--r--src/ext/README7
-rw-r--r--src/ext/ht.h1
-rw-r--r--src/ext/tinytest_macros.h10
-rw-r--r--src/or/buffers.c31
-rw-r--r--src/or/buffers.h29
-rw-r--r--src/or/circuitbuild.c4
-rw-r--r--src/or/circuitbuild.h4
-rw-r--r--src/or/circuitlist.c29
-rw-r--r--src/or/circuituse.c66
-rw-r--r--src/or/circuituse.h1
-rw-r--r--src/or/config.c73
-rw-r--r--src/or/connection.c4
-rwxr-xr-xsrc/or/control.c2
-rw-r--r--src/or/cpuworker.c7
-rw-r--r--src/or/directory.c40
-rw-r--r--src/or/dirserv.c16
-rw-r--r--src/or/dirvote.c9
-rw-r--r--src/or/dirvote.h6
-rw-r--r--src/or/dns.c2
-rw-r--r--src/or/entrynodes.c2
-rw-r--r--src/or/main.c30
-rw-r--r--src/or/microdesc.c18
-rw-r--r--src/or/networkstatus.c9
-rw-r--r--src/or/networkstatus.h4
-rw-r--r--src/or/nodelist.c4
-rw-r--r--src/or/onion.c12
-rw-r--r--src/or/onion_fast.c1
-rw-r--r--src/or/onion_ntor.c9
-rw-r--r--src/or/onion_tap.c4
-rw-r--r--src/or/or.h19
-rw-r--r--src/or/rephist.c128
-rw-r--r--src/or/rephist.h1
-rwxr-xr-xsrc/or/router.c3
-rw-r--r--src/or/routerlist.c17
-rw-r--r--src/or/routerparse.c2
-rw-r--r--src/or/statefile.c29
-rw-r--r--src/or/statefile.h2
-rw-r--r--src/or/status.c3
-rw-r--r--src/test/bench.c23
-rw-r--r--src/test/test.c24
-rw-r--r--src/test/test.h23
-rw-r--r--src/test/test_buffers.c125
-rw-r--r--src/test/test_cell_formats.c44
-rw-r--r--src/test/test_circuitlist.c79
-rw-r--r--src/test/test_config.c21
-rw-r--r--src/test/test_controller_events.c33
-rw-r--r--src/test/test_crypto.c3
-rw-r--r--src/test/test_dir.c25
-rw-r--r--src/test/test_extorport.c5
-rw-r--r--src/test/test_microdesc.c108
-rw-r--r--src/test/test_oom.c11
-rw-r--r--src/test/test_policy.c2
-rw-r--r--src/test/test_pt.c17
-rw-r--r--src/test/test_routerkeys.c1
-rw-r--r--src/test/test_status.c19
-rw-r--r--src/test/test_util.c51
67 files changed, 1097 insertions, 769 deletions
diff --git a/src/common/compat.c b/src/common/compat.c
index 1ba264a0c..111070cc1 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -1702,6 +1702,106 @@ log_credential_status(void)
}
#endif
+#ifndef _WIN32
+/** Cached struct from the last getpwname() call we did successfully. */
+static struct passwd *passwd_cached = NULL;
+
+/** Helper: copy a struct passwd object.
+ *
+ * We only copy the fields pw_uid, pw_gid, pw_name, pw_dir. Tor doesn't use
+ * any others, and I don't want to run into incompatibilities.
+ */
+static struct passwd *
+tor_passwd_dup(const struct passwd *pw)
+{
+ struct passwd *new_pw = tor_malloc_zero(sizeof(struct passwd));
+ if (pw->pw_name)
+ new_pw->pw_name = tor_strdup(pw->pw_name);
+ if (pw->pw_dir)
+ new_pw->pw_dir = tor_strdup(pw->pw_dir);
+ new_pw->pw_uid = pw->pw_uid;
+ new_pw->pw_gid = pw->pw_gid;
+
+ return new_pw;
+}
+
+/** Helper: free one of our cached 'struct passwd' values. */
+static void
+tor_passwd_free(struct passwd *pw)
+{
+ if (!pw)
+ return;
+
+ tor_free(pw->pw_name);
+ tor_free(pw->pw_dir);
+ tor_free(pw);
+}
+
+/** Wrapper around getpwnam() that caches result. Used so that we don't need
+ * to give the sandbox access to /etc/passwd.
+ *
+ * The following fields alone will definitely be copied in the output: pw_uid,
+ * pw_gid, pw_name, pw_dir. Other fields are not present in cached values.
+ *
+ * When called with a NULL argument, this function clears storage associated
+ * with static variables it uses.
+ **/
+const struct passwd *
+tor_getpwnam(const char *username)
+{
+ struct passwd *pw;
+
+ if (username == NULL) {
+ tor_passwd_free(passwd_cached);
+ passwd_cached = NULL;
+ return NULL;
+ }
+
+ if ((pw = getpwnam(username))) {
+ tor_passwd_free(passwd_cached);
+ passwd_cached = tor_passwd_dup(pw);
+ log_notice(LD_GENERAL, "Caching new entry %s for %s",
+ passwd_cached->pw_name, username);
+ return pw;
+ }
+
+ /* Lookup failed */
+ if (! passwd_cached || ! passwd_cached->pw_name)
+ return NULL;
+
+ if (! strcmp(username, passwd_cached->pw_name))
+ return passwd_cached;
+
+ return NULL;
+}
+
+/** Wrapper around getpwnam() that can use cached result from
+ * tor_getpwnam(). Used so that we don't need to give the sandbox access to
+ * /etc/passwd.
+ *
+ * The following fields alone will definitely be copied in the output: pw_uid,
+ * pw_gid, pw_name, pw_dir. Other fields are not present in cached values.
+ */
+const struct passwd *
+tor_getpwuid(uid_t uid)
+{
+ struct passwd *pw;
+
+ if ((pw = getpwuid(uid))) {
+ return pw;
+ }
+
+ /* Lookup failed */
+ if (! passwd_cached)
+ return NULL;
+
+ if (uid == passwd_cached->pw_uid)
+ return passwd_cached;
+
+ return NULL;
+}
+#endif
+
/** Call setuid and setgid to run as <b>user</b> and switch to their
* primary group. Return 0 on success. On failure, log and return -1.
*/
@@ -1709,7 +1809,7 @@ int
switch_id(const char *user)
{
#ifndef _WIN32
- struct passwd *pw = NULL;
+ const struct passwd *pw = NULL;
uid_t old_uid;
gid_t old_gid;
static int have_already_switched_id = 0;
@@ -1730,7 +1830,7 @@ switch_id(const char *user)
old_gid = getgid();
/* Lookup the user and group information, if we have a problem, bail out. */
- pw = getpwnam(user);
+ pw = tor_getpwnam(user);
if (pw == NULL) {
log_warn(LD_CONFIG, "Error setting configured user: %s not found", user);
return -1;
@@ -1901,10 +2001,10 @@ tor_disable_debugger_attach(void)
char *
get_user_homedir(const char *username)
{
- struct passwd *pw;
+ const struct passwd *pw;
tor_assert(username);
- if (!(pw = getpwnam(username))) {
+ if (!(pw = tor_getpwnam(username))) {
log_err(LD_CONFIG,"User \"%s\" not found.", username);
return NULL;
}
@@ -2429,6 +2529,12 @@ tor_pthread_helper_fn(void *_data)
func(arg);
return NULL;
}
+/**
+ * A pthread attribute to make threads start detached.
+ */
+static pthread_attr_t attr_detached;
+/** True iff we've called tor_threads_init() */
+static int threads_initialized = 0;
#endif
/** Minimalist interface to run a void function in the background. On
@@ -2452,12 +2558,12 @@ spawn_func(void (*func)(void *), void *data)
#elif defined(USE_PTHREADS)
pthread_t thread;
tor_pthread_data_t *d;
+ if (PREDICT_UNLIKELY(!threads_initialized))
+ tor_threads_init();
d = tor_malloc(sizeof(tor_pthread_data_t));
d->data = data;
d->func = func;
- if (pthread_create(&thread,NULL,tor_pthread_helper_fn,d))
- return -1;
- if (pthread_detach(thread))
+ if (pthread_create(&thread,&attr_detached,tor_pthread_helper_fn,d))
return -1;
return 0;
#else
@@ -2814,8 +2920,6 @@ tor_get_thread_id(void)
* "reentrant" mutexes (i.e., once we can re-lock if we're already holding
* them.) */
static pthread_mutexattr_t attr_reentrant;
-/** True iff we've called tor_threads_init() */
-static int threads_initialized = 0;
/** Initialize <b>mutex</b> so it can be locked. Every mutex must be set
* up with tor_mutex_init() or tor_mutex_new(); not both. */
void
@@ -2959,6 +3063,8 @@ tor_threads_init(void)
if (!threads_initialized) {
pthread_mutexattr_init(&attr_reentrant);
pthread_mutexattr_settype(&attr_reentrant, PTHREAD_MUTEX_RECURSIVE);
+ tor_assert(0==pthread_attr_init(&attr_detached));
+ tor_assert(0==pthread_attr_setdetachstate(&attr_detached, 1));
threads_initialized = 1;
set_main_thread();
}
@@ -3447,6 +3553,6 @@ get_total_system_memory(size_t *mem_out)
*mem_out = mem_cached = (size_t) m;
- return -1;
+ return 0;
}
diff --git a/src/common/compat.h b/src/common/compat.h
index 314b1aa00..683c4d089 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -633,6 +633,11 @@ int switch_id(const char *user);
char *get_user_homedir(const char *username);
#endif
+#ifndef _WIN32
+const struct passwd *tor_getpwnam(const char *username);
+const struct passwd *tor_getpwuid(uid_t uid);
+#endif
+
int get_parent_directory(char *fname);
char *make_path_absolute(char *fname);
diff --git a/src/common/gen_linux_syscalls.pl b/src/common/gen_linux_syscalls.pl
deleted file mode 100755
index 3c64098a0..000000000
--- a/src/common/gen_linux_syscalls.pl
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/perl -w
-
-use strict;
-my %syscalls = ();
-
-while (<>) {
- if (/^#define (__NR_\w+) /) {
- $syscalls{$1} = 1;
- }
-}
-
-print <<EOL;
-/* Automatically generated with
- gen_sandbox_syscalls.pl /usr/include/asm/unistd*.h
- Do not edit.
- */
-static const struct {
- int syscall_num; const char *syscall_name;
-} SYSCALLS_BY_NUMBER[] = {
-EOL
-
-for my $k (sort keys %syscalls) {
- my $name = $k;
- $name =~ s/^__NR_//;
- print <<EOL;
-#ifdef $k
- { $k, "$name" },
-#endif
-EOL
-
-}
-
-print <<EOL
- {0, NULL}
-};
-
-EOL
diff --git a/src/common/gen_server_ciphers.py b/src/common/gen_server_ciphers.py
deleted file mode 100755
index 97ed9d046..000000000
--- a/src/common/gen_server_ciphers.py
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/usr/bin/python
-# Copyright 2014, The Tor Project, Inc
-# See LICENSE for licensing information
-
-# This script parses openssl headers to find ciphersuite names, determines
-# which ones we should be willing to use as a server, and sorts them according
-# to preference rules.
-#
-# Run it on all the files in your openssl include directory.
-
-import re
-import sys
-
-EPHEMERAL_INDICATORS = [ "_EDH_", "_DHE_", "_ECDHE_" ]
-BAD_STUFF = [ "_DES_40_", "MD5", "_RC4_", "_DES_64_",
- "_SEED_", "_CAMELLIA_", "_NULL" ]
-
-# these never get #ifdeffed.
-MANDATORY = [
- "TLS1_TXT_DHE_RSA_WITH_AES_256_SHA",
- "TLS1_TXT_DHE_RSA_WITH_AES_128_SHA",
- "SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA",
-]
-
-def find_ciphers(filename):
- with open(filename) as f:
- for line in f:
- m = re.search(r'(?:SSL3|TLS1)_TXT_\w+', line)
- if m:
- yield m.group(0)
-
-def usable_cipher(ciph):
- ephemeral = False
- for e in EPHEMERAL_INDICATORS:
- if e in ciph:
- ephemeral = True
- if not ephemeral:
- return False
-
- if "_RSA_" not in ciph:
- return False
-
- for b in BAD_STUFF:
- if b in ciph:
- return False
- return True
-
-# All fields we sort on, in order of priority.
-FIELDS = [ 'cipher', 'fwsec', 'mode', 'digest', 'bitlength' ]
-# Map from sorted fields to recognized value in descending order of goodness
-FIELD_VALS = { 'cipher' : [ 'AES', 'DES'],
- 'fwsec' : [ 'ECDHE', 'DHE' ],
- 'mode' : [ 'GCM', 'CBC' ],
- 'digest' : [ 'SHA384', 'SHA256', 'SHA' ],
- 'bitlength' : [ '256', '128', '192' ],
-}
-
-class Ciphersuite(object):
- def __init__(self, name, fwsec, cipher, bitlength, mode, digest):
- self.name = name
- self.fwsec = fwsec
- self.cipher = cipher
- self.bitlength = bitlength
- self.mode = mode
- self.digest = digest
-
- for f in FIELDS:
- assert(getattr(self, f) in FIELD_VALS[f])
-
- def sort_key(self):
- return tuple(FIELD_VALS[f].index(getattr(self,f)) for f in FIELDS)
-
-
-def parse_cipher(ciph):
- m = re.match('(?:TLS1|SSL3)_TXT_(EDH|DHE|ECDHE)_RSA(?:_WITH)?_(AES|DES)_(256|128|192)(|_CBC|_CBC3|_GCM)_(SHA|SHA256|SHA384)$', ciph)
-
- if not m:
- print "/* Couldn't parse %s ! */"%ciph
- return None
-
- fwsec, cipher, bits, mode, digest = m.groups()
- if fwsec == 'EDH':
- fwsec = 'DHE'
-
- if mode in [ '_CBC3', '_CBC', '' ]:
- mode = 'CBC'
- elif mode == '_GCM':
- mode = 'GCM'
-
- return Ciphersuite(ciph, fwsec, cipher, bits, mode, digest)
-
-ALL_CIPHERS = []
-
-for fname in sys.argv[1:]:
- ALL_CIPHERS += (parse_cipher(c)
- for c in find_ciphers(fname)
- if usable_cipher(c) )
-
-ALL_CIPHERS.sort(key=Ciphersuite.sort_key)
-
-for c in ALL_CIPHERS:
- if c is ALL_CIPHERS[-1]:
- colon = ';'
- else:
- colon = ' ":"'
-
- if c.name in MANDATORY:
- print " /* Required */"
- print ' %s%s'%(c.name,colon)
- else:
- print "#ifdef %s"%c.name
- print ' %s%s'%(c.name,colon)
- print "#endif"
-
-
diff --git a/src/common/get_mozilla_ciphers.py b/src/common/get_mozilla_ciphers.py
deleted file mode 100644
index 0636eb365..000000000
--- a/src/common/get_mozilla_ciphers.py
+++ /dev/null
@@ -1,210 +0,0 @@
-#!/usr/bin/python
-# coding=utf-8
-# Copyright 2011, The Tor Project, Inc
-# original version by Arturo Filastò
-# See LICENSE for licensing information
-
-# This script parses Firefox and OpenSSL sources, and uses this information
-# to generate a ciphers.inc file.
-#
-# It takes two arguments: the location of a firefox source directory, and the
-# location of an openssl source directory.
-
-import os
-import re
-import sys
-
-if len(sys.argv) != 3:
- print >>sys.stderr, "Syntax: get_mozilla_ciphers.py <firefox-source-dir> <openssl-source-dir>"
- sys.exit(1)
-
-ff_root = sys.argv[1]
-ossl_root = sys.argv[2]
-
-def ff(s):
- return os.path.join(ff_root, s)
-def ossl(s):
- return os.path.join(ossl_root, s)
-
-#####
-# Read the cpp file to understand what Ciphers map to what name :
-# Make "ciphers" a map from name used in the javascript to a cipher macro name
-fileA = open(ff('security/manager/ssl/src/nsNSSComponent.cpp'),'r')
-
-# The input format is a file containing exactly one section of the form:
-# static CipherPref CipherPrefs[] = {
-# {"name", MACRO_NAME}, // comment
-# ...
-# {NULL, 0}
-# }
-
-inCipherSection = False
-cipherLines = []
-for line in fileA:
- if line.startswith('static const CipherPref sCipherPrefs[]'):
- # Get the starting boundary of the Cipher Preferences
- inCipherSection = True
- elif inCipherSection:
- line = line.strip()
- if line.startswith('{ nullptr, 0}'):
- # At the ending boundary of the Cipher Prefs
- break
- else:
- cipherLines.append(line)
-fileA.close()
-
-# Parse the lines and put them into a dict
-ciphers = {}
-cipher_pref = {}
-key_pending = None
-for line in cipherLines:
- m = re.search(r'^{\s*\"([^\"]+)\",\s*(\S+)\s*(?:,\s*(true|false))?\s*}', line)
- if m:
- assert not key_pending
- key,value,enabled = m.groups()
- if enabled == 'true':
- ciphers[key] = value
- cipher_pref[value] = key
- continue
- m = re.search(r'^{\s*\"([^\"]+)\",', line)
- if m:
- assert not key_pending
- key_pending = m.group(1)
- continue
- m = re.search(r'^\s*(\S+)(?:,\s*(true|false))?\s*}', line)
- if m:
- assert key_pending
- key = key_pending
- value,enabled = m.groups()
- key_pending = None
- if enabled == 'true':
- ciphers[key] = value
- cipher_pref[value] = key
-
-####
-# Now find the correct order for the ciphers
-fileC = open(ff('security/nss/lib/ssl/ssl3con.c'), 'r')
-firefox_ciphers = []
-inEnum=False
-for line in fileC:
- if not inEnum:
- if "ssl3CipherSuiteCfg cipherSuites[" in line:
- inEnum = True
- continue
-
- if line.startswith("};"):
- break
-
- m = re.match(r'^\s*\{\s*([A-Z_0-9]+),', line)
- if m:
- firefox_ciphers.append(m.group(1))
-
-fileC.close()
-
-#####
-# Read the JS file to understand what ciphers are enabled. The format is
-# pref("name", true/false);
-# Build a map enabled_ciphers from javascript name to "true" or "false",
-# and an (unordered!) list of the macro names for those ciphers that are
-# enabled.
-fileB = open(ff('netwerk/base/public/security-prefs.js'), 'r')
-
-enabled_ciphers = {}
-for line in fileB:
- m = re.match(r'pref\(\"([^\"]+)\"\s*,\s*(\S*)\s*\)', line)
- if not m:
- continue
- key, val = m.groups()
- if key.startswith("security.ssl3"):
- enabled_ciphers[key] = val
-fileB.close()
-
-used_ciphers = []
-for k, v in enabled_ciphers.items():
- if v == "true":
- used_ciphers.append(ciphers[k])
-
-#oSSLinclude = ('/usr/include/openssl/ssl3.h', '/usr/include/openssl/ssl.h',
-# '/usr/include/openssl/ssl2.h', '/usr/include/openssl/ssl23.h',
-# '/usr/include/openssl/tls1.h')
-oSSLinclude = ('ssl/ssl3.h', 'ssl/ssl.h',
- 'ssl/ssl2.h', 'ssl/ssl23.h',
- 'ssl/tls1.h')
-
-#####
-# This reads the hex code for the ciphers that are used by firefox.
-# sslProtoD is set to a map from macro name to macro value in sslproto.h;
-# cipher_codes is set to an (unordered!) list of these hex values.
-sslProto = open(ff('security/nss/lib/ssl/sslproto.h'), 'r')
-sslProtoD = {}
-
-for line in sslProto:
- m = re.match('#define\s+(\S+)\s+(\S+)', line)
- if m:
- key, value = m.groups()
- sslProtoD[key] = value
-sslProto.close()
-
-cipher_codes = []
-for x in used_ciphers:
- cipher_codes.append(sslProtoD[x].lower())
-
-####
-# Now read through all the openssl include files, and try to find the openssl
-# macro names for those files.
-openssl_macro_by_hex = {}
-all_openssl_macros = {}
-for fl in oSSLinclude:
- fp = open(ossl(fl), 'r')
- for line in fp.readlines():
- m = re.match('#define\s+(\S+)\s+(\S+)', line)
- if m:
- value,key = m.groups()
- if key.startswith('0x') and "_CK_" in value:
- key = key.replace('0x0300','0x').lower()
- #print "%s %s" % (key, value)
- openssl_macro_by_hex[key] = value
- all_openssl_macros[value]=key
- fp.close()
-
-# Now generate the output.
-print """\
-/* This is an include file used to define the list of ciphers clients should
- * advertise. Before including it, you should define the CIPHER and XCIPHER
- * macros.
- *
- * This file was automatically generated by get_mozilla_ciphers.py.
- */"""
-# Go in order by the order in CipherPrefs
-for firefox_macro in firefox_ciphers:
-
- try:
- js_cipher_name = cipher_pref[firefox_macro]
- except KeyError:
- # This one has no javascript preference.
- continue
-
- # The cipher needs to be enabled in security-prefs.js
- if enabled_ciphers.get(js_cipher_name, 'false') != 'true':
- continue
-
- hexval = sslProtoD[firefox_macro].lower()
-
- try:
- openssl_macro = openssl_macro_by_hex[hexval.lower()]
- openssl_macro = openssl_macro.replace("_CK_", "_TXT_")
- if openssl_macro not in all_openssl_macros:
- raise KeyError()
- format = {'hex':hexval, 'macro':openssl_macro, 'note':""}
- except KeyError:
- # openssl doesn't have a macro for this.
- format = {'hex':hexval, 'macro':firefox_macro,
- 'note':"/* No openssl macro found for "+hexval+" */\n"}
-
- res = """\
-%(note)s#ifdef %(macro)s
- CIPHER(%(hex)s, %(macro)s)
-#else
- XCIPHER(%(hex)s, %(macro)s)
-#endif""" % format
- print res
diff --git a/src/common/linux_syscalls.inc b/src/common/linux_syscalls.inc
index 912735660..cf47c7380 100644
--- a/src/common/linux_syscalls.inc
+++ b/src/common/linux_syscalls.inc
@@ -1,5 +1,5 @@
/* Automatically generated with
- gen_sandbox_syscalls.pl /usr/include/asm/unistd*.h
+ gen_linux_syscalls.pl /usr/include/asm/unistd*.h
Do not edit.
*/
static const struct {
diff --git a/src/common/log.c b/src/common/log.c
index 592dc2c5d..517fa4faa 100644
--- a/src/common/log.c
+++ b/src/common/log.c
@@ -562,6 +562,27 @@ tor_log_update_sigsafe_err_fds(void)
UNLOCK_LOGS();
}
+/** Add to <b>out</b> a copy of every currently configured log file name. Used
+ * to enable access to these filenames with the sandbox code. */
+void
+tor_log_get_logfile_names(smartlist_t *out)
+{
+ logfile_t *lf;
+ tor_assert(out);
+
+ LOCK_LOGS();
+
+ for (lf = logfiles; lf; lf = lf->next) {
+ if (lf->is_temporary || lf->is_syslog || lf->callback)
+ continue;
+ if (lf->filename == NULL)
+ continue;
+ smartlist_add(out, tor_strdup(lf->filename));
+ }
+
+ UNLOCK_LOGS();
+}
+
/** Output a message to the log, prefixed with a function name <b>fn</b>. */
#ifdef __GNUC__
/** GCC-based implementation of the log_fn backend, used when we have
diff --git a/src/common/sandbox.c b/src/common/sandbox.c
index 8516c754f..bb2b3ed74 100644
--- a/src/common/sandbox.c
+++ b/src/common/sandbox.c
@@ -115,6 +115,7 @@ static int filter_nopar_gen[] = {
#endif
SCMP_SYS(getrlimit),
SCMP_SYS(gettimeofday),
+ SCMP_SYS(gettid),
SCMP_SYS(getuid),
#ifdef __NR_getuid32
SCMP_SYS(getuid32),
@@ -129,6 +130,7 @@ static int filter_nopar_gen[] = {
SCMP_SYS(munmap),
SCMP_SYS(read),
SCMP_SYS(rt_sigreturn),
+ SCMP_SYS(sched_getaffinity),
SCMP_SYS(set_robust_list),
#ifdef __NR_sigreturn
SCMP_SYS(sigreturn),
@@ -204,6 +206,7 @@ sb_rt_sigaction(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
return rc;
}
+#if 0
/**
* Function responsible for setting up the execve syscall for
* the seccomp filter sandbox.
@@ -232,6 +235,7 @@ sb_execve(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
return 0;
}
+#endif
/**
* Function responsible for setting up the time syscall for
@@ -856,7 +860,9 @@ sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
static sandbox_filter_func_t filter_func[] = {
sb_rt_sigaction,
sb_rt_sigprocmask,
+#if 0
sb_execve,
+#endif
sb_time,
sb_accept4,
#ifdef __NR_mmap2
@@ -1240,6 +1246,7 @@ sandbox_cfg_allow_openat_filename_array(sandbox_cfg_t **cfg, ...)
return 0;
}
+#if 0
int
sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com)
{
@@ -1279,6 +1286,7 @@ sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, ...)
va_end(ap);
return 0;
}
+#endif
int
sandbox_getaddrinfo(const char *name, const char *servname,
@@ -1659,6 +1667,7 @@ sandbox_cfg_allow_openat_filename_array(sandbox_cfg_t **cfg, ...)
return 0;
}
+#if 0
int
sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com)
{
@@ -1672,6 +1681,7 @@ sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, ...)
(void)cfg;
return 0;
}
+#endif
int
sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file)
diff --git a/src/common/sandbox.h b/src/common/sandbox.h
index c40f5e0d1..b57215285 100644
--- a/src/common/sandbox.h
+++ b/src/common/sandbox.h
@@ -198,6 +198,7 @@ int sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file);
*/
int sandbox_cfg_allow_openat_filename_array(sandbox_cfg_t **cfg, ...);
+#if 0
/**
* Function used to add a execve allowed filename to a supplied configuration.
* The (char*) specifies the path to the allowed file; that pointer is stolen.
@@ -211,6 +212,7 @@ int sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com);
* one must be NULL.
*/
int sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, ...);
+#endif
/**
* Function used to add a stat/stat64 allowed filename to a configuration.
diff --git a/src/common/torlog.h b/src/common/torlog.h
index 4493b251d..34f70f3c0 100644
--- a/src/common/torlog.h
+++ b/src/common/torlog.h
@@ -156,9 +156,12 @@ void tor_log_err_sigsafe(const char *m, ...);
int tor_log_get_sigsafe_err_fds(const int **out);
void tor_log_update_sigsafe_err_fds(void);
-#if defined(__GNUC__) || defined(RUNNING_DOXYGEN)
+struct smartlist_t;
+void tor_log_get_logfile_names(struct smartlist_t *out);
+
extern int log_global_min_severity_;
+#if defined(__GNUC__) || defined(RUNNING_DOXYGEN)
void log_fn_(int severity, log_domain_mask_t domain,
const char *funcname, const char *format, ...)
CHECK_PRINTF(4,5);
diff --git a/src/common/util.c b/src/common/util.c
index 86bb8baae..e27036a84 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -303,7 +303,7 @@ tor_memdup_(const void *mem, size_t len DMALLOC_PARAMS)
/** As tor_memdup(), but add an extra 0 byte at the end of the resulting
* memory. */
void *
-tor_memdup_nulterm(const void *mem, size_t len DMALLOC_PARAMS)
+tor_memdup_nulterm_(const void *mem, size_t len DMALLOC_PARAMS)
{
char *dup;
tor_assert(len < SIZE_T_CEILING+1);
@@ -1516,7 +1516,7 @@ void
format_iso_time_nospace_usec(char *buf, const struct timeval *tv)
{
tor_assert(tv);
- format_iso_time_nospace(buf, tv->tv_sec);
+ format_iso_time_nospace(buf, (time_t)tv->tv_sec);
tor_snprintf(buf+ISO_TIME_LEN, 8, ".%06d", (int)tv->tv_usec);
}
@@ -1871,7 +1871,7 @@ check_private_dir(const char *dirname, cpd_check_t check,
char *f;
#ifndef _WIN32
int mask;
- struct passwd *pw = NULL;
+ const struct passwd *pw = NULL;
uid_t running_uid;
gid_t running_gid;
#else
@@ -1918,7 +1918,7 @@ check_private_dir(const char *dirname, cpd_check_t check,
if (effective_user) {
/* Look up the user and group information.
* If we have a problem, bail out. */
- pw = getpwnam(effective_user);
+ pw = tor_getpwnam(effective_user);
if (pw == NULL) {
log_warn(LD_CONFIG, "Error setting configured user: %s not found",
effective_user);
@@ -1932,13 +1932,13 @@ check_private_dir(const char *dirname, cpd_check_t check,
}
if (st.st_uid != running_uid) {
- struct passwd *pw = NULL;
+ const struct passwd *pw = NULL;
char *process_ownername = NULL;
- pw = getpwuid(running_uid);
+ pw = tor_getpwuid(running_uid);
process_ownername = pw ? tor_strdup(pw->pw_name) : tor_strdup("<unknown>");
- pw = getpwuid(st.st_uid);
+ pw = tor_getpwuid(st.st_uid);
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?",
@@ -2004,7 +2004,8 @@ write_str_to_file(const char *fname, const char *str, int bin)
#ifdef _WIN32
if (!bin && strchr(str, '\r')) {
log_warn(LD_BUG,
- "We're writing a text string that already contains a CR.");
+ "We're writing a text string that already contains a CR to %s",
+ escaped(fname));
}
#endif
return write_bytes_to_file(fname, str, strlen(str), bin);
@@ -4539,6 +4540,30 @@ stream_status_to_string(enum stream_status stream_status)
}
}
+/* DOCDOC */
+static void
+log_portfw_spawn_error_message(const char *buf,
+ const char *executable, int *child_status)
+{
+ /* Parse error message */
+ int retval, child_state, saved_errno;
+ retval = tor_sscanf(buf, SPAWN_ERROR_MESSAGE "%x/%x",
+ &child_state, &saved_errno);
+ if (retval == 2) {
+ log_warn(LD_GENERAL,
+ "Failed to start child process \"%s\" in state %d: %s",
+ executable, child_state, strerror(saved_errno));
+ if (child_status)
+ *child_status = 1;
+ } else {
+ /* Failed to parse message from child process, log it as a
+ warning */
+ log_warn(LD_GENERAL,
+ "Unexpected message from port forwarding helper \"%s\": %s",
+ executable, buf);
+ }
+}
+
#ifdef _WIN32
/** Return a smartlist containing lines outputted from
@@ -4686,23 +4711,7 @@ log_from_pipe(FILE *stream, int severity, const char *executable,
/* Check if buf starts with SPAWN_ERROR_MESSAGE */
if (strcmpstart(buf, SPAWN_ERROR_MESSAGE) == 0) {
- /* Parse error message */
- int retval, child_state, saved_errno;
- retval = tor_sscanf(buf, SPAWN_ERROR_MESSAGE "%x/%x",
- &child_state, &saved_errno);
- if (retval == 2) {
- log_warn(LD_GENERAL,
- "Failed to start child process \"%s\" in state %d: %s",
- executable, child_state, strerror(saved_errno));
- if (child_status)
- *child_status = 1;
- } else {
- /* Failed to parse message from child process, log it as a
- warning */
- log_warn(LD_GENERAL,
- "Unexpected message from port forwarding helper \"%s\": %s",
- executable, buf);
- }
+ log_portfw_spawn_error_message(buf, executable, child_status);
} else {
log_fn(severity, LD_GENERAL, "Port forwarding helper says: %s", buf);
}
@@ -4780,7 +4789,7 @@ get_string_from_pipe(FILE *stream, char *buf_out, size_t count)
/** Parse a <b>line</b> from tor-fw-helper and issue an appropriate
* log message to our user. */
static void
-handle_fw_helper_line(const char *line)
+handle_fw_helper_line(const char *executable, const char *line)
{
smartlist_t *tokens = smartlist_new();
char *message = NULL;
@@ -4791,6 +4800,19 @@ handle_fw_helper_line(const char *line)
int port = 0;
int success = 0;
+ if (strcmpstart(line, SPAWN_ERROR_MESSAGE) == 0) {
+ /* We need to check for SPAWN_ERROR_MESSAGE again here, since it's
+ * possible that it got sent after we tried to read it in log_from_pipe.
+ *
+ * XXX Ideally, we should be using one of stdout/stderr for the real
+ * output, and one for the output of the startup code. We used to do that
+ * before cd05f35d2c.
+ */
+ int child_status;
+ log_portfw_spawn_error_message(line, executable, &child_status);
+ goto done;
+ }
+
smartlist_split_string(tokens, line, NULL,
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
@@ -4870,7 +4892,8 @@ handle_fw_helper_line(const char *line)
/** Read what tor-fw-helper has to say in its stdout and handle it
* appropriately */
static int
-handle_fw_helper_output(process_handle_t *process_handle)
+handle_fw_helper_output(const char *executable,
+ process_handle_t *process_handle)
{
smartlist_t *fw_helper_output = NULL;
enum stream_status stream_status = 0;
@@ -4885,7 +4908,7 @@ handle_fw_helper_output(process_handle_t *process_handle)
/* Handle the lines we got: */
SMARTLIST_FOREACH_BEGIN(fw_helper_output, char *, line) {
- handle_fw_helper_line(line);
+ handle_fw_helper_line(executable, line);
tor_free(line);
} SMARTLIST_FOREACH_END(line);
@@ -5000,7 +5023,7 @@ tor_check_port_forwarding(const char *filename,
stderr_status = log_from_pipe(child_handle->stderr_handle,
LOG_INFO, filename, &retval);
#endif
- if (handle_fw_helper_output(child_handle) < 0) {
+ if (handle_fw_helper_output(filename, child_handle) < 0) {
log_warn(LD_GENERAL, "Failed to handle fw helper output.");
stdout_status = -1;
retval = -1;
diff --git a/src/ext/README b/src/ext/README
index 58ba7f699..5d5a6e151 100644
--- a/src/ext/README
+++ b/src/ext/README
@@ -42,3 +42,10 @@ curve25519_donna/*.c
A copy of Adam Langley's curve25519-donna mostly-portable
implementations of curve25519.
+
+csiphash.c
+siphash.h
+
+ Marek Majkowski's implementation of siphash 2-4, a secure keyed
+ hash algorithm to avoid collision-based DoS attacks against hash
+ tables.
diff --git a/src/ext/ht.h b/src/ext/ht.h
index 4a68673e6..871f5bbd2 100644
--- a/src/ext/ht.h
+++ b/src/ext/ht.h
@@ -58,6 +58,7 @@
#define HT_NEXT_RMV(name, head, elm) name##_HT_NEXT_RMV((head), (elm))
#define HT_CLEAR(name, head) name##_HT_CLEAR(head)
#define HT_INIT(name, head) name##_HT_INIT(head)
+#define HT_REP_IS_BAD_(name, head) name##_HT_REP_IS_BAD_(head)
/* Helper: */
static INLINE unsigned
ht_improve_hash(unsigned h)
diff --git a/src/ext/tinytest_macros.h b/src/ext/tinytest_macros.h
index db2dfcbe6..c3728d1fd 100644
--- a/src/ext/tinytest_macros.h
+++ b/src/ext/tinytest_macros.h
@@ -113,8 +113,8 @@
#define tt_assert_test_fmt_type(a,b,str_test,type,test,printf_type,printf_fmt, \
setup_block,cleanup_block,die_on_fail) \
TT_STMT_BEGIN \
- type val1_ = (type)(a); \
- type val2_ = (type)(b); \
+ type val1_ = (a); \
+ type val2_ = (b); \
int tt_status_ = (test); \
if (!tt_status_ || tinytest_get_verbosity_()>1) { \
printf_type print_; \
@@ -163,7 +163,7 @@
(val1_ op val2_),"%lu",TT_EXIT_TEST_FUNCTION)
#define tt_ptr_op(a,op,b) \
- tt_assert_test_type(a,b,#a" "#op" "#b,void*, \
+ tt_assert_test_type(a,b,#a" "#op" "#b,const void*, \
(val1_ op val2_),"%p",TT_EXIT_TEST_FUNCTION)
#define tt_str_op(a,op,b) \
@@ -173,7 +173,7 @@
#define tt_mem_op(expr1, op, expr2, len) \
tt_assert_test_fmt_type(expr1,expr2,#expr1" "#op" "#expr2, \
- const char *, \
+ const void *, \
(val1_ && val2_ && memcmp(val1_, val2_, len) op 0), \
char *, "%s", \
{ print_ = tinytest_format_hex_(value_, (len)); }, \
@@ -189,7 +189,7 @@
(val1_ op val2_),"%lu",(void)0)
#define tt_want_ptr_op(a,op,b) \
- tt_assert_test_type(a,b,#a" "#op" "#b,void*, \
+ tt_assert_test_type(a,b,#a" "#op" "#b,const void*, \
(val1_ op val2_),"%p",(void)0)
#define tt_want_str_op(a,op,b) \
diff --git a/src/or/buffers.c b/src/or/buffers.c
index e54751db2..033f86288 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -62,25 +62,8 @@ static int parse_socks_client(const uint8_t *data, size_t datalen,
int state, char **reason,
ssize_t *drain_out);
-#define DEBUG_CHUNK_ALLOC
-
/* Chunk manipulation functions */
-/** A single chunk on a buffer or in a freelist. */
-typedef struct chunk_t {
- struct chunk_t *next; /**< The next chunk on the buffer or freelist. */
- size_t datalen; /**< The number of bytes stored in this chunk */
- size_t memlen; /**< The number of usable bytes of storage in <b>mem</b>. */
-#ifdef DEBUG_CHUNK_ALLOC
- size_t DBG_alloc;
-#endif
- char *data; /**< A pointer to the first byte of data stored in <b>mem</b>. */
- uint32_t inserted_time; /**< Timestamp in truncated ms since epoch
- * when this chunk was inserted. */
- char mem[FLEXIBLE_ARRAY_MEMBER]; /**< The actual memory used for storage in
- * this chunk. */
-} chunk_t;
-
#define CHUNK_HEADER_LEN STRUCT_OFFSET(chunk_t, mem[0])
/** Return the number of bytes needed to allocate a chunk to hold
@@ -407,19 +390,6 @@ buf_dump_freelist_sizes(int severity)
#endif
}
-/** Magic value for buf_t.magic, to catch pointer errors. */
-#define BUFFER_MAGIC 0xB0FFF312u
-/** A resizeable buffer, optimized for reading and writing. */
-struct buf_t {
- uint32_t magic; /**< Magic cookie for debugging: Must be set to
- * BUFFER_MAGIC. */
- size_t datalen; /**< How many bytes is this buffer holding right now? */
- size_t default_chunk_size; /**< Don't allocate any chunks smaller than
- * this for this buffer. */
- chunk_t *head; /**< First chunk in the list, or NULL for none. */
- chunk_t *tail; /**< Last chunk in the list, or NULL for none. */
-};
-
/** Collapse data from the first N chunks from <b>buf</b> into buf->head,
* growing it as necessary, until buf->head has the first <b>bytes</b> bytes
* of data from the buffer, or until buf->head has all the data in <b>buf</b>.
@@ -2507,6 +2477,7 @@ write_to_buf_zlib(buf_t *buf, tor_zlib_state_t *state,
char *next;
size_t old_avail, avail;
int over = 0;
+
do {
int need_new_chunk = 0;
if (!buf->tail || ! CHUNK_REMAINING_CAPACITY(buf->tail)) {
diff --git a/src/or/buffers.h b/src/or/buffers.h
index a201282da..c90e14750 100644
--- a/src/or/buffers.h
+++ b/src/or/buffers.h
@@ -106,6 +106,35 @@ void assert_buf_ok(buf_t *buf);
STATIC int buf_find_string_offset(const buf_t *buf, const char *s, size_t n);
STATIC void buf_pullup(buf_t *buf, size_t bytes, int nulterminate);
void buf_get_first_chunk_data(const buf_t *buf, const char **cp, size_t *sz);
+
+#define DEBUG_CHUNK_ALLOC
+/** A single chunk on a buffer or in a freelist. */
+typedef struct chunk_t {
+ struct chunk_t *next; /**< The next chunk on the buffer or freelist. */
+ size_t datalen; /**< The number of bytes stored in this chunk */
+ size_t memlen; /**< The number of usable bytes of storage in <b>mem</b>. */
+#ifdef DEBUG_CHUNK_ALLOC
+ size_t DBG_alloc;
+#endif
+ char *data; /**< A pointer to the first byte of data stored in <b>mem</b>. */
+ uint32_t inserted_time; /**< Timestamp in truncated ms since epoch
+ * when this chunk was inserted. */
+ char mem[FLEXIBLE_ARRAY_MEMBER]; /**< The actual memory used for storage in
+ * this chunk. */
+} chunk_t;
+
+/** Magic value for buf_t.magic, to catch pointer errors. */
+#define BUFFER_MAGIC 0xB0FFF312u
+/** A resizeable buffer, optimized for reading and writing. */
+struct buf_t {
+ uint32_t magic; /**< Magic cookie for debugging: Must be set to
+ * BUFFER_MAGIC. */
+ size_t datalen; /**< How many bytes is this buffer holding right now? */
+ size_t default_chunk_size; /**< Don't allocate any chunks smaller than
+ * this for this buffer. */
+ chunk_t *head; /**< First chunk in the list, or NULL for none. */
+ chunk_t *tail; /**< Last chunk in the list, or NULL for none. */
+};
#endif
#endif
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index cd92326b3..9d06759de 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -9,6 +9,8 @@
* \brief The actual details of building circuits.
**/
+#define CIRCUITBUILD_PRIVATE
+
#include "or.h"
#include "channel.h"
#include "circpathbias.h"
@@ -83,7 +85,7 @@ channel_connect_for_circuit(const tor_addr_t *addr, uint16_t port,
*
* Return it, or 0 if can't get a unique circ_id.
*/
-static circid_t
+STATIC circid_t
get_unique_circ_id_by_chan(channel_t *chan)
{
/* This number is chosen somewhat arbitrarily; see comment below for more
diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h
index ebcb22c45..71caea94e 100644
--- a/src/or/circuitbuild.h
+++ b/src/or/circuitbuild.h
@@ -58,5 +58,9 @@ const char *build_state_get_exit_nickname(cpath_build_state_t *state);
const node_t *choose_good_entry_server(uint8_t purpose,
cpath_build_state_t *state);
+#ifdef CIRCUITBUILD_PRIVATE
+STATIC circid_t get_unique_circ_id_by_chan(channel_t *chan);
+#endif
+
#endif
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index e482fa535..6238e08e1 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -76,7 +76,15 @@ chan_circid_entries_eq_(chan_circid_circuit_map_t *a,
static INLINE unsigned int
chan_circid_entry_hash_(chan_circid_circuit_map_t *a)
{
- return ((unsigned)a->circ_id) ^ (unsigned)(uintptr_t)(a->chan);
+ /* Try to squeze the siphash input into 8 bytes to save any extra siphash
+ * rounds. This hash function is in the critical path. */
+ uintptr_t chan = (uintptr_t) (void*) a->chan;
+ uint32_t array[2];
+ array[0] = a->circ_id;
+ /* The low bits of the channel pointer are uninteresting, since the channel
+ * is a pretty big structure. */
+ array[1] = (uint32_t) (chan >> 6);
+ return (unsigned) siphash24g(array, sizeof(array));
}
/** Map from [chan,circid] to circuit. */
@@ -1821,7 +1829,7 @@ circuit_max_queued_cell_age(const circuit_t *c, uint32_t now)
age = now - cell->inserted_time;
if (! CIRCUIT_IS_ORIGIN(c)) {
- const or_circuit_t *orcirc = TO_OR_CIRCUIT((circuit_t*)c);
+ const or_circuit_t *orcirc = CONST_TO_OR_CIRCUIT(c);
if (NULL != (cell = TOR_SIMPLEQ_FIRST(&orcirc->p_chan_cells.head))) {
uint32_t age2 = now - cell->inserted_time;
if (age2 > age)
@@ -1863,10 +1871,10 @@ circuit_max_queued_data_age(const circuit_t *c, uint32_t now)
{
if (CIRCUIT_IS_ORIGIN(c)) {
return circuit_get_streams_max_data_age(
- TO_ORIGIN_CIRCUIT((circuit_t*)c)->p_streams, now);
+ CONST_TO_ORIGIN_CIRCUIT(c)->p_streams, now);
} else {
return circuit_get_streams_max_data_age(
- TO_OR_CIRCUIT((circuit_t*)c)->n_streams, now);
+ CONST_TO_OR_CIRCUIT(c)->n_streams, now);
}
}
@@ -2059,15 +2067,10 @@ assert_circuit_ok(const circuit_t *c)
tor_assert(c->purpose >= CIRCUIT_PURPOSE_MIN_ &&
c->purpose <= CIRCUIT_PURPOSE_MAX_);
- {
- /* Having a separate variable for this pleases GCC 4.2 in ways I hope I
- * never understand. -NM. */
- circuit_t *nonconst_circ = (circuit_t*) c;
- if (CIRCUIT_IS_ORIGIN(c))
- origin_circ = TO_ORIGIN_CIRCUIT(nonconst_circ);
- else
- or_circ = TO_OR_CIRCUIT(nonconst_circ);
- }
+ if (CIRCUIT_IS_ORIGIN(c))
+ origin_circ = CONST_TO_ORIGIN_CIRCUIT(c);
+ else
+ or_circ = CONST_TO_OR_CIRCUIT(c);
if (c->n_chan) {
tor_assert(!c->n_hop);
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index d10430668..467bef652 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -296,7 +296,7 @@ circuit_get_best(const entry_connection_t *conn,
}
if (!circuit_is_acceptable(origin_circ,conn,must_be_open,purpose,
- need_uptime,need_internal,now.tv_sec))
+ need_uptime,need_internal, (time_t)now.tv_sec))
continue;
/* now this is an acceptable circ to hand back. but that doesn't
@@ -683,9 +683,9 @@ circuit_expire_building(void)
victim->purpose,
circuit_purpose_to_string(victim->purpose));
} else if (circuit_build_times_count_close(
- get_circuit_build_times_mutable(),
- first_hop_succeeded,
- victim->timestamp_created.tv_sec)) {
+ get_circuit_build_times_mutable(),
+ first_hop_succeeded,
+ (time_t)victim->timestamp_created.tv_sec)) {
circuit_build_times_set_timeout(get_circuit_build_times_mutable());
}
}
@@ -783,6 +783,64 @@ circuit_expire_building(void)
}
}
+/**
+ * As a diagnostic for bug 8387, log information about how many one-hop
+ * circuits we have around that have been there for at least <b>age</b>
+ * seconds. Log a few of them.
+ */
+void
+circuit_log_ancient_one_hop_circuits(int age)
+{
+#define MAX_ANCIENT_ONEHOP_CIRCUITS_TO_LOG 10
+ time_t cutoff = time(NULL) - age;
+ int n_found = 0;
+ smartlist_t *log_these = smartlist_new();
+ const circuit_t *circ;
+
+ TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ const origin_circuit_t *ocirc;
+ if (! CIRCUIT_IS_ORIGIN(circ))
+ continue;
+ if (circ->timestamp_created.tv_sec >= cutoff)
+ continue;
+ ocirc = CONST_TO_ORIGIN_CIRCUIT(circ);
+
+ if (ocirc->build_state && ocirc->build_state->onehop_tunnel) {
+ ++n_found;
+
+ if (smartlist_len(log_these) < MAX_ANCIENT_ONEHOP_CIRCUITS_TO_LOG)
+ smartlist_add(log_these, (origin_circuit_t*) ocirc);
+ }
+ }
+
+ if (n_found == 0)
+ goto done;
+
+ log_notice(LD_HEARTBEAT,
+ "Diagnostic for issue 8387: Found %d one-hop circuits more "
+ "than %d seconds old! Logging %d...",
+ n_found, age, smartlist_len(log_these));
+
+ SMARTLIST_FOREACH_BEGIN(log_these, const origin_circuit_t *, ocirc) {
+ char created[ISO_TIME_LEN+1];
+ circ = TO_CIRCUIT(ocirc);
+ format_local_iso_time(created,
+ (time_t)circ->timestamp_created.tv_sec);
+
+ log_notice(LD_HEARTBEAT, " #%d created at %s. %s, %s. %s for close. "
+ "%s for new conns.",
+ ocirc_sl_idx,
+ created,
+ circuit_state_to_string(circ->state),
+ circuit_purpose_to_string(circ->purpose),
+ circ->marked_for_close ? "Marked" : "Not marked",
+ ocirc->unusable_for_new_conns ? "Not usable" : "usable");
+ } SMARTLIST_FOREACH_END(ocirc);
+
+ done:
+ smartlist_free(log_these);
+}
+
/** Remove any elements in <b>needed_ports</b> that are handled by an
* open or in-progress circuit.
*/
diff --git a/src/or/circuituse.h b/src/or/circuituse.h
index 11e5a6416..f228a6758 100644
--- a/src/or/circuituse.h
+++ b/src/or/circuituse.h
@@ -16,6 +16,7 @@ void circuit_expire_building(void);
void circuit_remove_handled_ports(smartlist_t *needed_ports);
int circuit_stream_is_being_handled(entry_connection_t *conn, uint16_t port,
int min);
+void circuit_log_ancient_one_hop_circuits(int age);
#if 0
int circuit_conforms_to_options(const origin_circuit_t *circ,
const or_options_t *options);
diff --git a/src/or/config.c b/src/or/config.c
index 7850e5227..0f7b1d2a2 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -357,7 +357,7 @@ static config_var_t option_vars_[] = {
V(OptimisticData, AUTOBOOL, "auto"),
V(PortForwarding, BOOL, "0"),
V(PortForwardingHelper, FILENAME, "tor-fw-helper"),
- V(PreferTunneledDirConns, BOOL, "1"),
+ OBSOLETE("PreferTunneledDirConns"),
V(ProtocolWarnings, BOOL, "0"),
V(PublishServerDescriptor, CSV, "1"),
V(PublishHidServDescriptors, BOOL, "1"),
@@ -412,7 +412,7 @@ static config_var_t option_vars_[] = {
V(TransListenAddress, LINELIST, NULL),
VPORT(TransPort, LINELIST, NULL),
V(TransProxyType, STRING, "default"),
- V(TunnelDirConns, BOOL, "1"),
+ OBSOLETE("TunnelDirConns"),
V(UpdateBridgesFromAuthority, BOOL, "0"),
V(UseBridges, BOOL, "0"),
V(UseEntryGuards, BOOL, "1"),
@@ -536,9 +536,11 @@ static int options_transition_affects_descriptor(
const or_options_t *old_options, const or_options_t *new_options);
static int check_nickname_list(char **lst, const char *name, char **msg);
-static int parse_client_transport_line(const char *line, int validate_only);
+static int parse_client_transport_line(const or_options_t *options,
+ const char *line, int validate_only);
-static int parse_server_transport_line(const char *line, int validate_only);
+static int parse_server_transport_line(const or_options_t *options,
+ const char *line, int validate_only);
static char *get_bindaddr_from_transport_listen_line(const char *line,
const char *transport);
static int parse_dir_authority_line(const char *line,
@@ -1141,13 +1143,11 @@ options_act_reversible(const or_options_t *old_options, char **msg)
if (!running_tor)
goto commit;
- if (!sandbox_is_active()) {
- mark_logs_temp(); /* Close current logs once new logs are open. */
- logs_marked = 1;
- if (options_init_logs(options, 0)<0) { /* Configure the tor_log(s) */
- *msg = tor_strdup("Failed to init Log options. See logs for details.");
- goto rollback;
- }
+ mark_logs_temp(); /* Close current logs once new logs are open. */
+ logs_marked = 1;
+ if (options_init_logs(options, 0)<0) { /* Configure the tor_log(s) */
+ *msg = tor_strdup("Failed to init Log options. See logs for details.");
+ goto rollback;
}
commit:
@@ -1426,7 +1426,7 @@ options_act(const or_options_t *old_options)
pt_prepare_proxy_list_for_config_read();
if (options->ClientTransportPlugin) {
for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
- if (parse_client_transport_line(cl->value, 0)<0) {
+ if (parse_client_transport_line(options, cl->value, 0)<0) {
log_warn(LD_BUG,
"Previously validated ClientTransportPlugin line "
"could not be added!");
@@ -1437,7 +1437,7 @@ options_act(const or_options_t *old_options)
if (options->ServerTransportPlugin && server_mode(options)) {
for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
- if (parse_server_transport_line(cl->value, 0)<0) {
+ if (parse_server_transport_line(options, cl->value, 0)<0) {
log_warn(LD_BUG,
"Previously validated ServerTransportPlugin line "
"could not be added!");
@@ -3029,6 +3029,11 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (options->KeepalivePeriod < 1)
REJECT("KeepalivePeriod option must be positive.");
+ if (options->PortForwarding && options->Sandbox) {
+ REJECT("PortForwarding is not compatible with Sandbox; at most one can "
+ "be set");
+ }
+
if (ensure_bandwidth_cap(&options->BandwidthRate,
"BandwidthRate", msg) < 0)
return -1;
@@ -3275,8 +3280,6 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (options->UseBridges && !options->Bridges)
REJECT("If you set UseBridges, you must specify at least one bridge.");
- if (options->UseBridges && !options->TunnelDirConns)
- REJECT("If you set UseBridges, you must set TunnelDirConns.");
for (cl = options->Bridges; cl; cl = cl->next) {
bridge_line_t *bridge_line = parse_bridge_line(cl->value);
@@ -3286,13 +3289,13 @@ options_validate(or_options_t *old_options, or_options_t *options,
}
for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
- if (parse_client_transport_line(cl->value, 1)<0)
- REJECT("Transport line did not parse. See logs for details.");
+ if (parse_client_transport_line(options, cl->value, 1)<0)
+ REJECT("Invalid client transport line. See logs for details.");
}
for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
- if (parse_server_transport_line(cl->value, 1)<0)
- REJECT("Server transport line did not parse. See logs for details.");
+ if (parse_server_transport_line(options, cl->value, 1)<0)
+ REJECT("Invalid server transport line. See logs for details.");
}
if (options->ServerTransportPlugin && !server_mode(options)) {
@@ -3389,15 +3392,6 @@ options_validate(or_options_t *old_options, or_options_t *options,
AF_INET6, 1, msg)<0)
return -1;
- 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,
{
@@ -3751,6 +3745,11 @@ options_transition_allowed(const or_options_t *old,
"Sandbox is active");
return -1;
}
+ if (! opt_streq(old->DirPortFrontPage, new_val->DirPortFrontPage)) {
+ *msg = tor_strdup("Can't change DirPortFrontPage"
+ " while Sandbox is active");
+ return -1;
+ }
}
return 0;
@@ -4745,7 +4744,8 @@ parse_bridge_line(const char *line)
* our internal transport list.
* - If it's a managed proxy line, launch the managed proxy. */
static int
-parse_client_transport_line(const char *line, int validate_only)
+parse_client_transport_line(const or_options_t *options,
+ const char *line, int validate_only)
{
smartlist_t *items = NULL;
int r;
@@ -4812,6 +4812,12 @@ parse_client_transport_line(const char *line, int validate_only)
goto err;
}
+ if (is_managed && options->Sandbox) {
+ log_warn(LD_CONFIG, "Managed proxies are not compatible with Sandbox mode."
+ "(ClientTransportPlugin line was %s)", escaped(line));
+ goto err;
+ }
+
if (is_managed) { /* managed */
if (!validate_only && is_useless_proxy) {
log_notice(LD_GENERAL, "Pluggable transport proxy (%s) does not provide "
@@ -5038,7 +5044,8 @@ get_options_for_server_transport(const char *transport)
* If <b>validate_only</b> is 0, the line is well-formed, and it's a
* managed proxy line, launch the managed proxy. */
static int
-parse_server_transport_line(const char *line, int validate_only)
+parse_server_transport_line(const or_options_t *options,
+ const char *line, int validate_only)
{
smartlist_t *items = NULL;
int r;
@@ -5093,6 +5100,12 @@ parse_server_transport_line(const char *line, int validate_only)
goto err;
}
+ if (is_managed && options->Sandbox) {
+ log_warn(LD_CONFIG, "Managed proxies are not compatible with Sandbox mode."
+ "(ServerTransportPlugin line was %s)", escaped(line));
+ goto err;
+ }
+
if (is_managed) { /* managed */
if (!validate_only) {
proxy_argc = line_length-2;
diff --git a/src/or/connection.c b/src/or/connection.c
index 3cc4e09fb..cef9172ff 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -1017,7 +1017,7 @@ connection_listener_new(const struct sockaddr *listensockaddr,
tor_socket_t s = TOR_INVALID_SOCKET; /* the socket we're going to make */
or_options_t const *options = get_options();
#if defined(HAVE_PWD_H) && defined(HAVE_SYS_UN_H)
- struct passwd *pw = NULL;
+ const struct passwd *pw = NULL;
#endif
uint16_t usePort = 0, gotPort = 0;
int start_reading = 0;
@@ -1157,7 +1157,7 @@ connection_listener_new(const struct sockaddr *listensockaddr,
}
#ifdef HAVE_PWD_H
if (options->User) {
- pw = getpwnam(options->User);
+ pw = tor_getpwnam(options->User);
if (pw == NULL) {
log_warn(LD_NET,"Unable to chown() %s socket: user %s not found.",
address, options->User);
diff --git a/src/or/control.c b/src/or/control.c
index d571900ac..2865d7832 100755
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1492,7 +1492,7 @@ getinfo_helper_misc(control_connection_t *conn, const char *question,
*answer = tor_strdup("");
#else
int myUid = geteuid();
- struct passwd *myPwEntry = getpwuid(myUid);
+ const struct passwd *myPwEntry = tor_getpwuid(myUid);
if (myPwEntry) {
*answer = tor_strdup(myPwEntry->pw_name);
diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c
index 6b6a68afe..61b2c29b3 100644
--- a/src/or/cpuworker.c
+++ b/src/or/cpuworker.c
@@ -528,7 +528,12 @@ spawn_cpuworker(void)
tor_assert(SOCKET_OK(fdarray[1]));
fd = fdarray[0];
- spawn_func(cpuworker_main, (void*)fdarray);
+ if (spawn_func(cpuworker_main, (void*)fdarray) < 0) {
+ tor_close_socket(fdarray[0]);
+ tor_close_socket(fdarray[1]);
+ tor_free(fdarray);
+ return -1;
+ }
log_debug(LD_OR,"just spawned a cpu worker.");
#ifndef TOR_IS_MULTITHREADED
tor_close_socket(fdarray[1]); /* don't need the worker's side of the pipe */
diff --git a/src/or/directory.c b/src/or/directory.c
index 8070a76a5..22ba056ee 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -261,7 +261,7 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
size_t payload_len, size_t extrainfo_len)
{
const or_options_t *options = get_options();
- int post_via_tor;
+ dir_indirection_t indirection;
const smartlist_t *dirservers = router_get_trusted_dir_servers();
int found = 0;
const int exclude_self = (dir_purpose == DIR_PURPOSE_UPLOAD_VOTE ||
@@ -305,11 +305,19 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
(int) extrainfo_len);
}
tor_addr_from_ipv4h(&ds_addr, ds->addr);
- post_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose) ||
- !fascist_firewall_allows_address_dir(&ds_addr, ds->dir_port);
+ if (purpose_needs_anonymity(dir_purpose, router_purpose)) {
+ indirection = DIRIND_ANONYMOUS;
+ } else if (!fascist_firewall_allows_address_dir(&ds_addr,ds->dir_port)) {
+ if (fascist_firewall_allows_address_or(&ds_addr,ds->or_port))
+ indirection = DIRIND_ONEHOP;
+ else
+ indirection = DIRIND_ANONYMOUS;
+ } else {
+ indirection = DIRIND_DIRECT_CONN;
+ }
directory_initiate_command_routerstatus(rs, dir_purpose,
router_purpose,
- post_via_tor,
+ indirection,
NULL, payload, upload_len, 0);
} SMARTLIST_FOREACH_END(ds);
if (!found) {
@@ -338,8 +346,6 @@ should_use_directory_guards(const or_options_t *options)
if (options->DownloadExtraInfo || options->FetchDirInfoEarly ||
options->FetchDirInfoExtraEarly || options->FetchUselessDescriptors)
return 0;
- if (! options->PreferTunneledDirConns)
- return 0;
return 1;
}
@@ -834,6 +840,7 @@ directory_command_should_use_begindir(const or_options_t *options,
int or_port, uint8_t router_purpose,
dir_indirection_t indirection)
{
+ (void) router_purpose;
if (!or_port)
return 0; /* We don't know an ORPort -- no chance. */
if (indirection == DIRIND_DIRECT_CONN || indirection == DIRIND_ANON_DIRPORT)
@@ -842,9 +849,6 @@ directory_command_should_use_begindir(const or_options_t *options,
if (!fascist_firewall_allows_address_or(addr, or_port) ||
directory_fetches_from_authorities(options))
return 0; /* We're firewalled or are acting like a relay -- also no. */
- if (!options->TunnelDirConns &&
- router_purpose != ROUTER_PURPOSE_BRIDGE)
- return 0; /* We prefer to avoid using begindir conns. Fine. */
return 1;
}
@@ -2303,7 +2307,7 @@ write_http_response_header_impl(dir_connection_t *conn, ssize_t length,
}
if (cache_lifetime > 0) {
char expbuf[RFC1123_TIME_LEN+1];
- format_rfc1123_time(expbuf, now + cache_lifetime);
+ format_rfc1123_time(expbuf, (time_t)(now + cache_lifetime));
/* We could say 'Cache-control: max-age=%d' here if we start doing
* http/1.1 */
tor_snprintf(cp, sizeof(tmp)-(cp-tmp),
@@ -3069,22 +3073,6 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
goto done;
}
- if (!strcmp(url,"/tor/dbg-stability.txt")) {
- const char *stability;
- size_t len;
- if (options->BridgeAuthoritativeDir ||
- ! authdir_mode_tests_reachability(options) ||
- ! (stability = rep_hist_get_router_stability_doc(time(NULL)))) {
- write_http_status_line(conn, 404, "Not found.");
- goto done;
- }
-
- len = strlen(stability);
- write_http_response_header(conn, len, 0, 0);
- connection_write_to_buf(stability, len, TO_CONN(conn));
- goto done;
- }
-
#if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
#define ADD_MALLINFO_LINE(x) do { \
smartlist_add_asprintf(lines, "%s %d\n", #x, mi.x); \
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index f5994e031..aedd09252 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -2507,7 +2507,7 @@ dirserv_read_measured_bandwidths(const char *from_file,
}
line[strlen(line)-1] = '\0';
- file_time = tor_parse_ulong(line, 10, 0, ULONG_MAX, &ok, NULL);
+ file_time = (time_t)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));
@@ -3296,8 +3296,6 @@ connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn)
}
body = signed_descriptor_get_body(sd);
if (conn->zlib_state) {
- /* XXXX024 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);
@@ -3314,6 +3312,11 @@ connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn)
if (!smartlist_len(conn->fingerprint_stack)) {
/* We just wrote the last one; finish up. */
+ if (conn->zlib_state) {
+ connection_write_to_buf_zlib("", 0, conn, 1);
+ tor_zlib_free(conn->zlib_state);
+ conn->zlib_state = NULL;
+ }
conn->dir_spool_src = DIR_SPOOL_NONE;
smartlist_free(conn->fingerprint_stack);
conn->fingerprint_stack = NULL;
@@ -3339,8 +3342,6 @@ connection_dirserv_add_microdescs_to_outbuf(dir_connection_t *conn)
if (!md || !md->body)
continue;
if (conn->zlib_state) {
- /* XXXX024 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) {
@@ -3352,6 +3353,11 @@ connection_dirserv_add_microdescs_to_outbuf(dir_connection_t *conn)
}
}
if (!smartlist_len(conn->fingerprint_stack)) {
+ if (conn->zlib_state) {
+ connection_write_to_buf_zlib("", 0, conn, 1);
+ tor_zlib_free(conn->zlib_state);
+ conn->zlib_state = NULL;
+ }
conn->dir_spool_src = DIR_SPOOL_NONE;
smartlist_free(conn->fingerprint_stack);
conn->fingerprint_stack = NULL;
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index 4d3ee9cdb..c7be343ca 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -3588,6 +3588,12 @@ dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method)
tor_free(p6);
}
+ if (consensus_method >= MIN_METHOD_FOR_ID_HASH_IN_MD) {
+ char idbuf[BASE64_DIGEST_LEN+1];
+ digest_to_base64(idbuf, ri->cache_info.identity_digest);
+ smartlist_add_asprintf(chunks, "id rsa1024 %s\n", idbuf);
+ }
+
output = smartlist_join_strings(chunks, "", 0, NULL);
{
@@ -3657,7 +3663,8 @@ static const struct consensus_method_range_t {
{MIN_METHOD_FOR_MICRODESC, MIN_METHOD_FOR_A_LINES - 1},
{MIN_METHOD_FOR_A_LINES, MIN_METHOD_FOR_P6_LINES - 1},
{MIN_METHOD_FOR_P6_LINES, MIN_METHOD_FOR_NTOR_KEY - 1},
- {MIN_METHOD_FOR_NTOR_KEY, MAX_SUPPORTED_CONSENSUS_METHOD},
+ {MIN_METHOD_FOR_NTOR_KEY, MIN_METHOD_FOR_ID_HASH_IN_MD - 1},
+ {MIN_METHOD_FOR_ID_HASH_IN_MD, MAX_SUPPORTED_CONSENSUS_METHOD},
{-1, -1}
};
diff --git a/src/or/dirvote.h b/src/or/dirvote.h
index 3a4951a95..4c57e4366 100644
--- a/src/or/dirvote.h
+++ b/src/or/dirvote.h
@@ -22,7 +22,7 @@
#define MIN_VOTE_INTERVAL 300
/** The highest consensus method that we currently support. */
-#define MAX_SUPPORTED_CONSENSUS_METHOD 17
+#define MAX_SUPPORTED_CONSENSUS_METHOD 18
/** Lowest consensus method that contains a 'directory-footer' marker */
#define MIN_METHOD_FOR_FOOTER 9
@@ -61,6 +61,10 @@
* Unmeasured=1 flag for unmeasured bandwidths */
#define MIN_METHOD_TO_CLIP_UNMEASURED_BW 17
+/** Lowest consensus method where authorities may include an "id" line in
+ * microdescriptors. */
+#define MIN_METHOD_FOR_ID_HASH_IN_MD 18
+
/** Default bandwidth to clip unmeasured bandwidths to using method >=
* MIN_METHOD_TO_CLIP_UNMEASURED_BW */
#define DEFAULT_MAX_UNMEASURED_BW_KB 20
diff --git a/src/or/dns.c b/src/or/dns.c
index 36271939b..a9c431865 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -2174,7 +2174,7 @@ static void
assert_cache_ok_(void)
{
cached_resolve_t **resolve;
- int bad_rep = _cache_map_HT_REP_IS_BAD(&cache_root);
+ int bad_rep = HT_REP_IS_BAD_(cache_map, &cache_root);
if (bad_rep) {
log_err(LD_BUG, "Bad rep type %d on dns cache hash table", bad_rep);
tor_assert(!bad_rep);
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index 70587bd75..957217ac6 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -378,7 +378,7 @@ add_an_entry_guard(const node_t *chosen, int reset_status, int prepend,
} else {
const routerstatus_t *rs;
rs = router_pick_directory_server(MICRODESC_DIRINFO|V3_DIRINFO,
- PDS_PREFER_TUNNELED_DIR_CONNS_|PDS_FOR_GUARD);
+ PDS_FOR_GUARD);
if (!rs)
return NULL;
node = node_get_by_id(rs->identity_digest);
diff --git a/src/or/main.c b/src/or/main.c
index e5a48cf98..1168f43c9 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1757,7 +1757,7 @@ refill_callback(periodic_timer_t *timer, void *arg)
accounting_add_bytes(bytes_read, bytes_written, seconds_rolled_over);
if (milliseconds_elapsed > 0)
- connection_bucket_refill(milliseconds_elapsed, now.tv_sec);
+ connection_bucket_refill(milliseconds_elapsed, (time_t)now.tv_sec);
stats_prev_global_read_bucket = global_read_bucket;
stats_prev_global_write_bucket = global_write_bucket;
@@ -2554,6 +2554,9 @@ tor_free_all(int postfork)
#endif /* ENABLE_MEMPOOLS */
if (!postfork) {
tor_tls_free_all();
+#ifndef _WIN32
+ tor_getpwnam(NULL);
+#endif
}
/* stuff in main.c */
@@ -2825,6 +2828,16 @@ sandbox_init_filter(void)
NULL, 0
);
+ {
+ smartlist_t *logfiles = smartlist_new();
+ tor_log_get_logfile_names(logfiles);
+ SMARTLIST_FOREACH(logfiles, char *, logfile_name, {
+ /* steals reference */
+ sandbox_cfg_allow_open_filename(&cfg, logfile_name);
+ });
+ smartlist_free(logfiles);
+ }
+
// orport
if (server_mode(get_options())) {
sandbox_cfg_allow_open_filename_array(&cfg,
@@ -2837,6 +2850,10 @@ sandbox_init_filter(void)
get_datadir_fname2("keys", "secret_onion_key_ntor.old"),
get_datadir_fname2("keys", "secret_onion_key.tmp"),
get_datadir_fname2("keys", "secret_id_key.tmp"),
+ get_datadir_fname2("stats", "bridge-stats"),
+ get_datadir_fname2("stats", "bridge-stats.tmp"),
+ get_datadir_fname2("stats", "dirreq-stats"),
+ get_datadir_fname2("stats", "dirreq-stats.tmp"),
get_datadir_fname("fingerprint"),
get_datadir_fname("fingerprint.tmp"),
get_datadir_fname("hashed-fingerprint"),
@@ -2847,12 +2864,19 @@ sandbox_init_filter(void)
NULL, 0
);
+ if (options->DirPortFrontPage) {
+ sandbox_cfg_allow_open_filename(&cfg,
+ tor_strdup(options->DirPortFrontPage));
+ }
+
RENAME_SUFFIX("fingerprint", ".tmp");
RENAME_SUFFIX2("keys", "secret_onion_key_ntor", ".tmp");
RENAME_SUFFIX2("keys", "secret_id_key", ".tmp");
RENAME_SUFFIX2("keys", "secret_id_key.old", ".tmp");
RENAME_SUFFIX2("keys", "secret_onion_key", ".tmp");
RENAME_SUFFIX2("keys", "secret_onion_key.old", ".tmp");
+ RENAME_SUFFIX2("stats", "bridge-stats", ".tmp");
+ RENAME_SUFFIX2("stats", "dirreq-stats", ".tmp");
RENAME_SUFFIX("hashed-fingerprint", ".tmp");
RENAME_SUFFIX("router-stability", ".tmp");
@@ -2865,7 +2889,7 @@ sandbox_init_filter(void)
sandbox_cfg_allow_stat_filename_array(&cfg,
get_datadir_fname("keys"),
- get_datadir_fname("stats/dirreq-stats"),
+ get_datadir_fname2("stats", "dirreq-stats"),
NULL, 0
);
}
@@ -2944,7 +2968,7 @@ tor_main(int argc, char *argv[])
if (tor_init(argc, argv)<0)
return -1;
- if (get_options()->Sandbox) {
+ if (get_options()->Sandbox && get_options()->command == CMD_RUN_TOR) {
sandbox_cfg_t* cfg = sandbox_init_filter();
if (sandbox_init(cfg)) {
diff --git a/src/or/microdesc.c b/src/or/microdesc.c
index ec85de0d6..fdb549a9a 100644
--- a/src/or/microdesc.c
+++ b/src/or/microdesc.c
@@ -386,18 +386,21 @@ microdesc_cache_clean(microdesc_cache_t *cache, time_t cutoff, int force)
smartlist_t *nodes = nodelist_find_nodes_with_microdesc(*mdp);
const networkstatus_t *ns = networkstatus_get_latest_consensus();
long networkstatus_age = -1;
+ const int ht_badness = HT_REP_IS_BAD_(microdesc_map, &cache->map);
if (ns) {
networkstatus_age = now - ns->valid_after;
}
log_warn(LD_BUG, "Microdescriptor seemed very old "
"(last listed %d hours ago vs %d hour cutoff), but is still "
"marked as being held by %d node(s). I found %d node(s) "
- "holding it. Current networkstatus is %ld hours old.",
+ "holding it. Current networkstatus is %ld hours old. "
+ "Hashtable badness is %d.",
(int)((now - (*mdp)->last_listed) / 3600),
(int)((now - cutoff) / 3600),
held_by_nodes,
smartlist_len(nodes),
- networkstatus_age / 3600);
+ networkstatus_age / 3600,
+ ht_badness);
SMARTLIST_FOREACH_BEGIN(nodes, const node_t *, node) {
const char *rs_match = "No RS";
@@ -664,8 +667,10 @@ microdesc_free_(microdesc_t *md, const char *fname, int lineno)
tor_fragile_assert();
}
if (md->held_by_nodes) {
+ microdesc_cache_t *cache = get_microdesc_cache();
int found=0;
const smartlist_t *nodes = nodelist_get_list();
+ const int ht_badness = HT_REP_IS_BAD_(microdesc_map, &cache->map);
SMARTLIST_FOREACH(nodes, node_t *, node, {
if (node->md == md) {
++found;
@@ -674,12 +679,13 @@ microdesc_free_(microdesc_t *md, const char *fname, int lineno)
});
if (found) {
log_warn(LD_BUG, "microdesc_free() called from %s:%d, but md was still "
- "referenced %d node(s); held_by_nodes == %u",
- fname, lineno, found, md->held_by_nodes);
+ "referenced %d node(s); held_by_nodes == %u, ht_badness == %d",
+ fname, lineno, found, md->held_by_nodes, ht_badness);
} else {
log_warn(LD_BUG, "microdesc_free() called from %s:%d with held_by_nodes "
- "set to %u, but md was not referenced by any nodes",
- fname, lineno, md->held_by_nodes);
+ "set to %u, but md was not referenced by any nodes. "
+ "ht_badness == %d",
+ fname, lineno, md->held_by_nodes, ht_badness);
}
tor_fragile_assert();
}
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index ef450073e..890da0ad1 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -10,6 +10,7 @@
* client or cache.
*/
+#define NETWORKSTATUS_PRIVATE
#include "or.h"
#include "channel.h"
#include "circuitmux.h"
@@ -183,7 +184,7 @@ router_reload_consensus_networkstatus(void)
}
/** Free all storage held by the vote_routerstatus object <b>rs</b>. */
-static void
+STATIC void
vote_routerstatus_free(vote_routerstatus_t *rs)
{
vote_microdesc_hash_t *h, *next;
@@ -829,7 +830,7 @@ update_consensus_networkstatus_fetch_time_impl(time_t now, int flav)
if (directory_fetches_dir_info_early(options)) {
/* 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;
+ start = (time_t)(c->fresh_until + min_sec_before_caching);
/* Some clients may need the consensus sooner than others. */
if (options->FetchDirInfoExtraEarly || authdir_mode_v3(options)) {
dl_interval = 60;
@@ -842,7 +843,7 @@ update_consensus_networkstatus_fetch_time_impl(time_t now, int flav)
} else {
/* We're an ordinary client or a bridge. Give all the caches enough
* time to download the consensus. */
- start = c->fresh_until + (interval*3)/4;
+ start = (time_t)(c->fresh_until + (interval*3)/4);
/* But download the next one well before this one is expired. */
dl_interval = ((c->valid_until - start) * 7 )/ 8;
@@ -850,7 +851,7 @@ update_consensus_networkstatus_fetch_time_impl(time_t now, int flav)
* to choose the rest of the interval *after* them. */
if (directory_fetches_dir_info_later(options)) {
/* Give all the *clients* enough time to download the consensus. */
- start = start + dl_interval + min_sec_before_caching;
+ start = (time_t)(start + dl_interval + min_sec_before_caching);
/* But try to get it before ours actually expires. */
dl_interval = (c->valid_until - start) - min_sec_before_caching;
}
diff --git a/src/or/networkstatus.h b/src/or/networkstatus.h
index 1659818f0..be0a86cdd 100644
--- a/src/or/networkstatus.h
+++ b/src/or/networkstatus.h
@@ -99,5 +99,9 @@ document_signature_t *document_signature_dup(const document_signature_t *sig);
void networkstatus_free_all(void);
int networkstatus_get_weight_scale_param(networkstatus_t *ns);
+#ifdef NETWORKSTATUS_PRIVATE
+STATIC void vote_routerstatus_free(vote_routerstatus_t *rs);
+#endif
+
#endif
diff --git a/src/or/nodelist.c b/src/or/nodelist.c
index a38a6d499..09232f9f9 100644
--- a/src/or/nodelist.c
+++ b/src/or/nodelist.c
@@ -1510,8 +1510,8 @@ update_router_have_minimum_dir_info(void)
}
if (should_delay_dir_fetches(get_options(), &delay_fetches_msg)) {
- log_notice(LD_DIR, "Delaying dir fetches: %s", delay_fetches_msg);
- strlcpy(dir_info_status, "%s", sizeof(dir_info_status));
+ log_notice(LD_DIR, "Delaying directory fetches: %s", delay_fetches_msg);
+ strlcpy(dir_info_status, delay_fetches_msg, sizeof(dir_info_status));
res = 0;
goto done;
}
diff --git a/src/or/onion.c b/src/or/onion.c
index 72571b7bd..ae39f451f 100644
--- a/src/or/onion.c
+++ b/src/or/onion.c
@@ -554,8 +554,10 @@ onion_skin_client_handshake(int type,
switch (type) {
case ONION_HANDSHAKE_TYPE_TAP:
- if (reply_len != TAP_ONIONSKIN_REPLY_LEN)
+ if (reply_len != TAP_ONIONSKIN_REPLY_LEN) {
+ log_warn(LD_CIRC, "TAP reply was not of the correct length.");
return -1;
+ }
if (onion_skin_TAP_client_handshake(handshake_state->u.tap,
(const char*)reply,
(char *)keys_out, keys_out_len) < 0)
@@ -565,8 +567,10 @@ onion_skin_client_handshake(int type,
return 0;
case ONION_HANDSHAKE_TYPE_FAST:
- if (reply_len != CREATED_FAST_LEN)
+ if (reply_len != CREATED_FAST_LEN) {
+ log_warn(LD_CIRC, "CREATED_FAST reply was not of the correct length.");
return -1;
+ }
if (fast_client_handshake(handshake_state->u.fast, reply,
keys_out, keys_out_len) < 0)
return -1;
@@ -575,8 +579,10 @@ onion_skin_client_handshake(int type,
return 0;
#ifdef CURVE25519_ENABLED
case ONION_HANDSHAKE_TYPE_NTOR:
- if (reply_len < NTOR_REPLY_LEN)
+ if (reply_len < NTOR_REPLY_LEN) {
+ log_warn(LD_CIRC, "ntor reply was not of the correct length.");
return -1;
+ }
{
size_t keys_tmp_len = keys_out_len + DIGEST_LEN;
uint8_t *keys_tmp = tor_malloc(keys_tmp_len);
diff --git a/src/or/onion_fast.c b/src/or/onion_fast.c
index 8e778dbc6..38b62decc 100644
--- a/src/or/onion_fast.c
+++ b/src/or/onion_fast.c
@@ -104,6 +104,7 @@ fast_client_handshake(const fast_handshake_state_t *handshake_state,
out_len = key_out_len+DIGEST_LEN;
out = tor_malloc(out_len);
if (crypto_expand_key_material_TAP(tmp, sizeof(tmp), out, out_len)) {
+ log_warn(LD_CIRC, "Failed to expand key material");
goto done;
}
if (tor_memneq(out, handshake_reply_out+DIGEST_LEN, DIGEST_LEN)) {
diff --git a/src/or/onion_ntor.c b/src/or/onion_ntor.c
index 9cf7d5dd6..ef501f69d 100644
--- a/src/or/onion_ntor.c
+++ b/src/or/onion_ntor.c
@@ -256,7 +256,7 @@ onion_skin_ntor_client_handshake(
si += CURVE25519_OUTPUT_LEN;
curve25519_handshake(si, &handshake_state->seckey_x,
&handshake_state->pubkey_B);
- bad |= safe_mem_is_zero(si, CURVE25519_OUTPUT_LEN);
+ bad |= (safe_mem_is_zero(si, CURVE25519_OUTPUT_LEN) << 1);
si += CURVE25519_OUTPUT_LEN;
APPEND(si, handshake_state->router_id, DIGEST_LEN);
APPEND(si, handshake_state->pubkey_B.public_key, CURVE25519_PUBKEY_LEN);
@@ -281,7 +281,7 @@ onion_skin_ntor_client_handshake(
/* Compute auth */
h_tweak(s.auth, s.auth_input, sizeof(s.auth_input), T->t_mac);
- bad |= tor_memneq(s.auth, auth_candidate, DIGEST256_LEN);
+ bad |= (tor_memneq(s.auth, auth_candidate, DIGEST256_LEN) << 2);
crypto_expand_key_material_rfc5869_sha256(
s.secret_input, sizeof(s.secret_input),
@@ -290,6 +290,11 @@ onion_skin_ntor_client_handshake(
key_out, key_out_len);
memwipe(&s, 0, sizeof(s));
+
+ if (bad) {
+ log_warn(LD_PROTOCOL, "Invalid result from curve25519 handshake: %d", bad);
+ }
+
return bad ? -1 : 0;
}
diff --git a/src/or/onion_tap.c b/src/or/onion_tap.c
index 3782e75ab..9a9f374b9 100644
--- a/src/or/onion_tap.c
+++ b/src/or/onion_tap.c
@@ -194,8 +194,10 @@ onion_skin_TAP_client_handshake(crypto_dh_t *handshake_state,
len = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, handshake_state,
handshake_reply, DH_KEY_LEN, key_material,
key_material_len);
- if (len < 0)
+ if (len < 0) {
+ log_warn(LD_PROTOCOL,"DH computation failed.");
goto err;
+ }
if (tor_memneq(key_material, handshake_reply+DH_KEY_LEN, DIGEST_LEN)) {
/* H(K) does *not* match. Something fishy. */
diff --git a/src/or/or.h b/src/or/or.h
index 701877c64..6aa6b59e8 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3231,20 +3231,33 @@ typedef struct or_circuit_rendinfo_s {
/** Convert a circuit_t* to a pointer to the enclosing or_circuit_t. Assert
* if the cast is impossible. */
static or_circuit_t *TO_OR_CIRCUIT(circuit_t *);
+static const or_circuit_t *CONST_TO_OR_CIRCUIT(const circuit_t *);
/** Convert a circuit_t* to a pointer to the enclosing origin_circuit_t.
* Assert if the cast is impossible. */
static origin_circuit_t *TO_ORIGIN_CIRCUIT(circuit_t *);
+static const origin_circuit_t *CONST_TO_ORIGIN_CIRCUIT(const circuit_t *);
static INLINE or_circuit_t *TO_OR_CIRCUIT(circuit_t *x)
{
tor_assert(x->magic == OR_CIRCUIT_MAGIC);
return DOWNCAST(or_circuit_t, x);
}
+static INLINE const or_circuit_t *CONST_TO_OR_CIRCUIT(const circuit_t *x)
+{
+ tor_assert(x->magic == OR_CIRCUIT_MAGIC);
+ return DOWNCAST(or_circuit_t, x);
+}
static INLINE origin_circuit_t *TO_ORIGIN_CIRCUIT(circuit_t *x)
{
tor_assert(x->magic == ORIGIN_CIRCUIT_MAGIC);
return DOWNCAST(origin_circuit_t, x);
}
+static INLINE const origin_circuit_t *CONST_TO_ORIGIN_CIRCUIT(
+ const circuit_t *x)
+{
+ tor_assert(x->magic == ORIGIN_CIRCUIT_MAGIC);
+ return DOWNCAST(origin_circuit_t, x);
+}
/** Bitfield type: things that we're willing to use invalid routers for. */
typedef enum invalid_router_usage_t {
@@ -3873,10 +3886,6 @@ typedef struct {
* testing our DNS server. */
int EnforceDistinctSubnets; /**< If true, don't allow multiple routers in the
* same network zone in the same circuit. */
- int TunnelDirConns; /**< If true, use BEGIN_DIR rather than BEGIN when
- * possible. */
- int PreferTunneledDirConns; /**< If true, avoid dirservers that don't
- * support BEGIN_DIR, when possible. */
int PortForwarding; /**< If true, use NAT-PMP or UPnP to automatically
* forward the DirPort and ORPort on the NAT device */
char *PortForwardingHelper; /** < Filename or full path of the port
@@ -4961,8 +4970,6 @@ typedef struct dir_server_t {
* node that's currently a guard. */
#define PDS_FOR_GUARD (1<<5)
-#define PDS_PREFER_TUNNELED_DIR_CONNS_ (1<<16)
-
/** Possible ways to weight routers when choosing one randomly. See
* routerlist_sl_choose_by_bandwidth() for more information.*/
typedef enum bandwidth_weight_rule_t {
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 70be39e23..5446c25e3 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -879,126 +879,6 @@ rep_hist_record_mtbf_data(time_t now, int missing_means_down)
return -1;
}
-/** Format the current tracked status of the router in <b>hist</b> at time
- * <b>now</b> for analysis; return it in a newly allocated string. */
-static char *
-rep_hist_format_router_status(or_history_t *hist, time_t now)
-{
- 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);
- up = 1;
- }
- if (hist->start_of_downtime) {
- format_iso_time(sod_buf, hist->start_of_downtime);
- down = 1;
- }
-
- wfu = get_weighted_fractional_uptime(hist, now);
- mtbf = get_stability(hist, now);
- tor_asprintf(&cp,
- "%s%s%s"
- "%s%s%s"
- "wfu %0.3f\n"
- " weighted-time %lu\n"
- " weighted-uptime %lu\n"
- "mtbf %0.1f\n"
- " weighted-run-length %lu\n"
- " total-run-weights %f\n",
- up?"uptime-started ":"", up?sor_buf:"", up?" UTC\n":"",
- down?"downtime-started ":"", down?sod_buf:"", down?" UTC\n":"",
- wfu,
- hist->total_weighted_time,
- hist->weighted_uptime,
- mtbf,
- hist->weighted_run_length,
- hist->total_run_weights
- );
- return cp;
-}
-
-/** The last stability analysis document that we created, or NULL if we never
- * have created one. */
-static char *last_stability_doc = NULL;
-/** The last time we created a stability analysis document, or 0 if we never
- * have created one. */
-static time_t built_last_stability_doc_at = 0;
-/** Shortest allowable time between building two stability documents. */
-#define MAX_STABILITY_DOC_BUILD_RATE (3*60)
-
-/** Return a pointer to a NUL-terminated document describing our view of the
- * stability of the routers we've been tracking. Return NULL on failure. */
-const char *
-rep_hist_get_router_stability_doc(time_t now)
-{
- char *result;
- smartlist_t *chunks;
- if (built_last_stability_doc_at + MAX_STABILITY_DOC_BUILD_RATE > now)
- return last_stability_doc;
-
- if (!history_map)
- return NULL;
-
- tor_free(last_stability_doc);
- chunks = smartlist_new();
-
- if (rep_hist_have_measured_enough_stability()) {
- smartlist_add(chunks, tor_strdup("we-have-enough-measurements\n"));
- } else {
- smartlist_add(chunks, tor_strdup("we-do-not-have-enough-measurements\n"));
- }
-
- DIGESTMAP_FOREACH(history_map, id, or_history_t *, hist) {
- const node_t *node;
- char dbuf[BASE64_DIGEST_LEN+1];
- char *info;
- digest_to_base64(dbuf, id);
- node = node_get_by_id(id);
- if (node) {
- char ip[INET_NTOA_BUF_LEN+1];
- char tbuf[ISO_TIME_LEN+1];
- time_t published = node_get_published_on(node);
- node_get_address_string(node,ip,sizeof(ip));
- if (published > 0)
- format_iso_time(tbuf, published);
- else
- strlcpy(tbuf, "???", sizeof(tbuf));
- smartlist_add_asprintf(chunks,
- "router %s %s %s\n"
- "published %s\n"
- "relevant-flags %s%s%s\n"
- "declared-uptime %ld\n",
- dbuf, node_get_nickname(node), ip,
- tbuf,
- node->is_running ? "Running " : "",
- node->is_valid ? "Valid " : "",
- node->ri && node->ri->is_hibernating ? "Hibernating " : "",
- node_get_declared_uptime(node));
- } else {
- smartlist_add_asprintf(chunks,
- "router %s {no descriptor}\n", dbuf);
- }
- info = rep_hist_format_router_status(hist, now);
- if (info)
- smartlist_add(chunks, info);
-
- } DIGESTMAP_FOREACH_END;
-
- result = smartlist_join_strings(chunks, "", 0, NULL);
- SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
- smartlist_free(chunks);
-
- last_stability_doc = result;
- built_last_stability_doc_at = time(NULL);
- return result;
-}
-
/** Helper: return the first j >= i such that !strcmpstart(sl[j], prefix) and
* such that no line sl[k] with i <= k < j starts with "R ". Return -1 if no
* such line exists. */
@@ -1051,7 +931,7 @@ correct_time(time_t t, time_t now, time_t stored_at, time_t started_measuring)
return 0;
else {
long run_length = stored_at - t;
- t = now - run_length;
+ t = (time_t)(now - run_length);
if (t < started_measuring)
t = started_measuring;
return t;
@@ -1212,7 +1092,7 @@ rep_hist_load_mtbf_data(time_t now)
hist->start_of_run = correct_time(start_of_run, now, stored_at,
tracked_since);
if (hist->start_of_run < latest_possible_start + wrl)
- latest_possible_start = hist->start_of_run - wrl;
+ latest_possible_start = (time_t)(hist->start_of_run - wrl);
hist->weighted_run_length = wrl;
hist->total_run_weights = trw;
@@ -2431,7 +2311,7 @@ rep_hist_buffer_stats_add_circ(circuit_t *circ, time_t end_of_interval)
return;
start_of_interval = (circ->timestamp_created.tv_sec >
start_of_buffer_stats_interval) ?
- circ->timestamp_created.tv_sec :
+ (time_t)circ->timestamp_created.tv_sec :
start_of_buffer_stats_interval;
interval_length = (int) (end_of_interval - start_of_interval);
if (interval_length <= 0)
@@ -3041,11 +2921,9 @@ rep_hist_free_all(void)
tor_free(write_array);
tor_free(dir_read_array);
tor_free(dir_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();
bidi_map_free();
diff --git a/src/or/rephist.h b/src/or/rephist.h
index df01ae6cb..cd6231e6e 100644
--- a/src/or/rephist.h
+++ b/src/or/rephist.h
@@ -47,7 +47,6 @@ 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);
diff --git a/src/or/router.c b/src/or/router.c
index 86cefc9a6..2cdbb0c8b 100755
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -1267,7 +1267,8 @@ router_perform_bandwidth_test(int num_circs, time_t now)
}
/** Return true iff our network is in some sense disabled: either we're
- * hibernating, entering hibernation, or */
+ * hibernating, entering hibernation, or the network is turned off with
+ * DisableNetwork. */
int
net_is_disabled(void)
{
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index c15274e99..8f3477a4a 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -1282,8 +1282,6 @@ const routerstatus_t *
router_pick_directory_server(dirinfo_type_t type, int flags)
{
const routerstatus_t *choice;
- if (get_options()->PreferTunneledDirConns)
- flags |= PDS_PREFER_TUNNELED_DIR_CONNS_;
if (!routerlist)
return NULL;
@@ -1385,8 +1383,6 @@ router_pick_dirserver_generic(smartlist_t *sourcelist,
{
const routerstatus_t *choice;
int busy = 0;
- if (get_options()->PreferTunneledDirConns)
- flags |= PDS_PREFER_TUNNELED_DIR_CONNS_;
choice = router_pick_trusteddirserver_impl(sourcelist, type, flags, &busy);
if (choice || !(flags & PDS_RETRY_IF_NO_SERVERS))
@@ -1411,10 +1407,7 @@ router_pick_dirserver_generic(smartlist_t *sourcelist,
/** Pick a random running valid directory server/mirror from our
* routerlist. Arguments are as for router_pick_directory_server(), except
- * that RETRY_IF_NO_SERVERS is ignored, and:
- *
- * If the PDS_PREFER_TUNNELED_DIR_CONNS_ flag is set, prefer directory servers
- * that we can use with BEGINDIR.
+ * that RETRY_IF_NO_SERVERS is ignored.
*/
static const routerstatus_t *
router_pick_directory_server_impl(dirinfo_type_t type, int flags)
@@ -1428,7 +1421,6 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags)
const networkstatus_t *consensus = networkstatus_get_latest_consensus();
int requireother = ! (flags & PDS_ALLOW_SELF);
int fascistfirewall = ! (flags & PDS_IGNORE_FASCISTFIREWALL);
- int prefer_tunnel = (flags & PDS_PREFER_TUNNELED_DIR_CONNS_);
int for_guard = (flags & PDS_FOR_GUARD);
int try_excluding = 1, n_excluded = 0;
@@ -1481,8 +1473,7 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags)
is_overloaded = status->last_dir_503_at + DIR_503_TIMEOUT > now;
- if (prefer_tunnel &&
- (!fascistfirewall ||
+ if ((!fascistfirewall ||
fascist_firewall_allows_address_or(&addr, status->or_port)))
smartlist_add(is_trusted ? trusted_tunnel :
is_overloaded ? overloaded_tunnel : tunnel, (void*)node);
@@ -1569,7 +1560,6 @@ router_pick_trusteddirserver_impl(const smartlist_t *sourcelist,
time_t now = time(NULL);
const int requireother = ! (flags & PDS_ALLOW_SELF);
const int fascistfirewall = ! (flags & PDS_IGNORE_FASCISTFIREWALL);
- const int prefer_tunnel = (flags & PDS_PREFER_TUNNELED_DIR_CONNS_);
const int no_serverdesc_fetching =(flags & PDS_NO_EXISTING_SERVERDESC_FETCH);
const int no_microdesc_fetching =(flags & PDS_NO_EXISTING_MICRODESC_FETCH);
const double auth_weight = (sourcelist == fallback_dir_servers) ?
@@ -1630,8 +1620,7 @@ router_pick_trusteddirserver_impl(const smartlist_t *sourcelist,
}
}
- if (prefer_tunnel &&
- d->or_port &&
+ if (d->or_port &&
(!fascistfirewall ||
fascist_firewall_allows_address_or(&addr, d->or_port)))
smartlist_add(is_overloaded ? overloaded_tunnel : tunnel, (void*)d);
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 14f800e7b..5add728d6 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -4129,11 +4129,13 @@ microdescs_parse_from_string(const char *s, const char *eos,
microdesc_free(md);
md = NULL;
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
memarea_clear(area);
smartlist_clear(tokens);
s = start_of_next_microdesc;
}
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
memarea_drop_all(area);
smartlist_free(tokens);
diff --git a/src/or/statefile.c b/src/or/statefile.c
index da3134171..7b9998fc1 100644
--- a/src/or/statefile.c
+++ b/src/or/statefile.c
@@ -294,6 +294,16 @@ or_state_save_broken(char *fname)
tor_free(fname2);
}
+STATIC or_state_t *
+or_state_new(void)
+{
+ or_state_t *new_state = tor_malloc_zero(sizeof(or_state_t));
+ new_state->magic_ = OR_STATE_MAGIC;
+ config_init(&state_format, new_state);
+
+ return new_state;
+}
+
/** Reload the persistent state from disk, generating a new state as needed.
* Return 0 on success, less than 0 on failure.
*/
@@ -321,9 +331,7 @@ or_state_load(void)
log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
goto done;
}
- new_state = tor_malloc_zero(sizeof(or_state_t));
- new_state->magic_ = OR_STATE_MAGIC;
- config_init(&state_format, new_state);
+ new_state = or_state_new();
if (contents) {
config_line_t *lines=NULL;
int assign_retval;
@@ -358,9 +366,7 @@ or_state_load(void)
tor_free(contents);
config_free(&state_format, new_state);
- new_state = tor_malloc_zero(sizeof(or_state_t));
- new_state->magic_ = OR_STATE_MAGIC;
- config_init(&state_format, new_state);
+ new_state = or_state_new();
} else if (contents) {
log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
} else {
@@ -625,10 +631,19 @@ save_transport_to_state(const char *transport,
tor_free(transport_addrport);
}
+STATIC void
+or_state_free(or_state_t *state)
+{
+ if (!state)
+ return;
+
+ config_free(&state_format, state);
+}
+
void
or_state_free_all(void)
{
- config_free(&state_format, global_state);
+ or_state_free(global_state);
global_state = NULL;
}
diff --git a/src/or/statefile.h b/src/or/statefile.h
index c1413ff95..15bb0b4aa 100644
--- a/src/or/statefile.h
+++ b/src/or/statefile.h
@@ -20,6 +20,8 @@ void or_state_free_all(void);
#ifdef STATEFILE_PRIVATE
STATIC config_line_t *get_transport_in_state_by_name(const char *transport);
+STATIC void or_state_free(or_state_t *state);
+STATIC or_state_t *or_state_new(void);
#endif
#endif
diff --git a/src/or/status.c b/src/or/status.c
index 7e2afbce8..afaa9de84 100644
--- a/src/or/status.c
+++ b/src/or/status.c
@@ -9,6 +9,7 @@
#define STATUS_PRIVATE
#include "or.h"
+#include "circuituse.h"
#include "config.h"
#include "status.h"
#include "nodelist.h"
@@ -135,6 +136,8 @@ log_heartbeat(time_t now)
if (public_server_mode(options))
rep_hist_log_circuit_handshake_stats(now);
+ circuit_log_ancient_one_hop_circuits(1800);
+
tor_free(uptime);
tor_free(bw_sent);
tor_free(bw_rcvd);
diff --git a/src/test/bench.c b/src/test/bench.c
index c9cc101b7..f6c33626f 100644
--- a/src/test/bench.c
+++ b/src/test/bench.c
@@ -338,6 +338,28 @@ bench_dmap(void)
}
static void
+bench_siphash(void)
+{
+ char buf[128];
+ int lens[] = { 7, 8, 15, 16, 20, 32, 111, 128, -1 };
+ int i, j;
+ uint64_t start, end;
+ const int N = 300000;
+ crypto_rand(buf, sizeof(buf));
+
+ for (i = 0; lens[i] > 0; ++i) {
+ reset_perftime();
+ start = perftime();
+ for (j = 0; j < N; ++j) {
+ siphash24g(buf, lens[i]);
+ }
+ end = perftime();
+ printf("siphash24g(%d): %.2f ns per call\n",
+ lens[i], NANOCOUNT(start,end,N));
+ }
+}
+
+static void
bench_cell_ops(void)
{
const int iters = 1<<16;
@@ -487,6 +509,7 @@ typedef struct benchmark_t {
static struct benchmark_t benchmarks[] = {
ENT(dmap),
+ ENT(siphash),
ENT(aes),
ENT(onion_TAP),
#ifdef CURVE25519_ENABLED
diff --git a/src/test/test.c b/src/test/test.c
index b49f94682..8bce9c91f 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -32,6 +32,7 @@ const char tor_git_revision[] = "";
#define ROUTER_PRIVATE
#define CIRCUITSTATS_PRIVATE
#define CIRCUITLIST_PRIVATE
+#define STATEFILE_PRIVATE
/*
* Linux doesn't provide lround in math.h by default, but mac os does...
@@ -61,6 +62,7 @@ double fabs(double x);
#include "policies.h"
#include "rephist.h"
#include "routerparse.h"
+#include "statefile.h"
#ifdef CURVE25519_ENABLED
#include "crypto_curve25519.h"
#include "onion_ntor.h"
@@ -418,9 +420,10 @@ test_onion_queues(void)
or_circuit_t *circ1 = or_circuit_new(0, NULL);
or_circuit_t *circ2 = or_circuit_new(0, NULL);
- create_cell_t *onionskin = NULL;
+ create_cell_t *onionskin = NULL, *create2_ptr;
create_cell_t *create1 = tor_malloc_zero(sizeof(create_cell_t));
create_cell_t *create2 = tor_malloc_zero(sizeof(create_cell_t));
+ create2_ptr = create2; /* remember, but do not free */
create_cell_init(create1, CELL_CREATE, ONION_HANDSHAKE_TYPE_TAP,
TAP_ONIONSKIN_CHALLENGE_LEN, buf1);
@@ -440,6 +443,7 @@ test_onion_queues(void)
test_eq_ptr(circ2, onion_next_task(&onionskin));
test_eq(1, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
+ tt_ptr_op(onionskin, ==, create2_ptr);
clear_pending_onions();
test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
@@ -450,6 +454,7 @@ test_onion_queues(void)
circuit_free(TO_CIRCUIT(circ2));
tor_free(create1);
tor_free(create2);
+ tor_free(onionskin);
}
static void
@@ -468,14 +473,14 @@ test_circuit_timeout(void)
circuit_build_times_t estimate;
circuit_build_times_t final;
double timeout1, timeout2;
- or_state_t state;
+ or_state_t *state=NULL;
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));
+ state = or_state_new();
circuitbuild_running_unit_tests();
#define timeout0 (build_time_t)(30*1000.0)
@@ -507,8 +512,9 @@ test_circuit_timeout(void)
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_state(&estimate, state);
+ circuit_build_times_free_timeouts(&final);
+ test_assert(circuit_build_times_parse_state(&final, state) == 0);
circuit_build_times_update_alpha(&final);
timeout2 = circuit_build_times_calculate_timeout(&final,
@@ -597,7 +603,10 @@ test_circuit_timeout(void)
}
done:
- return;
+ circuit_build_times_free_timeouts(&initial);
+ circuit_build_times_free_timeouts(&estimate);
+ circuit_build_times_free_timeouts(&final);
+ or_state_free(state);
}
/** Test encoding and parsing of rendezvous service descriptors. */
@@ -948,6 +957,7 @@ test_geoip(void)
geoip_start_dirreq((uint64_t) 1, 1024, DIRREQ_TUNNELED);
s = geoip_format_dirreq_stats(now + 86400);
test_streq(dirreq_stats_4, s);
+ tor_free(s);
/* Stop collecting directory request statistics and start gathering
* entry stats. */
@@ -1010,6 +1020,8 @@ test_geoip_with_pt(void)
get_options_mutable()->BridgeRelay = 1;
get_options_mutable()->BridgeRecordUsageByCountry = 1;
+ memset(&in6, 0, sizeof(in6));
+
/* No clients seen yet. */
s = geoip_get_transport_history();
tor_assert(!s);
diff --git a/src/test/test.h b/src/test/test.h
index 0ccf6c718..861ce5ac3 100644
--- a/src/test/test.h
+++ b/src/test/test.h
@@ -59,6 +59,29 @@
tt_assert_test_type(a,b,#a" "#op" "#b,double,(val1_ op val2_),"%f", \
TT_EXIT_TEST_FUNCTION)
+#ifdef _MSC_VER
+#define U64_PRINTF_TYPE uint64_t
+#define U64_PRINTF_TYPE int64_t
+#else
+#define U64_PRINTF_TYPE unsigned long long
+#define I64_PRINTF_TYPE long long
+#endif
+
+#define tt_size_op(a,op,b) \
+ tt_assert_test_fmt_type(a,b,#a" "#op" "#b,size_t,(val1_ op val2_), \
+ U64_PRINTF_TYPE, U64_FORMAT, \
+ {print_ = (U64_PRINTF_TYPE) value_;}, {}, TT_EXIT_TEST_FUNCTION)
+
+#define tt_u64_op(a,op,b) \
+ tt_assert_test_fmt_type(a,b,#a" "#op" "#b,uint64_t,(val1_ op val2_), \
+ U64_PRINTF_TYPE, U64_FORMAT, \
+ {print_ = (U64_PRINTF_TYPE) value_;}, {}, TT_EXIT_TEST_FUNCTION)
+
+#define tt_i64_op(a,op,b) \
+ tt_assert_test_fmt_type(a,b,#a" "#op" "#b,int64_t,(val1_ op val2_), \
+ I64_PRINTF_TYPE, I64_FORMAT, \
+ {print_ = (I64_PRINTF_TYPE) value_;}, {}, TT_EXIT_TEST_FUNCTION)
+
const char *get_fname(const char *name);
crypto_pk_t *pk_generate(int idx);
diff --git a/src/test/test_buffers.c b/src/test/test_buffers.c
index c2cfd2700..61ac5bc36 100644
--- a/src/test/test_buffers.c
+++ b/src/test/test_buffers.c
@@ -222,7 +222,7 @@ test_buffer_pullup(void *arg)
buf_pullup(buf, 16, 1);
buf_get_first_chunk_data(buf, &cp, &sz);
tt_ptr_op(cp, ==, NULL);
- tt_ptr_op(sz, ==, 0);
+ tt_uint_op(sz, ==, 0);
/* Let's make sure nothing got allocated */
tt_int_op(buf_get_total_allocation(), ==, 0);
@@ -522,6 +522,7 @@ test_buffer_allocation_tracking(void *arg)
buf_free(buf1);
buf_free(buf2);
buf_shrink_freelists(1);
+ tor_free(junk);
}
static void
@@ -596,6 +597,124 @@ test_buffer_time_tracking(void *arg)
buf_free(buf2);
}
+static void
+test_buffers_zlib_impl(int finalize_with_nil)
+{
+ char *msg = NULL;
+ char *contents = NULL;
+ char *expanded = NULL;
+ buf_t *buf = NULL;
+ tor_zlib_state_t *zlib_state = NULL;
+ size_t out_len, in_len;
+ int done;
+
+ buf = buf_new_with_capacity(128); /* will round up */
+ zlib_state = tor_zlib_new(1, ZLIB_METHOD);
+
+ msg = tor_malloc(512);
+ crypto_rand(msg, 512);
+ tt_int_op(write_to_buf_zlib(buf, zlib_state, msg, 128, 0), ==, 0);
+ tt_int_op(write_to_buf_zlib(buf, zlib_state, msg+128, 128, 0), ==, 0);
+ tt_int_op(write_to_buf_zlib(buf, zlib_state, msg+256, 256, 0), ==, 0);
+ done = !finalize_with_nil;
+ tt_int_op(write_to_buf_zlib(buf, zlib_state, "all done", 9, done), ==, 0);
+ if (finalize_with_nil) {
+ tt_int_op(write_to_buf_zlib(buf, zlib_state, "", 0, 1), ==, 0);
+ }
+
+ in_len = buf_datalen(buf);
+ contents = tor_malloc(in_len);
+
+ tt_int_op(fetch_from_buf(contents, in_len, buf), ==, 0);
+
+ tt_int_op(0, ==, tor_gzip_uncompress(&expanded, &out_len,
+ contents, in_len,
+ ZLIB_METHOD, 1,
+ LOG_WARN));
+
+ tt_int_op(out_len, >=, 128);
+ tt_mem_op(msg, ==, expanded, 128);
+ tt_int_op(out_len, >=, 512);
+ tt_mem_op(msg, ==, expanded, 512);
+ tt_int_op(out_len, ==, 512+9);
+ tt_mem_op("all done", ==, expanded+512, 9);
+
+ done:
+ buf_free(buf);
+ tor_zlib_free(zlib_state);
+ tor_free(contents);
+ tor_free(expanded);
+ tor_free(msg);
+}
+
+static void
+test_buffers_zlib(void *arg)
+{
+ (void) arg;
+ test_buffers_zlib_impl(0);
+}
+static void
+test_buffers_zlib_fin_with_nil(void *arg)
+{
+ (void) arg;
+ test_buffers_zlib_impl(1);
+}
+
+static void
+test_buffers_zlib_fin_at_chunk_end(void *arg)
+{
+ char *msg = NULL;
+ char *contents = NULL;
+ char *expanded = NULL;
+ buf_t *buf = NULL;
+ tor_zlib_state_t *zlib_state = NULL;
+ size_t out_len, in_len;
+ size_t sz, headerjunk;
+ (void) arg;
+
+ buf = buf_new_with_capacity(128); /* will round up */
+ sz = buf_get_default_chunk_size(buf);
+ msg = tor_malloc_zero(sz);
+
+ write_to_buf(msg, 1, buf);
+ tt_assert(buf->head);
+
+ /* Fill up the chunk so the zlib stuff won't fit in one chunk. */
+ tt_uint_op(buf->head->memlen, <, sz);
+ headerjunk = buf->head->memlen - 7;
+ write_to_buf(msg, headerjunk-1, buf);
+ tt_uint_op(buf->head->datalen, ==, headerjunk);
+ printf("<%u>\n", (unsigned)buf_datalen(buf));
+ tt_uint_op(buf_datalen(buf), ==, headerjunk);
+ /* Write an empty string, with finalization on. */
+ zlib_state = tor_zlib_new(1, ZLIB_METHOD);
+ tt_int_op(write_to_buf_zlib(buf, zlib_state, "", 0, 1), ==, 0);
+
+ printf("<%u>\n", (unsigned)buf_datalen(buf));
+
+ in_len = buf_datalen(buf);
+ contents = tor_malloc(in_len);
+
+ tt_int_op(fetch_from_buf(contents, in_len, buf), ==, 0);
+
+ tt_uint_op(in_len, >, headerjunk);
+
+ tt_int_op(0, ==, tor_gzip_uncompress(&expanded, &out_len,
+ contents + headerjunk, in_len - headerjunk,
+ ZLIB_METHOD, 1,
+ LOG_WARN));
+
+ tt_int_op(out_len, ==, 0);
+ tt_assert(expanded);
+
+ done:
+ buf_free(buf);
+ tor_zlib_free(zlib_state);
+ tor_free(contents);
+ tor_free(expanded);
+ tor_free(msg);
+}
+
struct testcase_t buffer_tests[] = {
{ "basic", test_buffers_basic, TT_FORK, NULL, NULL },
{ "copy", test_buffer_copy, TT_FORK, NULL, NULL },
@@ -604,6 +723,10 @@ struct testcase_t buffer_tests[] = {
{ "allocation_tracking", test_buffer_allocation_tracking, TT_FORK,
NULL, NULL },
{ "time_tracking", test_buffer_time_tracking, TT_FORK, NULL, NULL },
+ { "zlib", test_buffers_zlib, TT_FORK, NULL, NULL },
+ { "zlib_fin_with_nil", test_buffers_zlib_fin_with_nil, TT_FORK, NULL, NULL },
+ { "zlib_fin_at_chunk_end", test_buffers_zlib_fin_at_chunk_end, TT_FORK,
+ NULL, NULL},
END_OF_TESTCASES
};
diff --git a/src/test/test_cell_formats.c b/src/test/test_cell_formats.c
index b0eb2fca2..d7f60680c 100644
--- a/src/test/test_cell_formats.c
+++ b/src/test/test_cell_formats.c
@@ -8,7 +8,9 @@
#define CONNECTION_EDGE_PRIVATE
#define RELAY_PRIVATE
#include "or.h"
+#include "channel.h"
#include "connection_edge.h"
+#include "connection_or.h"
#include "onion.h"
#include "onion_tap.h"
#include "onion_fast.h"
@@ -1212,6 +1214,47 @@ test_cfmt_resolved_cells(void *arg)
#undef CLEAR_CELL
}
+static void
+test_cfmt_is_destroy(void *arg)
+{
+ cell_t cell;
+ packed_cell_t packed;
+ circid_t circid = 0;
+ channel_t *chan;
+ (void)arg;
+
+ chan = tor_malloc_zero(sizeof(channel_t));
+
+ memset(&cell, 0xff, sizeof(cell));
+ cell.circ_id = 3003;
+ cell.command = CELL_RELAY;
+
+ cell_pack(&packed, &cell, 0);
+ chan->wide_circ_ids = 0;
+ tt_assert(! packed_cell_is_destroy(chan, &packed, &circid));
+ tt_int_op(circid, ==, 0);
+
+ cell_pack(&packed, &cell, 1);
+ chan->wide_circ_ids = 1;
+ tt_assert(! packed_cell_is_destroy(chan, &packed, &circid));
+ tt_int_op(circid, ==, 0);
+
+ cell.command = CELL_DESTROY;
+
+ cell_pack(&packed, &cell, 0);
+ chan->wide_circ_ids = 0;
+ tt_assert(packed_cell_is_destroy(chan, &packed, &circid));
+ tt_int_op(circid, ==, 3003);
+
+ circid = 0;
+ cell_pack(&packed, &cell, 1);
+ chan->wide_circ_ids = 1;
+ tt_assert(packed_cell_is_destroy(chan, &packed, &circid));
+
+ done:
+ tor_free(chan);
+}
+
#define TEST(name, flags) \
{ #name, test_cfmt_ ## name, flags, 0, NULL }
@@ -1224,6 +1267,7 @@ struct testcase_t cell_format_tests[] = {
TEST(extend_cells, 0),
TEST(extended_cells, 0),
TEST(resolved_cells, 0),
+ TEST(is_destroy, 0),
END_OF_TESTCASES
};
diff --git a/src/test/test_circuitlist.c b/src/test/test_circuitlist.c
index ad8d0ac3a..b19edd1fd 100644
--- a/src/test/test_circuitlist.c
+++ b/src/test/test_circuitlist.c
@@ -2,9 +2,11 @@
/* See LICENSE for licensing information */
#define TOR_CHANNEL_INTERNAL_
+#define CIRCUITBUILD_PRIVATE
#define CIRCUITLIST_PRIVATE
#include "or.h"
#include "channel.h"
+#include "circuitbuild.h"
#include "circuitlist.h"
#include "test.h"
@@ -51,7 +53,7 @@ circuitmux_detach_mock(circuitmux_t *cmux, circuit_t *circ)
tt_int_op(cam.ncalls, ==, 1); \
tt_ptr_op(cam.cmux, ==, (mux_)); \
tt_ptr_op(cam.circ, ==, (circ_)); \
- tt_ptr_op(cam.dir, ==, (dir_)); \
+ tt_int_op(cam.dir, ==, (dir_)); \
memset(&cam, 0, sizeof(cam)); \
} while (0)
@@ -257,9 +259,84 @@ test_rend_token_maps(void *arg)
circuit_free(TO_CIRCUIT(c4));
}
+static void
+test_pick_circid(void *arg)
+{
+ bitarray_t *ba = NULL;
+ channel_t *chan1, *chan2;
+ circid_t circid;
+ int i;
+ (void) arg;
+
+ chan1 = tor_malloc_zero(sizeof(channel_t));
+ chan2 = tor_malloc_zero(sizeof(channel_t));
+ chan2->wide_circ_ids = 1;
+
+ chan1->circ_id_type = CIRC_ID_TYPE_NEITHER;
+ tt_int_op(0, ==, get_unique_circ_id_by_chan(chan1));
+
+ /* Basic tests, with no collisions */
+ chan1->circ_id_type = CIRC_ID_TYPE_LOWER;
+ for (i = 0; i < 50; ++i) {
+ circid = get_unique_circ_id_by_chan(chan1);
+ tt_uint_op(0, <, circid);
+ tt_uint_op(circid, <, (1<<15));
+ }
+ chan1->circ_id_type = CIRC_ID_TYPE_HIGHER;
+ for (i = 0; i < 50; ++i) {
+ circid = get_unique_circ_id_by_chan(chan1);
+ tt_uint_op((1<<15), <, circid);
+ tt_uint_op(circid, <, (1<<16));
+ }
+
+ chan2->circ_id_type = CIRC_ID_TYPE_LOWER;
+ for (i = 0; i < 50; ++i) {
+ circid = get_unique_circ_id_by_chan(chan2);
+ tt_uint_op(0, <, circid);
+ tt_uint_op(circid, <, (1u<<31));
+ }
+ chan2->circ_id_type = CIRC_ID_TYPE_HIGHER;
+ for (i = 0; i < 50; ++i) {
+ circid = get_unique_circ_id_by_chan(chan2);
+ tt_uint_op((1u<<31), <, circid);
+ }
+
+ /* Now make sure that we can behave well when we are full up on circuits */
+ chan1->circ_id_type = CIRC_ID_TYPE_LOWER;
+ chan2->circ_id_type = CIRC_ID_TYPE_LOWER;
+ chan1->wide_circ_ids = chan2->wide_circ_ids = 0;
+ ba = bitarray_init_zero((1<<15));
+ for (i = 0; i < (1<<15); ++i) {
+ circid = get_unique_circ_id_by_chan(chan1);
+ if (circid == 0) {
+ tt_int_op(i, >, (1<<14));
+ break;
+ }
+ tt_uint_op(circid, <, (1<<15));
+ tt_assert(! bitarray_is_set(ba, circid));
+ bitarray_set(ba, circid);
+ channel_mark_circid_unusable(chan1, circid);
+ }
+ tt_int_op(i, <, (1<<15));
+ /* Make sure that being full on chan1 does not interfere with chan2 */
+ for (i = 0; i < 100; ++i) {
+ circid = get_unique_circ_id_by_chan(chan2);
+ tt_uint_op(circid, >, 0);
+ tt_uint_op(circid, <, (1<<15));
+ channel_mark_circid_unusable(chan2, circid);
+ }
+
+ done:
+ tor_free(chan1);
+ tor_free(chan2);
+ bitarray_free(ba);
+ circuit_free_all();
+}
+
struct testcase_t circuitlist_tests[] = {
{ "maps", test_clist_maps, TT_FORK, NULL, NULL },
{ "rend_token_maps", test_rend_token_maps, TT_FORK, NULL, NULL },
+ { "pick_circid", test_pick_circid, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
diff --git a/src/test/test_config.c b/src/test/test_config.c
index dbb50798b..94ac4dca1 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -124,6 +124,7 @@ test_config_addressmap(void *arg)
test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
/* Test top-level-domain matching a bit harder */
+ config_free_lines(get_options_mutable()->AddressMap);
addressmap_clear_configured();
strlcpy(buf, "MapAddress *.com *.torserver.exit\n"
"MapAddress *.torproject.org 1.1.1.1\n"
@@ -153,6 +154,7 @@ test_config_addressmap(void *arg)
test_streq(address, "2.2.2.2");
/* We don't support '*' as a mapping directive */
+ config_free_lines(get_options_mutable()->AddressMap);
addressmap_clear_configured();
strlcpy(buf, "MapAddress * *.torserver.exit\n", sizeof(buf));
config_get_lines(buf, &(get_options_mutable()->AddressMap), 0);
@@ -170,7 +172,8 @@ test_config_addressmap(void *arg)
#undef addressmap_rewrite
done:
- ;
+ config_free_lines(get_options_mutable()->AddressMap);
+ get_options_mutable()->AddressMap = NULL;
}
static int
@@ -193,9 +196,9 @@ static void
test_config_check_or_create_data_subdir(void *arg)
{
or_options_t *options = get_options_mutable();
- char *datadir = options->DataDirectory = tor_strdup(get_fname("datadir-0"));
+ char *datadir;
const char *subdir = "test_stats";
- char *subpath = get_datadir_fname(subdir);
+ char *subpath;
struct stat st;
int r;
#if !defined (_WIN32) || defined (WINCE)
@@ -203,6 +206,10 @@ test_config_check_or_create_data_subdir(void *arg)
#endif
(void)arg;
+ tor_free(options->DataDirectory);
+ datadir = options->DataDirectory = tor_strdup(get_fname("datadir-0"));
+ subpath = get_datadir_fname(subdir);
+
#if defined (_WIN32) && !defined (WINCE)
tt_int_op(mkdir(options->DataDirectory), ==, 0);
#else
@@ -251,7 +258,7 @@ static void
test_config_write_to_data_subdir(void *arg)
{
or_options_t* options = get_options_mutable();
- char *datadir = options->DataDirectory = tor_strdup(get_fname("datadir-1"));
+ char *datadir;
char *cp = NULL;
const char* subdir = "test_stats";
const char* fname = "test_file";
@@ -270,9 +277,13 @@ test_config_write_to_data_subdir(void *arg)
"accusam et justo duo dolores et\n"
"ea rebum. Stet clita kasd gubergren, no sea takimata\n"
"sanctus est Lorem ipsum dolor sit amet.";
- char* filepath = get_datadir_fname2(subdir, fname);
+ char* filepath = NULL;
(void)arg;
+ tor_free(options->DataDirectory);
+ datadir = options->DataDirectory = tor_strdup(get_fname("datadir-1"));
+ filepath = get_datadir_fname2(subdir, fname);
+
#if defined (_WIN32) && !defined (WINCE)
tt_int_op(mkdir(options->DataDirectory), ==, 0);
#else
diff --git a/src/test/test_controller_events.c b/src/test/test_controller_events.c
index 3a9aeca2f..b45e97a41 100644
--- a/src/test/test_controller_events.c
+++ b/src/test/test_controller_events.c
@@ -118,26 +118,26 @@ test_cntev_sum_up_cell_stats(void *arg)
cell_stats = tor_malloc_zero(sizeof(cell_stats_t));
add_testing_cell_stats_entry(circ, CELL_RELAY, 0, 0, 0);
sum_up_cell_stats_by_command(circ, cell_stats);
- tt_int_op(1, ==, cell_stats->added_cells_appward[CELL_RELAY]);
+ tt_u64_op(1, ==, cell_stats->added_cells_appward[CELL_RELAY]);
/* A single RELAY cell was added to the exitward queue. */
add_testing_cell_stats_entry(circ, CELL_RELAY, 0, 0, 1);
sum_up_cell_stats_by_command(circ, cell_stats);
- tt_int_op(1, ==, cell_stats->added_cells_exitward[CELL_RELAY]);
+ tt_u64_op(1, ==, cell_stats->added_cells_exitward[CELL_RELAY]);
/* A single RELAY cell was removed from the appward queue where it spent
* 20 msec. */
add_testing_cell_stats_entry(circ, CELL_RELAY, 2, 1, 0);
sum_up_cell_stats_by_command(circ, cell_stats);
- tt_int_op(20, ==, cell_stats->total_time_appward[CELL_RELAY]);
- tt_int_op(1, ==, cell_stats->removed_cells_appward[CELL_RELAY]);
+ tt_u64_op(20, ==, cell_stats->total_time_appward[CELL_RELAY]);
+ tt_u64_op(1, ==, cell_stats->removed_cells_appward[CELL_RELAY]);
/* A single RELAY cell was removed from the exitward queue where it
* spent 30 msec. */
add_testing_cell_stats_entry(circ, CELL_RELAY, 3, 1, 1);
sum_up_cell_stats_by_command(circ, cell_stats);
- tt_int_op(30, ==, cell_stats->total_time_exitward[CELL_RELAY]);
- tt_int_op(1, ==, cell_stats->removed_cells_exitward[CELL_RELAY]);
+ tt_u64_op(30, ==, cell_stats->total_time_exitward[CELL_RELAY]);
+ tt_u64_op(1, ==, cell_stats->removed_cells_exitward[CELL_RELAY]);
done:
tor_free(cell_stats);
@@ -148,6 +148,7 @@ static void
test_cntev_append_cell_stats(void *arg)
{
smartlist_t *event_parts;
+ char *cp = NULL;
const char *key = "Z";
uint64_t include_if_non_zero[CELL_COMMAND_MAX_ + 1],
number_to_include[CELL_COMMAND_MAX_ + 1];
@@ -178,7 +179,9 @@ test_cntev_append_cell_stats(void *arg)
append_cell_stats_by_command(event_parts, key,
include_if_non_zero,
number_to_include);
- tt_str_op("Z=relay:1", ==, smartlist_pop_last(event_parts));
+ cp = smartlist_pop_last(event_parts);
+ tt_str_op("Z=relay:1", ==, cp);
+ tor_free(cp);
/* Add four CREATE cells. */
include_if_non_zero[CELL_CREATE] = 3;
@@ -186,20 +189,22 @@ test_cntev_append_cell_stats(void *arg)
append_cell_stats_by_command(event_parts, key,
include_if_non_zero,
number_to_include);
- tt_str_op("Z=create:4,relay:1", ==, smartlist_pop_last(event_parts));
+ cp = smartlist_pop_last(event_parts);
+ tt_str_op("Z=create:4,relay:1", ==, cp);
done:
- ;
+ tor_free(cp);
+ smartlist_free(event_parts);
}
static void
test_cntev_format_cell_stats(void *arg)
{
char *event_string = NULL;
- origin_circuit_t *ocirc;
- or_circuit_t *or_circ;
+ origin_circuit_t *ocirc = NULL;
+ or_circuit_t *or_circ = NULL;
cell_stats_t *cell_stats = NULL;
- channel_tls_t *n_chan, *p_chan;
+ channel_tls_t *n_chan=NULL, *p_chan=NULL;
(void)arg;
n_chan = tor_malloc_zero(sizeof(channel_tls_t));
@@ -282,6 +287,10 @@ test_cntev_format_cell_stats(void *arg)
done:
tor_free(cell_stats);
tor_free(event_string);
+ tor_free(or_circ);
+ tor_free(ocirc);
+ tor_free(p_chan);
+ tor_free(n_chan);
}
#define TEST(name, flags) \
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index 1fda33476..5d8edb655 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -1132,7 +1132,8 @@ test_crypto_curve25519_persist(void *arg)
content = read_file_to_str(fname, RFTS_BIN, &st);
tt_assert(content);
taglen = strlen("== c25519v1: testing ==");
- tt_int_op(st.st_size, ==, 32+CURVE25519_PUBKEY_LEN+CURVE25519_SECKEY_LEN);
+ tt_u64_op((uint64_t)st.st_size, ==,
+ 32+CURVE25519_PUBKEY_LEN+CURVE25519_SECKEY_LEN);
tt_assert(fast_memeq(content, "== c25519v1: testing ==", taglen));
tt_assert(tor_mem_is_zero(content+taglen, 32-taglen));
cp = content + 32;
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index 9e01bdbd4..c03b63be2 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -11,6 +11,7 @@
#define ROUTER_PRIVATE
#define ROUTERLIST_PRIVATE
#define HIBERNATE_PRIVATE
+#define NETWORKSTATUS_PRIVATE
#include "or.h"
#include "config.h"
#include "directory.h"
@@ -194,6 +195,7 @@ test_dir_formats(void)
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);
+ tor_free(buf);
strlcpy(buf2,
"router Fred 10.3.2.1 9005 0 0\n"
@@ -277,6 +279,8 @@ test_dir_formats(void)
routerinfo_free(r1);
if (r2)
routerinfo_free(r2);
+ if (rp2)
+ routerinfo_free(rp2);
tor_free(buf);
tor_free(pk1_str);
@@ -1011,16 +1015,14 @@ vote_tweaks_for_v3ns(networkstatus_t *v, int voter, time_t now)
/* Monkey around with the list a bit */
vrs = smartlist_get(v->routerstatus_list, 2);
smartlist_del_keeporder(v->routerstatus_list, 2);
- tor_free(vrs->version);
- tor_free(vrs);
+ vote_routerstatus_free(vrs);
vrs = smartlist_get(v->routerstatus_list, 0);
vrs->status.is_fast = 1;
if (voter == 3) {
vrs = smartlist_get(v->routerstatus_list, 0);
smartlist_del_keeporder(v->routerstatus_list, 0);
- tor_free(vrs->version);
- tor_free(vrs);
+ vote_routerstatus_free(vrs);
vrs = smartlist_get(v->routerstatus_list, 0);
memset(vrs->status.descriptor_digest, (int)'Z', DIGEST_LEN);
test_assert(router_add_to_routerlist(
@@ -1064,7 +1066,7 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
test_eq(rs->or_port, 443);
test_eq(rs->dir_port, 8000);
/* no flags except "running" (16) and "v2dir" (64) */
- test_eq(vrs->flags, U64_LITERAL(80));
+ tt_u64_op(vrs->flags, ==, U64_LITERAL(80));
} else if (tor_memeq(rs->identity_digest,
"\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
"\x5\x5\x5\x5",
@@ -1090,10 +1092,10 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
test_eq(rs->ipv6_orport, 4711);
if (voter == 1) {
/* all except "authority" (1) and "v2dir" (64) */
- test_eq(vrs->flags, U64_LITERAL(190));
+ tt_u64_op(vrs->flags, ==, U64_LITERAL(190));
} else {
/* 1023 - authority(1) - madeofcheese(16) - madeoftin(32) - v2dir(256) */
- test_eq(vrs->flags, U64_LITERAL(718));
+ tt_u64_op(vrs->flags, ==, U64_LITERAL(718));
}
} else if (tor_memeq(rs->identity_digest,
"\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
@@ -1360,7 +1362,8 @@ test_a_networkstatus(
vote->dist_seconds = 300;
authority_cert_free(vote->cert);
vote->cert = authority_cert_dup(cert2);
- vote->net_params = smartlist_new();
+ SMARTLIST_FOREACH(vote->net_params, char *, c, tor_free(c));
+ smartlist_clear(vote->net_params);
smartlist_split_string(vote->net_params, "bar=2000000000 circuitwindow=20",
NULL, 0, 0);
tor_free(vote->client_versions);
@@ -1404,7 +1407,8 @@ test_a_networkstatus(
vote->dist_seconds = 250;
authority_cert_free(vote->cert);
vote->cert = authority_cert_dup(cert3);
- vote->net_params = smartlist_new();
+ SMARTLIST_FOREACH(vote->net_params, char *, c, tor_free(c));
+ smartlist_clear(vote->net_params);
smartlist_split_string(vote->net_params, "circuitwindow=80 foo=660",
NULL, 0, 0);
smartlist_add(vote->supported_methods, tor_strdup("4"));
@@ -1771,7 +1775,7 @@ test_dir_random_weighted(void *testdata)
inp[i].u64 = vals[i];
total += vals[i];
}
- tt_int_op(total, ==, 45);
+ tt_u64_op(total, ==, 45);
for (i=0; i<n; ++i) {
choice = choose_array_element_by_weight(inp, 10);
tt_int_op(choice, >=, 0);
@@ -1981,6 +1985,7 @@ vote_tweaks_for_umbw(networkstatus_t *v, int voter, time_t now)
(void)now;
test_assert(v->supported_methods);
+ SMARTLIST_FOREACH(v->supported_methods, char *, c, tor_free(c));
smartlist_clear(v->supported_methods);
/* Method 17 is MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB */
smartlist_split_string(v->supported_methods,
diff --git a/src/test/test_extorport.c b/src/test/test_extorport.c
index f91ac7415..93c8f77d5 100644
--- a/src/test/test_extorport.c
+++ b/src/test/test_extorport.c
@@ -172,6 +172,7 @@ test_ext_or_init_auth(void *arg)
(void)arg;
/* Check default filename location */
+ tor_free(options->DataDirectory);
options->DataDirectory = tor_strdup("foo");
cp = get_ext_or_auth_cookie_file_name();
tt_str_op(cp, ==, "foo"PATH_SEPARATOR"extended_orport_auth_cookie");
@@ -201,7 +202,7 @@ test_ext_or_init_auth(void *arg)
tt_int_op(ext_or_auth_cookie_is_set, ==, 1);
cp = read_file_to_str(fn, RFTS_BIN, &st);
tt_ptr_op(cp, !=, NULL);
- tt_int_op(st.st_size, ==, 64);
+ tt_u64_op((uint64_t)st.st_size, ==, 64);
test_memeq(cp, "! Extended ORPort Auth Cookie !\x0a", 32);
test_memeq(cp+32, ext_or_auth_cookie, 32);
memcpy(cookie0, ext_or_auth_cookie, 32);
@@ -337,7 +338,7 @@ test_ext_or_cookie_auth_testvec(void *arg)
handle_client_auth_nonce(client_nonce, 32, &client_hash, &reply,
&reply_len));
tt_ptr_op(reply, !=, NULL );
- tt_ptr_op(reply_len, ==, 64);
+ tt_uint_op(reply_len, ==, 64);
test_memeq(reply+32, "te road There is always another ", 32);
/* HMACSHA256("Gliding wrapt in a brown mantle,"
* "ExtORPort authentication server-to-client hash"
diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c
index 53a03a48a..78f4823b8 100644
--- a/src/test/test_microdesc.c
+++ b/src/test/test_microdesc.c
@@ -5,7 +5,10 @@
#include "or.h"
#include "config.h"
+#include "dirvote.h"
#include "microdesc.h"
+#include "routerlist.h"
+#include "routerparse.h"
#include "test.h"
@@ -261,6 +264,7 @@ test_md_cache_broken(void *data)
options = get_options_mutable();
tt_assert(options);
+ tor_free(options->DataDirectory);
options->DataDirectory = tor_strdup(get_fname("md_datadir_test2"));
#ifdef _WIN32
@@ -284,9 +288,113 @@ test_md_cache_broken(void *data)
microdesc_free_all();
}
+/* Generated by chutney. */
+static const char test_ri[] =
+ "router test005r 127.0.0.1 5005 0 7005\n"
+ "platform Tor 0.2.5.4-alpha-dev on Linux\n"
+ "protocols Link 1 2 Circuit 1\n"
+ "published 2014-05-06 22:57:55\n"
+ "fingerprint 09DE 3BA2 48C2 1C3F 3760 6CD3 8460 43A6 D5EC F59E\n"
+ "uptime 0\n"
+ "bandwidth 1073741824 1073741824 0\n"
+ "extra-info-digest 361F9428F9FA4DD854C03DDBCC159D0D9FA996C9\n"
+ "onion-key\n"
+ "-----BEGIN RSA PUBLIC KEY-----\n"
+ "MIGJAoGBANBJz8Vldl12aFeSMPLiA4nOetLDN0oxU8bB1SDhO7Uu2zdWYVYAF5J0\n"
+ "st7WvrVy/jA9v/fsezNAPskBanecHRSkdMTpkcgRPMHE7CTGEwIy1Yp1X4bPgDlC\n"
+ "VCnbs5Pcts5HnWEYNK7qHDAUn+IlmjOO+pTUY8uyq+GQVz6H9wFlAgMBAAE=\n"
+ "-----END RSA PUBLIC KEY-----\n"
+ "signing-key\n"
+ "-----BEGIN RSA PUBLIC KEY-----\n"
+ "MIGJAoGBANbGUC4802Ke6C3nOVxN0U0HhIRrs32cQFEL4v+UUMJPgjbistHBvOax\n"
+ "CWVR/sMXM2kKJeGThJ9ZUs2p9dDG4WHPUXgkMqzTTEeeFa7pQKU0brgbmLaJq0Pi\n"
+ "mxmqC5RkTHa5bQvq6QlSFprAEoovV27cWqBM9jVdV9hyc//6kwPzAgMBAAE=\n"
+ "-----END RSA PUBLIC KEY-----\n"
+ "hidden-service-dir\n"
+ "ntor-onion-key Gg73xH7+kTfT6bi1uNVx9gwQdQas9pROIfmc4NpAdC4=\n"
+ "reject *:25\n"
+ "reject *:119\n"
+ "reject *:135-139\n"
+ "reject *:445\n"
+ "reject *:563\n"
+ "reject *:1214\n"
+ "reject *:4661-4666\n"
+ "reject *:6346-6429\n"
+ "reject *:6699\n"
+ "reject *:6881-6999\n"
+ "accept *:*\n"
+ "router-signature\n"
+ "-----BEGIN SIGNATURE-----\n"
+ "ImzX5PF2vRCrG1YzGToyjoxYhgh1vtHEDjmP+tIS/iil1DSnHZNpHSuHp0L1jE9S\n"
+ "yZyrtKaqpBE/aecAM3j4CWCn/ipnAAQkHcyRLin1bYvqBtRzyopVCRlUhF+uWrLq\n"
+ "t0xkIE39ss/EwmQr7iIgkdVH4oRIMsjYnFFJBG26nYY=\n"
+ "-----END SIGNATURE-----\n";
+
+static const char test_md_8[] =
+ "onion-key\n"
+ "-----BEGIN RSA PUBLIC KEY-----\n"
+ "MIGJAoGBANBJz8Vldl12aFeSMPLiA4nOetLDN0oxU8bB1SDhO7Uu2zdWYVYAF5J0\n"
+ "st7WvrVy/jA9v/fsezNAPskBanecHRSkdMTpkcgRPMHE7CTGEwIy1Yp1X4bPgDlC\n"
+ "VCnbs5Pcts5HnWEYNK7qHDAUn+IlmjOO+pTUY8uyq+GQVz6H9wFlAgMBAAE=\n"
+ "-----END RSA PUBLIC KEY-----\n"
+ "p reject 25,119,135-139,445,563,1214,4661-4666,6346-6429,6699,6881-6999\n";
+
+static const char test_md_16[] =
+ "onion-key\n"
+ "-----BEGIN RSA PUBLIC KEY-----\n"
+ "MIGJAoGBANBJz8Vldl12aFeSMPLiA4nOetLDN0oxU8bB1SDhO7Uu2zdWYVYAF5J0\n"
+ "st7WvrVy/jA9v/fsezNAPskBanecHRSkdMTpkcgRPMHE7CTGEwIy1Yp1X4bPgDlC\n"
+ "VCnbs5Pcts5HnWEYNK7qHDAUn+IlmjOO+pTUY8uyq+GQVz6H9wFlAgMBAAE=\n"
+ "-----END RSA PUBLIC KEY-----\n"
+ "ntor-onion-key Gg73xH7+kTfT6bi1uNVx9gwQdQas9pROIfmc4NpAdC4=\n"
+ "p reject 25,119,135-139,445,563,1214,4661-4666,6346-6429,6699,6881-6999\n";
+
+static const char test_md_18[] =
+ "onion-key\n"
+ "-----BEGIN RSA PUBLIC KEY-----\n"
+ "MIGJAoGBANBJz8Vldl12aFeSMPLiA4nOetLDN0oxU8bB1SDhO7Uu2zdWYVYAF5J0\n"
+ "st7WvrVy/jA9v/fsezNAPskBanecHRSkdMTpkcgRPMHE7CTGEwIy1Yp1X4bPgDlC\n"
+ "VCnbs5Pcts5HnWEYNK7qHDAUn+IlmjOO+pTUY8uyq+GQVz6H9wFlAgMBAAE=\n"
+ "-----END RSA PUBLIC KEY-----\n"
+ "ntor-onion-key Gg73xH7+kTfT6bi1uNVx9gwQdQas9pROIfmc4NpAdC4=\n"
+ "p reject 25,119,135-139,445,563,1214,4661-4666,6346-6429,6699,6881-6999\n"
+ "id rsa1024 Cd47okjCHD83YGzThGBDptXs9Z4\n";
+
+static void
+test_md_generate(void *arg)
+{
+ routerinfo_t *ri;
+ microdesc_t *md = NULL;
+ (void)arg;
+
+ ri = router_parse_entry_from_string(test_ri, NULL, 0, 0, NULL);
+ tt_assert(ri);
+ md = dirvote_create_microdescriptor(ri, 8);
+ tt_str_op(md->body, ==, test_md_8);
+
+ /* XXXX test family lines. */
+ /* XXXX test method 14 for A lines. */
+ /* XXXX test method 15 for P6 lines. */
+
+ microdesc_free(md);
+ md = NULL;
+ md = dirvote_create_microdescriptor(ri, 16);
+ tt_str_op(md->body, ==, test_md_16);
+
+ microdesc_free(md);
+ md = NULL;
+ md = dirvote_create_microdescriptor(ri, 18);
+ tt_str_op(md->body, ==, test_md_18);
+
+ done:
+ microdesc_free(md);
+ routerinfo_free(ri);
+}
+
struct testcase_t microdesc_tests[] = {
{ "cache", test_md_cache, TT_FORK, NULL, NULL },
{ "broken_cache", test_md_cache_broken, TT_FORK, NULL, NULL },
+ { "generate", test_md_generate, 0, NULL, NULL },
END_OF_TESTCASES
};
diff --git a/src/test/test_oom.c b/src/test/test_oom.c
index 1afe3fd16..32f4803bb 100644
--- a/src/test/test_oom.c
+++ b/src/test/test_oom.c
@@ -6,6 +6,7 @@
#define RELAY_PRIVATE
#define BUFFERS_PRIVATE
#define CIRCUITLIST_PRIVATE
+#define CONNECTION_PRIVATE
#include "or.h"
#include "buffers.h"
#include "circuitlist.h"
@@ -226,6 +227,7 @@ test_oom_streambuf(void *arg)
struct timeval tv = { 1389641159, 0 };
uint32_t tvms;
int i;
+ smartlist_t *edgeconns = smartlist_new();
(void) arg;
@@ -270,17 +272,21 @@ test_oom_streambuf(void *arg)
tor_gettimeofday_cache_set(&tv);
ec = dummy_edge_conn_new(c1, CONN_TYPE_EXIT, 1000, 1000);
tt_assert(ec);
+ smartlist_add(edgeconns, ec);
tv.tv_usec += 10*1000;
tor_gettimeofday_cache_set(&tv);
ec = dummy_edge_conn_new(c2, CONN_TYPE_AP, 1000, 1000);
tt_assert(ec);
+ smartlist_add(edgeconns, ec);
tv.tv_usec += 10*1000;
tor_gettimeofday_cache_set(&tv);
ec = dummy_edge_conn_new(c4, CONN_TYPE_EXIT, 1000, 1000); /* Yes, 4 twice*/
tt_assert(ec);
+ smartlist_add(edgeconns, ec);
tv.tv_usec += 10*1000;
tor_gettimeofday_cache_set(&tv);
ec = dummy_edge_conn_new(c4, CONN_TYPE_EXIT, 1000, 1000);
+ smartlist_add(edgeconns, ec);
tt_assert(ec);
}
@@ -315,6 +321,7 @@ test_oom_streambuf(void *arg)
tor_gettimeofday_cache_set(&tv);
ec = dummy_edge_conn_new(c4, CONN_TYPE_EXIT, 1000, 1000);
tt_assert(ec);
+ smartlist_add(edgeconns, ec);
}
tt_int_op(buf_get_total_allocation(), ==, 4096*17*2);
tt_int_op(circuit_max_queued_item_age(c4, tvms), ==, 1000);
@@ -350,6 +357,10 @@ test_oom_streambuf(void *arg)
circuit_free(c4);
circuit_free(c5);
+ SMARTLIST_FOREACH(edgeconns, edge_connection_t *, ec,
+ connection_free_(TO_CONN(ec)));
+ smartlist_free(edgeconns);
+
UNMOCK(circuit_mark_for_close_);
}
diff --git a/src/test/test_policy.c b/src/test/test_policy.c
index e3e7b3673..4cdcd034b 100644
--- a/src/test/test_policy.c
+++ b/src/test/test_policy.c
@@ -394,6 +394,7 @@ test_dump_exit_policy_to_string(void *arg)
ep = router_dump_exit_policy_to_string(ri,1,1);
test_streq("accept *:*\nreject *:25\nreject 8.8.8.8:*",ep);
+ tor_free(ep);
policy_entry =
router_parse_addr_policy_item_from_string("reject6 [FC00::]/7:*",-1);
@@ -421,6 +422,7 @@ test_dump_exit_policy_to_string(void *arg)
if (ri->exit_policy) {
SMARTLIST_FOREACH(ri->exit_policy, addr_policy_t *,
entry, addr_policy_free(entry));
+ smartlist_free(ri->exit_policy);
}
tor_free(ri);
tor_free(ep);
diff --git a/src/test/test_pt.c b/src/test/test_pt.c
index 327792105..f71627df1 100644
--- a/src/test/test_pt.c
+++ b/src/test/test_pt.c
@@ -129,6 +129,8 @@ test_pt_parsing(void)
test_assert(parse_version(line, mp) == 0);
done:
+ reset_mp(mp);
+ smartlist_free(mp->transports);
tor_free(mp);
}
@@ -227,6 +229,10 @@ test_pt_protocol(void)
test_assert(mp->conf_state == PT_PROTO_CONFIGURED);
done:
+ reset_mp(mp);
+ smartlist_free(mp->transports);
+ tor_free(mp->argv[0]);
+ tor_free(mp->argv);
tor_free(mp);
}
@@ -423,7 +429,7 @@ test_pt_configure_proxy(void *arg)
}
done:
- tor_free(dummy_state);
+ or_state_free(dummy_state);
UNMOCK(tor_get_lines_from_handle);
UNMOCK(tor_process_handle_destroy);
UNMOCK(get_or_state);
@@ -433,6 +439,15 @@ test_pt_configure_proxy(void *arg)
smartlist_free(controlevent_msgs);
controlevent_msgs = NULL;
}
+ if (mp->transports) {
+ SMARTLIST_FOREACH(mp->transports, transport_t *, t, transport_free(t));
+ smartlist_free(mp->transports);
+ }
+ smartlist_free(mp->transports_to_launch);
+ tor_free(mp->process_handle);
+ tor_free(mp->argv[0]);
+ tor_free(mp->argv);
+ tor_free(mp);
}
#define PT_LEGACY(name) \
diff --git a/src/test/test_routerkeys.c b/src/test/test_routerkeys.c
index 1c8174b06..182e0f6f8 100644
--- a/src/test/test_routerkeys.c
+++ b/src/test/test_routerkeys.c
@@ -27,6 +27,7 @@ test_routerkeys_write_fingerprint(void *arg)
tt_assert(key);
options->ORPort_set = 1; /* So that we can get the server ID key */
+ tor_free(options->DataDirectory);
options->DataDirectory = tor_strdup(ddir);
options->Nickname = tor_strdup("haflinger");
set_server_identity_key(key);
diff --git a/src/test/test_status.c b/src/test/test_status.c
index b704053d0..46dd47313 100644
--- a/src/test/test_status.c
+++ b/src/test/test_status.c
@@ -613,6 +613,9 @@ NS_DECL(or_state_t *, get_or_state, (void));
NS_DECL(int, accounting_is_enabled, (const or_options_t *options));
NS_DECL(time_t, accounting_get_end_time, (void));
+static or_state_t * NS(mock_state) = NULL;
+static or_options_t * NS(mock_options) = NULL;
+
static void
NS(test_main)(void *arg)
{
@@ -652,6 +655,8 @@ NS(test_main)(void *arg)
NS_UNMOCK(server_mode);
NS_UNMOCK(accounting_is_enabled);
NS_UNMOCK(accounting_get_end_time);
+ tor_free_(NS(mock_state));
+ tor_free_(NS(mock_options));
}
static double
@@ -669,10 +674,10 @@ NS(we_are_hibernating)(void)
static const or_options_t *
NS(get_options)(void)
{
- or_options_t *mock_options = tor_malloc_zero(sizeof(or_options_t));
- mock_options->AccountingMax = 0;
+ NS(mock_options) = tor_malloc_zero(sizeof(or_options_t));
+ NS(mock_options)->AccountingMax = 0;
- return mock_options;
+ return NS(mock_options);
}
static int
@@ -771,11 +776,11 @@ NS(accounting_get_end_time)(void)
static or_state_t *
NS(get_or_state)(void)
{
- or_state_t *mock_state = tor_malloc_zero(sizeof(or_state_t));
- mock_state->AccountingBytesReadInInterval = 0;
- mock_state->AccountingBytesWrittenInInterval = 0;
+ NS(mock_state) = tor_malloc_zero(sizeof(or_state_t));
+ NS(mock_state)->AccountingBytesReadInInterval = 0;
+ NS(mock_state)->AccountingBytesWrittenInInterval = 0;
- return mock_state;
+ return NS(mock_state);
}
#undef NS_SUBMODULE
diff --git a/src/test/test_util.c b/src/test/test_util.c
index eadbf730e..c7fa14118 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -153,7 +153,7 @@ test_util_write_chunks_to_file(void *arg)
// assert the file has been written (expected size)
str = read_file_to_str(fname, RFTS_BIN, &st);
tt_assert(str != NULL);
- tt_int_op(st.st_size, ==, data_str_len);
+ tt_u64_op((uint64_t)st.st_size, ==, data_str_len);
test_mem_op(data_str, ==, str, data_str_len);
tor_free(str);
@@ -184,14 +184,14 @@ test_util_write_chunks_to_file(void *arg)
// assert the file has been written (expected size)
str = read_file_to_str(fname, RFTS_BIN, &st);
tt_assert(str != NULL);
- tt_int_op(st.st_size, ==, data_str_len);
+ tt_u64_op((uint64_t)st.st_size, ==, data_str_len);
test_mem_op(data_str, ==, str, data_str_len);
tor_free(str);
// assert the tempfile still contains the known string
str = read_file_to_str(tempname, RFTS_BIN, &st);
tt_assert(str != NULL);
- tt_int_op(st.st_size, ==, temp_str_len);
+ tt_u64_op((uint64_t)st.st_size, ==, temp_str_len);
test_mem_op(temp_str, ==, str, temp_str_len);
done:
@@ -346,7 +346,7 @@ test_util_time(void)
tv.tv_sec = (time_t)1326296338;
tv.tv_usec = 3060;
- format_iso_time(timestr, tv.tv_sec);
+ format_iso_time(timestr, (time_t)tv.tv_sec);
test_streq("2012-01-11 15:38:58", timestr);
/* The output of format_local_iso_time will vary by timezone, and setting
our timezone for testing purposes would be a nontrivial flaky pain.
@@ -354,7 +354,7 @@ test_util_time(void)
format_local_iso_time(timestr, tv.tv_sec);
test_streq("2012-01-11 10:38:58", timestr);
*/
- format_iso_time_nospace(timestr, tv.tv_sec);
+ format_iso_time_nospace(timestr, (time_t)tv.tv_sec);
test_streq("2012-01-11T15:38:58", timestr);
test_eq(strlen(timestr), ISO_TIME_LEN);
format_iso_time_nospace_usec(timestr, &tv);
@@ -1092,7 +1092,7 @@ test_util_strmisc(void)
test_eq(i, 0);
test_eq(0UL, tor_parse_ulong(TOOBIG, 10, 0, ULONG_MAX, &i, NULL));
test_eq(i, 0);
- test_eq(U64_LITERAL(0), tor_parse_uint64(TOOBIG, 10,
+ tt_u64_op(U64_LITERAL(0), ==, tor_parse_uint64(TOOBIG, 10,
0, UINT64_MAX, &i, NULL));
test_eq(i, 0);
}
@@ -1290,21 +1290,21 @@ test_util_pow2(void)
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(U64_LITERAL(0xffffffffffffffff)),
+ tt_u64_op(round_to_power_of_2(120), ==, 128);
+ tt_u64_op(round_to_power_of_2(128), ==, 128);
+ tt_u64_op(round_to_power_of_2(130), ==, 128);
+ tt_u64_op(round_to_power_of_2(U64_LITERAL(40000000000000000)), ==,
+ U64_LITERAL(1)<<55);
+ tt_u64_op(round_to_power_of_2(U64_LITERAL(0xffffffffffffffff)), ==,
U64_LITERAL(1)<<63);
- test_eq(round_to_power_of_2(0), 1);
- test_eq(round_to_power_of_2(1), 1);
- test_eq(round_to_power_of_2(2), 2);
- test_eq(round_to_power_of_2(3), 2);
- test_eq(round_to_power_of_2(4), 4);
- test_eq(round_to_power_of_2(5), 4);
- test_eq(round_to_power_of_2(6), 4);
- test_eq(round_to_power_of_2(7), 8);
+ tt_u64_op(round_to_power_of_2(0), ==, 1);
+ tt_u64_op(round_to_power_of_2(1), ==, 1);
+ tt_u64_op(round_to_power_of_2(2), ==, 2);
+ tt_u64_op(round_to_power_of_2(3), ==, 2);
+ tt_u64_op(round_to_power_of_2(4), ==, 4);
+ tt_u64_op(round_to_power_of_2(5), ==, 4);
+ tt_u64_op(round_to_power_of_2(6), ==, 4);
+ tt_u64_op(round_to_power_of_2(7), ==, 8);
done:
;
@@ -2247,18 +2247,21 @@ test_util_asprintf(void *ptr)
test_assert(cp);
test_streq("simple string 100% safe", cp);
test_eq(strlen(cp), r);
+ tor_free(cp);
/* empty string */
r = tor_asprintf(&cp, "%s", "");
test_assert(cp);
test_streq("", cp);
test_eq(strlen(cp), r);
+ tor_free(cp);
/* numbers (%i) */
r = tor_asprintf(&cp, "I like numbers-%2i, %i, etc.", -1, 2);
test_assert(cp);
test_streq("I like numbers--1, 2, etc.", cp);
test_eq(strlen(cp), r);
+ /* don't free cp; next test uses it. */
/* numbers (%d) */
r = tor_asprintf(&cp2, "First=%d, Second=%d", 101, 202);
@@ -3149,6 +3152,8 @@ smartlist_new_from_text_lines(const char *lines)
last_line = smartlist_pop_last(sl);
if (last_line != NULL && *last_line != '\0') {
smartlist_add(sl, last_line);
+ } else {
+ tor_free(last_line);
}
return sl;
@@ -3628,17 +3633,17 @@ test_util_max_mem(void *arg)
r = get_total_system_memory(&memory1);
r2 = get_total_system_memory(&memory2);
tt_int_op(r, ==, r2);
- tt_int_op(memory2, ==, memory1);
+ tt_uint_op(memory2, ==, memory1);
TT_BLATHER(("System memory: "U64_FORMAT, U64_PRINTF_ARG(memory1)));
if (r==0) {
/* You have at least a megabyte. */
- tt_int_op(memory1, >, (1<<20));
+ tt_uint_op(memory1, >, (1<<20));
} else {
/* You do not have a petabyte. */
#if SIZEOF_SIZE_T == SIZEOF_UINT64_T
- tt_int_op(memory1, <, (U64_LITERAL(1)<<50));
+ tt_uint_op(memory1, <, (U64_LITERAL(1)<<50));
#endif
}