summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--ChangeLog126
-rw-r--r--changes/aes_hackery11
-rw-r--r--changes/af_unspec4
-rw-r--r--changes/bug24745
-rw-r--r--changes/bug28935
-rw-r--r--changes/bug38329
-rw-r--r--changes/bug42305
-rw-r--r--changes/bug43494
-rw-r--r--changes/bug43675
-rw-r--r--changes/bug43684
-rw-r--r--changes/bug43713
-rw-r--r--changes/bug44268
-rw-r--r--changes/bug44349
-rw-r--r--changes/bug44375
-rw-r--r--changes/bug44579
-rw-r--r--changes/bug4457_master6
-rw-r--r--changes/bug44694
-rw-r--r--changes/bug45544
-rw-r--r--changes/checkSpaces5
-rw-r--r--changes/fix-msvc4
-rw-r--r--changes/geoip-november20113
-rw-r--r--changes/test_bench5
-rw-r--r--configure.in7
-rwxr-xr-xcontrib/checkSpace.pl2
-rw-r--r--contrib/tor-mingw.nsi.in2
-rw-r--r--doc/HACKING2
-rw-r--r--doc/tor.1.txt10
-rw-r--r--src/common/compat.c20
-rw-r--r--src/common/compat_libevent.c5
-rw-r--r--src/common/container.c19
-rw-r--r--src/or/command.c61
-rw-r--r--src/or/config.c17
-rw-r--r--src/or/connection_or.c8
-rw-r--r--src/or/connection_or.h2
-rw-r--r--src/or/cpuworker.c14
-rw-r--r--src/or/dirserv.c24
-rw-r--r--src/or/main.c20
-rw-r--r--src/or/ntmain.c2
-rw-r--r--src/or/or.h20
-rw-r--r--src/or/relay.c6
-rw-r--r--src/or/relay.h5
-rw-r--r--src/test/Makefile.am12
-rw-r--r--src/test/bench.c327
-rw-r--r--src/test/test.c98
-rw-r--r--src/test/test_addr.c23
-rw-r--r--src/win32/orconfig.h2
47 files changed, 665 insertions, 288 deletions
diff --git a/.gitignore b/.gitignore
index 610965b858..26e9e3808a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -144,6 +144,8 @@
# /src/test
/src/test/Makefile
/src/test/Makefile.in
+/src/test/bench
+/src/test/bench.exe
/src/test/test
/src/test/test-child
/src/test/test.exe
diff --git a/ChangeLog b/ChangeLog
index a67ed7e66b..4b9d9f05de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,29 @@
-Changes in version 0.2.3.8-alpha - 2011-11-??
+Changes in version 0.2.3.8-alpha - 2011-11-22
+ Tor 0.2.3.8-alpha fixes some crash and assert bugs, including a
+ socketpair-related bug that has been bothering Windows users. It adds
+ support to serve microdescriptors to controllers, so Vidalia's network
+ map can resume listing relays (once Vidalia implements its side),
+ and adds better support for hardware AES acceleration. Finally, it
+ starts the process of adjusting the bandwidth cutoff for getting the
+ "Fast" flag from 20KB to (currently) 32KB -- preliminary results show
+ that tiny relays harm performance more than they help network capacity.
+
o Major bugfixes:
+ - Initialize Libevent with the EVENT_BASE_FLAG_NOLOCK flag enabled, so
+ that it doesn't attempt to allocate a socketpair. This could cause
+ some problems on Windows systems with overzealous firewalls. Fix for
+ bug 4457; workaround for Libevent versions 2.0.1-alpha through
+ 2.0.15-stable.
- Correctly sanity-check that we don't underflow on a memory
allocation (and then assert) for hidden service introduction
point decryption. Bug discovered by Dan Rosenberg. Fixes bug 4410;
bugfix on 0.2.1.5-alpha.
+ - Remove the artificially low cutoff of 20KB to guarantee the Fast
+ flag. In the past few years the average relay speed has picked
+ up, and while the "top 7/8 of the network get the Fast flag" and
+ "all relays with 20KB or more of capacity get the Fast flag" rules
+ used to have the same result, now the top 7/8 of the network has
+ a capacity more like 32KB. Bugfix on 0.2.1.14-rc. Fixes bug 4489.
- Fix a rare assertion failure when checking whether a v0 hidden
service descriptor has any usable introduction points left, and
we don't have enough information to build a circuit to the first
@@ -11,24 +31,120 @@ Changes in version 0.2.3.8-alpha - 2011-11-??
0.2.3.x no longer uses v0 HS descriptors, but this assertion can
trigger on (and crash) v0 HS authorities. Fixes bug 4411.
Bugfix on 0.2.3.1-alpha; diagnosed by frosty_un.
- - Don't crash when we, as the bridge authority, are asked for our own
+ - Make bridge authorities not crash when they are asked for their own
descriptor. Bugfix on 0.2.3.7-alpha, reported by Lucky Green.
+ - When running as a client, do not print a misleading (and plain
+ wrong) log message that we're collecting "directory request"
+ statistics: clients don't collect statistics. Also don't create a
+ useless (because empty) stats file in the stats/ directory. Fixes
+ bug 4353; bugfix on 0.2.2.34 and 0.2.3.7-alpha.
- o Minor bugfixes:
+ o Major features:
+ - Allow Tor controllers like Vidalia to obtain the microdescriptor
+ for a relay by identity digest or nickname. Previously,
+ microdescriptors were only available by their own digests, so a
+ controller would have to ask for and parse the whole microdescriptor
+ consensus in order to look up a single relay's microdesc. Fixes
+ bug 3832; bugfix on 0.2.3.1-alpha.
+ - Use OpenSSL's EVP interface for AES encryption, so that all AES
+ operations can use hardware acceleration (if present). Resolves
+ ticket 4442.
+
+ o Minor bugfixes (on 0.2.2.x and earlier):
+ - Detect failure to initialize Libevent. This fix provides better
+ detection for future instances of bug 4457.
+ - Avoid frequent calls to the fairly expensive cull_wedged_cpuworkers
+ function. This was eating up hideously large amounts of time on some
+ busy servers. Fixes bug 4518; bugfix on 0.0.9.8.
+ - Don't warn about unused log_mutex in log.c when building with
+ --disable-threads using a recent GCC. Fixes bug 4437; bugfix on
+ 0.1.0.6-rc which introduced --disable-threads.
+ - Allow manual 'authenticate' commands to the controller interface
+ from netcat (nc) as well as telnet. We were rejecting them because
+ they didn't come with the expected whitespace at the end of the
+ command. Bugfix on 0.1.1.1-alpha; fixes bug 2893.
+ - Fix some (not actually triggerable) buffer size checks in usage of
+ tor_inet_ntop. Fixes bug 4434; bugfix on Tor 0.2.0.1-alpha. Patch
+ by Anders Sundman.
+ - Fix parsing of some corner-cases with tor_inet_pton(). Fixes
+ bug 4515; bugfix on 0.2.0.1-alpha; fix by Anders Sundman.
+ - When configuring, starting, or stopping an NT service, stop
+ immediately after the service configuration attempt has succeeded
+ or failed. Fixes bug 3963; bugfix on 0.2.0.7-alpha.
+ - When sending a NETINFO cell, include the original address
+ received for the other side, not its canonical address. Found
+ by "troll_un"; fixes bug 4349; bugfix on 0.2.0.10-alpha.
+ - Rename the bench_{aes,dmap} functions to test_*, so that tinytest
+ can pick them up when the tests aren't disabled. Bugfix on
+ 0.2.2.4-alpha which introduced tinytest.
- Fix a memory leak when we check whether a hidden service
descriptor has any usable introduction points left. Fixes bug
4424. Bugfix on 0.2.2.25-alpha.
- Fix a memory leak in launch_direct_bridge_descriptor_fetch() that
occurred when a client tried to fetch a descriptor for a bridge
- in ExcludeNodes. Fixes #4383; bugfix on 0.2.2.25-alpha.
+ in ExcludeNodes. Fixes bug 4383; bugfix on 0.2.2.25-alpha.
+
+ o Minor bugfixes (on 0.2.3.x):
+ - Make util unit tests build correctly with MSVC. Bugfix on
+ 0.2.3.3-alpha. Patch by Gisle Vanem.
+ - Successfully detect AUTH_CHALLENGE cells with no recognized
+ authentication type listed. Fixes bug 4367; bugfix on 0.2.3.6-alpha.
+ Found by frosty_un.
+ - If a relay receives an AUTH_CHALLENGE cell it can't answer,
+ it should still send a NETINFO cell to allow the connection to
+ become open. Fixes bug 4368; fix on 0.2.3.6-alpha; bug found by
+ "frosty".
+ - Log less loudly when we get an invalid authentication certificate
+ from a source other than a directory authority: it's not unusual
+ to see invalid certs because of clock skew. Fixes bug 4370; bugfix
+ on 0.2.3.6-alpha.
+ - Tolerate servers with more clock skew in their authentication
+ certificates than previously. Fixes bug 4371; bugfix on
+ 0.2.3.6-alpha.
+ - Fix a couple of compile warnings on Windows. Fixes bug 4469; bugfix
+ on 0.2.3.4-alpha and 0.2.3.6-alpha.
+
+ o Minor features:
+ - Add two new config options for directory authorities:
+ AuthDirFastGuarantee sets a bandwidth threshold for guaranteeing the
+ Fast flag, and AuthDirGuardBWGuarantee sets a bandwidth threshold
+ that is always sufficient to satisfy the bandwidth requirement for
+ the Guard flag. Now it will be easier for researchers to simulate
+ Tor networks with different values. Resolves ticket 4484.
+ - When Tor ignores a hidden service specified in its configuration,
+ include the hidden service's directory in the warning message.
+ Previously, we would only tell the user that some hidden service
+ was ignored. Bugfix on 0.0.6; fixes bug 4426.
+ - When we fail to initialize Libevent, retry with IOCP disabled so we
+ don't need to turn on multi-threading support in Libevent, which in
+ turn requires a working socketpair(). This is a workaround for bug
+ 4457, which affects Libevent versions from 2.0.1-alpha through
+ 2.0.15-stable.
+ - Detect when we try to build on a platform that doesn't define
+ AF_UNSPEC to 0. We don't work there, so refuse to compile.
+ - Update to the November 1 2011 Maxmind GeoLite Country database.
o Packaging changes:
- - Make it easier to automate expert package builds on Windows
+ - Make it easier to automate expert package builds on Windows,
by removing an absolute path from makensis.exe command.
o Code simplifications and refactoring:
- Remove some redundant #include directives throughout the code.
Patch from Andrea Gelmini.
+ - Unconditionally use OpenSSL's AES implementation instead of our
+ old built-in one. OpenSSL's AES has been better for a while, and
+ relatively few servers should still be on any version of OpenSSL
+ that doesn't have good optimized assembly AES.
+ - Use the name "CERTS" consistently to refer to the new cell type;
+ we were calling it CERT in some places and CERTS in others.
+
+ o Testing:
+ - Numerous new unit tests for functions in util.c and address.c by
+ Anders Sundman.
+ - The long-disabled benchmark tests are now split into their own
+ ./src/test/bench binary.
+ - The benchmark tests can now use more accurate timers than
+ gettimeofday() when such timers are available.
Changes in version 0.2.3.7-alpha - 2011-10-30
diff --git a/changes/aes_hackery b/changes/aes_hackery
deleted file mode 100644
index 739c8a0d66..0000000000
--- a/changes/aes_hackery
+++ /dev/null
@@ -1,11 +0,0 @@
- o Code simplification and refactoring:
- - Unconditionally use OpenSSL's AES implementation instead of our
- old built-in one. OpenSSL's AES has been better for a while, and
- relatively few servers should still be on any version of OpenSSL
- that doesn't have good optimized assembly AES.
-
- o Major features:
- - Use OpenSSL's EVP interface for AES encryption, so that all
- AES operations can use hardware acceleration (if present).
- Resolves issue #4442.
-
diff --git a/changes/af_unspec b/changes/af_unspec
deleted file mode 100644
index 19ef4b4ccf..0000000000
--- a/changes/af_unspec
+++ /dev/null
@@ -1,4 +0,0 @@
- o Minor features:
- - Detect when we build on a platform that doesn't define AF_UNSPEC to 0.
- We don't work there, so refuse to compile.
-
diff --git a/changes/bug2474 b/changes/bug2474
new file mode 100644
index 0000000000..02d3eb7ba9
--- /dev/null
+++ b/changes/bug2474
@@ -0,0 +1,5 @@
+ o Minor features
+ - Try to make the introductory warning message that Tor prints on
+ startup more useful for actually finding help and information.
+ Resolves bug2474.
+
diff --git a/changes/bug2893 b/changes/bug2893
deleted file mode 100644
index f6d235cf53..0000000000
--- a/changes/bug2893
+++ /dev/null
@@ -1,5 +0,0 @@
- o Minor bugfixes:
- - Allow manual 'authenticate' commands to the controller interface
- from nc as well as telnet. We were rejecting them because they
- didn't come with the expected whitespace at the end of the command.
- Bugfix on 0.1.1.1-alpha; fixes bug 2893.
diff --git a/changes/bug3832 b/changes/bug3832
deleted file mode 100644
index 230f0d797b..0000000000
--- a/changes/bug3832
+++ /dev/null
@@ -1,9 +0,0 @@
- o Major features:
-
- - Allow Tor controllers like Vidalia to obtain the microdescriptor
- for a relay by identity digest or nickname. Previously,
- microdescriptors were only available by their own digests, so a
- controller would have to ask for and parse the whole
- microdescriptor consensus in order to look up a single relay's
- microdesc. Fixes bug 3832; bugfix on 0.2.3.1-alpha.
-
diff --git a/changes/bug4230 b/changes/bug4230
new file mode 100644
index 0000000000..c1ba5847fc
--- /dev/null
+++ b/changes/bug4230
@@ -0,0 +1,5 @@
+ o Minor bugfixes:
+ - Resolve an integer overflow bug in smartlist_ensure_capacity.
+ Fixes bug 4230; bugfix on Tor 0.1.0.1-rc. Based on a patch by
+ Mansour Moufid.
+
diff --git a/changes/bug4349 b/changes/bug4349
deleted file mode 100644
index 633916bdfd..0000000000
--- a/changes/bug4349
+++ /dev/null
@@ -1,4 +0,0 @@
- o Minor bugfixes:
- - When sending a NETINFO cell, include the original address
- received for the other side, not its canonical address. Found
- by "troll_un"; fixes bug 4349; bugfix on 0.2.0.10-alpha.
diff --git a/changes/bug4367 b/changes/bug4367
deleted file mode 100644
index 77236d0e61..0000000000
--- a/changes/bug4367
+++ /dev/null
@@ -1,5 +0,0 @@
- o Minor bugfixes:
- - Successfully detect AUTH_CHALLENGE cells with no recognized
- authentication type listed. Fixes bug 4367; bugfix on 0.2.3.6-alpha.
- Found by frosty_un.
-
diff --git a/changes/bug4368 b/changes/bug4368
deleted file mode 100644
index 54b4882bc3..0000000000
--- a/changes/bug4368
+++ /dev/null
@@ -1,4 +0,0 @@
- o Minor bugfixes:
- - If a relay receives an AUTH_CHALLENGE it can't answer, it should
- still send a NETINFO cell to allow the connection to become open.
- Fixes bug 4368; fix on 0.2.3.6-alpha; bug found by "frosty".
diff --git a/changes/bug4371 b/changes/bug4371
deleted file mode 100644
index 37e6faa840..0000000000
--- a/changes/bug4371
+++ /dev/null
@@ -1,3 +0,0 @@
- o Minor bugfixes:
- - Tolerate servers with more clock skew than previously. Fixes bug 4371;
- bugfix on 0.2.3.6-alpha.
diff --git a/changes/bug4426 b/changes/bug4426
deleted file mode 100644
index 1322243d09..0000000000
--- a/changes/bug4426
+++ /dev/null
@@ -1,8 +0,0 @@
- o Minor features:
-
- - When Tor ignores a hidden service specified in its
- configuration, include the hidden service's directory in the
- warning message. Previously, we would only tell the user that
- some hidden service was ignored. Bugfix on 0.0.6; fixes bug
- 4426.
-
diff --git a/changes/bug4434 b/changes/bug4434
deleted file mode 100644
index d602088f41..0000000000
--- a/changes/bug4434
+++ /dev/null
@@ -1,9 +0,0 @@
- o Minor bugfixes:
- - Fix some (not actually triggerable) buffer size checks in usage of
- tor_inet_ntop. Fixes bug 4434; bugfix on Tor 0.2.0.1-alpha. Patch
- by Anders Sundman.
-
- o Testing:
- - Numerous new unit tests for functions in util.c and address.c by
- Anders Sundman.
-
diff --git a/changes/bug4437 b/changes/bug4437
deleted file mode 100644
index 985c670b15..0000000000
--- a/changes/bug4437
+++ /dev/null
@@ -1,5 +0,0 @@
- o Minor bugfixes:
- - Don't warn about unused log_mutex in log.c when building with
- --disable-threads using a recent GCC. Fixes bug 4437; bugfix on
- 0.1.0.6-rc which introduced --disable-threads.
-
diff --git a/changes/bug4457 b/changes/bug4457
deleted file mode 100644
index fe7c95ff80..0000000000
--- a/changes/bug4457
+++ /dev/null
@@ -1,9 +0,0 @@
- o Minor bugfixes:
- - Initialize Libevent with the EVENT_BASE_FLAG_NOLOCK flag enabled, so
- that it doesn't attempt to allocate a socketpair. This could cause
- some problems on windows systems with overzealous firewalls. Fix for
- bug 4457; workaround for Libevent versions 2.0.1-alpha through
- 2.0.15-stable.
-
- - Detect failure to initialize Libevent. Better detection for bug 4457.
-
diff --git a/changes/bug4457_master b/changes/bug4457_master
deleted file mode 100644
index d394643b6d..0000000000
--- a/changes/bug4457_master
+++ /dev/null
@@ -1,6 +0,0 @@
- o Minor features:
- - When we fail to initialize Libevent, retry with IOCP disabled so we
- don't need to turn on multi-threading support in Libevent, which in
- turn requires a working socketpair(). This is a workaround for bug
- 4457, which affects Libevent versions from 2.0.1-alpha through
- 2.0.15-stable.
diff --git a/changes/bug4469 b/changes/bug4469
deleted file mode 100644
index e9e390ccfe..0000000000
--- a/changes/bug4469
+++ /dev/null
@@ -1,4 +0,0 @@
- o Minor bugfixes:
- - Fix a couple of compile warnings on Windows. Fixes bug 4469; bugfix
- on 0.2.3.4-alpha and 0.2.3.6-alpha.
-
diff --git a/changes/bug4554 b/changes/bug4554
new file mode 100644
index 0000000000..e4754c29e9
--- /dev/null
+++ b/changes/bug4554
@@ -0,0 +1,4 @@
+ o Minor bugfixes:
+ - Fix a compile warning in tor_inet_pton(). Bugfix on 0.2.3.8-alpha;
+ fixes bug 4554.
+
diff --git a/changes/checkSpaces b/changes/checkSpaces
new file mode 100644
index 0000000000..91f79ed0fa
--- /dev/null
+++ b/changes/checkSpaces
@@ -0,0 +1,5 @@
+ o Minor bugfixes:
+ - Prevent a false positive from the check-spaces script by disabling
+ the "whitespace between function name and (" check for functions
+ named 'op()'.
+
diff --git a/changes/fix-msvc b/changes/fix-msvc
deleted file mode 100644
index 62f05476b9..0000000000
--- a/changes/fix-msvc
+++ /dev/null
@@ -1,4 +0,0 @@
- o Minor bugfixes:
- - Make util unit tests build correctly with MSVC. Bugfix on
- 0.2.3.3-alpha. Patch by Gisle Vanem.
-
diff --git a/changes/geoip-november2011 b/changes/geoip-november2011
deleted file mode 100644
index 3aa8dc05c2..0000000000
--- a/changes/geoip-november2011
+++ /dev/null
@@ -1,3 +0,0 @@
- o Minor features:
- - Update to the November 1 2011 Maxmind GeoLite Country database.
-
diff --git a/changes/test_bench b/changes/test_bench
deleted file mode 100644
index 8ae895b116..0000000000
--- a/changes/test_bench
+++ /dev/null
@@ -1,5 +0,0 @@
- o Minor bugfixes:
- - Rename the bench_{aes,dmap} functions to test_*, so that tinytest can
- pick them up when the tests aren't disabled. Bugfix on 0.2.2.4-alpha
- which introduced tinytest.
-
diff --git a/configure.in b/configure.in
index 17f5c8d5e3..64d9d6db7b 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.3.7-alpha)
+AM_INIT_AUTOMAKE(tor, 0.2.3.8-alpha-dev)
AM_CONFIG_HEADER(orconfig.h)
AC_CANONICAL_HOST
@@ -276,6 +276,7 @@ AC_SEARCH_LIBS(socket, [socket])
AC_SEARCH_LIBS(gethostbyname, [nsl])
AC_SEARCH_LIBS(dlopen, [dl])
AC_SEARCH_LIBS(inet_aton, [resolv])
+AC_SEARCH_LIBS([clock_gettime], [rt], [have_rt=yes])
if test "$enable_threads" = "yes"; then
AC_SEARCH_LIBS(pthread_create, [pthread])
@@ -288,6 +289,7 @@ dnl exports strlcpy without defining it in a header.
AC_CHECK_FUNCS(
accept4 \
+ clock_gettime \
flock \
ftime \
getaddrinfo \
@@ -363,9 +365,6 @@ dnl On Gnu/Linux or any place we require it, we'll add librt to the Libevent
dnl linking for static builds.
STATIC_LIBEVENT_FLAGS=""
if test "$enable_static_libevent" = "yes"; then
- dnl Determine if we have clock_gettime in librt
- AC_SEARCH_LIBS([clock_gettime], [rt],
- [have_rt=yes])
if test "$have_rt" = yes; then
STATIC_LIBEVENT_FLAGS=" -lrt "
fi
diff --git a/contrib/checkSpace.pl b/contrib/checkSpace.pl
index 6eb32e5620..a18df99b16 100755
--- a/contrib/checkSpace.pl
+++ b/contrib/checkSpace.pl
@@ -97,7 +97,7 @@ for $fn (@ARGV) {
if ($1 ne "if" and $1 ne "while" and $1 ne "for" and
$1 ne "switch" and $1 ne "return" and $1 ne "int" and
$1 ne "elsif" and $1 ne "WINAPI" and $2 ne "WINAPI" and
- $1 ne "void" and $1 ne "__attribute__") {
+ $1 ne "void" and $1 ne "__attribute__" and $1 ne "op") {
print " fn ():$fn:$.\n";
}
}
diff --git a/contrib/tor-mingw.nsi.in b/contrib/tor-mingw.nsi.in
index eadae39eef..8ea9f32b97 100644
--- a/contrib/tor-mingw.nsi.in
+++ b/contrib/tor-mingw.nsi.in
@@ -8,7 +8,7 @@
!include "LogicLib.nsh"
!include "FileFunc.nsh"
!insertmacro GetParameters
-!define VERSION "0.2.3.7-alpha"
+!define VERSION "0.2.3.8-alpha-dev"
!define INSTALLER "tor-${VERSION}-win32.exe"
!define WEBSITE "https://www.torproject.org/"
!define LICENSE "LICENSE"
diff --git a/doc/HACKING b/doc/HACKING
index b0689d82c1..bc409dc0d0 100644
--- a/doc/HACKING
+++ b/doc/HACKING
@@ -473,7 +473,7 @@ git branches too.
a while to see if anybody has problems building it. Try to get Sebastian
or somebody to try building it on Windows.
-6) Get at least two of weasel/arma/karsten to put the new version number
+6) Get at least two of weasel/arma/sebastian to put the new version number
in their approved versions list.
7) Sign the tarball, then sign and push the git tag:
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index b54735d383..f5be391052 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -1406,6 +1406,16 @@ DIRECTORY AUTHORITY SERVER OPTIONS
Authoritative directories only. Like AuthDirMaxServersPerAddr, but applies
to addresses shared with directory authorities. (Default: 5)
+**AuthDirFastGuarantee** __N__ **bytes**|**KB**|**MB**|**GB**::
+ Authoritative directories only. If non-zero, always vote the
+ Fast flag for any relay advertising this amount of capacity or
+ more. (Default: 100 KB)
+
+**AuthDirGuardBWGuarantee** __N__ **bytes**|**KB**|**MB**|**GB**::
+ Authoritative directories only. If non-zero, this advertised capacity
+ or more is always sufficient to satisfy the bandwidth requirement
+ for the Guard flag. (Default: 250 KB)
+
**BridgePassword** __Password__::
If set, contains an HTTP authenticator that tells a bridge authority to
serve all requested bridge information. Used for debugging. (Default:
diff --git a/src/common/compat.c b/src/common/compat.c
index ba49af757c..9a2c9d764b 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -1733,24 +1733,30 @@ tor_inet_pton(int af, const char *src, void *dst)
return 0;
if (TOR_ISXDIGIT(*src)) {
char *next;
+ ssize_t len;
long r = strtol(src, &next, 16);
- if (next > 4+src)
- return 0;
- if (next == src)
- return 0;
- if (r<0 || r>65536)
+ tor_assert(next != NULL);
+ tor_assert(next != src);
+
+ len = *next == '\0' ? eow - src : next - src;
+ if (len > 4)
return 0;
+ if (len > 1 && !TOR_ISXDIGIT(src[1]))
+ return 0; /* 0x is not valid */
+ tor_assert(r >= 0);
+ tor_assert(r < 65536);
words[i++] = (uint16_t)r;
setWords++;
src = next;
if (*src != ':' && src != eow)
return 0;
++src;
- } else if (*src == ':' && i > 0 && gapPos==-1) {
+ } else if (*src == ':' && i > 0 && gapPos == -1) {
gapPos = i;
++src;
- } else if (*src == ':' && i == 0 && src[1] == ':' && gapPos==-1) {
+ } else if (*src == ':' && i == 0 && src+1 < eow && src[1] == ':' &&
+ gapPos == -1) {
gapPos = i;
src += 2;
} else {
diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c
index 7a28c9bc9b..0cedef8d5e 100644
--- a/src/common/compat_libevent.c
+++ b/src/common/compat_libevent.c
@@ -243,8 +243,8 @@ tor_libevent_initialize(tor_libevent_cfg *torcfg)
* again. */
#if defined(MS_WINDOWS) && defined(USE_BUFFEREVENTS)
if (torcfg->disable_iocp == 0) {
- log_warn(LD_GENERAL, "Unable to initialize Libevent. Trying again with "
- "IOCP disabled.");
+ log_warn(LD_GENERAL, "Unable to initialize Libevent. Trying again "
+ "with IOCP disabled.");
} else
#endif
{
@@ -254,7 +254,6 @@ tor_libevent_initialize(tor_libevent_cfg *torcfg)
torcfg->disable_iocp = 1;
goto retry;
}
-
}
#else
the_event_base = event_init();
diff --git a/src/common/container.c b/src/common/container.c
index 92bfd2ec89..31cc6c5a6c 100644
--- a/src/common/container.c
+++ b/src/common/container.c
@@ -62,13 +62,22 @@ smartlist_clear(smartlist_t *sl)
static INLINE void
smartlist_ensure_capacity(smartlist_t *sl, int size)
{
+#if SIZEOF_SIZE_T > SIZEOF_INT
+#define MAX_CAPACITY (INT_MAX)
+#else
+#define MAX_CAPACITY (int)((SIZE_MAX / (sizeof(void*))))
+#endif
if (size > sl->capacity) {
- int higher = sl->capacity * 2;
- while (size > higher)
- higher *= 2;
- tor_assert(higher > 0); /* detect overflow */
+ int higher = sl->capacity;
+ if (PREDICT_UNLIKELY(size > MAX_CAPACITY/2)) {
+ tor_assert(size <= MAX_CAPACITY);
+ higher = MAX_CAPACITY;
+ } else {
+ while (size > higher)
+ higher *= 2;
+ }
sl->capacity = higher;
- sl->list = tor_realloc(sl->list, sizeof(void*)*sl->capacity);
+ sl->list = tor_realloc(sl->list, sizeof(void*)*((size_t)sl->capacity));
}
}
diff --git a/src/or/command.c b/src/or/command.c
index a963d4210b..023f2bead5 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -49,7 +49,7 @@ uint64_t stats_n_netinfo_cells_processed = 0;
/** How many CELL_VPADDING cells have we received, ever? */
uint64_t stats_n_vpadding_cells_processed = 0;
/** How many CELL_CERTS cells have we received, ever? */
-uint64_t stats_n_cert_cells_processed = 0;
+uint64_t stats_n_certs_cells_processed = 0;
/** How many CELL_AUTH_CHALLENGE cells have we received, ever? */
uint64_t stats_n_auth_challenge_cells_processed = 0;
/** How many CELL_AUTHENTICATE cells have we received, ever? */
@@ -63,7 +63,7 @@ static void command_process_destroy_cell(cell_t *cell, or_connection_t *conn);
static void command_process_versions_cell(var_cell_t *cell,
or_connection_t *conn);
static void command_process_netinfo_cell(cell_t *cell, or_connection_t *conn);
-static void command_process_cert_cell(var_cell_t *cell,
+static void command_process_certs_cell(var_cell_t *cell,
or_connection_t *conn);
static void command_process_auth_challenge_cell(var_cell_t *cell,
or_connection_t *conn);
@@ -214,19 +214,19 @@ command_process_var_cell(var_cell_t *cell, or_connection_t *conn)
#ifdef KEEP_TIMING_STATS
/* how many of each cell have we seen so far this second? needs better
* name. */
- static int num_versions=0, num_cert=0;
+ static int num_versions=0, num_certs=0;
time_t now = time(NULL);
if (now > current_second) { /* the second has rolled over */
/* print stats */
log_info(LD_OR,
- "At end of second: %d versions (%d ms), %d cert (%d ms)",
+ "At end of second: %d versions (%d ms), %d certs (%d ms)",
num_versions, versions_time/1000,
- cert, cert_time/1000);
+ num_certs, certs_time/1000);
- num_versions = num_cert = 0;
- versions_time = cert_time = 0;
+ num_versions = num_certs = 0;
+ versions_time = certs_time = 0;
/* remember which second it is, for next time */
current_second = now;
@@ -293,9 +293,9 @@ command_process_var_cell(var_cell_t *cell, or_connection_t *conn)
++stats_n_vpadding_cells_processed;
/* Do nothing */
break;
- case CELL_CERT:
- ++stats_n_cert_cells_processed;
- PROCESS_CELL(cert, cell, conn);
+ case CELL_CERTS:
+ ++stats_n_certs_cells_processed;
+ PROCESS_CELL(certs, cell, conn);
break;
case CELL_AUTH_CHALLENGE:
++stats_n_auth_challenge_cells_processed;
@@ -719,8 +719,8 @@ command_process_versions_cell(var_cell_t *cell, or_connection_t *conn)
}
}
if (send_certs) {
- if (connection_or_send_cert_cell(conn) < 0) {
- log_warn(LD_OR, "Couldn't send cert cell");
+ if (connection_or_send_certs_cell(conn) < 0) {
+ log_warn(LD_OR, "Couldn't send certs cell");
connection_mark_for_close(TO_CONN(conn));
return;
}
@@ -887,9 +887,9 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn)
assert_connection_ok(TO_CONN(conn),time(NULL));
}
-/** Process a CERT cell from an OR connection.
+/** Process a CERTS cell from an OR connection.
*
- * If the other side should not have sent us a CERT cell, or the cell is
+ * If the other side should not have sent us a CERTS cell, or the cell is
* malformed, or it is supposed to authenticate the TLS key but it doesn't,
* then mark the connection.
*
@@ -899,12 +899,12 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn)
* If it's the server side, wait for an AUTHENTICATE cell.
*/
static void
-command_process_cert_cell(var_cell_t *cell, or_connection_t *conn)
+command_process_certs_cell(var_cell_t *cell, or_connection_t *conn)
{
#define ERR(s) \
do { \
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, \
- "Received a bad CERT cell from %s:%d: %s", \
+ "Received a bad CERTS cell from %s:%d: %s", \
safe_str(conn->_base.address), conn->_base.port, (s)); \
connection_mark_for_close(TO_CONN(conn)); \
goto err; \
@@ -921,7 +921,7 @@ command_process_cert_cell(var_cell_t *cell, or_connection_t *conn)
ERR("We're not doing a v3 handshake!");
if (conn->link_proto < 3)
ERR("We're not using link protocol >= 3");
- if (conn->handshake_state->received_cert_cell)
+ if (conn->handshake_state->received_certs_cell)
ERR("We already got one");
if (conn->handshake_state->authenticated) {
/* Should be unreachable, but let's make sure. */
@@ -951,7 +951,7 @@ command_process_cert_cell(var_cell_t *cell, or_connection_t *conn)
tor_cert_t *cert = tor_cert_decode(ptr + 3, cert_len);
if (!cert) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
- "Received undecodable certificate in CERT cell from %s:%d",
+ "Received undecodable certificate in CERTS cell from %s:%d",
safe_str(conn->_base.address), conn->_base.port);
} else {
if (cert_type == OR_CERT_TYPE_TLS_LINK) {
@@ -985,15 +985,24 @@ command_process_cert_cell(var_cell_t *cell, or_connection_t *conn)
}
if (conn->handshake_state->started_here) {
+ int severity;
if (! (id_cert && link_cert))
ERR("The certs we wanted were missing");
/* Okay. We should be able to check the certificates now. */
if (! tor_tls_cert_matches_key(conn->tls, link_cert)) {
ERR("The link certificate didn't match the TLS public key");
}
- if (! tor_tls_cert_is_valid(LOG_PROTOCOL_WARN, link_cert, id_cert, 0))
+ /* Note that this warns more loudly about time and validity if we were
+ * _trying_ to connect to an authority, not necessarily if we _did_ connect
+ * to one. */
+ if (router_digest_is_trusted_dir(conn->identity_digest))
+ severity = LOG_WARN;
+ else
+ severity = LOG_PROTOCOL_WARN;
+
+ if (! tor_tls_cert_is_valid(severity, link_cert, id_cert, 0))
ERR("The link certificate was not valid");
- if (! tor_tls_cert_is_valid(LOG_PROTOCOL_WARN, id_cert, id_cert, 1))
+ if (! tor_tls_cert_is_valid(severity, id_cert, id_cert, 1))
ERR("The ID certificate was not valid");
conn->handshake_state->authenticated = 1;
@@ -1041,7 +1050,7 @@ command_process_cert_cell(var_cell_t *cell, or_connection_t *conn)
id_cert = auth_cert = NULL;
}
- conn->handshake_state->received_cert_cell = 1;
+ conn->handshake_state->received_certs_cell = 1;
err:
tor_cert_free(id_cert);
tor_cert_free(link_cert);
@@ -1055,7 +1064,7 @@ command_process_cert_cell(var_cell_t *cell, or_connection_t *conn)
* originator of the connection), or it's ill-formed, or we aren't doing a v3
* handshake, mark the connection. If the cell is well-formed but we don't
* want to authenticate, just drop it. If the cell is well-formed *and* we
- * want to authenticate, send an AUTHENTICATE cell. */
+ * want to authenticate, send an AUTHENTICATE cell and then a NETINFO cell. */
static void
command_process_auth_challenge_cell(var_cell_t *cell, or_connection_t *conn)
{
@@ -1079,7 +1088,7 @@ command_process_auth_challenge_cell(var_cell_t *cell, or_connection_t *conn)
ERR("We didn't originate this connection");
if (conn->handshake_state->received_auth_challenge)
ERR("We already received one");
- if (! conn->handshake_state->received_cert_cell)
+ if (! conn->handshake_state->received_certs_cell)
ERR("We haven't gotten a CERTS cell yet");
if (cell->payload_len < OR_AUTH_CHALLENGE_LEN + 2)
ERR("It was too short");
@@ -1137,7 +1146,7 @@ command_process_auth_challenge_cell(var_cell_t *cell, or_connection_t *conn)
* If it's ill-formed or we weren't supposed to get one or we're not doing a
* v3 handshake, then mark the connection. If it does not authenticate the
* other side of the connection successfully (because it isn't signed right,
- * we didn't get a CERT cell, etc) mark the connection. Otherwise, accept
+ * we didn't get a CERTS cell, etc) mark the connection. Otherwise, accept
* the identity of the router on the other side of the connection.
*/
static void
@@ -1168,8 +1177,8 @@ command_process_authenticate_cell(var_cell_t *cell, or_connection_t *conn)
/* Should be impossible given other checks */
ERR("The peer is already authenticated");
}
- if (! conn->handshake_state->received_cert_cell)
- ERR("We never got a cert cell");
+ if (! conn->handshake_state->received_certs_cell)
+ ERR("We never got a certs cell");
if (conn->handshake_state->auth_cert == NULL)
ERR("We never got an authentication certificate");
if (conn->handshake_state->id_cert == NULL)
diff --git a/src/or/config.c b/src/or/config.c
index 4710b5590b..ef9e4ecee4 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -184,6 +184,8 @@ static config_var_t _option_vars[] = {
V(AuthDirBadDir, LINELIST, NULL),
V(AuthDirBadExit, LINELIST, NULL),
V(AuthDirInvalid, LINELIST, NULL),
+ V(AuthDirFastGuarantee, MEMUNIT, "100 KB"),
+ V(AuthDirGuardBWGuarantee, MEMUNIT, "250 KB"),
V(AuthDirReject, LINELIST, NULL),
V(AuthDirRejectUnlisted, BOOL, "0"),
V(AuthDirListBadDirs, BOOL, "0"),
@@ -1542,6 +1544,15 @@ options_act(const or_options_t *old_options)
options->BridgeAuthoritativeDir) {
time_t now = time(NULL);
int print_notice = 0;
+
+ /* If we aren't acting as a server, we can't collect stats anyway. */
+ if (!server_mode(options)) {
+ options->CellStatistics = 0;
+ options->DirReqStatistics = 0;
+ options->EntryStatistics = 0;
+ options->ExitPortStatistics = 0;
+ }
+
if ((!old_options || !old_options->CellStatistics) &&
options->CellStatistics) {
rep_hist_buffer_stats_init(now);
@@ -3536,6 +3547,12 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (ensure_bandwidth_cap(&options->PerConnBWBurst,
"PerConnBWBurst", msg) < 0)
return -1;
+ if (ensure_bandwidth_cap(&options->AuthDirFastGuarantee,
+ "AuthDirFastGuarantee", msg) < 0)
+ return -1;
+ if (ensure_bandwidth_cap(&options->AuthDirGuardBWGuarantee,
+ "AuthDirGuardBWGuarantee", msg) < 0)
+ return -1;
if (options->RelayBandwidthRate && !options->RelayBandwidthBurst)
options->RelayBandwidthBurst = options->RelayBandwidthRate;
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 320d8cb501..cce99e4d65 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -1435,7 +1435,7 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
* side of <b>conn</b> is <b>peer_id</b>. For v1 and v2 handshakes,
* this is right after we get a certificate chain in a TLS handshake
* or renegotiation. For v3 handshakes, this is right after we get a
- * certificate chain in a CERT cell.
+ * certificate chain in a CERTS cell.
*
* If we want any particular ID before, record the one we got.
*
@@ -1954,10 +1954,10 @@ connection_or_send_netinfo(or_connection_t *conn)
return 0;
}
-/** Send a CERT cell on the connection <b>conn</b>. Return 0 on success, -1
+/** Send a CERTS cell on the connection <b>conn</b>. Return 0 on success, -1
* on failure. */
int
-connection_or_send_cert_cell(or_connection_t *conn)
+connection_or_send_certs_cell(or_connection_t *conn)
{
const tor_cert_t *link_cert = NULL, *id_cert = NULL;
const uint8_t *link_encoded = NULL, *id_encoded = NULL;
@@ -1981,7 +1981,7 @@ connection_or_send_cert_cell(or_connection_t *conn)
2 * ( 1 + 2 ) /* For each cert: 1 byte for type, 2 for length */ +
link_len + id_len;
cell = var_cell_new(cell_len);
- cell->command = CELL_CERT;
+ cell->command = CELL_CERTS;
cell->payload[0] = 2;
pos = 1;
diff --git a/src/or/connection_or.h b/src/or/connection_or.h
index df009ab39e..62a15b1cf2 100644
--- a/src/or/connection_or.h
+++ b/src/or/connection_or.h
@@ -69,7 +69,7 @@ int connection_or_send_destroy(circid_t circ_id, or_connection_t *conn,
int reason);
int connection_or_send_versions(or_connection_t *conn, int v3_plus);
int connection_or_send_netinfo(or_connection_t *conn);
-int connection_or_send_cert_cell(or_connection_t *conn);
+int connection_or_send_certs_cell(or_connection_t *conn);
int connection_or_send_auth_challenge_cell(or_connection_t *conn);
int connection_or_compute_authenticate_cell_body(or_connection_t *conn,
uint8_t *out, size_t outlen,
diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c
index bf8964c29c..914003790a 100644
--- a/src/or/cpuworker.c
+++ b/src/or/cpuworker.c
@@ -445,9 +445,19 @@ assign_onionskin_to_cpuworker(connection_t *cpuworker,
{
char qbuf[1];
char tag[TAG_LEN];
+ time_t now = approx_time();
+ static time_t last_culled_cpuworkers = 0;
- cull_wedged_cpuworkers();
- spawn_enough_cpuworkers();
+ /* Checking for wedged cpuworkers requires a linear search over all
+ * connections, so let's do it only once a minute.
+ */
+#define CULL_CPUWORKERS_INTERVAL 60
+
+ if (last_culled_cpuworkers + CULL_CPUWORKERS_INTERVAL <= now) {
+ cull_wedged_cpuworkers();
+ spawn_enough_cpuworkers();
+ last_culled_cpuworkers = now;
+ }
if (1) {
if (num_cpuworkers_busy == num_cpuworkers) {
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index e4cbcaaded..be62459b16 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -1720,12 +1720,6 @@ should_generate_v2_networkstatus(void)
/** If a router's MTBF is at least this value, then it is always stable.
* See above. (Corresponds to about 7 days for current decay rates.) */
#define MTBF_TO_GUARANTEE_STABLE (60*60*24*5)
-/** Similarly, we protect sufficiently fast nodes from being pushed
- * out of the set of Fast nodes. */
-#define BANDWIDTH_TO_GUARANTEE_FAST ROUTER_REQUIRED_MIN_BANDWIDTH
-/** Similarly, every node with sufficient bandwidth can be considered
- * for Guard status. */
-#define BANDWIDTH_TO_GUARANTEE_GUARD (250*1024)
/** Similarly, every node with at least this much weighted time known can be
* considered familiar enough to be a guard. Corresponds to about 20 days for
* current decay rates.
@@ -1870,6 +1864,7 @@ dirserv_compute_performance_thresholds(routerlist_t *rl)
long *tks;
double *mtbfs, *wfus;
time_t now = time(NULL);
+ const or_options_t *options = get_options();
/* initialize these all here, in case there are no routers */
stable_uptime = 0;
@@ -1942,8 +1937,11 @@ dirserv_compute_performance_thresholds(routerlist_t *rl)
if (guard_tk > TIME_KNOWN_TO_GUARANTEE_FAMILIAR)
guard_tk = TIME_KNOWN_TO_GUARANTEE_FAMILIAR;
- if (fast_bandwidth > BANDWIDTH_TO_GUARANTEE_FAST)
- fast_bandwidth = BANDWIDTH_TO_GUARANTEE_FAST;
+ /* Protect sufficiently fast nodes from being pushed out of the set
+ * of Fast nodes. */
+ if (options->AuthDirFastGuarantee &&
+ fast_bandwidth > options->AuthDirFastGuarantee)
+ fast_bandwidth = (uint32_t)options->AuthDirFastGuarantee;
/* Now that we have a time-known that 7/8 routers are known longer than,
* fill wfus with the wfu of every such "familiar" router. */
@@ -2375,6 +2373,8 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
const or_options_t *options = get_options();
int unstable_version =
!tor_version_as_new_as(ri->platform,"0.1.1.16-rc-cvs");
+ uint32_t routerbw = router_get_advertised_bandwidth(ri);
+
memset(rs, 0, sizeof(routerstatus_t));
rs->is_authority =
@@ -2400,10 +2400,10 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
rs->is_valid = node->is_valid;
if (node->is_fast &&
- (router_get_advertised_bandwidth(ri) >= BANDWIDTH_TO_GUARANTEE_GUARD ||
- router_get_advertised_bandwidth(ri) >=
- MIN(guard_bandwidth_including_exits,
- guard_bandwidth_excluding_exits)) &&
+ ((options->AuthDirGuardBWGuarantee &&
+ routerbw >= options->AuthDirGuardBWGuarantee) ||
+ routerbw >= MIN(guard_bandwidth_including_exits,
+ guard_bandwidth_excluding_exits)) &&
(options->GiveGuardFlagTo_CVE_2011_2768_VulnerableRelays ||
is_router_version_good_for_possible_guard(ri->platform))) {
long tk = rep_hist_get_weighted_time_known(
diff --git a/src/or/main.c b/src/or/main.c
index 9f6d307a3e..10b80a4dd9 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -2265,14 +2265,24 @@ tor_init(int argc, char *argv[])
}
quiet_level = quiet;
- log(LOG_NOTICE, LD_GENERAL, "Tor v%s%s. This is experimental software. "
- "Do not rely on it for strong anonymity. (Running on %s)", get_version(),
+ {
+ const char *version = get_version();
+ log_notice(LD_GENERAL, "Tor v%s%s running on %s.", version,
#ifdef USE_BUFFEREVENTS
- " (with bufferevents)",
+ " (with bufferevents)",
#else
- "",
+ "",
#endif
- get_uname());
+ get_uname());
+
+ log_notice(LD_GENERAL, "WARNING: Tor can't help you if you use it wrong. "
+ "Learn how to be safe at "
+ "https://www.torproject.org/download/download#warning");
+
+ if (strstr(version, "alpha") || strstr(version, "beta"))
+ log_notice(LD_GENERAL, "This version is not a stable Tor release. "
+ "Expect more bugs than usual.");
+ }
if (network_init()<0) {
log_err(LD_BUG,"Error initializing network; exiting.");
diff --git a/src/or/ntmain.c b/src/or/ntmain.c
index 4eb487e976..8d03ea8087 100644
--- a/src/or/ntmain.c
+++ b/src/or/ntmain.c
@@ -727,6 +727,7 @@ nt_service_parse_options(int argc, char **argv, int *should_exit)
if ((argc >= 3) &&
(!strcmp(argv[1], "-service") || !strcmp(argv[1], "--service"))) {
nt_service_loadlibrary();
+ *should_exit = 1;
if (!strcmp(argv[2], "install"))
return nt_service_install(argc, argv);
if (!strcmp(argv[2], "remove"))
@@ -736,7 +737,6 @@ nt_service_parse_options(int argc, char **argv, int *should_exit)
if (!strcmp(argv[2], "stop"))
return nt_service_cmd_stop();
printf("Unrecognized service command '%s'\n", argv[2]);
- *should_exit = 1;
return 1;
}
if (argc >= 2) {
diff --git a/src/or/or.h b/src/or/or.h
index 7fb7e9cb22..f186eac7bd 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -826,7 +826,7 @@ typedef enum {
#define CELL_RELAY_EARLY 9
#define CELL_VPADDING 128
-#define CELL_CERT 129
+#define CELL_CERTS 129
#define CELL_AUTH_CHALLENGE 130
#define CELL_AUTHENTICATE 131
@@ -1088,10 +1088,10 @@ typedef struct listener_connection_t {
#define OR_AUTH_CHALLENGE_LEN 32
/**
- * @name Certificate types for CERT cells.
+ * @name Certificate types for CERTS cells.
*
* These values are defined by the protocol, and affect how an X509
- * certificate in a CERT cell is interpreted and used.
+ * certificate in a CERTS cell is interpreted and used.
*
* @{ */
/** A certificate that authenticates a TLS link key. The subject key
@@ -1137,8 +1137,8 @@ typedef struct or_handshake_state_t {
unsigned int received_versions : 1;
/** True iff we have received and processed an AUTH_CHALLENGE cell */
unsigned int received_auth_challenge : 1;
- /** True iff we have received and processed a CERT cell. */
- unsigned int received_cert_cell : 1;
+ /** True iff we have received and processed a CERTS cell. */
+ unsigned int received_certs_cell : 1;
/** True iff we have received and processed an AUTHENTICATE cell */
unsigned int received_authenticate : 1;
@@ -1171,7 +1171,7 @@ typedef struct or_handshake_state_t {
crypto_digest_env_t *digest_received;
/** @} */
- /** Certificates that a connection initiator sent us in a CERT cell; we're
+ /** Certificates that a connection initiator sent us in a CERTS cell; we're
* holding on to them until we get an AUTHENTICATE cell.
*
* @{
@@ -3162,6 +3162,14 @@ typedef struct {
* exploitation of CVE-2011-2768 against their clients? */
int GiveGuardFlagTo_CVE_2011_2768_VulnerableRelays;
+ /** If non-zero, always vote the Fast flag for any relay advertising
+ * this amount of capacity or more. */
+ uint64_t AuthDirFastGuarantee;
+
+ /** If non-zero, this advertised capacity or more is always sufficient
+ * to satisfy the bandwidth requirement for the Guard flag. */
+ uint64_t AuthDirGuardBWGuarantee;
+
char *AccountingStart; /**< How long is the accounting interval, and when
* does it start? */
uint64_t AccountingMax; /**< How many bytes do we allow per accounting
diff --git a/src/or/relay.c b/src/or/relay.c
index 51a29a20ee..ac3114bda5 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -11,6 +11,7 @@
**/
#include <math.h>
+#define RELAY_PRIVATE
#include "or.h"
#include "buffers.h"
#include "circuitbuild.h"
@@ -33,9 +34,6 @@
#include "routerlist.h"
#include "routerparse.h"
-static int relay_crypt(circuit_t *circ, cell_t *cell,
- cell_direction_t cell_direction,
- crypt_path_t **layer_hint, char *recognized);
static edge_connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell,
cell_direction_t cell_direction,
crypt_path_t *layer_hint);
@@ -297,7 +295,7 @@ circuit_receive_relay_cell(cell_t *cell, circuit_t *circ,
* Return -1 to indicate that we should mark the circuit for close,
* else return 0.
*/
-static int
+int
relay_crypt(circuit_t *circ, cell_t *cell, cell_direction_t cell_direction,
crypt_path_t **layer_hint, char *recognized)
{
diff --git a/src/or/relay.h b/src/or/relay.h
index 7fce8edcaf..1cd4008bb9 100644
--- a/src/or/relay.h
+++ b/src/or/relay.h
@@ -66,5 +66,10 @@ void circuit_clear_cell_queue(circuit_t *circ, or_connection_t *orconn);
void tor_gettimeofday_cache_clear(void);
+#ifdef RELAY_PRIVATE
+int relay_crypt(circuit_t *circ, cell_t *cell, cell_direction_t cell_direction,
+ crypt_path_t **layer_hint, char *recognized);
+#endif
+
#endif
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
index 301452b4ec..ffe1f942e7 100644
--- a/src/test/Makefile.am
+++ b/src/test/Makefile.am
@@ -1,6 +1,6 @@
TESTS = test
-noinst_PROGRAMS = test test-child
+noinst_PROGRAMS = test test-child bench
AM_CPPFLAGS = -DSHARE_DATADIR="\"$(datadir)\"" \
-DLOCALSTATEDIR="\"$(localstatedir)\"" \
@@ -23,6 +23,9 @@ test_SOURCES = \
test_util.c \
tinytest.c
+bench_SOURCES = \
+ bench.c
+
test_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
@TOR_LDFLAGS_libevent@
test_LDADD = ../or/libtor.a ../common/libor.a ../common/libor-crypto.a \
@@ -30,6 +33,13 @@ test_LDADD = ../or/libtor.a ../common/libor.a ../common/libor-crypto.a \
@TOR_ZLIB_LIBS@ -lm @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \
@TOR_LIB_WS32@ @TOR_LIB_GDI@
+bench_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
+ @TOR_LDFLAGS_libevent@
+bench_LDADD = ../or/libtor.a ../common/libor.a ../common/libor-crypto.a \
+ ../common/libor-event.a \
+ @TOR_ZLIB_LIBS@ -lm @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \
+ @TOR_LIB_WS32@ @TOR_LIB_GDI@
+
noinst_HEADERS = \
tinytest.h \
tinytest_macros.h \
diff --git a/src/test/bench.c b/src/test/bench.c
new file mode 100644
index 0000000000..ff2794e7c7
--- /dev/null
+++ b/src/test/bench.c
@@ -0,0 +1,327 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2011, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/* Ordinarily defined in tor_main.c; this bit is just here to provide one
+ * since we're not linking to tor_main.c */
+const char tor_git_revision[] = "";
+
+/**
+ * \file bench.c
+ * \brief Benchmarks for lower level Tor modules.
+ **/
+
+#include "orconfig.h"
+
+#define RELAY_PRIVATE
+
+#include "or.h"
+#include "relay.h"
+
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID)
+static uint64_t nanostart;
+static inline uint64_t
+timespec_to_nsec(const struct timespec *ts)
+{
+ return ((uint64_t)ts->tv_sec)*1000000000 + ts->tv_nsec;
+}
+
+static void
+reset_perftime(void)
+{
+ struct timespec ts;
+ int r;
+ r = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
+ tor_assert(r == 0);
+ nanostart = timespec_to_nsec(&ts);
+}
+
+static uint64_t
+perftime(void)
+{
+ struct timespec ts;
+ int r;
+ r = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
+ tor_assert(r == 0);
+ return timespec_to_nsec(&ts) - nanostart;
+}
+
+#else
+static struct timeval tv_start = { 0, 0 };
+static void
+reset_perftime(void)
+{
+ tor_gettimeofday(&tv_start);
+}
+static uint64_t
+perftime(void)
+{
+ struct timeval now, out;
+ tor_gettimeofday(&now);
+ timersub(&now, &tv_start, &out);
+ return ((uint64_t)out.tv_sec)*1000000000 + out.tv_usec*1000;
+}
+#endif
+
+#define NANOCOUNT(start,end,iters) \
+ ( ((double)((end)-(start))) / (iters) )
+
+/** Run AES performance benchmarks. */
+static void
+bench_aes(void)
+{
+ int len, i;
+ char *b1, *b2;
+ crypto_cipher_env_t *c;
+ uint64_t start, end;
+ const int bytes_per_iter = (1<<24);
+ reset_perftime();
+ c = crypto_new_cipher_env();
+ crypto_cipher_generate_key(c);
+ crypto_cipher_encrypt_init_cipher(c);
+ for (len = 1; len <= 8192; len *= 2) {
+ int iters = bytes_per_iter / len;
+ b1 = tor_malloc_zero(len);
+ b2 = tor_malloc_zero(len);
+ start = perftime();
+ for (i = 0; i < iters; ++i) {
+ crypto_cipher_encrypt(c, b1, b2, len);
+ }
+ end = perftime();
+ tor_free(b1);
+ tor_free(b2);
+ printf("%d bytes: %.2f nsec per byte\n", len,
+ NANOCOUNT(start, end, iters*len));
+ }
+ crypto_free_cipher_env(c);
+}
+
+static void
+bench_cell_aes(void)
+{
+ uint64_t start, end;
+ const int len = 509;
+ const int iters = (1<<16);
+ const int max_misalign = 15;
+ char *b = tor_malloc(len+max_misalign);
+ crypto_cipher_env_t *c;
+ int i, misalign;
+
+ c = crypto_new_cipher_env();
+ crypto_cipher_generate_key(c);
+ crypto_cipher_encrypt_init_cipher(c);
+
+ reset_perftime();
+ for (misalign = 0; misalign <= max_misalign; ++misalign) {
+ start = perftime();
+ for (i = 0; i < iters; ++i) {
+ crypto_cipher_crypt_inplace(c, b+misalign, len);
+ }
+ end = perftime();
+ printf("%d bytes, misaligned by %d: %.2f nsec per byte\n", len, misalign,
+ NANOCOUNT(start, end, iters*len));
+ }
+
+ crypto_free_cipher_env(c);
+ tor_free(b);
+}
+
+/** Run digestmap_t performance benchmarks. */
+static void
+bench_dmap(void)
+{
+ smartlist_t *sl = smartlist_create();
+ smartlist_t *sl2 = smartlist_create();
+ uint64_t start, end, pt2, pt3, pt4;
+ int iters = 8192;
+ const int elts = 4000;
+ const int fpostests = 100000;
+ char d[20];
+ int i,n=0, fp = 0;
+ digestmap_t *dm = digestmap_new();
+ digestset_t *ds = digestset_new(elts);
+
+ for (i = 0; i < elts; ++i) {
+ crypto_rand(d, 20);
+ smartlist_add(sl, tor_memdup(d, 20));
+ }
+ for (i = 0; i < elts; ++i) {
+ crypto_rand(d, 20);
+ smartlist_add(sl2, tor_memdup(d, 20));
+ }
+ printf("nbits=%d\n", ds->mask+1);
+
+ reset_perftime();
+
+ start = perftime();
+ for (i = 0; i < iters; ++i) {
+ SMARTLIST_FOREACH(sl, const char *, cp, digestmap_set(dm, cp, (void*)1));
+ }
+ pt2 = perftime();
+ printf("digestmap_set: %.2f ns per element\n",
+ NANOCOUNT(start, pt2, iters*elts));
+
+ for (i = 0; i < iters; ++i) {
+ SMARTLIST_FOREACH(sl, const char *, cp, digestmap_get(dm, cp));
+ SMARTLIST_FOREACH(sl2, const char *, cp, digestmap_get(dm, cp));
+ }
+ pt3 = perftime();
+ printf("digestmap_get: %.2f ns per element\n",
+ NANOCOUNT(pt2, pt3, iters*elts*2));
+
+ for (i = 0; i < iters; ++i) {
+ SMARTLIST_FOREACH(sl, const char *, cp, digestset_add(ds, cp));
+ }
+ pt4 = perftime();
+ printf("digestset_add: %.2f ns per element\n",
+ NANOCOUNT(pt3, pt4, iters*elts));
+
+ for (i = 0; i < iters; ++i) {
+ SMARTLIST_FOREACH(sl, const char *, cp, n += digestset_isin(ds, cp));
+ SMARTLIST_FOREACH(sl2, const char *, cp, n += digestset_isin(ds, cp));
+ }
+ end = perftime();
+ printf("digestset_isin: %.2f ns per element.\n",
+ NANOCOUNT(pt4, end, iters*elts*2));
+ /* We need to use this, or else the whole loop gets optimized out. */
+ printf("Hits == %d\n", n);
+
+ for (i = 0; i < fpostests; ++i) {
+ crypto_rand(d, 20);
+ if (digestset_isin(ds, d)) ++fp;
+ }
+ printf("False positive rate on digestset: %.2f%%\n",
+ (fp/(double)fpostests)*100);
+
+ digestmap_free(dm, NULL);
+ digestset_free(ds);
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ SMARTLIST_FOREACH(sl2, char *, cp, tor_free(cp));
+ smartlist_free(sl);
+ smartlist_free(sl2);
+}
+
+static void
+bench_cell_ops(void)
+{
+ const int iters = 1<<16;
+ int i;
+
+ /* benchmarks for cell ops at relay. */
+ or_circuit_t *or_circ = tor_malloc_zero(sizeof(or_circuit_t));
+ cell_t *cell = tor_malloc(sizeof(cell_t));
+ int outbound;
+ uint64_t start, end;
+
+ crypto_rand((char*)cell->payload, sizeof(cell->payload));
+
+ /* Mock-up or_circuit_t */
+ or_circ->_base.magic = OR_CIRCUIT_MAGIC;
+ or_circ->_base.purpose = CIRCUIT_PURPOSE_OR;
+
+ /* Initialize crypto */
+ or_circ->p_crypto = crypto_new_cipher_env();
+ crypto_cipher_generate_key(or_circ->p_crypto);
+ crypto_cipher_encrypt_init_cipher(or_circ->p_crypto);
+ or_circ->n_crypto = crypto_new_cipher_env();
+ crypto_cipher_generate_key(or_circ->n_crypto);
+ crypto_cipher_encrypt_init_cipher(or_circ->n_crypto);
+ or_circ->p_digest = crypto_new_digest_env();
+ or_circ->n_digest = crypto_new_digest_env();
+
+ reset_perftime();
+
+ for (outbound = 0; outbound <= 1; ++outbound) {
+ cell_direction_t d = outbound ? CELL_DIRECTION_OUT : CELL_DIRECTION_IN;
+ start = perftime();
+ for (i = 0; i < iters; ++i) {
+ char recognized = 0;
+ crypt_path_t *layer_hint = NULL;
+ relay_crypt(TO_CIRCUIT(or_circ), cell, d, &layer_hint, &recognized);
+ }
+ end = perftime();
+ printf("%sbound cells: %.2f ns per cell. (%.2f ns per byte of payload)\n",
+ outbound?"Out":" In",
+ NANOCOUNT(start,end,iters),
+ NANOCOUNT(start,end,iters*CELL_PAYLOAD_SIZE));
+ }
+
+ crypto_free_digest_env(or_circ->p_digest);
+ crypto_free_digest_env(or_circ->n_digest);
+ crypto_free_cipher_env(or_circ->p_crypto);
+ crypto_free_cipher_env(or_circ->n_crypto);
+ tor_free(or_circ);
+ tor_free(cell);
+}
+
+typedef void (*bench_fn)(void);
+
+typedef struct benchmark_t {
+ const char *name;
+ bench_fn fn;
+ int enabled;
+} benchmark_t;
+
+#define ENT(s) { #s , bench_##s, 0 }
+
+static struct benchmark_t benchmarks[] = {
+ ENT(dmap),
+ ENT(aes),
+ ENT(cell_aes),
+ ENT(cell_ops),
+ {NULL,NULL,0}
+};
+
+static benchmark_t *
+find_benchmark(const char *name)
+{
+ benchmark_t *b;
+ for (b = benchmarks; b->name; ++b) {
+ if (!strcmp(name, b->name)) {
+ return b;
+ }
+ }
+ return NULL;
+}
+
+/** Main entry point for benchmark code: parse the command line, and run
+ * some benchmarks. */
+int
+main(int argc, const char **argv)
+{
+ int i;
+ int list=0, n_enabled=0;
+ benchmark_t *b;
+
+ tor_threads_init();
+
+ for (i = 1; i < argc; ++i) {
+ if (!strcmp(argv[i], "--list")) {
+ list = 1;
+ } else {
+ benchmark_t *b = find_benchmark(argv[i]);
+ ++n_enabled;
+ if (b) {
+ b->enabled = 1;
+ } else {
+ printf("No such benchmark as %s\n", argv[i]);
+ }
+ }
+ }
+
+ reset_perftime();
+
+ crypto_seed_rng(1);
+
+ for (b = benchmarks; b->name; ++b) {
+ if (b->enabled || n_enabled == 0) {
+ printf("===== %s =====\n", b->name);
+ if (!list)
+ b->fn();
+ }
+ }
+
+ return 0;
+}
+
diff --git a/src/test/test.c b/src/test/test.c
index 185bf5a30c..d4edf1484b 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -1265,102 +1265,6 @@ test_policies(void)
}
}
-/** Run AES performance benchmarks. */
-static void
-test_bench_aes(void)
-{
- int len, i;
- char *b1, *b2;
- crypto_cipher_env_t *c;
- struct timeval start, end;
- const int iters = 100000;
- uint64_t nsec;
- c = crypto_new_cipher_env();
- crypto_cipher_generate_key(c);
- crypto_cipher_encrypt_init_cipher(c);
- for (len = 1; len <= 8192; len *= 2) {
- b1 = tor_malloc_zero(len);
- b2 = tor_malloc_zero(len);
- tor_gettimeofday(&start);
- for (i = 0; i < iters; ++i) {
- crypto_cipher_encrypt(c, b1, b2, len);
- }
- tor_gettimeofday(&end);
- tor_free(b1);
- tor_free(b2);
- nsec = (uint64_t) tv_udiff(&start,&end);
- nsec *= 1000;
- nsec /= (iters*len);
- printf("%d bytes: "U64_FORMAT" nsec per byte\n", len,
- U64_PRINTF_ARG(nsec));
- }
- crypto_free_cipher_env(c);
-}
-
-/** Run digestmap_t performance benchmarks. */
-static void
-test_bench_dmap(void)
-{
- smartlist_t *sl = smartlist_create();
- smartlist_t *sl2 = smartlist_create();
- struct timeval start, end, pt2, pt3, pt4;
- const int iters = 10000;
- const int elts = 4000;
- const int fpostests = 1000000;
- char d[20];
- int i,n=0, fp = 0;
- digestmap_t *dm = digestmap_new();
- digestset_t *ds = digestset_new(elts);
-
- for (i = 0; i < elts; ++i) {
- crypto_rand(d, 20);
- smartlist_add(sl, tor_memdup(d, 20));
- }
- for (i = 0; i < elts; ++i) {
- crypto_rand(d, 20);
- smartlist_add(sl2, tor_memdup(d, 20));
- }
- printf("nbits=%d\n", ds->mask+1);
-
- tor_gettimeofday(&start);
- for (i = 0; i < iters; ++i) {
- SMARTLIST_FOREACH(sl, const char *, cp, digestmap_set(dm, cp, (void*)1));
- }
- tor_gettimeofday(&pt2);
- for (i = 0; i < iters; ++i) {
- SMARTLIST_FOREACH(sl, const char *, cp, digestmap_get(dm, cp));
- SMARTLIST_FOREACH(sl2, const char *, cp, digestmap_get(dm, cp));
- }
- tor_gettimeofday(&pt3);
- for (i = 0; i < iters; ++i) {
- SMARTLIST_FOREACH(sl, const char *, cp, digestset_add(ds, cp));
- }
- tor_gettimeofday(&pt4);
- for (i = 0; i < iters; ++i) {
- SMARTLIST_FOREACH(sl, const char *, cp, n += digestset_isin(ds, cp));
- SMARTLIST_FOREACH(sl2, const char *, cp, n += digestset_isin(ds, cp));
- }
- tor_gettimeofday(&end);
-
- for (i = 0; i < fpostests; ++i) {
- crypto_rand(d, 20);
- if (digestset_isin(ds, d)) ++fp;
- }
-
- printf("%ld\n",(unsigned long)tv_udiff(&start, &pt2));
- printf("%ld\n",(unsigned long)tv_udiff(&pt2, &pt3));
- printf("%ld\n",(unsigned long)tv_udiff(&pt3, &pt4));
- printf("%ld\n",(unsigned long)tv_udiff(&pt4, &end));
- printf("-- %d\n", n);
- printf("++ %f\n", fp/(double)fpostests);
- digestmap_free(dm, NULL);
- digestset_free(ds);
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- SMARTLIST_FOREACH(sl2, char *, cp, tor_free(cp));
- smartlist_free(sl);
- smartlist_free(sl2);
-}
-
/** Test encoding and parsing of rendezvous service descriptors. */
static void
test_rend_fns(void)
@@ -1913,8 +1817,6 @@ static struct testcase_t test_array[] = {
ENT(geoip),
FORK(stats),
- DISABLED(bench_aes),
- DISABLED(bench_dmap),
END_OF_TESTCASES
};
diff --git a/src/test/test_addr.c b/src/test/test_addr.c
index b14ddb3d70..9d8e1fe8c5 100644
--- a/src/test/test_addr.c
+++ b/src/test/test_addr.c
@@ -186,7 +186,6 @@ test_addr_ip6_helpers(void)
struct sockaddr_in *sin;
struct sockaddr_in6 *sin6;
- // struct in_addr b1, b2;
/* Test tor_inet_ntop and tor_inet_pton: IPv6 */
{
const char *ip = "2001::1234";
@@ -302,12 +301,23 @@ test_addr_ip6_helpers(void)
test_ntop6_reduces("1000:0001:0000:0007:0000:0000:0000:0000",
"1000:1:0:7::");
+ /* Bad af param */
+ test_eq(tor_inet_pton(AF_UNSPEC, 0, 0), -1);
+
/* === Test pton: invalid in6. */
test_pton6_bad("foobar.");
+ test_pton6_bad("-1::");
+ test_pton6_bad("00001::");
+ test_pton6_bad("10000::");
+ test_pton6_bad("::10000");
test_pton6_bad("55555::");
test_pton6_bad("9:-60::");
+ test_pton6_bad("9:+60::");
+ test_pton6_bad("9|60::");
+ test_pton6_bad("0x60::");
+ test_pton6_bad("::0x60");
+ test_pton6_bad("9:0x60::");
test_pton6_bad("1:2:33333:4:0002:3::");
- //test_pton6_bad("1:2:3333:4:00002:3::");// BAD, but glibc doesn't say so.
test_pton6_bad("1:2:3333:4:fish:3::");
test_pton6_bad("1:2:3:4:5:6:7:8:9");
test_pton6_bad("1:2:3:4:5:6:7");
@@ -315,8 +325,14 @@ test_addr_ip6_helpers(void)
test_pton6_bad("1:2:3:4:5:6:1.2.3");
test_pton6_bad("::1.2.3");
test_pton6_bad("::1.2.3.4.5");
+ test_pton6_bad("::ffff:0xff.0.0.0");
+ test_pton6_bad("::ffff:ff.0.0.0");
+ test_pton6_bad("::ffff:256.0.0.0");
+ test_pton6_bad("::ffff:-1.0.0.0");
test_pton6_bad("99");
test_pton6_bad("");
+ test_pton6_bad(".");
+ test_pton6_bad(":");
test_pton6_bad("1::2::3:4");
test_pton6_bad("a:::b:c");
test_pton6_bad(":::a:b:c");
@@ -325,6 +341,9 @@ test_addr_ip6_helpers(void)
/* test internal checking */
test_external_ip("fbff:ffff::2:7", 0);
test_internal_ip("fc01::2:7", 0);
+ test_internal_ip("fc01::02:7", 0);
+ test_internal_ip("fc01::002:7", 0);
+ test_internal_ip("fc01::0002:7", 0);
test_internal_ip("fdff:ffff::f:f", 0);
test_external_ip("fe00::3:f", 0);
diff --git a/src/win32/orconfig.h b/src/win32/orconfig.h
index 7460d4fb94..34d7c75b01 100644
--- a/src/win32/orconfig.h
+++ b/src/win32/orconfig.h
@@ -234,7 +234,7 @@
#define USING_TWOS_COMPLEMENT
/* Version number of package */
-#define VERSION "0.2.3.7-alpha"
+#define VERSION "0.2.3.8-alpha-dev"