summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/address.c4
-rw-r--r--src/common/address.h2
-rw-r--r--src/common/aes.c2
-rw-r--r--src/common/aes.h2
-rw-r--r--src/common/compat.c3
-rw-r--r--src/common/compat.h23
-rw-r--r--src/common/compat_libevent.c2
-rw-r--r--src/common/container.c2
-rw-r--r--src/common/container.h2
-rw-r--r--src/common/crypto.c2
-rw-r--r--src/common/crypto.h2
-rw-r--r--src/common/ht.h2
-rw-r--r--src/common/log.c2
-rw-r--r--src/common/log.h2
-rw-r--r--src/common/memarea.c2
-rw-r--r--src/common/memarea.h2
-rw-r--r--src/common/mempool.c2
-rw-r--r--src/common/mempool.h2
-rw-r--r--src/common/sha256.c2
-rw-r--r--src/common/torgzip.c2
-rw-r--r--src/common/torgzip.h2
-rw-r--r--src/common/torint.h2
-rw-r--r--src/common/tortls.c2
-rw-r--r--src/common/tortls.h2
-rw-r--r--src/common/tortls_states.h2
-rw-r--r--src/common/util.c2
-rw-r--r--src/common/util.h2
-rw-r--r--src/or/buffers.c2
-rw-r--r--src/or/circuitbuild.c7
-rw-r--r--src/or/circuitlist.c2
-rw-r--r--src/or/circuituse.c2
-rw-r--r--src/or/command.c2
-rw-r--r--src/or/config.c13
-rw-r--r--src/or/connection.c6
-rw-r--r--src/or/connection_edge.c26
-rw-r--r--src/or/connection_or.c4
-rw-r--r--src/or/control.c2
-rw-r--r--src/or/cpuworker.c2
-rw-r--r--src/or/directory.c2
-rw-r--r--src/or/dirserv.c12
-rw-r--r--src/or/dirvote.c503
-rw-r--r--src/or/dns.c2
-rw-r--r--src/or/dnsserv.c2
-rw-r--r--src/or/eventdns_tor.h2
-rw-r--r--src/or/geoip.c2
-rw-r--r--src/or/hibernate.c2
-rw-r--r--src/or/main.c2
-rw-r--r--src/or/microdesc.c2
-rw-r--r--src/or/networkstatus.c51
-rw-r--r--src/or/ntmain.c2
-rw-r--r--src/or/onion.c2
-rw-r--r--src/or/or.h28
-rw-r--r--src/or/policies.c2
-rw-r--r--src/or/reasons.c2
-rw-r--r--src/or/relay.c2
-rw-r--r--src/or/rendclient.c2
-rw-r--r--src/or/rendcommon.c2
-rw-r--r--src/or/rendmid.c2
-rw-r--r--src/or/rendservice.c2
-rw-r--r--src/or/rephist.c6
-rw-r--r--src/or/router.c5
-rw-r--r--src/or/routerlist.c250
-rw-r--r--src/or/routerparse.c524
-rw-r--r--src/or/tor_main.c2
-rw-r--r--src/test/test.c3
-rw-r--r--src/test/test.h2
-rw-r--r--src/test/test_addr.c2
-rw-r--r--src/test/test_containers.c2
-rw-r--r--src/test/test_crypto.c2
-rw-r--r--src/test/test_data.c2
-rw-r--r--src/test/test_dir.c2
-rw-r--r--src/test/test_util.c2
-rw-r--r--src/tools/tor-gencert.c2
-rw-r--r--src/tools/tor-resolve.c2
-rw-r--r--src/win32/orconfig.h2
75 files changed, 1405 insertions, 179 deletions
diff --git a/src/common/address.c b/src/common/address.c
index 7729f29147..4569373f3b 100644
--- a/src/common/address.c
+++ b/src/common/address.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2003-2004, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -726,7 +726,7 @@ tor_addr_is_loopback(const tor_addr_t *addr)
}
/** Set <b>dest</b> to equal the IPv4 address in <b>v4addr</b> (given in
- * network order. */
+ * network order). */
void
tor_addr_from_ipv4n(tor_addr_t *dest, uint32_t v4addr)
{
diff --git a/src/common/address.h b/src/common/address.h
index 4d4c91075b..6116bb4b1c 100644
--- a/src/common/address.h
+++ b/src/common/address.h
@@ -1,6 +1,6 @@
/* Copyright (c) 2003-2004, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/common/aes.c b/src/common/aes.c
index eb7f8fe3fc..2b6f0234b7 100644
--- a/src/common/aes.c
+++ b/src/common/aes.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001, Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/common/aes.h b/src/common/aes.h
index f3e5796c78..4fb735cfe5 100644
--- a/src/common/aes.h
+++ b/src/common/aes.h
@@ -1,6 +1,6 @@
/* Copyright (c) 2003, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/* Implements a minimal interface to counter-mode AES. */
diff --git a/src/common/compat.c b/src/common/compat.c
index e256f45a26..26038c1099 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2003-2004, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -1883,7 +1883,6 @@ spawn_exit(void)
* call _exit, not exit, from child processes. */
_exit(0);
#endif
-
}
/** Set *timeval to the current time of day. On error, log and terminate.
diff --git a/src/common/compat.h b/src/common/compat.h
index f3e30452bd..dbadd60509 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -1,6 +1,6 @@
/* Copyright (c) 2003-2004, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#ifndef _TOR_COMPAT_H
@@ -196,18 +196,26 @@ size_t strlcpy(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2));
#define U64_SCANF_ARG(a) (a)
/** Expands to a literal uint64_t-typed constant for the value <b>n</b>. */
#define U64_LITERAL(n) (n ## ui64)
+#define I64_PRINTF_ARG(a) (a)
+#define I64_SCANF_ARG(a) (a)
+#define I64_LITERAL(n) (n ## i64)
#else
#define U64_PRINTF_ARG(a) ((long long unsigned int)(a))
#define U64_SCANF_ARG(a) ((long long unsigned int*)(a))
#define U64_LITERAL(n) (n ## llu)
+#define I64_PRINTF_ARG(a) ((long long signed int)(a))
+#define I64_SCANF_ARG(a) ((long long signed int*)(a))
+#define I64_LITERAL(n) (n ## ll)
#endif
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
/** The formatting string used to put a uint64_t value in a printf() or
* scanf() function. See also U64_PRINTF_ARG and U64_SCANF_ARG. */
#define U64_FORMAT "%I64u"
+#define I64_FORMAT "%I64d"
#else
#define U64_FORMAT "%llu"
+#define I64_FORMAT "%lld"
#endif
/** Represents an mmaped file. Allocated via tor_mmap_file; freed with
@@ -549,6 +557,19 @@ void tor_cond_signal_all(tor_cond_t *cond);
#endif
#endif
+/** Macros for MIN/MAX. Never use these when the arguments could have
+ * side-effects.
+ * {With GCC extensions we could probably define a safer MIN/MAX. But
+ * depending on that safety would be dangerous, since not every platform
+ * has it.}
+ **/
+#ifndef MAX
+#define MAX(a,b) ( ((a)<(b)) ? (b) : (a) )
+#endif
+#ifndef MIN
+#define MIN(a,b) ( ((a)>(b)) ? (b) : (a) )
+#endif
+
/* Platform-specific helpers. */
#ifdef MS_WINDOWS
char *format_win32_error(DWORD err);
diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c
index dcf51cbbd3..18e057f957 100644
--- a/src/common/compat_libevent.c
+++ b/src/common/compat_libevent.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, The Tor Project, Inc. */
+/* Copyright (c) 2009-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/common/container.c b/src/common/container.c
index f452a51e42..ab5a9b0325 100644
--- a/src/common/container.c
+++ b/src/common/container.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2003-2004, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/common/container.h b/src/common/container.h
index 8077d56ebd..3568de0159 100644
--- a/src/common/container.h
+++ b/src/common/container.h
@@ -1,6 +1,6 @@
/* Copyright (c) 2003-2004, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#ifndef _TOR_CONTAINER_H
diff --git a/src/common/crypto.c b/src/common/crypto.c
index e7b0ff194f..1a1dad616c 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001, Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/common/crypto.h b/src/common/crypto.h
index 239acb5871..1b004dd4b8 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -1,7 +1,7 @@
/* Copyright (c) 2001, Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/common/ht.h b/src/common/ht.h
index 5187c90e6f..f598856d8a 100644
--- a/src/common/ht.h
+++ b/src/common/ht.h
@@ -1,6 +1,6 @@
/* Copyright (c) 2002, Christopher Clark.
* Copyright (c) 2005-2006, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See license at end. */
/* Based on ideas by Christopher Clark and interfaces from Niels Provos. */
diff --git a/src/common/log.c b/src/common/log.c
index dfea58f47c..6bf94721f8 100644
--- a/src/common/log.c
+++ b/src/common/log.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001, Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/common/log.h b/src/common/log.h
index 9f9a4277fb..21219569e3 100644
--- a/src/common/log.h
+++ b/src/common/log.h
@@ -1,7 +1,7 @@
/* Copyright (c) 2001, Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/common/memarea.c b/src/common/memarea.c
index 661bd85da8..0402e5f208 100644
--- a/src/common/memarea.c
+++ b/src/common/memarea.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, The Tor Project, Inc. */
+/* Copyright (c) 2008-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/** \file memarea.c
diff --git a/src/common/memarea.h b/src/common/memarea.h
index 04ffae7cae..95d855f6d9 100644
--- a/src/common/memarea.h
+++ b/src/common/memarea.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, The Tor Project, Inc. */
+/* Copyright (c) 2008-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/* Tor dependencies */
diff --git a/src/common/mempool.c b/src/common/mempool.c
index 60fcb2ca7a..256388a9fd 100644
--- a/src/common/mempool.c
+++ b/src/common/mempool.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2009, The Tor Project, Inc. */
+/* Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#if 1
/* Tor dependencies */
diff --git a/src/common/mempool.h b/src/common/mempool.h
index d6813f1baa..ae1feea843 100644
--- a/src/common/mempool.h
+++ b/src/common/mempool.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2009, The Tor Project, Inc. */
+/* Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/common/sha256.c b/src/common/sha256.c
index d445ae4e6d..4236d48f5f 100644
--- a/src/common/sha256.c
+++ b/src/common/sha256.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, The Tor Project, Inc. */
+/* Copyright (c) 2009-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/* This SHA256 implementation is adapted from the public domain one in
LibTomCrypt, version 1.6. Tor uses it on platforms where OpenSSL doesn't
diff --git a/src/common/torgzip.c b/src/common/torgzip.c
index 4f1b46adde..27d9c42efd 100644
--- a/src/common/torgzip.c
+++ b/src/common/torgzip.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/common/torgzip.h b/src/common/torgzip.h
index d6432283c3..5139f4bcad 100644
--- a/src/common/torgzip.h
+++ b/src/common/torgzip.h
@@ -1,6 +1,6 @@
/* Copyright (c) 2003, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/common/torint.h b/src/common/torint.h
index be624e04c6..57f18212ad 100644
--- a/src/common/torint.h
+++ b/src/common/torint.h
@@ -1,6 +1,6 @@
/* Copyright (c) 2003, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/common/tortls.c b/src/common/tortls.c
index 82653c455a..b4984802fb 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2003, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/common/tortls.h b/src/common/tortls.h
index 871fec3365..e4b1ad65f2 100644
--- a/src/common/tortls.h
+++ b/src/common/tortls.h
@@ -1,6 +1,6 @@
/* Copyright (c) 2003, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#ifndef _TOR_TORTLS_H
diff --git a/src/common/tortls_states.h b/src/common/tortls_states.h
index 986b5a8a0d..00f476dd66 100644
--- a/src/common/tortls_states.h
+++ b/src/common/tortls_states.h
@@ -1,6 +1,6 @@
/* Copyright (c) 2003, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/* Helper file: included only in tortls.c */
diff --git a/src/common/util.c b/src/common/util.c
index f7e5dd06c5..1c0db392d0 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2003, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/common/util.h b/src/common/util.h
index b55bb91c51..ba38f4c7ed 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -1,6 +1,6 @@
/* Copyright (c) 2003-2004, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/buffers.c b/src/or/buffers.c
index c990b6619a..4dbd9a7a0b 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index cb9ba9e9b0..233d60f15c 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -1030,7 +1030,6 @@ circuit_build_times_set_timeout(circuit_build_times_t *cbt)
"Set circuit build timeout to %lds (%lfms, Xm: %d, a: %lf) "
"based on %d circuit times", tor_lround(cbt->timeout_ms/1000),
cbt->timeout_ms, cbt->Xm, cbt->alpha, cbt->total_build_times);
-
}
/** Iterate over values of circ_id, starting from conn-\>next_circ_id,
@@ -1111,11 +1110,11 @@ circuit_list_path_impl(origin_circuit_t *circ, int verbose, int verbose_names)
const char *id;
if (!hop)
break;
- id = hop->extend_info->identity_digest;
if (!verbose && hop->state != CPATH_STATE_OPEN)
break;
if (!hop->extend_info)
break;
+ id = hop->extend_info->identity_digest;
if (verbose_names) {
elt = tor_malloc(MAX_VERBOSE_NICKNAME_LEN+1);
if ((ri = router_get_by_digest(id))) {
@@ -2133,6 +2132,8 @@ circuit_all_predicted_ports_handled(time_t now, int *need_uptime,
smartlist_t *LongLivedServices = get_options()->LongLivedPorts;
tor_assert(need_uptime);
tor_assert(need_capacity);
+ // Always predict need_capacity
+ *need_capacity = 1;
enough = (smartlist_len(sl) == 0);
for (i = 0; i < smartlist_len(sl); ++i) {
port = smartlist_get(sl, i);
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index fed1ccf9e6..73e2e06cce 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -1,7 +1,7 @@
/* Copyright 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 59b6998b99..9eda9e2480 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/command.c b/src/or/command.c
index b1e6fa23a3..8d838a0a23 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/config.c b/src/or/config.c
index 3e7c86cdb5..5d07cd7343 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -299,6 +299,7 @@ static config_var_t _option_vars[] = {
V(RecommendedClientVersions, LINELIST, NULL),
V(RecommendedServerVersions, LINELIST, NULL),
OBSOLETE("RedirectExit"),
+ V(RefuseUnknownExits, BOOL, "0"),
V(RejectPlaintextPorts, CSV, ""),
V(RelayBandwidthBurst, MEMUNIT, "0"),
V(RelayBandwidthRate, MEMUNIT, "0"),
@@ -2137,7 +2138,7 @@ print_usage(void)
printf(
"Copyright (c) 2001-2004, Roger Dingledine\n"
"Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson\n"
-"Copyright (c) 2007-2009, The Tor Project, Inc.\n\n"
+"Copyright (c) 2007-2010, The Tor Project, Inc.\n\n"
"tor -f <torrc> [args]\n"
"See man page for options, or https://www.torproject.org/ for "
"documentation.\n");
@@ -2173,7 +2174,7 @@ resolve_my_address(int warn_severity, or_options_t *options,
uint32_t *addr_out, char **hostname_out)
{
struct in_addr in;
- uint32_t addr;
+ uint32_t addr; /* host order */
char hostname[256];
int explicit_ip=1;
int explicit_hostname=1;
@@ -2203,8 +2204,8 @@ resolve_my_address(int warn_severity, or_options_t *options,
if (tor_inet_aton(hostname, &in) == 0) {
/* then we have to resolve it */
explicit_ip = 0;
- if (!tor_lookup_hostname(hostname, &addr)) {
- uint32_t interface_ip;
+ if (tor_lookup_hostname(hostname, &addr)) { /* failed to resolve */
+ uint32_t interface_ip; /* host order */
if (explicit_hostname) {
log_fn(warn_severity, LD_CONFIG,
@@ -2225,7 +2226,7 @@ resolve_my_address(int warn_severity, or_options_t *options,
log_fn(notice_severity, LD_CONFIG, "Learned IP address '%s' for "
"local interface. Using that.", tmpbuf);
strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
- } else {
+ } else { /* resolved hostname into addr */
in.s_addr = htonl(addr);
if (!explicit_hostname &&
diff --git a/src/or/connection.c b/src/or/connection.c
index cf13345741..7b1493bfc5 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -3095,10 +3095,10 @@ alloc_http_authenticator(const char *authenticator)
static void
client_check_address_changed(int sock)
{
- uint32_t iface_ip, ip_out;
+ uint32_t iface_ip, ip_out; /* host order */
struct sockaddr_in out_addr;
socklen_t out_addr_len = (socklen_t) sizeof(out_addr);
- uint32_t *ip;
+ uint32_t *ip; /* host order */
if (!last_interface_ip)
get_interface_address(LOG_INFO, &last_interface_ip);
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 8e2fcf977e..a173dc1226 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -2505,16 +2505,28 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
tor_free(address);
return 0;
}
- if (or_circ && or_circ->is_first_hop &&
- !get_options()->AllowSingleHopExits) {
+ if (or_circ && or_circ->p_conn && !get_options()->AllowSingleHopExits &&
+ (or_circ->is_first_hop ||
+ (!connection_or_digest_is_known_relay(
+ or_circ->p_conn->identity_digest) &&
+// XXX022 commented out so we can test it first in 0.2.2.11 -RD
+// networkstatus_get_param(NULL, "refuseunknownexits", 1)))) {
+ get_options()->RefuseUnknownExits))) {
/* Don't let clients use us as a single-hop proxy, unless the user
- * has explicitly allowed that in the config. It attracts attackers
+ * has explicitly allowed that in the config. It attracts attackers
* and users who'd be better off with, well, single-hop proxies.
*/
- log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
- "Attempt to open a stream on first hop of circuit. Closing.");
+// log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+ log_notice(LD_PROTOCOL,
+ "Attempt by %s to open a stream %s. Closing.",
+ safe_str(or_circ->p_conn->_base.address),
+ or_circ->is_first_hop ? "on first hop of circuit" :
+ "from unknown relay");
relay_send_end_cell_from_edge(rh.stream_id, circ,
- END_STREAM_REASON_TORPROTOCOL, NULL);
+ or_circ->is_first_hop ?
+ END_STREAM_REASON_TORPROTOCOL :
+ END_STREAM_REASON_MISC,
+ NULL);
tor_free(address);
return 0;
}
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 1aa0bb35b7..98525f16a2 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -322,7 +322,7 @@ connection_or_finished_connecting(or_connection_t *or_conn)
/** Return 1 if identity digest <b>id_digest</b> is known to be a
* currently or recently running relay. Otherwise return 0. */
-static int
+int
connection_or_digest_is_known_relay(const char *id_digest)
{
if (router_get_consensus_status_by_id(id_digest))
diff --git a/src/or/control.c b/src/or/control.c
index 4fc9b7f345..5797edfdce 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c
index 219fb9d9be..fde149978c 100644
--- a/src/or/cpuworker.c
+++ b/src/or/cpuworker.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2003-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/directory.c b/src/or/directory.c
index ef0816eb41..39e67c957f 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "or.h"
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 8009647c91..b5c4c7b506 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define DIRSERV_PRIVATE
@@ -1122,12 +1122,12 @@ directory_fetches_from_authorities(or_options_t *options)
return 0;
if (server_mode(options) && router_pick_published_address(options, &addr)<0)
return 1; /* we don't know our IP address; ask an authority. */
- if (options->DirPort == 0)
+ if (options->DirPort == 0 && !options->RefuseUnknownExits)
return 0;
if (!server_mode(options) || !advertised_server_mode())
return 0;
me = router_get_my_routerinfo();
- if (!me || !me->dir_port)
+ if (!me || (!me->dir_port && !options->RefuseUnknownExits))
return 0; /* if dirport not advertised, return 0 too */
return 1;
}
@@ -1167,7 +1167,11 @@ directory_caches_v2_dir_info(or_options_t *options)
int
directory_caches_dir_info(or_options_t *options)
{
- return options->BridgeRelay != 0 || options->DirPort != 0;
+ if (options->BridgeRelay || options->DirPort)
+ return 1;
+ if (!server_mode(options) || !advertised_server_mode())
+ return 0;
+ return options->RefuseUnknownExits;
}
/** Return 1 if we want to allow remote people to ask us directory
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index 2e57ca4a79..bae222a191 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define DIRVOTE_PRIVATE
@@ -39,8 +39,15 @@ static int dirvote_publish_consensus(void);
static char *make_consensus_method_list(int low, int high, const char *sep);
/** The highest consensus method that we currently support. */
-#define MAX_SUPPORTED_CONSENSUS_METHOD 8
+#define MAX_SUPPORTED_CONSENSUS_METHOD 9
+/** Lowest consensus method that contains a 'directory-footer' marker */
+#define MIN_METHOD_FOR_FOOTER 9
+
+/** Lowest consensus method that contains bandwidth weights */
+#define MIN_METHOD_FOR_BW_WEIGHTS 9
+
+/** Lowest consensus method that contains consensus params */
#define MIN_METHOD_FOR_PARAMS 7
/** Lowest consensus method that generates microdescriptors */
@@ -71,6 +78,7 @@ format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
uint32_t addr;
routerlist_t *rl = router_get_routerlist();
char *version_lines = NULL;
+ int r;
networkstatus_voter_info_t *voter;
tor_assert(private_signing_key);
@@ -97,13 +105,22 @@ format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
version_lines = tor_malloc(v_len);
cp = version_lines;
if (client_versions) {
- tor_snprintf(cp, v_len-(cp-version_lines),
+ r = tor_snprintf(cp, v_len-(cp-version_lines),
"client-versions %s\n", client_versions);
+ if (r < 0) {
+ log_err(LD_BUG, "Insufficient memory for client-versions line");
+ tor_assert(0);
+ }
cp += strlen(cp);
}
- if (server_versions)
- tor_snprintf(cp, v_len-(cp-version_lines),
+ if (server_versions) {
+ r = tor_snprintf(cp, v_len-(cp-version_lines),
"server-versions %s\n", server_versions);
+ if (r < 0) {
+ log_err(LD_BUG, "Insufficient memory for server-versions line");
+ tor_assert(0);
+ }
+ }
} else {
version_lines = tor_strdup("");
}
@@ -111,6 +128,7 @@ format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
len = 8192;
len += strlen(version_lines);
len += (RS_ENTRY_LEN+MICRODESC_LINE_LEN)*smartlist_len(rl->routers);
+ len += strlen("\ndirectory-footer\n");
len += v3_ns->cert->cache_info.signed_descriptor_len;
status = tor_malloc(len);
@@ -135,7 +153,7 @@ format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
params = tor_strdup("");
tor_assert(cert);
- tor_snprintf(status, len,
+ r = tor_snprintf(status, len,
"network-status-version 3\n"
"vote-status %s\n"
"consensus-methods %s\n"
@@ -159,6 +177,11 @@ format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
voter->nickname, fingerprint, voter->address,
ipaddr, voter->dir_port, voter->or_port, voter->contact);
+ if (r < 0) {
+ log_err(LD_BUG, "Insufficient memory for network status line");
+ tor_assert(0);
+ }
+
tor_free(params);
tor_free(flags);
tor_free(methods);
@@ -168,7 +191,11 @@ format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
if (!tor_digest_is_zero(voter->legacy_id_digest)) {
char fpbuf[HEX_DIGEST_LEN+1];
base16_encode(fpbuf, sizeof(fpbuf), voter->legacy_id_digest, DIGEST_LEN);
- tor_snprintf(outp, endp-outp, "legacy-dir-key %s\n", fpbuf);
+ r = tor_snprintf(outp, endp-outp, "legacy-dir-key %s\n", fpbuf);
+ if (r < 0) {
+ log_err(LD_BUG, "Insufficient memory for legacy-dir-key line");
+ tor_assert(0);
+ }
outp += strlen(outp);
}
@@ -199,6 +226,13 @@ format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
}
} SMARTLIST_FOREACH_END(vrs);
+ r = tor_snprintf(outp, endp-outp, "directory-footer\n");
+ if (r < 0) {
+ log_err(LD_BUG, "Insufficient memory for directory-footer line");
+ tor_assert(0);
+ }
+ outp += strlen(outp);
+
{
char signing_key_fingerprint[FINGERPRINT_LEN+1];
if (tor_snprintf(outp, endp-outp, "directory-signature ")<0) {
@@ -648,6 +682,385 @@ dirvote_compute_params(smartlist_t *votes)
return result;
}
+#define RANGE_CHECK(a,b,c,d,e,f,g,mx) \
+ ((a) >= 0 && (a) <= (mx) && (b) >= 0 && (b) <= (mx) && \
+ (c) >= 0 && (c) <= (mx) && (d) >= 0 && (d) <= (mx) && \
+ (e) >= 0 && (e) <= (mx) && (f) >= 0 && (f) <= (mx) && \
+ (g) >= 0 && (g) <= (mx))
+
+#define CHECK_EQ(a, b, margin) \
+ ((a)-(b) >= 0 ? (a)-(b) <= (margin) : (b)-(a) <= (margin))
+
+typedef enum {
+ BW_WEIGHTS_NO_ERROR = 0,
+ BW_WEIGHTS_RANGE_ERROR = 1,
+ BW_WEIGHTS_SUMG_ERROR = 2,
+ BW_WEIGHTS_SUME_ERROR = 3,
+ BW_WEIGHTS_SUMD_ERROR = 4,
+ BW_WEIGHTS_BALANCE_MID_ERROR = 5,
+ BW_WEIGHTS_BALANCE_EG_ERROR = 6
+} bw_weights_error_t;
+
+/**
+ * Verify that any weightings satisfy the balanced formulas.
+ */
+static bw_weights_error_t
+networkstatus_check_weights(int64_t Wgg, int64_t Wgd, int64_t Wmg,
+ int64_t Wme, int64_t Wmd, int64_t Wee,
+ int64_t Wed, int64_t scale, int64_t G,
+ int64_t M, int64_t E, int64_t D, int64_t T,
+ int64_t margin, int do_balance) {
+ bw_weights_error_t berr = BW_WEIGHTS_NO_ERROR;
+
+ // Wed + Wmd + Wgd == 1
+ if (!CHECK_EQ(Wed + Wmd + Wgd, scale, margin)) {
+ berr = BW_WEIGHTS_SUMD_ERROR;
+ goto out;
+ }
+
+ // Wmg + Wgg == 1
+ if (!CHECK_EQ(Wmg + Wgg, scale, margin)) {
+ berr = BW_WEIGHTS_SUMG_ERROR;
+ goto out;
+ }
+
+ // Wme + Wee == 1
+ if (!CHECK_EQ(Wme + Wee, scale, margin)) {
+ berr = BW_WEIGHTS_SUME_ERROR;
+ goto out;
+ }
+
+ // Verify weights within range 0->1
+ if (!RANGE_CHECK(Wgg, Wgd, Wmg, Wme, Wmd, Wed, Wee, scale)) {
+ berr = BW_WEIGHTS_RANGE_ERROR;
+ goto out;
+ }
+
+ if (do_balance) {
+ // Wgg*G + Wgd*D == Wee*E + Wed*D, already scaled
+ if (!CHECK_EQ(Wgg*G + Wgd*D, Wee*E + Wed*D, (margin*T)/3)) {
+ berr = BW_WEIGHTS_BALANCE_EG_ERROR;
+ goto out;
+ }
+
+ // Wgg*G + Wgd*D == M*scale + Wmd*D + Wme*E + Wmg*G, already scaled
+ if (!CHECK_EQ(Wgg*G + Wgd*D, M*scale + Wmd*D + Wme*E + Wmg*G,
+ (margin*T)/3)) {
+ berr = BW_WEIGHTS_BALANCE_MID_ERROR;
+ goto out;
+ }
+ }
+
+out:
+ if (berr) {
+ log_info(LD_DIR,
+ "Bw weight mismatch %d. G="I64_FORMAT" M="I64_FORMAT
+ " E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT,
+ berr,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ }
+
+ return berr;
+}
+
+static void
+networkstatus_compute_bw_weights_v9(smartlist_t *chunks, int64_t G, int64_t M,
+ int64_t E, int64_t D, int64_t T,
+ int64_t weight_scale)
+{
+ int64_t Wgg = -1, Wgd = -1;
+ int64_t Wmg = -1, Wme = -1, Wmd = -1;
+ int64_t Wed = -1, Wee = -1;
+ const char *casename;
+ char buf[512];
+ int r;
+
+ if (G <= 0 || M <= 0 || E <= 0 || D <= 0) {
+ log_warn(LD_DIR, "Consensus with empty bandwidth: "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
+ " D="I64_FORMAT" T="I64_FORMAT,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ return;
+ }
+
+ /*
+ * Computed from cases in 3.4.3 of dir-spec.txt
+ *
+ * 1. Neither are scarce
+ * 2. Both Guard and Exit are scarce
+ * a. R+D <= S
+ * b. R+D > S
+ * 3. One of Guard or Exit is scarce
+ * a. S+D < T/3
+ * b. S+D >= T/3
+ */
+ if (3*E >= T && 3*G >= T) { // E >= T/3 && G >= T/3
+ bw_weights_error_t berr = 0;
+ /* Case 1: Neither are scarce.
+ *
+ * Attempt to ensure that we have a large amount of exit bandwidth
+ * in the middle position.
+ */
+ casename = "Case 1 (Wme*E = Wmd*D)";
+ Wgg = (weight_scale*(D+E+G+M))/(3*G);
+ if (D==0) Wmd = 0;
+ else Wmd = (weight_scale*(2*D + 2*E - G - M))/(6*D);
+ Wme = (weight_scale*(2*D + 2*E - G - M))/(6*E);
+ Wee = (weight_scale*(-2*D + 4*E + G + M))/(6*E);
+ Wgd = 0;
+ Wmg = weight_scale - Wgg;
+ Wed = weight_scale - Wmd;
+
+ berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed,
+ weight_scale, G, M, E, D, T, 10, 1);
+
+ if (berr) {
+ log_warn(LD_DIR, "Bw Weights error %d for case %s. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
+ " D="I64_FORMAT" T="I64_FORMAT,
+ berr, casename,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ }
+ } else if (3*E < T && 3*G < T) { // E < T/3 && G < T/3
+ int64_t R = MIN(E, G);
+ int64_t S = MAX(E, G);
+ /*
+ * Case 2: Both Guards and Exits are scarce
+ * Balance D between E and G, depending upon
+ * D capacity and scarcity.
+ */
+ if (R+D < S) { // Subcase a
+ Wgg = weight_scale;
+ Wee = weight_scale;
+ Wmg = 0;
+ Wme = 0;
+ Wmd = 0;
+ if (E < G) {
+ casename = "Case 2a (E scarce)";
+ Wed = weight_scale;
+ Wgd = 0;
+ } else { /* E >= G */
+ casename = "Case 2a (G scarce)";
+ Wed = 0;
+ Wgd = weight_scale;
+ }
+ } else { // Subcase b: R+D > S
+ bw_weights_error_t berr = 0;
+ casename = "Case 2b (Wme*E == Wmd*D)";
+ if (D != 0) {
+ Wgg = weight_scale;
+ Wgd = (weight_scale*(D + E - 2*G + M))/(3*D); // T/3 >= G (Ok)
+ Wmd = (weight_scale*(D + E + G - 2*M))/(6*D); // T/3 >= M
+ Wme = (weight_scale*(D + E + G - 2*M))/(6*E);
+ Wee = (weight_scale*(-D + 5*E - G + 2*M))/(6*E); // 2E+M >= T/3
+ Wmg = 0;
+ Wed = weight_scale - Wgd - Wmd;
+
+ berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed,
+ weight_scale, G, M, E, D, T, 10, 1);
+ }
+
+ if (D == 0 || berr) { // Can happen if M > T/3
+ casename = "Case 2b (E=G)";
+ Wgg = weight_scale;
+ Wee = weight_scale;
+ Wmg = 0;
+ Wme = 0;
+ Wmd = 0;
+ if (D == 0) Wgd = 0;
+ else Wgd = (weight_scale*(D+E-G))/(2*D);
+ Wed = weight_scale - Wgd;
+ berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
+ Wed, weight_scale, G, M, E, D, T, 10, 1);
+ }
+ if (berr != BW_WEIGHTS_NO_ERROR &&
+ berr != BW_WEIGHTS_BALANCE_MID_ERROR) {
+ log_warn(LD_DIR, "Bw Weights error %d for case %s. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
+ " D="I64_FORMAT" T="I64_FORMAT,
+ berr, casename,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ }
+ }
+ } else { // if (E < T/3 || G < T/3) {
+ int64_t S = MIN(E, G);
+ // Case 3: Exactly one of Guard or Exit is scarce
+ if (!(3*E < T || 3*G < T) || !(3*G >= T || 3*E >= T)) {
+ log_warn(LD_BUG,
+ "Bw-Weights Case 3 but with G="I64_FORMAT" M="
+ I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ }
+
+ if (3*(S+D) < T) { // Subcase a: S+D < T/3
+ if (G < E) {
+ casename = "Case 3a (G scarce)";
+ Wgg = Wgd = weight_scale;
+ Wmd = Wed = Wmg = 0;
+ // Minor subcase, if E is more scarce than M,
+ // keep its bandwidth in place.
+ if (E < M) Wme = 0;
+ else Wme = (weight_scale*(E-M))/(2*E);
+ Wee = weight_scale-Wme;
+ } else { // G >= E
+ casename = "Case 3a (E scarce)";
+ Wee = Wed = weight_scale;
+ Wmd = Wgd = Wme = 0;
+ // Minor subcase, if G is more scarce than M,
+ // keep its bandwidth in place.
+ if (G < M) Wmg = 0;
+ else Wmg = (weight_scale*(G-M))/(2*G);
+ Wgg = weight_scale-Wmg;
+ }
+ } else { // Subcase b: S+D >= T/3
+ bw_weights_error_t berr = 0;
+ // D != 0 because S+D >= T/3
+ if (G < E) {
+ casename = "Case 3b (G scarce, Wme*E == Wmd*D)";
+ Wgd = (weight_scale*(D + E - 2*G + M))/(3*D);
+ Wmd = (weight_scale*(D + E + G - 2*M))/(6*D);
+ Wme = (weight_scale*(D + E + G - 2*M))/(6*E);
+ Wee = (weight_scale*(-D + 5*E - G + 2*M))/(6*E);
+ Wgg = weight_scale;
+ Wmg = 0;
+ Wed = weight_scale - Wgd - Wmd;
+
+ berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
+ Wed, weight_scale, G, M, E, D, T, 10, 1);
+ } else { // G >= E
+ casename = "Case 3b (E scarce, Wme*E == Wmd*D)";
+ Wgg = (weight_scale*(D + E + G + M))/(3*G);
+ Wmd = (weight_scale*(2*D + 2*E - G - M))/(6*D);
+ Wme = (weight_scale*(2*D + 2*E - G - M))/(6*E);
+ Wee = (weight_scale*(-2*D + 4*E + G + M))/(6*E);
+ Wgd = 0;
+ Wmg = weight_scale - Wgg;
+ Wed = weight_scale - Wmd;
+
+ berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
+ Wed, weight_scale, G, M, E, D, T, 10, 1);
+ }
+ if (berr) {
+ log_warn(LD_DIR, "Bw Weights error %d for case %s. "
+ "G="I64_FORMAT" M="I64_FORMAT
+ " E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT,
+ berr, casename,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ }
+ }
+ }
+
+ /* We cast down the weights to 32 bit ints on the assumption that
+ * weight_scale is ~= 10000. We need to ensure a rogue authority
+ * doesn't break this assumption to rig our weights */
+ tor_assert(0 < weight_scale && weight_scale < INT32_MAX);
+
+ if (Wgg < 0 || Wgg > weight_scale) {
+ log_warn(LD_DIR, "Bw %s: Wgg="I64_FORMAT"! G="I64_FORMAT
+ " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename, I64_PRINTF_ARG(Wgg),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+
+ Wgg = MAX(MIN(Wgg, weight_scale), 0);
+ }
+ if (Wgd < 0 || Wgd > weight_scale) {
+ log_warn(LD_DIR, "Bw %s: Wgd="I64_FORMAT"! G="I64_FORMAT
+ " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename, I64_PRINTF_ARG(Wgd),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ Wgd = MAX(MIN(Wgd, weight_scale), 0);
+ }
+ if (Wmg < 0 || Wmg > weight_scale) {
+ log_warn(LD_DIR, "Bw %s: Wmg="I64_FORMAT"! G="I64_FORMAT
+ " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename, I64_PRINTF_ARG(Wmg),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ Wmg = MAX(MIN(Wmg, weight_scale), 0);
+ }
+ if (Wme < 0 || Wme > weight_scale) {
+ log_warn(LD_DIR, "Bw %s: Wme="I64_FORMAT"! G="I64_FORMAT
+ " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename, I64_PRINTF_ARG(Wme),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ Wme = MAX(MIN(Wme, weight_scale), 0);
+ }
+ if (Wmd < 0 || Wmd > weight_scale) {
+ log_warn(LD_DIR, "Bw %s: Wmd="I64_FORMAT"! G="I64_FORMAT
+ " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename, I64_PRINTF_ARG(Wmd),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ Wmd = MAX(MIN(Wmd, weight_scale), 0);
+ }
+ if (Wee < 0 || Wee > weight_scale) {
+ log_warn(LD_DIR, "Bw %s: Wee="I64_FORMAT"! G="I64_FORMAT
+ " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename, I64_PRINTF_ARG(Wee),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ Wee = MAX(MIN(Wee, weight_scale), 0);
+ }
+ if (Wed < 0 || Wed > weight_scale) {
+ log_warn(LD_DIR, "Bw %s: Wed="I64_FORMAT"! G="I64_FORMAT
+ " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename, I64_PRINTF_ARG(Wed),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+ Wed = MAX(MIN(Wed, weight_scale), 0);
+ }
+
+ // Add consensus weight keywords
+ smartlist_add(chunks, tor_strdup("bandwidth-weights "));
+ /*
+ * Provide Wgm=Wgg, Wmm=1, Wem=Wee, Weg=Wed. May later determine
+ * that middle nodes need different bandwidth weights for dirport traffic,
+ * or that weird exit policies need special weight, or that bridges
+ * need special weight.
+ *
+ * NOTE: This list is sorted.
+ */
+ r = tor_snprintf(buf, sizeof(buf),
+ "Wbd=%d Wbe=%d Wbg=%d Wbm=%d "
+ "Wdb=%d "
+ "Web=%d Wed=%d Wee=%d Weg=%d Wem=%d "
+ "Wgb=%d Wgd=%d Wgg=%d Wgm=%d "
+ "Wmb=%d Wmd=%d Wme=%d Wmg=%d Wmm=%d\n",
+ (int)Wmd, (int)Wme, (int)Wmg, (int)weight_scale,
+ (int)weight_scale,
+ (int)weight_scale, (int)Wed, (int)Wee, (int)Wed, (int)Wee,
+ (int)weight_scale, (int)Wgd, (int)Wgg, (int)Wgg,
+ (int)weight_scale, (int)Wmd, (int)Wme, (int)Wmg, (int)weight_scale);
+ if (r<0) {
+ log_warn(LD_BUG,
+ "Not enough space in buffer for bandwidth-weights line.");
+ *buf = '\0';
+ }
+ smartlist_add(chunks, tor_strdup(buf));
+ log_notice(LD_CIRC, "Computed bandwidth weights for %s: "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT,
+ casename,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
+}
+
/** Given a list of vote networkstatus_t in <b>votes</b>, our public
* authority <b>identity_key</b>, our private authority <b>signing_key</b>,
* and the number of <b>total_authorities</b> that we believe exist in our
@@ -673,9 +1086,10 @@ networkstatus_compute_consensus(smartlist_t *votes,
char *client_versions = NULL, *server_versions = NULL;
smartlist_t *flags;
const char *flavor_name;
+ int64_t G=0, M=0, E=0, D=0, T=0; /* For bandwidth weights */
const routerstatus_format_type_t rs_format =
flavor == FLAV_NS ? NS_V3_CONSENSUS : NS_V3_CONSENSUS_MICRODESC;
-
+ char *params = NULL;
tor_assert(flavor == FLAV_NS || flavor == FLAV_MICRODESC);
tor_assert(total_authorities >= smartlist_len(votes));
@@ -812,7 +1226,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
if (consensus_method >= MIN_METHOD_FOR_PARAMS) {
- char *params = dirvote_compute_params(votes);
+ params = dirvote_compute_params(votes);
if (params) {
smartlist_add(chunks, tor_strdup("params "));
smartlist_add(chunks, params);
@@ -1007,6 +1421,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
const char *chosen_name = NULL;
int exitsummary_disagreement = 0;
int is_named = 0, is_unnamed = 0, is_running = 0;
+ int is_guard = 0, is_exit = 0;
int naming_conflict = 0;
int n_listing = 0;
int i;
@@ -1126,7 +1541,11 @@ networkstatus_compute_consensus(smartlist_t *votes,
} else {
if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2) {
smartlist_add(chosen_flags, (char*)fl);
- if (!strcmp(fl, "Running"))
+ if (!strcmp(fl, "Exit"))
+ is_exit = 1;
+ else if (!strcmp(fl, "Guard"))
+ is_guard = 1;
+ else if (!strcmp(fl, "Running"))
is_running = 1;
}
}
@@ -1154,6 +1573,23 @@ networkstatus_compute_consensus(smartlist_t *votes,
rs_out.bandwidth = median_uint32(bandwidths, num_bandwidths);
}
+ if (consensus_method >= MIN_METHOD_FOR_BW_WEIGHTS) {
+ if (rs_out.has_bandwidth) {
+ T += rs_out.bandwidth;
+ if (is_exit && is_guard)
+ D += rs_out.bandwidth;
+ else if (is_exit)
+ E += rs_out.bandwidth;
+ else if (is_guard)
+ G += rs_out.bandwidth;
+ else
+ M += rs_out.bandwidth;
+ } else {
+ log_warn(LD_BUG, "Missing consensus bandwidth for router %s",
+ rs_out.nickname);
+ }
+ }
+
/* Ok, we already picked a descriptor digest we want to list
* previously. Now we want to use the exit policy summary from
* that descriptor. If everybody plays nice all the voters who
@@ -1298,6 +1734,47 @@ networkstatus_compute_consensus(smartlist_t *votes,
tor_free(measured_bws);
}
+ if (consensus_method >= MIN_METHOD_FOR_FOOTER) {
+ /* Starting with consensus method 9, we clearly mark the directory
+ * footer region */
+ smartlist_add(chunks, tor_strdup("directory-footer\n"));
+ }
+
+ if (consensus_method >= MIN_METHOD_FOR_BW_WEIGHTS) {
+ int64_t weight_scale = BW_WEIGHT_SCALE;
+ char *bw_weight_param = NULL;
+
+ // Parse params, extract BW_WEIGHT_SCALE if present
+ // DO NOT use consensus_param_bw_weight_scale() in this code!
+ // The consensus is not formed yet!
+ if (params) {
+ if (strcmpstart(params, "bwweightscale=") == 0)
+ bw_weight_param = params;
+ else
+ bw_weight_param = strstr(params, " bwweightscale=");
+ }
+
+ if (bw_weight_param) {
+ int ok=0;
+ char *eq = strchr(bw_weight_param, '=');
+ if (eq) {
+ weight_scale = tor_parse_long(eq+1, 10, INT32_MIN, INT32_MAX, &ok,
+ NULL);
+ if (!ok) {
+ log_warn(LD_DIR, "Bad element '%s' in bw weight param",
+ escaped(bw_weight_param));
+ weight_scale = BW_WEIGHT_SCALE;
+ }
+ } else {
+ log_warn(LD_DIR, "Bad element '%s' in bw weight param",
+ escaped(bw_weight_param));
+ weight_scale = BW_WEIGHT_SCALE;
+ }
+ }
+
+ networkstatus_compute_bw_weights_v9(chunks, G, M, E, D, T, weight_scale);
+ }
+
/* Add a signature. */
{
char digest[DIGEST256_LEN];
@@ -1379,11 +1856,15 @@ networkstatus_compute_consensus(smartlist_t *votes,
networkstatus_t *c;
if (!(c = networkstatus_parse_vote_from_string(result, NULL,
NS_TYPE_CONSENSUS))) {
- log_err(LD_BUG,"Generated a networkstatus consensus we couldn't "
+ log_err(LD_BUG, "Generated a networkstatus consensus we couldn't "
"parse.");
tor_free(result);
return NULL;
}
+ // Verify balancing parameters
+ if (consensus_method >= MIN_METHOD_FOR_BW_WEIGHTS) {
+ networkstatus_verify_bw_weights(c);
+ }
networkstatus_vote_free(c);
}
diff --git a/src/or/dns.c b/src/or/dns.c
index a9f6426042..54acef4be2 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2003-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/dnsserv.c b/src/or/dnsserv.c
index 8e3e55e795..2e5301eae0 100644
--- a/src/or/dnsserv.c
+++ b/src/or/dnsserv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2009, The Tor Project, Inc. */
+/* Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/eventdns_tor.h b/src/or/eventdns_tor.h
index 3d84fc7794..141ff09f1e 100644
--- a/src/or/eventdns_tor.h
+++ b/src/or/eventdns_tor.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2009, The Tor Project, Inc. */
+/* Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
diff --git a/src/or/geoip.c b/src/or/geoip.c
index 25ce180b3e..b5a0374c49 100644
--- a/src/or/geoip.c
+++ b/src/or/geoip.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2009, The Tor Project, Inc. */
+/* Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/hibernate.c b/src/or/hibernate.c
index d68682d730..3c52a31729 100644
--- a/src/or/hibernate.c
+++ b/src/or/hibernate.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/main.c b/src/or/main.c
index f4ee16ca1f..74075b6257 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/microdesc.c b/src/or/microdesc.c
index f29611f930..b3c54a84f5 100644
--- a/src/or/microdesc.c
+++ b/src/or/microdesc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, The Tor Project, Inc. */
+/* Copyright (c) 2009-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "or.h"
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index a507f1be2d..8110c78388 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -1264,7 +1264,6 @@ update_consensus_networkstatus_fetch_time(time_t now)
time_to_download_next_consensus = now;
log_info(LD_DIR, "No live consensus; we should fetch one immediately.");
}
-
}
/** Return 1 if there's a reason we shouldn't try any directory
@@ -2038,6 +2037,25 @@ networkstatus_dump_bridge_status_to_file(time_t now)
tor_free(status);
}
+int32_t
+get_net_param_from_list(smartlist_t *net_params, const char *param_name,
+ int default_val)
+{
+ size_t name_len = strlen(param_name);
+
+ SMARTLIST_FOREACH_BEGIN(net_params, const char *, p) {
+ if (!strcmpstart(p, param_name) && p[name_len] == '=') {
+ int ok=0;
+ long v = tor_parse_long(p+name_len+1, 10, INT32_MIN,
+ INT32_MAX, &ok, NULL);
+ if (ok)
+ return (int32_t) v;
+ }
+ } SMARTLIST_FOREACH_END(p);
+
+ return default_val;
+}
+
/** Return the value of a integer parameter from the networkstatus <b>ns</b>
* whose name is <b>param_name</b>. If <b>ns</b> is NULL, try loading the
* latest consensus ourselves. Return <b>default_val</b> if no latest
@@ -2046,27 +2064,30 @@ int32_t
networkstatus_get_param(networkstatus_t *ns, const char *param_name,
int32_t default_val)
{
- size_t name_len;
-
if (!ns) /* if they pass in null, go find it ourselves */
ns = networkstatus_get_latest_consensus();
if (!ns || !ns->net_params)
return default_val;
- name_len = strlen(param_name);
+ return get_net_param_from_list(ns->net_params, param_name, default_val);
+}
- SMARTLIST_FOREACH_BEGIN(ns->net_params, const char *, p) {
- if (!strcmpstart(p, param_name) && p[name_len] == '=') {
- int ok=0;
- long v = tor_parse_long(p+name_len+1, 10, INT32_MIN,
- INT32_MAX, &ok, NULL);
- if (ok)
- return (int32_t) v;
- }
- } SMARTLIST_FOREACH_END(p);
+/** Return the value of a integer bw weight parameter from the networkstatus
+ * <b>ns</b> whose name is <b>weight_name</b>. If <b>ns</b> is NULL, try
+ * loading the latest consensus ourselves. Return <b>default_val</b> if no
+ * latest consensus, or if it has no parameter called <b>param_name</b>. */
+int32_t
+networkstatus_get_bw_weight(networkstatus_t *ns, const char *weight_name,
+ int32_t default_val)
+{
+ if (!ns) /* if they pass in null, go find it ourselves */
+ ns = networkstatus_get_latest_consensus();
- return default_val;
+ if (!ns || !ns->weight_params)
+ return default_val;
+
+ return get_net_param_from_list(ns->weight_params, weight_name, default_val);
}
/** Return the name of the consensus flavor <b>flav</b> as used to identify
diff --git a/src/or/ntmain.c b/src/or/ntmain.c
index e5a855eec4..6f349cca6a 100644
--- a/src/or/ntmain.c
+++ b/src/or/ntmain.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define MAIN_PRIVATE
diff --git a/src/or/onion.c b/src/or/onion.c
index f8913cd23b..8870874246 100644
--- a/src/or/onion.c
+++ b/src/or/onion.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/or.h b/src/or/or.h
index 434de7819e..737c197425 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -1771,6 +1771,10 @@ typedef struct networkstatus_t {
* consensus, sorted by key. */
smartlist_t *net_params;
+ /** List of key=value strings for the bw weight parameters in the
+ * consensus. */
+ smartlist_t *weight_params;
+
/** List of networkstatus_voter_info_t. For a vote, only one element
* is included. For a consensus, one element is included for every voter
* whose vote contributed to the consensus. */
@@ -2458,6 +2462,11 @@ typedef struct {
int ConstrainedSockets; /**< Shrink xmit and recv socket buffers. */
uint64_t ConstrainedSockSize; /**< Size of constrained buffers. */
+ /** Whether we should drop exit streams from Tors that we don't know
+ * are relays. XXX022 In here for 0.2.2.11 as a temporary test before
+ * we switch over to putting it in consensusparams. -RD */
+ int RefuseUnknownExits;
+
/** Application ports that require all nodes in circ to have sufficient
* uptime. */
smartlist_t *LongLivedPorts;
@@ -3528,6 +3537,7 @@ int connection_or_process_inbuf(or_connection_t *conn);
int connection_or_flushed_some(or_connection_t *conn);
int connection_or_finished_flushing(or_connection_t *conn);
int connection_or_finished_connecting(or_connection_t *conn);
+int connection_or_digest_is_known_relay(const char *id_digest);
void connection_or_connect_failed(or_connection_t *conn,
int reason, const char *msg);
@@ -3950,6 +3960,9 @@ int dirserv_read_measured_bandwidths(const char *from_file,
/** Smallest allowable voting interval. */
#define MIN_VOTE_INTERVAL 300
+/** Precision multiplier for the Bw weights */
+#define BW_WEIGHT_SCALE 10000
+
void dirvote_free_all(void);
/* vote manipulation */
@@ -4345,10 +4358,14 @@ void signed_descs_update_status_from_consensus_networkstatus(
char *networkstatus_getinfo_helper_single(routerstatus_t *rs);
char *networkstatus_getinfo_by_purpose(const char *purpose_string, time_t now);
void networkstatus_dump_bridge_status_to_file(time_t now);
+int32_t get_net_param_from_list(smartlist_t *net_params, const char *name,
+ int default_val);
int32_t networkstatus_get_param(networkstatus_t *ns, const char *param_name,
int32_t default_val);
int getinfo_helper_networkstatus(control_connection_t *conn,
const char *question, char **answer);
+int32_t networkstatus_get_bw_weight(networkstatus_t *ns, const char *weight,
+ int32_t default_val);
const char *networkstatus_get_flavor_name(consensus_flavor_t flav);
int networkstatus_parse_flavor_name(const char *flavname);
void document_signature_free(document_signature_t *sig);
@@ -4947,11 +4964,13 @@ uint32_t router_get_advertised_bandwidth_capped(routerinfo_t *router);
/** Possible ways to weight routers when choosing one randomly. See
* routerlist_sl_choose_by_bandwidth() for more information.*/
typedef enum {
- NO_WEIGHTING, WEIGHT_FOR_EXIT, WEIGHT_FOR_GUARD
+ NO_WEIGHTING, WEIGHT_FOR_EXIT, WEIGHT_FOR_MID, WEIGHT_FOR_GUARD,
+ WEIGHT_FOR_DIR
} bandwidth_weight_rule_t;
routerinfo_t *routerlist_sl_choose_by_bandwidth(smartlist_t *sl,
bandwidth_weight_rule_t rule);
-routerstatus_t *routerstatus_sl_choose_by_bandwidth(smartlist_t *sl);
+routerstatus_t *routerstatus_sl_choose_by_bandwidth(smartlist_t *sl,
+ bandwidth_weight_rule_t rule);
/** Flags to be passed to control router_choose_random_node() to indicate what
* kind of nodes to pick according to what algorithm. */
@@ -5133,7 +5152,7 @@ typedef struct tor_version_t {
char git_tag[DIGEST_LEN];
} tor_version_t;
-int router_get_router_hash(const char *s, char *digest);
+int router_get_router_hash(const char *s, size_t s_len, char *digest);
int router_get_dir_hash(const char *s, char *digest);
int router_get_runningrouters_hash(const char *s, char *digest);
int router_get_networkstatus_v2_hash(const char *s, char *digest);
@@ -5177,6 +5196,7 @@ void dump_distinct_digest_count(int severity);
int compare_routerstatus_entries(const void **_a, const void **_b);
networkstatus_v2_t *networkstatus_v2_parse_from_string(const char *s);
+int networkstatus_verify_bw_weights(networkstatus_t *ns);
networkstatus_t *networkstatus_parse_vote_from_string(const char *s,
const char **eos_out,
networkstatus_type_t ns_type);
diff --git a/src/or/policies.c b/src/or/policies.c
index a49de01e18..90e159a880 100644
--- a/src/or/policies.c
+++ b/src/or/policies.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/reasons.c b/src/or/reasons.c
index 0544990679..46483b2770 100644
--- a/src/or/reasons.c
+++ b/src/or/reasons.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/relay.c b/src/or/relay.c
index ae1b062cf6..599d3d9c80 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index cbdb9a676c..9a31c2d73f 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
index c42f834445..814abd8cc8 100644
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/rendmid.c b/src/or/rendmid.c
index 57f5b6daed..c9f4bf8b70 100644
--- a/src/or/rendmid.c
+++ b/src/or/rendmid.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index 9fcf248c37..7795db0d70 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
diff --git a/src/or/rephist.c b/src/or/rephist.c
index af8104ef63..0e55db2d63 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -1908,8 +1908,8 @@ rep_hist_get_predicted_internal(time_t now, int *need_uptime,
return 0; /* too long ago */
if (predicted_internal_uptime_time + PREDICTED_CIRCS_RELEVANCE_TIME >= now)
*need_uptime = 1;
- if (predicted_internal_capacity_time + PREDICTED_CIRCS_RELEVANCE_TIME >= now)
- *need_capacity = 1;
+ // Always predict that we need capacity.
+ *need_capacity = 1;
return 1;
}
diff --git a/src/or/router.c b/src/or/router.c
index 257bca935b..347d7f9eff 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define ROUTER_PRIVATE
@@ -1416,6 +1416,7 @@ router_rebuild_descriptor(int force)
ei->cache_info.send_unencrypted = 1;
router_get_router_hash(ri->cache_info.signed_descriptor_body,
+ strlen(ri->cache_info.signed_descriptor_body),
ri->cache_info.signed_descriptor_digest);
routerinfo_set_country(ri);
@@ -1778,7 +1779,7 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
strlcpy(s+written, "router-signature\n", maxlen-written);
written += strlen(s+written);
s[written] = '\0';
- if (router_get_router_hash(s, digest) < 0) {
+ if (router_get_router_hash(s, strlen(s), digest) < 0) {
return -1;
}
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 1b9df56031..0173c27e4e 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -583,8 +583,6 @@ signed_desc_append_to_journal(signed_descriptor_t *desc,
const char *body = signed_descriptor_get_body_impl(desc,1);
size_t len = desc->signed_descriptor_len + desc->annotations_len;
- tor_assert(len == strlen(body));
-
if (append_bytes_to_file(fname, body, len, 1)) {
log_warn(LD_FS, "Unable to store router descriptor");
tor_free(fname);
@@ -1096,9 +1094,10 @@ router_pick_directory_server_impl(authority_type_t type, int flags)
} SMARTLIST_FOREACH_END(status);
if (smartlist_len(tunnel)) {
- result = routerstatus_sl_choose_by_bandwidth(tunnel);
+ result = routerstatus_sl_choose_by_bandwidth(tunnel, WEIGHT_FOR_DIR);
} else if (smartlist_len(overloaded_tunnel)) {
- result = routerstatus_sl_choose_by_bandwidth(overloaded_tunnel);
+ result = routerstatus_sl_choose_by_bandwidth(overloaded_tunnel,
+ WEIGHT_FOR_DIR);
} else if (smartlist_len(trusted_tunnel)) {
/* FFFF We don't distinguish between trusteds and overloaded trusteds
* yet. Maybe one day we should. */
@@ -1106,9 +1105,10 @@ router_pick_directory_server_impl(authority_type_t type, int flags)
* is a feature, but it could easily be a bug. -RD */
result = smartlist_choose(trusted_tunnel);
} else if (smartlist_len(direct)) {
- result = routerstatus_sl_choose_by_bandwidth(direct);
+ result = routerstatus_sl_choose_by_bandwidth(direct, WEIGHT_FOR_DIR);
} else if (smartlist_len(overloaded_direct)) {
- result = routerstatus_sl_choose_by_bandwidth(overloaded_direct);
+ result = routerstatus_sl_choose_by_bandwidth(overloaded_direct,
+ WEIGHT_FOR_DIR);
} else {
result = smartlist_choose(trusted_direct);
}
@@ -1538,6 +1538,204 @@ kb_to_bytes(uint32_t bw)
/** Helper function:
* choose a random element of smartlist <b>sl</b>, weighted by
+ * the advertised bandwidth of each element using the consensus
+ * bandwidth weights.
+ *
+ * If <b>statuses</b> is zero, then <b>sl</b> is a list of
+ * routerinfo_t's. Otherwise it's a list of routerstatus_t's.
+ *
+ * If <b>rule</b>==WEIGHT_FOR_EXIT. we're picking an exit node: consider all
+ * nodes' bandwidth equally regardless of their Exit status, since there may
+ * be some in the list because they exit to obscure ports. If
+ * <b>rule</b>==NO_WEIGHTING, we're picking a non-exit node: weight
+ * exit-node's bandwidth less depending on the smallness of the fraction of
+ * Exit-to-total bandwidth. If <b>rule</b>==WEIGHT_FOR_GUARD, we're picking a
+ * guard node: consider all guard's bandwidth equally. Otherwise, weight
+ * guards proportionally less.
+ */
+static void *
+smartlist_choose_by_bandwidth_weights(smartlist_t *sl,
+ bandwidth_weight_rule_t rule,
+ int statuses)
+{
+ int64_t weight_scale;
+ int64_t rand_bw;
+ double Wg = -1, Wm = -1, We = -1, Wd = -1;
+ double Wgb = -1, Wmb = -1, Web = -1, Wdb = -1;
+ double weighted_bw = 0;
+ double *bandwidths;
+ double tmp = 0;
+ unsigned int i;
+
+ /* Can't choose exit and guard at same time */
+ tor_assert(rule == NO_WEIGHTING ||
+ rule == WEIGHT_FOR_EXIT ||
+ rule == WEIGHT_FOR_GUARD ||
+ rule == WEIGHT_FOR_MID ||
+ rule == WEIGHT_FOR_DIR);
+
+ if (smartlist_len(sl) == 0) {
+ log_info(LD_CIRC,
+ "Empty routerlist passed in to consensus weight node "
+ "selection for rule %d", rule);
+ return NULL;
+ }
+
+ weight_scale = networkstatus_get_param(NULL, "bwweightscale",
+ BW_WEIGHT_SCALE);
+
+ if (rule == WEIGHT_FOR_GUARD) {
+ Wg = networkstatus_get_bw_weight(NULL, "Wgg", -1);
+ Wm = networkstatus_get_bw_weight(NULL, "Wgm", -1); /* Bridges */
+ We = 0;
+ Wd = networkstatus_get_bw_weight(NULL, "Wgd", -1);
+
+ Wgb = networkstatus_get_bw_weight(NULL, "Wgb", -1);
+ Wmb = networkstatus_get_bw_weight(NULL, "Wmb", -1);
+ Web = networkstatus_get_bw_weight(NULL, "Web", -1);
+ Wdb = networkstatus_get_bw_weight(NULL, "Wdb", -1);
+ } else if (rule == WEIGHT_FOR_MID) {
+ Wg = networkstatus_get_bw_weight(NULL, "Wmg", -1);
+ Wm = networkstatus_get_bw_weight(NULL, "Wmm", -1);
+ We = networkstatus_get_bw_weight(NULL, "Wme", -1);
+ Wd = networkstatus_get_bw_weight(NULL, "Wmd", -1);
+
+ Wgb = networkstatus_get_bw_weight(NULL, "Wgb", -1);
+ Wmb = networkstatus_get_bw_weight(NULL, "Wmb", -1);
+ Web = networkstatus_get_bw_weight(NULL, "Web", -1);
+ Wdb = networkstatus_get_bw_weight(NULL, "Wdb", -1);
+ } else if (rule == WEIGHT_FOR_EXIT) {
+ // Guards CAN be exits if they have weird exit policies
+ // They are d then I guess...
+ We = networkstatus_get_bw_weight(NULL, "Wee", -1);
+ Wm = networkstatus_get_bw_weight(NULL, "Wem", -1); /* Odd exit policies */
+ Wd = networkstatus_get_bw_weight(NULL, "Wed", -1);
+ Wg = networkstatus_get_bw_weight(NULL, "Weg", -1); /* Odd exit policies */
+
+ Wgb = networkstatus_get_bw_weight(NULL, "Wgb", -1);
+ Wmb = networkstatus_get_bw_weight(NULL, "Wmb", -1);
+ Web = networkstatus_get_bw_weight(NULL, "Web", -1);
+ Wdb = networkstatus_get_bw_weight(NULL, "Wdb", -1);
+ } else if (rule == WEIGHT_FOR_DIR) {
+ We = networkstatus_get_bw_weight(NULL, "Wbe", -1);
+ Wm = networkstatus_get_bw_weight(NULL, "Wbm", -1);
+ Wd = networkstatus_get_bw_weight(NULL, "Wbd", -1);
+ Wg = networkstatus_get_bw_weight(NULL, "Wbg", -1);
+
+ Wgb = Wmb = Web = Wdb = weight_scale;
+ } else if (rule == NO_WEIGHTING) {
+ Wg = Wm = We = Wd = weight_scale;
+ Wgb = Wmb = Web = Wdb = weight_scale;
+ }
+
+ if (Wg < 0 || Wm < 0 || We < 0 || Wd < 0 || Wgb < 0 || Wmb < 0 || Wdb < 0
+ || Web < 0) {
+ log_debug(LD_CIRC,
+ "Got negative bandwidth weights. Defaulting to old selection"
+ " algorithm.");
+ return NULL; // Use old algorithm.
+ }
+
+ Wg /= weight_scale;
+ Wm /= weight_scale;
+ We /= weight_scale;
+ Wd /= weight_scale;
+
+ Wgb /= weight_scale;
+ Wmb /= weight_scale;
+ Web /= weight_scale;
+ Wdb /= weight_scale;
+
+ bandwidths = tor_malloc_zero(sizeof(double)*smartlist_len(sl));
+
+ // Cycle through smartlist and total the bandwidth.
+ for (i = 0; i < (unsigned)smartlist_len(sl); ++i) {
+ int is_exit = 0, is_guard = 0, is_dir = 0, this_bw = 0;
+ double weight = 1;
+ if (statuses) {
+ routerstatus_t *status = smartlist_get(sl, i);
+ is_exit = status->is_exit;
+ is_guard = status->is_possible_guard;
+ is_dir = (status->dir_port != 0);
+ if (!status->has_bandwidth) {
+ tor_free(bandwidths);
+ /* This should never happen, unless all the authorites downgrade
+ * to 0.2.0 or rogue routerstatuses get inserted into our consensus. */
+ log_warn(LD_BUG,
+ "Consensus is not listing bandwidths. Defaulting back to "
+ "old router selection algorithm.");
+ return NULL;
+ }
+ this_bw = kb_to_bytes(status->bandwidth);
+ } else {
+ routerstatus_t *rs;
+ routerinfo_t *router = smartlist_get(sl, i);
+ rs = router_get_consensus_status_by_id(
+ router->cache_info.identity_digest);
+ is_exit = router->is_exit;
+ is_guard = router->is_possible_guard;
+ is_dir = (router->dir_port != 0);
+ if (rs && rs->has_bandwidth) {
+ this_bw = kb_to_bytes(rs->bandwidth);
+ } else { /* bridge or other descriptor not in our consensus */
+ this_bw = router_get_advertised_bandwidth_capped(router);
+ }
+ }
+ if (is_guard && is_exit) {
+ weight = (is_dir ? Wdb*Wd : Wd);
+ } else if (is_guard) {
+ weight = (is_dir ? Wgb*Wg : Wg);
+ } else if (is_exit) {
+ weight = (is_dir ? Web*We : We);
+ } else { // middle
+ weight = (is_dir ? Wmb*Wm : Wm);
+ }
+
+ bandwidths[i] = weight*this_bw;
+ weighted_bw += weight*this_bw;
+ }
+
+ log_debug(LD_CIRC, "Choosing node for rule %d based on weights "
+ "Wg=%lf Wm=%lf We=%lf Wd=%lf with total bw %lf", rule,
+ Wg, Wm, We, Wd, weighted_bw);
+
+ /* If there is no bandwidth, choose at random */
+ if (DBL_TO_U64(weighted_bw) == 0) {
+ log_warn(LD_CIRC,
+ "Weighted bandwidth is %lf in node selection for rule %d",
+ weighted_bw, rule);
+ tor_free(bandwidths);
+ return smartlist_choose(sl);
+ }
+
+ rand_bw = crypto_rand_uint64(DBL_TO_U64(weighted_bw));
+ rand_bw++; /* crypto_rand_uint64() counts from 0, and we need to count
+ * from 1 below. See bug 1203 for details. */
+
+ /* Last, count through sl until we get to the element we picked */
+ tmp = 0.0;
+ for (i=0; i < (unsigned)smartlist_len(sl); i++) {
+ tmp += bandwidths[i];
+ if (tmp >= rand_bw)
+ break;
+ }
+
+ if (i == (unsigned)smartlist_len(sl)) {
+ /* This was once possible due to round-off error, but shouldn't be able
+ * to occur any longer. */
+ tor_fragile_assert();
+ --i;
+ log_warn(LD_BUG, "Round-off error in computing bandwidth had an effect on "
+ " which router we chose. Please tell the developers. "
+ "%lf " U64_FORMAT " %lf", tmp, U64_PRINTF_ARG(rand_bw),
+ weighted_bw);
+ }
+ tor_free(bandwidths);
+ return smartlist_get(sl, i);
+}
+
+/** Helper function:
+ * choose a random element of smartlist <b>sl</b>, weighted by
* the advertised bandwidth of each element.
*
* If <b>statuses</b> is zero, then <b>sl</b> is a list of
@@ -1572,11 +1770,24 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, bandwidth_weight_rule_t rule,
bitarray_t *guard_bits;
int me_idx = -1;
+ // This function does not support WEIGHT_FOR_DIR
+ // or WEIGHT_FOR_MID
+ if (rule == WEIGHT_FOR_DIR || rule == WEIGHT_FOR_MID) {
+ rule = NO_WEIGHTING;
+ }
+
/* Can't choose exit and guard at same time */
tor_assert(rule == NO_WEIGHTING ||
rule == WEIGHT_FOR_EXIT ||
rule == WEIGHT_FOR_GUARD);
+ if (smartlist_len(sl) == 0) {
+ log_info(LD_CIRC,
+ "Empty routerlist passed in to old node selection for rule %d",
+ rule);
+ return NULL;
+ }
+
/* First count the total bandwidth weight, and make a list
* of each value. <0 means "unknown; no routerinfo." We use the
* bits of negative values to remember whether the router was fast (-x)&1
@@ -1797,17 +2008,28 @@ routerinfo_t *
routerlist_sl_choose_by_bandwidth(smartlist_t *sl,
bandwidth_weight_rule_t rule)
{
- return smartlist_choose_by_bandwidth(sl, rule, 0);
+ routerinfo_t *ret;
+ if ((ret = smartlist_choose_by_bandwidth_weights(sl, rule, 0))) {
+ return ret;
+ } else {
+ return smartlist_choose_by_bandwidth(sl, rule, 0);
+ }
}
/** Choose a random element of status list <b>sl</b>, weighted by
* the advertised bandwidth of each status.
*/
routerstatus_t *
-routerstatus_sl_choose_by_bandwidth(smartlist_t *sl)
+routerstatus_sl_choose_by_bandwidth(smartlist_t *sl,
+ bandwidth_weight_rule_t rule)
{
/* We are choosing neither exit nor guard here. Weight accordingly. */
- return smartlist_choose_by_bandwidth(sl, NO_WEIGHTING, 1);
+ routerstatus_t *ret;
+ if ((ret = smartlist_choose_by_bandwidth_weights(sl, rule, 1))) {
+ return ret;
+ } else {
+ return smartlist_choose_by_bandwidth(sl, rule, 1);
+ }
}
/** Return a random running router from the routerlist. Never
@@ -1843,7 +2065,7 @@ router_choose_random_node(smartlist_t *excludedsmartlist,
tor_assert(!(weight_for_exit && need_guard));
rule = weight_for_exit ? WEIGHT_FOR_EXIT :
- (need_guard ? WEIGHT_FOR_GUARD : NO_WEIGHTING);
+ (need_guard ? WEIGHT_FOR_GUARD : WEIGHT_FOR_MID);
/* Exclude relays that allow single hop exit circuits, if the user
* wants to (such relays might be risky) */
@@ -1869,10 +2091,8 @@ router_choose_random_node(smartlist_t *excludedsmartlist,
if (excludedset)
routerset_subtract_routers(sl,excludedset);
- if (need_capacity || need_guard)
- choice = routerlist_sl_choose_by_bandwidth(sl, rule);
- else
- choice = smartlist_choose(sl);
+ // Always weight by bandwidth
+ choice = routerlist_sl_choose_by_bandwidth(sl, rule);
smartlist_free(sl);
if (!choice && (need_uptime || need_capacity || need_guard)) {
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index f4af7cd5e2..293e8c5d98 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -11,6 +11,8 @@
#include "or.h"
#include "memarea.h"
+#undef log
+#include <math.h>
/****************************************************************************/
@@ -104,6 +106,7 @@ typedef enum {
K_KNOWN_FLAGS,
K_PARAMS,
+ K_BW_WEIGHTS,
K_VOTE_DIGEST,
K_CONSENSUS_DIGEST,
K_ADDITIONAL_DIGEST,
@@ -111,6 +114,7 @@ typedef enum {
K_CONSENSUS_METHODS,
K_CONSENSUS_METHOD,
K_LEGACY_DIR_KEY,
+ K_DIRECTORY_FOOTER,
A_PURPOSE,
A_LAST_LISTED,
@@ -485,7 +489,9 @@ static token_rule_t networkstatus_consensus_token_table[] = {
/** List of tokens allowable in the footer of v1/v2 directory/networkstatus
* footers. */
static token_rule_t networkstatus_vote_footer_token_table[] = {
- T( "directory-signature", K_DIRECTORY_SIGNATURE, GE(2), NEED_OBJ ),
+ T01("directory-footer", K_DIRECTORY_FOOTER, NO_ARGS, NO_OBJ ),
+ T01("bandwidth-weights", K_BW_WEIGHTS, ARGS, NO_OBJ ),
+ T( "directory-signature", K_DIRECTORY_SIGNATURE, GE(2), NEED_OBJ ),
END_OF_TABLE
};
@@ -516,11 +522,12 @@ static int router_add_exit_policy(routerinfo_t *router,directory_token_t *tok);
static addr_policy_t *router_parse_addr_policy(directory_token_t *tok);
static addr_policy_t *router_parse_addr_policy_private(directory_token_t *tok);
-static int router_get_hash_impl(const char *s, char *digest,
+static int router_get_hash_impl(const char *s, size_t s_len, char *digest,
const char *start_str, const char *end_str,
char end_char,
digest_algorithm_t alg);
-static int router_get_hashes_impl(const char *s, digests_t *digests,
+static int router_get_hashes_impl(const char *s, size_t s_len,
+ digests_t *digests,
const char *start_str, const char *end_str,
char end_char);
static void token_clear(directory_token_t *tok);
@@ -602,7 +609,7 @@ dump_desc(const char *desc, const char *type)
int
router_get_dir_hash(const char *s, char *digest)
{
- return router_get_hash_impl(s,digest,
+ return router_get_hash_impl(s, strlen(s), digest,
"signed-directory","\ndirectory-signature",'\n',
DIGEST_SHA1);
}
@@ -611,9 +618,9 @@ router_get_dir_hash(const char *s, char *digest)
* <b>s</b>. Return 0 on success, -1 on failure.
*/
int
-router_get_router_hash(const char *s, char *digest)
+router_get_router_hash(const char *s, size_t s_len, char *digest)
{
- return router_get_hash_impl(s,digest,
+ return router_get_hash_impl(s, s_len, digest,
"router ","\nrouter-signature", '\n',
DIGEST_SHA1);
}
@@ -624,7 +631,7 @@ router_get_router_hash(const char *s, char *digest)
int
router_get_runningrouters_hash(const char *s, char *digest)
{
- return router_get_hash_impl(s,digest,
+ return router_get_hash_impl(s, strlen(s), digest,
"network-status","\ndirectory-signature", '\n',
DIGEST_SHA1);
}
@@ -634,7 +641,7 @@ router_get_runningrouters_hash(const char *s, char *digest)
int
router_get_networkstatus_v2_hash(const char *s, char *digest)
{
- return router_get_hash_impl(s,digest,
+ return router_get_hash_impl(s, strlen(s), digest,
"network-status-version","\ndirectory-signature",
'\n',
DIGEST_SHA1);
@@ -645,7 +652,7 @@ router_get_networkstatus_v2_hash(const char *s, char *digest)
int
router_get_networkstatus_v3_hashes(const char *s, digests_t *digests)
{
- return router_get_hashes_impl(s,digests,
+ return router_get_hashes_impl(s,strlen(s),digests,
"network-status-version",
"\ndirectory-signature",
' ');
@@ -657,7 +664,7 @@ int
router_get_networkstatus_v3_hash(const char *s, char *digest,
digest_algorithm_t alg)
{
- return router_get_hash_impl(s,digest,
+ return router_get_hash_impl(s, strlen(s), digest,
"network-status-version",
"\ndirectory-signature",
' ', alg);
@@ -668,8 +675,8 @@ router_get_networkstatus_v3_hash(const char *s, char *digest,
int
router_get_extrainfo_hash(const char *s, char *digest)
{
- return router_get_hash_impl(s,digest,"extra-info","\nrouter-signature",'\n',
- DIGEST_SHA1);
+ return router_get_hash_impl(s, strlen(s), digest, "extra-info",
+ "\nrouter-signature",'\n', DIGEST_SHA1);
}
/** Helper: used to generate signatures for routers, directories and
@@ -1238,6 +1245,8 @@ dump_distinct_digest_count(int severity)
* s through end into the signed_descriptor_body of the resulting
* routerinfo_t.
*
+ * If <b>end</b> is NULL, <b>s</b> must be properly NULL-terminated.
+ *
* If <b>allow_annotations</b>, it's okay to encounter annotations in <b>s</b>
* before the router; if it's false, reject the router if it's annotated. If
* <b>prepend_annotations</b> is set, it should contain some annotations:
@@ -1300,7 +1309,7 @@ router_parse_entry_from_string(const char *s, const char *end,
}
}
- if (router_get_router_hash(s, digest) < 0) {
+ if (router_get_router_hash(s, end - s, digest) < 0) {
log_warn(LD_DIR, "Couldn't compute router hash.");
goto err;
}
@@ -1722,7 +1731,7 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
log_warn(LD_DIR, "Error tokenizing key certificate");
goto err;
}
- if (router_get_hash_impl(s, digest, "dir-key-certificate-version",
+ if (router_get_hash_impl(s, strlen(s), digest, "dir-key-certificate-version",
"\ndir-key-certification", '\n', DIGEST_SHA1) < 0)
goto err;
tok = smartlist_get(tokens, 0);
@@ -1866,23 +1875,28 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
/** Helper: given a string <b>s</b>, return the start of the next router-status
* object (starting with "r " at the start of a line). If none is found,
- * return the start of the next directory signature. If none is found, return
- * the end of the string. */
+ * return the start of the directory footer, or the next directory signature.
+ * If none is found, return the end of the string. */
static INLINE const char *
find_start_of_next_routerstatus(const char *s)
{
- const char *eos = strstr(s, "\nr ");
- if (eos) {
- const char *eos2 = tor_memstr(s, eos-s, "\ndirectory-signature");
- if (eos2 && eos2 < eos)
- return eos2;
- else
- return eos+1;
- } else {
- if ((eos = strstr(s, "\ndirectory-signature")))
- return eos+1;
- return s + strlen(s);
- }
+ const char *eos, *footer, *sig;
+ if ((eos = strstr(s, "\nr ")))
+ ++eos;
+ else
+ eos = s + strlen(s);
+
+ footer = tor_memstr(s, eos-s, "\ndirectory-footer");
+ sig = tor_memstr(s, eos-s, "\ndirectory-signature");
+
+ if (footer && sig)
+ return MIN(footer, sig) + 1;
+ else if (footer)
+ return footer+1;
+ else if (sig)
+ return sig+1;
+ else
+ return eos;
}
/** Given a string at *<b>s</b>, containing a routerstatus object, and an
@@ -2327,6 +2341,395 @@ networkstatus_v2_parse_from_string(const char *s)
return ns;
}
+/** Verify the bandwidth weights of a network status document */
+int
+networkstatus_verify_bw_weights(networkstatus_t *ns)
+{
+ int64_t weight_scale;
+ int64_t G=0, M=0, E=0, D=0, T=0;
+ double Wgg, Wgm, Wgd, Wmg, Wmm, Wme, Wmd, Weg, Wem, Wee, Wed;
+ double Gtotal=0, Mtotal=0, Etotal=0;
+ const char *casename = NULL;
+ int valid = 1;
+
+ weight_scale = networkstatus_get_param(ns, "bwweightscale", BW_WEIGHT_SCALE);
+ Wgg = networkstatus_get_bw_weight(ns, "Wgg", -1);
+ Wgm = networkstatus_get_bw_weight(ns, "Wgm", -1);
+ Wgd = networkstatus_get_bw_weight(ns, "Wgd", -1);
+ Wmg = networkstatus_get_bw_weight(ns, "Wmg", -1);
+ Wmm = networkstatus_get_bw_weight(ns, "Wmm", -1);
+ Wme = networkstatus_get_bw_weight(ns, "Wme", -1);
+ Wmd = networkstatus_get_bw_weight(ns, "Wmd", -1);
+ Weg = networkstatus_get_bw_weight(ns, "Weg", -1);
+ Wem = networkstatus_get_bw_weight(ns, "Wem", -1);
+ Wee = networkstatus_get_bw_weight(ns, "Wee", -1);
+ Wed = networkstatus_get_bw_weight(ns, "Wed", -1);
+
+ if (Wgg<0 || Wgm<0 || Wgd<0 || Wmg<0 || Wmm<0 || Wme<0 || Wmd<0 || Weg<0
+ || Wem<0 || Wee<0 || Wed<0) {
+ log_warn(LD_BUG, "No bandwidth weights produced in consensus!");
+ return 0;
+ }
+
+ // First, sanity check basic summing properties that hold for all cases
+ // We use > 1 as the check for these because they are computed as integers.
+ // Sometimes there are rounding errors.
+ if (fabs(Wmm - weight_scale) > 1) {
+ log_warn(LD_BUG, "Wmm=%lf != "I64_FORMAT,
+ Wmm, I64_PRINTF_ARG(weight_scale));
+ valid = 0;
+ }
+
+ if (fabs(Wem - Wee) > 1) {
+ log_warn(LD_BUG, "Wem=%lf != Wee=%lf", Wem, Wee);
+ valid = 0;
+ }
+
+ if (fabs(Wgm - Wgg) > 1) {
+ log_warn(LD_BUG, "Wgm=%lf != Wgg=%lf", Wgm, Wgg);
+ valid = 0;
+ }
+
+ if (fabs(Weg - Wed) > 1) {
+ log_warn(LD_BUG, "Wed=%lf != Weg=%lf", Wed, Weg);
+ valid = 0;
+ }
+
+ if (fabs(Wgg + Wmg - weight_scale) > 0.001*weight_scale) {
+ log_warn(LD_BUG, "Wgg=%lf != "I64_FORMAT" - Wmg=%lf", Wgg,
+ I64_PRINTF_ARG(weight_scale), Wmg);
+ valid = 0;
+ }
+
+ if (fabs(Wee + Wme - weight_scale) > 0.001*weight_scale) {
+ log_warn(LD_BUG, "Wee=%lf != "I64_FORMAT" - Wme=%lf", Wee,
+ I64_PRINTF_ARG(weight_scale), Wme);
+ valid = 0;
+ }
+
+ if (fabs(Wgd + Wmd + Wed - weight_scale) > 0.001*weight_scale) {
+ log_warn(LD_BUG, "Wgd=%lf + Wmd=%lf + Wed=%lf != "I64_FORMAT,
+ Wgd, Wmd, Wed, I64_PRINTF_ARG(weight_scale));
+ valid = 0;
+ }
+
+ Wgg /= weight_scale;
+ Wgm /= weight_scale;
+ Wgd /= weight_scale;
+
+ Wmg /= weight_scale;
+ Wmm /= weight_scale;
+ Wme /= weight_scale;
+ Wmd /= weight_scale;
+
+ Weg /= weight_scale;
+ Wem /= weight_scale;
+ Wee /= weight_scale;
+ Wed /= weight_scale;
+
+ // Then, gather G, M, E, D, T to determine case
+ SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, routerstatus_t *, rs) {
+ if (rs->has_bandwidth) {
+ T += rs->bandwidth;
+ if (rs->is_exit && rs->is_possible_guard) {
+ D += rs->bandwidth;
+ Gtotal += Wgd*rs->bandwidth;
+ Mtotal += Wmd*rs->bandwidth;
+ Etotal += Wed*rs->bandwidth;
+ } else if (rs->is_exit) {
+ E += rs->bandwidth;
+ Mtotal += Wme*rs->bandwidth;
+ Etotal += Wee*rs->bandwidth;
+ } else if (rs->is_possible_guard) {
+ G += rs->bandwidth;
+ Gtotal += Wgg*rs->bandwidth;
+ Mtotal += Wmg*rs->bandwidth;
+ } else {
+ M += rs->bandwidth;
+ Mtotal += Wmm*rs->bandwidth;
+ }
+ } else {
+ log_warn(LD_BUG, "Missing consensus bandwidth for router %s",
+ rs->nickname);
+ }
+ } SMARTLIST_FOREACH_END(rs);
+
+ // Finally, check equality conditions depending upon case 1, 2 or 3
+ // Full equality cases: 1, 3b
+ // Partial equality cases: 2b (E=G), 3a (M=E)
+ // Fully unknown: 2a
+ if (3*E >= T && 3*G >= T) {
+ // Case 1: Neither are scarce
+ casename = "Case 1";
+ if (fabs(Etotal-Mtotal) > 0.01*MAX(Etotal,Mtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Etotal %lf != Mtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Etotal, Mtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Etotal %lf != Gtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Etotal, Gtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ if (fabs(Gtotal-Mtotal) > 0.01*MAX(Gtotal,Mtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Mtotal %lf != Gtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Mtotal, Gtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ } else if (3*E < T && 3*G < T) {
+ int64_t R = MIN(E, G);
+ int64_t S = MAX(E, G);
+ /*
+ * Case 2: Both Guards and Exits are scarce
+ * Balance D between E and G, depending upon
+ * D capacity and scarcity. Devote no extra
+ * bandwidth to middle nodes.
+ */
+ if (R+D < S) { // Subcase a
+ double Rtotal, Stotal;
+ if (E < G) {
+ Rtotal = Etotal;
+ Stotal = Gtotal;
+ } else {
+ Rtotal = Gtotal;
+ Stotal = Etotal;
+ }
+ casename = "Case 2a";
+ // Rtotal < Stotal
+ if (Rtotal > Stotal) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Rtotal %lf > Stotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Rtotal, Stotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ // Rtotal < T/3
+ if (3*Rtotal > T) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: 3*Rtotal %lf > T "
+ I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
+ " D="I64_FORMAT" T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Rtotal*3, I64_PRINTF_ARG(T),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ // Stotal < T/3
+ if (3*Stotal > T) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: 3*Stotal %lf > T "
+ I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
+ " D="I64_FORMAT" T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Stotal*3, I64_PRINTF_ARG(T),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ // Mtotal > T/3
+ if (3*Mtotal < T) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: 3*Mtotal %lf < T "
+ I64_FORMAT". "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Mtotal*3, I64_PRINTF_ARG(T),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ } else { // Subcase b: R+D > S
+ casename = "Case 2b";
+
+ /* Check the rare-M redirect case. */
+ if (D != 0 && 3*M < T) {
+ casename = "Case 2b (balanced)";
+ if (fabs(Etotal-Mtotal) > 0.01*MAX(Etotal,Mtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Etotal %lf != Mtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Etotal, Mtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Etotal %lf != Gtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Etotal, Gtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ if (fabs(Gtotal-Mtotal) > 0.01*MAX(Gtotal,Mtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Mtotal %lf != Gtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Mtotal, Gtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ } else {
+ if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Etotal %lf != Gtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Etotal, Gtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ }
+ }
+ } else { // if (E < T/3 || G < T/3) {
+ int64_t S = MIN(E, G);
+ int64_t NS = MAX(E, G);
+ if (3*(S+D) < T) { // Subcase a:
+ double Stotal;
+ double NStotal;
+ if (G < E) {
+ casename = "Case 3a (G scarce)";
+ Stotal = Gtotal;
+ NStotal = Etotal;
+ } else { // if (G >= E) {
+ casename = "Case 3a (E scarce)";
+ NStotal = Gtotal;
+ Stotal = Etotal;
+ }
+ // Stotal < T/3
+ if (3*Stotal > T) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: 3*Stotal %lf > T "
+ I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
+ " D="I64_FORMAT" T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Stotal*3, I64_PRINTF_ARG(T),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ if (NS >= M) {
+ if (fabs(NStotal-Mtotal) > 0.01*MAX(NStotal,Mtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: NStotal %lf != Mtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, NStotal, Mtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ } else {
+ // if NS < M, NStotal > T/3 because only one of G or E is scarce
+ if (3*NStotal < T) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: 3*NStotal %lf < T "
+ I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT
+ " E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, NStotal*3, I64_PRINTF_ARG(T),
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ }
+ } else { // Subcase b: S+D >= T/3
+ casename = "Case 3b";
+ if (fabs(Etotal-Mtotal) > 0.01*MAX(Etotal,Mtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Etotal %lf != Mtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Etotal, Mtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Etotal %lf != Gtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Etotal, Gtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ if (fabs(Gtotal-Mtotal) > 0.01*MAX(Gtotal,Mtotal)) {
+ log_warn(LD_DIR,
+ "Bw Weight Failure for %s: Mtotal %lf != Gtotal %lf. "
+ "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
+ " T="I64_FORMAT". "
+ "Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
+ casename, Mtotal, Gtotal,
+ I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
+ I64_PRINTF_ARG(D), I64_PRINTF_ARG(T),
+ Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
+ valid = 0;
+ }
+ }
+ }
+
+ if (valid)
+ log_notice(LD_DIR, "Bandwidth-weight %s is verified and valid.",
+ casename);
+
+ return valid;
+}
+
/** Parse a v3 networkstatus vote, opinion, or consensus (depending on
* ns_type), from <b>s</b>, and return the result. Return NULL on failure. */
networkstatus_t *
@@ -2675,6 +3078,46 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
goto err;
}
+ {
+ int found_sig = 0;
+ SMARTLIST_FOREACH_BEGIN(footer_tokens, directory_token_t *, _tok) {
+ tok = _tok;
+ if (tok->tp == K_DIRECTORY_SIGNATURE)
+ found_sig = 1;
+ else if (found_sig) {
+ log_warn(LD_DIR, "Extraneous token after first directory-signature");
+ goto err;
+ }
+ } SMARTLIST_FOREACH_END(_tok);
+ }
+
+ if ((tok = find_opt_by_keyword(footer_tokens, K_DIRECTORY_FOOTER))) {
+ if (tok != smartlist_get(footer_tokens, 0)) {
+ log_warn(LD_DIR, "Misplaced directory-footer token");
+ goto err;
+ }
+ }
+
+ tok = find_opt_by_keyword(footer_tokens, K_BW_WEIGHTS);
+ if (tok) {
+ ns->weight_params = smartlist_create();
+ for (i = 0; i < tok->n_args; ++i) {
+ int ok=0;
+ char *eq = strchr(tok->args[i], '=');
+ if (!eq) {
+ log_warn(LD_DIR, "Bad element '%s' in weight params",
+ escaped(tok->args[i]));
+ goto err;
+ }
+ tor_parse_long(eq+1, 10, INT32_MIN, INT32_MAX, &ok, NULL);
+ if (!ok) {
+ log_warn(LD_DIR, "Bad element '%s' in params", escaped(tok->args[i]));
+ goto err;
+ }
+ smartlist_add(ns->weight_params, tor_strdup(tok->args[i]));
+ }
+ }
+
SMARTLIST_FOREACH_BEGIN(footer_tokens, directory_token_t *, _tok) {
char declared_identity[DIGEST_LEN];
networkstatus_voter_info_t *v;
@@ -3632,13 +4075,13 @@ find_all_exitpolicy(smartlist_t *s)
}
static int
-router_get_hash_impl_helper(const char *s,
+router_get_hash_impl_helper(const char *s, size_t s_len,
const char *start_str,
const char *end_str, char end_c,
const char **start_out, const char **end_out)
{
- char *start, *end;
- start = strstr(s, start_str);
+ const char *start, *end;
+ start = tor_memstr(s, s_len, start_str);
if (!start) {
log_warn(LD_DIR,"couldn't find start of hashed material \"%s\"",start_str);
return -1;
@@ -3649,12 +4092,13 @@ router_get_hash_impl_helper(const char *s,
start_str);
return -1;
}
- end = strstr(start+strlen(start_str), end_str);
+ end = tor_memstr(start+strlen(start_str),
+ s_len - (start-s) - strlen(start_str), end_str);
if (!end) {
log_warn(LD_DIR,"couldn't find end of hashed material \"%s\"",end_str);
return -1;
}
- end = strchr(end+strlen(end_str), end_c);
+ end = memchr(end+strlen(end_str), end_c, s_len - (end-s) - strlen(end_str));
if (!end) {
log_warn(LD_DIR,"couldn't find EOL");
return -1;
@@ -3674,13 +4118,14 @@ router_get_hash_impl_helper(const char *s,
* If no such substring exists, return -1.
*/
static int
-router_get_hash_impl(const char *s, char *digest,
+router_get_hash_impl(const char *s, size_t s_len, char *digest,
const char *start_str,
const char *end_str, char end_c,
digest_algorithm_t alg)
{
const char *start=NULL, *end=NULL;
- if (router_get_hash_impl_helper(s,start_str,end_str,end_c,&start,&end)<0)
+ if (router_get_hash_impl_helper(s,s_len,start_str,end_str,end_c,
+ &start,&end)<0)
return -1;
if (alg == DIGEST_SHA1) {
@@ -3700,12 +4145,13 @@ router_get_hash_impl(const char *s, char *digest,
/** As router_get_hash_impl, but compute all hashes. */
static int
-router_get_hashes_impl(const char *s, digests_t *digests,
+router_get_hashes_impl(const char *s, size_t s_len, digests_t *digests,
const char *start_str,
const char *end_str, char end_c)
{
const char *start=NULL, *end=NULL;
- if (router_get_hash_impl_helper(s,start_str,end_str,end_c,&start,&end)<0)
+ if (router_get_hash_impl_helper(s,s_len,start_str,end_str,end_c,
+ &start,&end)<0)
return -1;
if (crypto_digest_all(digests, start, end-start)) {
@@ -4123,7 +4569,7 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
goto err;
}
/* Compute descriptor hash for later validation. */
- if (router_get_hash_impl(desc, desc_hash,
+ if (router_get_hash_impl(desc, strlen(desc), desc_hash,
"rendezvous-service-descriptor ",
"\nsignature", '\n', DIGEST_SHA1) < 0) {
log_warn(LD_REND, "Couldn't compute descriptor hash.");
diff --git a/src/or/tor_main.c b/src/or/tor_main.c
index 4a6be7cddd..117369c565 100644
--- a/src/or/tor_main.c
+++ b/src/or/tor_main.c
@@ -1,6 +1,6 @@
/* Copyright 2001-2004 Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/** String describing which Tor subversion repository version the source was
diff --git a/src/test/test.c b/src/test/test.c
index 760558b65a..8d596981ef 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/* Ordinarily defined in tor_main.c; this bit is just here to provide one
@@ -607,7 +607,6 @@ test_circuit_timeout(void)
if (circuit_build_times_add_timeout(&final, 1, approx_time()-1))
final.have_computed_timeout = 1;
-
}
done:
diff --git a/src/test/test.h b/src/test/test.h
index ed0eb316ad..550c57a812 100644
--- a/src/test/test.h
+++ b/src/test/test.h
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2003, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#ifndef _TOR_TEST_H
diff --git a/src/test/test_addr.c b/src/test/test_addr.c
index 327fc651f6..bafc0a968e 100644
--- a/src/test/test_addr.c
+++ b/src/test/test_addr.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
diff --git a/src/test/test_containers.c b/src/test/test_containers.c
index efc879b8c2..1fc248cb46 100644
--- a/src/test/test_containers.c
+++ b/src/test/test_containers.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index 656c3c94fc..7aca098bc7 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
diff --git a/src/test/test_data.c b/src/test/test_data.c
index bd7d989856..f926ee17dd 100644
--- a/src/test/test_data.c
+++ b/src/test/test_data.c
@@ -1,6 +1,6 @@
/* Copyright 2001-2004 Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/** First of 3 example authority certificates for unit testing. */
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index b7ee403299..a746beda2c 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
diff --git a/src/test/test_util.c b/src/test/test_util.c
index 0e40ae44ab..ad5a27e517 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
+ * Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
diff --git a/src/tools/tor-gencert.c b/src/tools/tor-gencert.c
index 04d53be072..9eb9c798e0 100644
--- a/src/tools/tor-gencert.c
+++ b/src/tools/tor-gencert.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2009 The Tor Project, Inc. */
+/* Copyright (c) 2007-2010 The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
diff --git a/src/tools/tor-resolve.c b/src/tools/tor-resolve.c
index fe7f793dbb..dbab3da9c6 100644
--- a/src/tools/tor-resolve.c
+++ b/src/tools/tor-resolve.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
- * Copyright (c) 2007-2009, The Tor Project, Inc.
+ * Copyright (c) 2007-2010, The Tor Project, Inc.
*/
/* See LICENSE for licensing information */
diff --git a/src/win32/orconfig.h b/src/win32/orconfig.h
index 0075a5efe4..ce6d854b47 100644
--- a/src/win32/orconfig.h
+++ b/src/win32/orconfig.h
@@ -226,5 +226,5 @@
#define USING_TWOS_COMPLEMENT
/* Version number of package */
-#define VERSION "0.2.2.9-alpha-dev"
+#define VERSION "0.2.2.10-alpha-dev"