summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--ChangeLog101
-rw-r--r--LICENSE2
-rw-r--r--Makefile.am2
-rw-r--r--changes/build_manpage_from_tarball_without_asciidoc8
-rw-r--r--changes/dont_segfault_while_making_consensus_without_params5
-rw-r--r--configure.in13
-rw-r--r--contrib/bundle.nsi2
-rwxr-xr-xcontrib/checkSpace.pl12
-rw-r--r--contrib/netinst.nsi2
-rw-r--r--contrib/polipo/README2
-rw-r--r--contrib/tor-exit-notice.html1
-rw-r--r--contrib/tor-mingw.nsi.in2
-rw-r--r--debian/src-test-test.h2
-rw-r--r--doc/Makefile.am10
-rwxr-xr-xdoc/asciidoc-helper.sh51
-rw-r--r--doc/spec/control-spec.txt6
-rw-r--r--doc/spec/dir-spec.txt210
-rw-r--r--doc/spec/path-spec.txt52
-rw-r--r--doc/spec/proposals/000-index.txt2
-rw-r--r--doc/spec/proposals/170-user-path-config.txt95
-rw-r--r--doc/tor.1.txt3
-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
97 files changed, 1920 insertions, 251 deletions
diff --git a/.gitignore b/.gitignore
index fc86adc8e3..b5d4442ca6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -142,6 +142,7 @@
/src/or/or_sha1.i
/src/or/micro-revision.*
/src/or/tor
+/src/or/tor.exe
/src/or/libtor.a
# /src/test
@@ -154,6 +155,9 @@
/src/tools/tor-checkkey
/src/tools/tor-resolve
/src/tools/tor-gencert
+/src/tools/tor-checkkey.exe
+/src/tools/tor-resolve.exe
+/src/tools/tor-gencert.exe
/src/tools/Makefile
/src/tools/Makefile.in
diff --git a/ChangeLog b/ChangeLog
index f09671f171..7d742574d4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,18 +1,80 @@
-Changes in version 0.2.2.10-alpha - 2010-??-??
+Changes in version 0.2.2.11-alpha - 2010-03-??
+ o Minor features:
+ - Experiment with a more aggressive approach to preventing clients
+ from making one-hop exit streams. Exit relays who want to try it
+ out can set "RefuseUnknownExits 1" in their torrc, and then look
+ for "Attempt by %s to open a stream" log messages. Let us know
+ how it goes!
+
o Minor bugfixes:
+ - When we cleaned up the contrib/tor-exit-notice.html file, we left
+ out some key text. Fixes bug 1295.
+
+
+Changes in version 0.2.2.10-alpha - 2010-03-07
+ Tor 0.2.2.10-alpha fixes a regression introduced in 0.2.2.9-alpha that
+ could prevent relays from guessing their IP address correctly. It also
+ starts the groundwork for another client-side performance boost, since
+ currently we're not making efficient use of relays that have both the
+ Guard flag and the Exit flag.
+
+ o Major bugfixes:
+ - Fix a regression from our patch for bug 1244 that caused relays
+ to guess their IP address incorrectly if they didn't set Address
+ in their torrc and/or their address fails to resolve. Bugfix on
+ 0.2.2.9-alpha; fixes bug 1269.
+
+ o Major features (performance):
+ - Directory authorities now compute consensus weightings that instruct
+ clients how to weight relays flagged as Guard, Exit, Guard+Exit,
+ and no flag. Clients that use these weightings will distribute
+ network load more evenly across these different relay types. The
+ weightings are in the consensus so we can change them globally in
+ the future. Extra thanks to "outofwords" for finding some nasty
+ security bugs in the first implementation of this feature.
+
+ o Minor features (performance):
+ - Always perform router selections using weighted relay bandwidth,
+ even if we don't need a high capacity circuit at the time. Non-fast
+ circuits now only differ from fast ones in that they can use relays
+ not marked with the Fast flag. This "feature" could turn out to
+ be a horrible bug; we should investigate more before it goes into
+ a stable release.
+
+ o Minor features:
+ - Allow disabling building of the manpages. Skipping the manpage
+ speeds up the build considerably.
+
+ o Minor bugfixes (on 0.2.2.x):
- Fix a memleak in the EXTENDCIRCUIT logic. Spotted by coverity.
Bugfix on 0.2.2.9-alpha.
- - Fix a dereference-then-NULL-check sequence when publishing
- descriptors. Bugfix on tor-0.2.1.5-alpha. Discovered by ekir,
- fixes bug 1255.
- Disallow values larger than INT32_MAX for PerConnBWRate|Burst
config option. Bugfix on 0.2.2.7-alpha.
+ - Ship the asciidoc-helper file in the tarball, so that people can
+ build from source if they want to, and touching the .1.txt files
+ doesn't break the build. Bugfix on 0.2.2.9-alpha.
+
+ o Minor bugfixes (on 0.2.1.x or earlier):
+ - Fix a dereference-then-NULL-check sequence when publishing
+ descriptors. Bugfix on 0.2.1.5-alpha. Discovered by ekir; fixes
+ bug 1255.
+ - Fix another dereference-then-NULL-check sequence. Bugfix on
+ 0.2.1.14-rc. Discovered by ekir; fixes bug 1256.
+ - Make sure we treat potentially not NUL-terminated strings correctly.
+ Bugfix on 0.1.1.13-alpha. Discovered by rieo; fixes bug 1257.
o Code simplifications and refactoring:
- Fix some urls in the exit notice file and make it XHTML1.1 strict
compliant. Based on a patch from Christian Kujau.
+ - Don't use sed in asciidoc-helper anymore.
+ - Make the build process fail if asciidoc cannot be found and
+ building with asciidoc isn't disabled.
+
Changes in version 0.2.2.9-alpha - 2010-02-22
+ Tor 0.2.2.9-alpha makes Tor work again on the latest OS X, updates the
+ location of a directory authority, and cleans up a bunch of small bugs.
+
o Directory authority changes:
- Change IP address for dannenberg (v3 directory authority), and
remove moria2 (obsolete v1, v2 directory authority and v0 hidden
@@ -33,9 +95,9 @@ Changes in version 0.2.2.9-alpha - 2010-02-22
that didn't allow exiting to any ports. This bug could screw
with load balancing and stats. Bugfix on 0.1.1.6-alpha; fixes bug
1238. Bug discovered by Martin Kowalczyk.
- - When freeing a cipher, zero it out completely. We only zeroed
- the first ptrsize bytes. Bugfix on tor-0.0.2pre8. Discovered
- and patched by ekir. Fixes bug 1254.
+ - When freeing a session key, zero it out completely. We only zeroed
+ the first ptrsize bytes. Bugfix on 0.0.2pre8. Discovered and
+ patched by ekir. Fixes bug 1254.
o Minor bugfixes:
- Fix static compilation by listing the openssl libraries in the right
@@ -93,6 +155,27 @@ Changes in version 0.2.2.9-alpha - 2010-02-22
open() without checking it.
+Changes in version 0.2.1.25 - 2010-03-??
+ o Major bugfixes:
+ - Fix a regression from our patch for bug 1244 that caused relays
+ to guess their IP address incorrectly if they didn't set Address
+ in their torrc and/or their address fails to resolve. Bugfix on
+ 0.2.1.23; fixes bug 1269.
+ - When freeing a session key, zero it out completely. We only zeroed
+ the first ptrsize bytes. Bugfix on 0.0.2pre8. Discovered and
+ patched by ekir. Fixes bug 1254.
+
+ o Minor bugfixes:
+ - Fix a dereference-then-NULL-check sequence when publishing
+ descriptors. Bugfix on 0.2.1.5-alpha. Discovered by ekir; fixes
+ bug 1255.
+ - Fix another dereference-then-NULL-check sequence. Bugfix on
+ 0.2.1.14-rc. Discovered by ekir; fixes bug 1256.
+ - Make sure we treat potentially not NUL-terminated strings correctly.
+ Bugfix on 0.1.1.13-alpha. Discovered by rieo; fixes bug 1257.
+
+
+
Changes in version 0.2.1.24 - 2010-02-21
Tor 0.2.1.24 makes Tor work again on the latest OS X -- this time
for sure!
@@ -147,6 +230,10 @@ Changes in version 0.2.1.23 - 2010-02-13
Changes in version 0.2.2.8-alpha - 2010-01-26
+ Tor 0.2.2.8-alpha fixes a crash bug in 0.2.2.7-alpha that has been
+ causing bridge relays to disappear. If you're running a bridge,
+ please upgrade.
+
o Major bugfixes:
- Fix a memory corruption bug on bridges that occured during the
inclusion of stats data in extra-info descriptors. Also fix the
diff --git a/LICENSE b/LICENSE
index bb1ebd4e48..c70312b7ee 100644
--- a/LICENSE
+++ b/LICENSE
@@ -14,7 +14,7 @@ Tor is distributed under this license:
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.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
diff --git a/Makefile.am b/Makefile.am
index b7dc6c8a5e..af3746e77a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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
AUTOMAKE_OPTIONS = foreign
diff --git a/changes/build_manpage_from_tarball_without_asciidoc b/changes/build_manpage_from_tarball_without_asciidoc
new file mode 100644
index 0000000000..7e7bb56eb5
--- /dev/null
+++ b/changes/build_manpage_from_tarball_without_asciidoc
@@ -0,0 +1,8 @@
+ o Minor bugfixes:
+ - When building the manpage from a tarball, we required asciidoc, even
+ though the asciidoc -> roff/html conversion was already done while
+ building the tarball. We now make it so that make complains when
+ we need asciidoc (either because someone is compiling directly from git,
+ or because they altered the asciidoc manpage in their tarball). Bugfix
+ on 0.2.2.9-alpha.
+
diff --git a/changes/dont_segfault_while_making_consensus_without_params b/changes/dont_segfault_while_making_consensus_without_params
new file mode 100644
index 0000000000..e0bcd4086d
--- /dev/null
+++ b/changes/dont_segfault_while_making_consensus_without_params
@@ -0,0 +1,5 @@
+ o Minor bugfixes:
+ - When none of the authorities vote on any params, Tor segfaults when
+ trying to make the consensus from the votes. This is currently
+ not critical, because authorities do include params in their votes.
+ Bugfix on 0.2.2.10-alpha, fixes bug 1322.
diff --git a/configure.in b/configure.in
index e948503113..d2868a28b5 100644
--- a/configure.in
+++ b/configure.in
@@ -4,7 +4,7 @@ dnl Copyright (c) 2007-2008, The Tor Project, Inc.
dnl See LICENSE for licensing information
AC_INIT
-AM_INIT_AUTOMAKE(tor, 0.2.2.9-alpha-dev)
+AM_INIT_AUTOMAKE(tor, 0.2.2.10-alpha-dev)
AM_CONFIG_HEADER(orconfig.h)
AC_CANONICAL_HOST
@@ -49,6 +49,15 @@ AC_ARG_ENABLE(transparent,
*) AC_MSG_ERROR(bad value for --enable-transparent) ;;
esac], [transparent=true])
+AC_ARG_ENABLE(asciidoc,
+ AS_HELP_STRING(--disable-asciidoc, don't use asciidoc (disables building of manpages)),
+ [case "${enableval}" in
+ yes) asciidoc=true ;;
+ no) asciidoc=false ;;
+ *) AC_MSG_ERROR(bad value for --disable-asciidoc) ;;
+ esac], [asciidoc=true])
+
+
AC_ARG_ENABLE(threads,
AS_HELP_STRING(--disable-threads, disable multi-threading support))
@@ -98,6 +107,8 @@ dnl check for asciidoc and a2x
AC_PATH_PROG([ASCIIDOC], [asciidoc], none)
AC_PATH_PROG([A2X], [a2x], none)
+AM_CONDITIONAL(USE_ASCIIDOC, test x$asciidoc = xtrue)
+
AC_PATH_PROG([SHA1SUM], [sha1sum], none)
AC_PATH_PROG([OPENSSL], [openssl], none)
diff --git a/contrib/bundle.nsi b/contrib/bundle.nsi
index 0f1d82f3e6..ffc64df3c8 100644
--- a/contrib/bundle.nsi
+++ b/contrib/bundle.nsi
@@ -22,7 +22,7 @@ VIProductVersion "${VERSION}"
VIAddVersionKey "ProductName" "Tor"
VIAddVersionKey "Comments" "${WEBSITE}"
VIAddVersionKey "LegalTrademarks" "Three line BSD"
-VIAddVersionKey "LegalCopyright" "©2004-2009, Roger Dingledine, Nick Mathewson, The Tor Project, Inc."
+VIAddVersionKey "LegalCopyright" "©2004-2010, Roger Dingledine, Nick Mathewson, The Tor Project, Inc."
VIAddVersionKey "FileDescription" "Tor is an implementation of Onion Routing. You can read more at ${WEBSITE}"
VIAddVersionKey "FileVersion" "${VERSION}"
diff --git a/contrib/checkSpace.pl b/contrib/checkSpace.pl
index db061a0828..b694abff64 100755
--- a/contrib/checkSpace.pl
+++ b/contrib/checkSpace.pl
@@ -28,11 +28,15 @@ for $fn (@ARGV) {
if ($C && /\s(?:if|while|for|switch)\(/) {
print " KW(:$fn:$.\n";
}
- ## Warn about #else #if instead of #elif.
- if (($lastline =~ /^\# *else/) and ($_ =~ /^\# *if/)) {
+ ## Warn about #else #if instead of #elif.
+ if (($lastline =~ /^\# *else/) and ($_ =~ /^\# *if/)) {
print " #else#if:$fn:$.\n";
- }
- $lastline = $_;
+ }
+ $lastline = $_;
+ ## Warn about unnecessary empty lines.
+ if ($lastnil && /^\s*}\n/) {
+ print " UnnecNL:$fn:$.\n";
+ }
## Warn about multiple empty lines.
if ($lastnil && /^$/) {
print " DoubleNL:$fn:$.\n";
diff --git a/contrib/netinst.nsi b/contrib/netinst.nsi
index ef93aa0700..622310e9a3 100644
--- a/contrib/netinst.nsi
+++ b/contrib/netinst.nsi
@@ -22,7 +22,7 @@ VIProductVersion "${VERSION}"
VIAddVersionKey "ProductName" "Tor"
VIAddVersionKey "Comments" "${WEBSITE}"
VIAddVersionKey "LegalTrademarks" "Three line BSD"
-VIAddVersionKey "LegalCopyright" "©2004-2009, Roger Dingledine, Nick Mathewson, The Tor Project, Inc."
+VIAddVersionKey "LegalCopyright" "©2004-2010, Roger Dingledine, Nick Mathewson, The Tor Project, Inc."
VIAddVersionKey "FileDescription" "Tor is an implementation of Onion Routing. You can read more at ${WEBSITE}"
VIAddVersionKey "FileVersion" "${VERSION}"
diff --git a/contrib/polipo/README b/contrib/polipo/README
index 8bc23a09d9..6670d579ec 100644
--- a/contrib/polipo/README
+++ b/contrib/polipo/README
@@ -1,5 +1,5 @@
Copyright 2007-2008 Andrew Lewman
-Copyright 2009 The Tor Project
+Copyright 2009-2010 The Tor Project
----------------
General Comments
diff --git a/contrib/tor-exit-notice.html b/contrib/tor-exit-notice.html
index 78a148ccc6..8b37edc3fe 100644
--- a/contrib/tor-exit-notice.html
+++ b/contrib/tor-exit-notice.html
@@ -29,6 +29,7 @@ They are marked with FIXME.
Tor Exit Router</p>
<p>
+Most likely you are accessing this website because you had some issue with
the traffic coming from this IP. This router is part of the <a
href="https://www.torproject.org/">Tor Anonymity Network</a>, which is
dedicated to <a href="https://www.torproject.org/overview.html">providing
diff --git a/contrib/tor-mingw.nsi.in b/contrib/tor-mingw.nsi.in
index de382a78a6..523ca760da 100644
--- a/contrib/tor-mingw.nsi.in
+++ b/contrib/tor-mingw.nsi.in
@@ -9,7 +9,7 @@
!include "FileFunc.nsh"
!insertmacro GetParameters
-!define VERSION "0.2.2.9-alpha-dev"
+!define VERSION "0.2.2.10-alpha-dev"
!define INSTALLER "tor-${VERSION}-win32.exe"
!define WEBSITE "https://www.torproject.org/"
!define LICENSE "LICENSE"
diff --git a/debian/src-test-test.h b/debian/src-test-test.h
index ed0eb316ad..550c57a812 100644
--- a/debian/src-test-test.h
+++ b/debian/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/doc/Makefile.am b/doc/Makefile.am
index 492dd3bd51..e7edb0476b 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -13,13 +13,17 @@
# part of the source distribution, so that people without asciidoc can
# just use the .1 and .html files.
+if USE_ASCIIDOC
asciidoc_files = tor tor-gencert tor-resolve torify
+else
+asciidoc_files =
+endif
html_in = $(asciidoc_files:=.html.in)
man_in = $(asciidoc_files:=.1.in)
-EXTRA_DIST = HACKING \
+EXTRA_DIST = HACKING asciidoc-helper.sh \
$(html_in) $(man_in) $(asciidoc_files:=.1.txt) \
tor-osx-dmg-creation.txt tor-rpm-creation.txt \
tor-win32-mingw-creation.txt
@@ -39,7 +43,7 @@ DIST_SUBDIRS = spec
# Generate the html documentation from asciidoc, but don't do
# machine-specific replacements yet
$(html_in) :
- $(top_srcdir)/doc/asciidoc-helper.sh html @ASCIIDOC@ @SED@ $(top_srcdir)/doc/$@
+ $(top_srcdir)/doc/asciidoc-helper.sh html @ASCIIDOC@ $(top_srcdir)/doc/$@
tor.html.in : tor.1.txt
torify.html.in : torify.1.txt
@@ -49,7 +53,7 @@ tor-resolve.html.in : tor-resolve.1.txt
# Generate the manpage from asciidoc, but don't do
# machine-specific replacements yet
$(man_in) :
- $(top_srcdir)/doc/asciidoc-helper.sh man @A2X@ @SED@ $(top_srcdir)/doc/$@
+ $(top_srcdir)/doc/asciidoc-helper.sh man @A2X@ $(top_srcdir)/doc/$@
tor.1.in : tor.1.txt
torify.1.in : torify.1.txt
diff --git a/doc/asciidoc-helper.sh b/doc/asciidoc-helper.sh
index 90a003d496..8e9e5eda3d 100755
--- a/doc/asciidoc-helper.sh
+++ b/doc/asciidoc-helper.sh
@@ -4,51 +4,56 @@
# See LICENSE for licensing information
# Run this to generate .html.in or .1.in files from asciidoc files.
# Arguments:
-# html|man asciidocpath sedpath outputfile
+# html|man asciidocpath outputfile
set -e
-if [ $# != 4 ]; then
+if [ $# != 3 ]; then
exit 1;
fi
-output=$4
-input=`echo $output | $3 -e 's/html\.in$/1\.txt/g' -e 's/1\.in$/1\.txt/g'`
-base=`echo $output | $3 -e 's/\.html\.in$//g' -e 's/\.1\.in$//g'`
+output=$3
if [ "$1" = "html" ]; then
+ input=${output%%.html.in}.1.txt
+ base=${output%%.html.in}
if [ "$2" != none ]; then
"$2" -d manpage -o $output $input;
else
echo "==================================";
echo;
- echo "The manpage in html form for $base will ";
- echo "NOT be available, because asciidoc doesn't appear to be ";
- echo "installed!";
+ echo "You need asciidoc installed to be able to build the manpage.";
+ echo "To build without manpages, use the --disable-asciidoc argument";
+ echo "when calling configure.";
echo;
echo "==================================";
+ exit 1;
fi
elif [ "$1" = "man" ]; then
- if test "$2" != none; then
- if $2 -f manpage $input; then
- mv $base.1 $output;
- else
- echo "==================================";
- echo;
- echo "a2x is installed, but some required docbook support files are";
- echo "missing. Please install docbook-xsl and docbook-xml (Debian)";
- echo "or similar.";
- echo;
- echo "==================================";
- fi;
+ input=${output%%.1.in}.1.txt
+ base=${output%%.1.in}
+
+ if test "$2" = none; then
+ echo "==================================";
+ echo;
+ echo "You need asciidoc installed to be able to build the manpage.";
+ echo "To build without manpages, use the --disable-asciidoc argument";
+ echo "when calling configure.";
+ echo;
+ echo "==================================";
+ exit 1;
+ fi
+ if "$2" -f manpage $input; then
+ mv $base.1 $output;
else
echo "==================================";
echo;
- echo "The manpage for $base will NOT be ";
- echo "available, because a2x doesn't appear to be installed!";
+ echo "a2x is installed, but some required docbook support files are";
+ echo "missing. Please install docbook-xsl and docbook-xml (Debian)";
+ echo "or similar.";
echo;
echo "==================================";
+ exit 1;
fi
fi
-touch $output; \
diff --git a/doc/spec/control-spec.txt b/doc/spec/control-spec.txt
index 7d3312a5a8..b60baba052 100644
--- a/doc/spec/control-spec.txt
+++ b/doc/spec/control-spec.txt
@@ -87,6 +87,10 @@
2.4. General-use tokens
+ ; CRLF means, "the ASCII Carriage Return character (decimal value value 13)
+ ; followed by the ASCII Linefeed character (decimal value 10)."
+ CRLF = CR LF
+
; Identifiers for servers.
ServerID = Nickname / Fingerprint
@@ -588,7 +592,7 @@
List of currently recommended versions.
"status/version/current"
Status of the current version. One of: new, old, unrecommended,
- recommended, new in series, obsolete.
+ recommended, new in series, obsolete, unknown.
"status/clients-seen"
A summary of which countries we've seen clients from recently,
formatted the same as the CLIENTS_SEEN status event described in
diff --git a/doc/spec/dir-spec.txt b/doc/spec/dir-spec.txt
index 19a32027af..cfe6cd8f92 100644
--- a/doc/spec/dir-spec.txt
+++ b/doc/spec/dir-spec.txt
@@ -10,7 +10,7 @@
Caches and authorities must still support older versions of the
directory protocols, until the versions of Tor that require them are
- finally out of commission. See Section XXXX on backward compatibility.
+ finally out of commission.
This document merges and supersedes the following proposals:
@@ -182,7 +182,8 @@
All directory information is uploaded and downloaded with HTTP.
[Authorities also generate and caches also cache documents produced and
- used by earlier versions of this protocol; see section XXX for notes.]
+ used by earlier versions of this protocol; see dir-spec-v1.txt and
+ dir-spec-v2.txt for notes on those versions.]
1.1. What's different from version 2?
@@ -591,7 +592,7 @@
with unrecognized items; the protocols line should be preceded with
an "opt" until these Tors are obsolete.]
- "allow-single-hop-exits"
+ "allow-single-hop-exits" NL
[At most once.]
@@ -612,7 +613,7 @@
Fingerprint is encoded in hex (using upper-case letters), with
no spaces.
- "published"
+ "published" YYYY-MM-DD HH:MM:SS NL
[Exactly once.]
@@ -1015,7 +1016,7 @@
generate exactly the same consensus given the same set of votes.
The procedure for deciding when to generate vote and consensus status
- documents are described in section XXX below.
+ documents are described in section 1.4 on the voting timeline.
Status documents contain a preamble, an authority section, a list of
router status entries, and one or more footer signature, in that order.
@@ -1304,8 +1305,57 @@
or does not support (if 'reject') for exit to "most
addresses".
- The signature section contains the following item, which appears
- Exactly Once for a vote, and At Least Once for a consensus.
+ The footer section is delineated in all votes and consensuses supporting
+ consensus method 9 and above with the following:
+
+ "directory-footer" NL
+
+ It contains two subsections, a bandwidths-weights line and a
+ directory-signature.
+
+ The bandwidths-weights line appears At Most Once for a consensus. It does
+ not appear in votes.
+
+ "bandwidth-weights" SP
+ "Wbd=" INT SP "Wbe=" INT SP "Wbg=" INT SP "Wbm=" INT SP
+ "Wdb=" INT SP
+ "Web=" INT SP "Wed=" INT SP "Wee=" INT SP "Weg=" INT SP "Wem=" INT SP
+ "Wgb=" INT SP "Wgd=" INT SP "Wgg=" INT SP "Wgm=" INT SP
+ "Wmb=" INT SP "Wmd=" INT SP "Wme=" INT SP "Wmg=" INT SP "Wmm=" INT NL
+
+ These values represent the weights to apply to router bandwidths during
+ path selection. They are sorted in alphabetical order in the list. The
+ integer values are divided by BW_WEIGHT_SCALE=10000 or the consensus
+ param "bwweightscale". They are:
+
+ Wgg - Weight for Guard-flagged nodes in the guard position
+ Wgm - Weight for non-flagged nodes in the guard Position
+ Wgd - Weight for Guard+Exit-flagged nodes in the guard Position
+
+ Wmg - Weight for Guard-flagged nodes in the middle Position
+ Wmm - Weight for non-flagged nodes in the middle Position
+ Wme - Weight for Exit-flagged nodes in the middle Position
+ Wmd - Weight for Guard+Exit flagged nodes in the middle Position
+
+ Weg - Weight for Guard flagged nodes in the exit Position
+ Wem - Weight for non-flagged nodes in the exit Position
+ Wee - Weight for Exit-flagged nodes in the exit Position
+ Wed - Weight for Guard+Exit-flagged nodes in the exit Position
+
+ Wgb - Weight for BEGIN_DIR-supporting Guard-flagged nodes
+ Wmb - Weight for BEGIN_DIR-supporting non-flagged nodes
+ Web - Weight for BEGIN_DIR-supporting Exit-flagged nodes
+ Wdb - Weight for BEGIN_DIR-supporting Guard+Exit-flagged nodes
+
+ Wbg - Weight for Guard+Exit-flagged nodes for BEGIN_DIR requests
+ Wbm - Weight for Guard+Exit-flagged nodes for BEGIN_DIR requests
+ Wbe - Weight for Guard+Exit-flagged nodes for BEGIN_DIR requests
+ Wbd - Weight for Guard+Exit-flagged nodes for BEGIN_DIR requests
+
+ These values are calculated as specified in Section 3.4.3.
+
+ The signature contains the following item, which appears Exactly Once
+ for a vote, and At Least Once for a consensus.
"directory-signature" SP identity SP signing-key-digest NL Signature
@@ -1318,7 +1368,7 @@
the signing authority, and "signing-key-digest" is the hex-encoded
digest of the current authority signing key of the signing authority.
-3.3. Deciding how to vote.
+3.3. Assigning flags in a vote
(This section describes how directory authorities choose which status
flags to apply to routers, as of Tor 0.2.0.0-alpha-dev. Later directory
@@ -1554,6 +1604,9 @@
"4" -- No longer list routers that are not running in the consensus
"5" -- adds support for "w" and "p" lines.
"6" -- Prefers measured bandwidth values rather than advertised
+ "7" -- Provides keyword=integer pairs of consensus parameters
+ "8" -- Provides microdescriptor summaries
+ "9" -- Provides weights for selecting flagged routers in paths
Before generating a consensus, an authority must decide which consensus
method to use. To do this, it looks for the highest version number
@@ -1586,6 +1639,147 @@
use an accept-style summary and list as much of the port list as is
possible within these 1000 bytes. [XXXX be more specific.]
+3.4.3. Computing Bandwidth Weights
+
+ Let weight_scale = 10000
+
+ Let G be the total bandwidth for Guard-flagged nodes.
+ Let M be the total bandwidth for non-flagged nodes.
+ Let E be the total bandwidth for Exit-flagged nodes.
+ Let D be the total bandwidth for Guard+Exit-flagged nodes.
+ Let T = G+M+E+D
+
+ Let Wgd be the weight for choosing a Guard+Exit for the guard position.
+ Let Wmd be the weight for choosing a Guard+Exit for the middle position.
+ Let Wed be the weight for choosing a Guard+Exit for the exit position.
+
+ Let Wme be the weight for choosing an Exit for the middle position.
+ Let Wmg be the weight for choosing a Guard for the middle position.
+
+ Let Wgg be the weight for choosing a Guard for the guard position.
+ Let Wee be the weight for choosing an Exit for the exit position.
+
+ Balanced network conditions then arise from solutions to the following
+ system of equations:
+
+ Wgg*G + Wgd*D == M + Wmd*D + Wme*E + Wmg*G (guard bw = middle bw)
+ Wgg*G + Wgd*D == Wee*E + Wed*D (guard bw = exit bw)
+ Wed*D + Wmd*D + Wgd*D == D (aka: Wed+Wmd+Wdg = 1)
+ Wmg*G + Wgg*G == G (aka: Wgg = 1-Wmg)
+ Wme*E + Wee*E == E (aka: Wee = 1-Wme)
+
+ We are short 2 constraints with the above set. The remaining constraints
+ come from examining different cases of network load.
+
+ Case 1: E >= T/3 && G >= T/3 (Neither Exit nor Guard Scarce)
+
+ In this case, the additional two constraints are: Wme*E == Wmd*D and
+ Wgd == 0, which maximizes Exit-flagged bandwidth in the middle position.
+
+ This leads to the solution:
+
+ 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)
+ Wmg = weight_scale - Wgg
+ Wed = weight_scale - Wmd
+ Wgd = 0
+
+ Case 2: E < T/3 && G < T/3 (Both are scarce)
+
+ Let R denote the more scarce class (Rare) between Guard vs Exit.
+ Let S denote the less scarce class.
+
+ Subcase a: R+D < S
+
+ In this subcase, we simply devote all of D bandwidth to the
+ scarce class.
+
+ Wgg = Wee = weight_scale
+ Wmg = Wme = Wmd = 0;
+ if E < G:
+ Wed = weight_scale
+ Wgd = 0
+ else:
+ Wed = 0
+ Wgd = weight_scale
+
+ Subcase b: R+D >= S
+
+ In this case, if M <= T/3, we have enough bandwidth to try to achieve
+ a balancing condition, and add the constraints Wgg == 1 and
+ Wme*E == Wmd*D:
+
+ 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
+
+ If M >= T/3, the above solution will not be valid (one of the weights
+ will be < 0 or > 1). In this case, we use:
+
+ Wgg = weight_scale
+ Wee = weight_scale
+ Wmg = Wme = Wmd = 0
+ Wgd = (weight_scale*(D+E-G))/(2*D)
+ Wed = weight_scale - Wgd
+
+ Case 3: One of E < T/3 or G < T/3
+
+ Let S be the scarce class (of E or G).
+
+ Subcase a: (S+D) < T/3:
+ if G=S:
+ Wgg = Wgd = weight_scale;
+ Wmd = Wed = Wmg = 0;
+ Wme = (weight_scale*(E-M))/(2*E);
+ Wee = weight_scale-Wme;
+ if E=S:
+ Wee = Wed = weight_scale;
+ Wmd = Wgd = Wmg = 0;
+ Wmg = (weight_scale*(G-M))/(2*G);
+ Wgg = weight_scale-Wmg;
+
+ Subcase b: (S+D) >= T/3
+ if G=S:
+ Add constraints Wmg = 0, Wme*E == Wmd*D to maximize exit bandwidth
+ in the middle position:
+ 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;
+ if E=S:
+ Add constraints Wgd = 0, 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;
+
+ To ensure consensus, all calculations are performed using integer math
+ with a fixed precision determined by the bwweightscale consensus
+ parameter (defaults at 10000).
+
+ For future balancing improvements, Tor clients support 11 additional weights
+ for directory requests and middle weighting. These weights are currently
+ set at weight_scale, with the exception of the following groups of
+ assignments:
+
+ Directory requests use middle weights:
+ Wbd=Wmd, Wbg=Wmg, Wbe=Wme, Wbm=Wmm
+
+ Handle bridges and strange exit policies:
+ Wgm=Wgg, Wem=Wee, Weg=Wed
+
3.5. Detached signatures
Assuming full connectivity, every authority should compute and sign the
diff --git a/doc/spec/path-spec.txt b/doc/spec/path-spec.txt
index 78f3b63bcb..8a85718a08 100644
--- a/doc/spec/path-spec.txt
+++ b/doc/spec/path-spec.txt
@@ -192,23 +192,41 @@ of their choices.
below)
- XXXX Choosing the length
- For circuits that do not need to be "fast", when choosing among
- multiple candidates for a path element, we choose randomly.
-
- For "fast" circuits, we pick a given router as an exit with probability
- proportional to its bandwidth.
-
- For non-exit positions on "fast" circuits, we pick routers as above, but
- we weight the bandwidth of Exit-flagged nodes depending
- on the fraction of bandwidth available from non-Exit nodes. Call the
- total bandwidth for Exit nodes under consideration E,
- and the total bandwidth for all nodes under
- consideration T. If E<T/3, we do not consider Exit-flagged nodes.
- Otherwise, we weight their bandwidth with the factor (E-T/3)/E. This
- ensures that bandwidth is evenly distributed over nodes in 3-hop paths.
-
- Similarly, guard nodes are weighted by the factor (G-T/3)/G, and not
- considered for non-guard positions if this value is less than 0.
+ For "fast" circuits, we only choose nodes with the Fast flag. For
+ non-"fast" circuits, all nodes are eligible.
+
+ For all circuits, we weight node selection according to router bandwidth.
+
+ We also weight the bandwidth of Exit and Guard flagged nodes depending on
+ the fraction of total bandwidth that they make up and depending upon the
+ position they are being selected for.
+
+ These weights are published in the consensus, and are computed as described
+ in Section 3.4.3 of dir-spec.txt. They are:
+
+ Wgg - Weight for Guard-flagged nodes in the guard position
+ Wgm - Weight for non-flagged nodes in the guard Position
+ Wgd - Weight for Guard+Exit-flagged nodes in the guard Position
+
+ Wmg - Weight for Guard-flagged nodes in the middle Position
+ Wmm - Weight for non-flagged nodes in the middle Position
+ Wme - Weight for Exit-flagged nodes in the middle Position
+ Wmd - Weight for Guard+Exit flagged nodes in the middle Position
+
+ Weg - Weight for Guard flagged nodes in the exit Position
+ Wem - Weight for non-flagged nodes in the exit Position
+ Wee - Weight for Exit-flagged nodes in the exit Position
+ Wed - Weight for Guard+Exit-flagged nodes in the exit Position
+
+ Wgb - Weight for BEGIN_DIR-supporting Guard-flagged nodes
+ Wmb - Weight for BEGIN_DIR-supporting non-flagged nodes
+ Web - Weight for BEGIN_DIR-supporting Exit-flagged nodes
+ Wdb - Weight for BEGIN_DIR-supporting Guard+Exit-flagged nodes
+
+ Wbg - Weight for Guard+Exit-flagged nodes for BEGIN_DIR requests
+ Wbm - Weight for Guard+Exit-flagged nodes for BEGIN_DIR requests
+ Wbe - Weight for Guard+Exit-flagged nodes for BEGIN_DIR requests
+ Wbd - Weight for Guard+Exit-flagged nodes for BEGIN_DIR requests
Additionally, we may be building circuits with one or more requests in
mind. Each kind of request puts certain constraints on paths:
diff --git a/doc/spec/proposals/000-index.txt b/doc/spec/proposals/000-index.txt
index 664c5654da..62327a1e61 100644
--- a/doc/spec/proposals/000-index.txt
+++ b/doc/spec/proposals/000-index.txt
@@ -90,6 +90,7 @@ Proposals by number:
167 Vote on network parameters in consensus [CLOSED]
168 Reduce default circuit window [OPEN]
169 Eliminate TLS renegotiation for the Tor connection handshake [DRAFT]
+170 Configuration options regarding circuit building [DRAFT]
Proposals by status:
@@ -101,6 +102,7 @@ Proposals by status:
141 Download server descriptors on demand
144 Increase the diversity of circuits by detecting nodes belonging the same provider
169 Eliminate TLS renegotiation for the Tor connection handshake [for 0.2.2]
+ 170 Configuration options regarding circuit building
NEEDS-REVISION:
131 Help users to verify they are using Tor
OPEN:
diff --git a/doc/spec/proposals/170-user-path-config.txt b/doc/spec/proposals/170-user-path-config.txt
new file mode 100644
index 0000000000..fa74c76f73
--- /dev/null
+++ b/doc/spec/proposals/170-user-path-config.txt
@@ -0,0 +1,95 @@
+Title: Configuration options regarding circuit building
+Filename: 170-user-path-config.txt
+Author: Sebastian Hahn
+Created: 01-March-2010
+Status: Draft
+
+Overview:
+
+ This document outlines how Tor handles the user configuration
+ options to influence the circuit building process.
+
+Motivation:
+
+ Tor's treatment of the configuration *Nodes options was surprising
+ to many users, and quite a few conspiracy theories have crept up. We
+ should update our specification and code to better describe and
+ communicate what is going during circuit building, and how we're
+ honoring configuration. So far, we've been tracking a bugreport
+ about this behaviour (
+ https://bugs.torproject.org/flyspray/index.php?do=details&id=1090 )
+ and Nick replied in a thread on or-talk (
+ http://archives.seul.org/or/talk/Feb-2010/msg00117.html ).
+
+ This proposal tries to document our intention for those configuration
+ options.
+
+Design:
+
+ Five configuration options are available to users to influence Tor's
+ circuit building. EntryNodes and ExitNodes define a list of nodes
+ that are for the Entry/Exit position in all circuits. ExcludeNodes
+ is a list of nodes that are used for no circuit, and
+ ExcludeExitNodes is a list of nodes that aren't used as the last
+ hop. StrictNodes defines Tor's behaviour in case of a conflict, for
+ example when a node that is excluded is the only available
+ introduction point. Setting StrictNodes to 1 breaks Tor's
+ functionality in that case, and it will refuse to build such a
+ circuit.
+
+ Neither Nick's email nor bug 1090 have clear suggestions how we
+ should behave in each case, so I tried to come up with something
+ that made sense to me.
+
+Security implications:
+
+ Deviating from normal circuit building can break one's anonymity, so
+ the documentation of the above option should contain a warning to
+ make users aware of the pitfalls.
+
+Specification:
+
+ It is proposed that the "User configuration" part of path-spec
+ (section 2.2.2) be replaced with this:
+
+ Users can alter the default behavior for path selection with
+ configuration options. In case of conflicts (excluding and requiring
+ the same node) the "StrictNodes" option is used to determine
+ behaviour. If a nodes is both excluded and required via a
+ configuration option, the exclusion takes preference.
+
+ - If "ExitNodes" is provided, then every request requires an exit
+ node on the ExitNodes list. If a request is supported by no nodes
+ on that list, and "StrictNodes" is false, then Tor treats that
+ request as if ExitNodes were not provided.
+
+ - "EntryNodes" behaves analogously.
+
+ - If "ExcludeNodes" is provided, then no circuit uses any of the
+ nodes listed. If a circuit requires an excluded node to be used,
+ and "StrictNodes" is false, then Tor uses the node in that
+ position while not using any other of the excluded nodes.
+
+ - If "ExcludeExitNodes" is provided, then Tor will not use the nodes
+ listed for the exit position in a circuit. If a circuit requires
+ an excluded node to be used in the exit position and "StrictNodes"
+ is false, then Tor builds that circuit as if ExcludeExitNodes were
+ not provided.
+
+ - If a user tries to connect to or resolve a hostname of the form
+ <target>.<servername>.exit and the "AllowDotExit" configuration
+ option is set to 1, the request is rewritten to a request for
+ <target>, and the request is only supported by the exit whose
+ nickname or fingerprint is <servername>. If "AllowDotExit" is set
+ to 0 (default), any request for <anything>.exit is denied.
+
+ - When any of the *Nodes settings are changed, all circuits are
+ expired immediately, to prevent a situation where a previously
+ built circuit is used even though some of its nodes are now
+ excluded.
+
+
+Compatibility:
+
+ The old Strict*Nodes options are deprecated, and the StrictNodes
+ option is new. Tor users may need to update their configuration file.
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index d999344b48..2ae5005d8c 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -320,7 +320,8 @@ Other options can be specified either on the command-line (--option
**OutboundBindAddress** __IP__::
Make all outbound connections originate from the IP address specified. This
is only useful when you have multiple network interfaces, and you want all
- of Tor's outgoing connections to use a single one.
+ of Tor's outgoing connections to use a single one. This setting will be
+ ignored for connections to the loopback addresses (127.0.0.0/8 and ::1).
**PidFile** __FILE__::
On startup, write our PID to FILE. On clean shutdown, remove
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"