summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog667
-rw-r--r--ReleaseNotes580
-rw-r--r--changes/181054
-rw-r--r--changes/bug189186
-rw-r--r--changes/bug208874
-rw-r--r--changes/bug239094
-rw-r--r--changes/bug244844
-rw-r--r--changes/bug247697
-rw-r--r--changes/bug249143
-rw-r--r--changes/bug249787
-rw-r--r--changes/bug251204
-rw-r--r--changes/bug252234
-rw-r--r--changes/bug254154
-rw-r--r--changes/feature251504
-rw-r--r--changes/ticket238736
-rw-r--r--changes/ticket243436
-rw-r--r--changes/ticket247146
-rw-r--r--changes/ticket250714
-rw-r--r--changes/ticket250815
-rw-r--r--changes/ticket251626
-rw-r--r--changes/ticket252024
-rw-r--r--changes/ticket252613
-rw-r--r--changes/ticket252687
-rw-r--r--changes/ticket253234
-rw-r--r--changes/ticket41873
-rw-r--r--changes/ticket62364
-rw-r--r--configure.ac37
-rw-r--r--contrib/win32build/tor-mingw.nsi.in2
-rw-r--r--doc/HACKING/CodingStandardsRust.md22
-rw-r--r--doc/tor.1.txt33
-rw-r--r--src/common/address.c18
-rw-r--r--src/common/buffers.h1
-rw-r--r--src/common/compat.c19
-rw-r--r--src/common/compat.h2
-rw-r--r--src/common/compat_winthreads.c1
-rw-r--r--src/common/compress.c10
-rw-r--r--src/common/compress.h1
-rw-r--r--src/common/compress_zstd.c112
-rw-r--r--src/common/compress_zstd.h7
-rw-r--r--src/common/crypto.c24
-rw-r--r--src/common/crypto.h11
-rw-r--r--src/common/util.h18
-rw-r--r--src/or/channel.c15
-rw-r--r--src/or/channel.h3
-rw-r--r--src/or/channeltls.c5
-rw-r--r--src/or/circuitbuild.c10
-rw-r--r--src/or/circuitlist.c5
-rw-r--r--src/or/circuitmux.c678
-rw-r--r--src/or/circuitmux_ewma.c115
-rw-r--r--src/or/circuitmux_ewma.h7
-rw-r--r--src/or/circuituse.c5
-rw-r--r--src/or/config.c28
-rw-r--r--src/or/connection.c25
-rw-r--r--src/or/connection_edge.c6
-rw-r--r--src/or/control.c3
-rw-r--r--src/or/directory.c2
-rw-r--r--src/or/dirserv.c5
-rw-r--r--src/or/hibernate.c2
-rw-r--r--src/or/hs_client.c6
-rw-r--r--src/or/hs_common.c1
-rw-r--r--src/or/hs_intropoint.c1
-rw-r--r--src/or/hs_service.c1
-rw-r--r--src/or/keypin.c11
-rw-r--r--src/or/main.c107
-rw-r--r--src/or/main.h2
-rw-r--r--src/or/networkstatus.c23
-rw-r--r--src/or/nodelist.c26
-rw-r--r--src/or/nodelist.h4
-rw-r--r--src/or/onion.c14
-rw-r--r--src/or/or.h25
-rw-r--r--src/or/relay.c43
-rw-r--r--src/or/relay.h1
-rw-r--r--src/or/rendclient.c4
-rw-r--r--src/or/rephist.c1
-rw-r--r--src/or/router.c129
-rw-r--r--src/or/router.h2
-rw-r--r--src/or/status.c1
-rw-r--r--src/or/transports.c182
-rw-r--r--src/rust/protover/ffi.rs34
-rw-r--r--src/rust/protover/lib.rs1
-rw-r--r--src/rust/protover/protover.rs95
-rw-r--r--src/rust/tor_util/strings.rs154
-rw-r--r--src/test/test_channel.c5
-rw-r--r--src/test/test_circuitlist.c1
-rw-r--r--src/test/test_circuitmux.c2
-rw-r--r--src/test/test_config.c4
-rw-r--r--src/test/test_dir_handle_get.c1
-rw-r--r--src/test/test_helpers.c1
-rw-r--r--src/test/test_hs_intropoint.c1
-rw-r--r--src/test/test_util.c43
-rw-r--r--src/test/testing_common.c2
-rw-r--r--src/tools/tor-gencert.c1
-rw-r--r--src/win32/orconfig.h2
93 files changed, 2206 insertions, 1317 deletions
diff --git a/ChangeLog b/ChangeLog
index e572f3d12a..bd925bf4b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,670 @@
+
+Changes in version 0.3.3.3-alpha - 2018-03-03
+ Tor 0.3.3.3-alpha is the third alpha release for the 0.3.3.x series.
+ It includes an important security fix for a remote crash attack
+ against directory authorities tracked as TROVE-2018-001.
+
+ Additionally, with this release, we are upgrading the severity of a
+ bug fixed in 0.3.3.2-alpha. Bug 24700, which was fixed in
+ 0.3.3.2-alpha, can be remotely triggered in order to crash relays with
+ a use-after-free pattern. As such, we are now tracking that bug as
+ TROVE-2018-002 and CVE-2018-0491. This bug affected versions
+ 0.3.2.1-alpha through 0.3.2.9, as well as 0.3.3.1-alpha.
+
+ This release also fixes several minor bugs and annoyances from
+ earlier releases.
+
+ Relays running 0.3.2.x should upgrade to one of the versions released
+ today, for the fix to TROVE-2018-002. Directory authorities should
+ also upgrade. (Relays on earlier versions might want to update too for
+ the DoS mitigations.)
+
+ o Major bugfixes (denial-of-service, directory authority):
+ - Fix a protocol-list handling bug that could be used to remotely crash
+ directory authorities with a null-pointer exception. Fixes bug 25074;
+ bugfix on 0.2.9.4-alpha. Also tracked as TROVE-2018-001 and
+ CVE-2018-0490.
+
+ o Minor features (compatibility, OpenSSL):
+ - Tor will now support TLS1.3 once OpenSSL 1.1.1 is released.
+ Previous versions of Tor would not have worked with OpenSSL 1.1.1,
+ since they neither disabled TLS 1.3 nor enabled any of the
+ ciphersuites it requires. Now we enable the TLS 1.3 ciphersuites.
+ Closes ticket 24978.
+
+ o Minor features (logging):
+ - Clarify the log messages produced when getrandom() or a related
+ entropy-generation mechanism gives an error. Closes ticket 25120.
+
+ o Minor features (testing):
+ - Add a "make test-rust" target to run the rust tests only. Closes
+ ticket 25071.
+
+ o Minor bugfixes (denial-of-service):
+ - Fix a possible crash on malformed consensus. If a consensus had
+ contained an unparseable protocol line, it could have made clients
+ and relays crash with a null-pointer exception. To exploit this
+ issue, however, an attacker would need to be able to subvert the
+ directory authority system. Fixes bug 25251; bugfix on
+ 0.2.9.4-alpha. Also tracked as TROVE-2018-004.
+
+ o Minor bugfixes (DoS mitigation):
+ - Add extra safety checks when refilling the circuit creation bucket
+ to ensure we never set a value above the allowed maximum burst.
+ Fixes bug 25202; bugfix on 0.3.3.2-alpha.
+ - When a new consensus arrives, don't update our DoS-mitigation
+ parameters if we aren't a public relay. Fixes bug 25223; bugfix
+ on 0.3.3.2-alpha.
+
+ o Minor bugfixes (man page, SocksPort):
+ - Remove dead code from the old "SocksSocket" option, and rename
+ SocksSocketsGroupWritable to UnixSocksGroupWritable. The old option
+ still works, but is deprecated. Fixes bug 24343; bugfix on 0.2.6.3.
+
+ o Minor bugfixes (performance):
+ - Reduce the number of circuits that will be opened at once during
+ the circuit build timeout phase. This is done by increasing the
+ idle timeout to 3 minutes, and lowering the maximum number of
+ concurrent learning circuits to 10. Fixes bug 24769; bugfix
+ on 0.3.1.1-alpha.
+
+ o Minor bugfixes (spec conformance):
+ - Forbid "-0" as a protocol version. Fixes part of bug 25249; bugfix on
+ 0.2.9.4-alpha.
+ - Forbid UINT32_MAX as a protocol version. Fixes part of bug 25249;
+ bugfix on 0.2.9.4-alpha.
+
+ o Minor bugfixes (spec conformance, rust):
+ - Resolve a denial-of-service issue caused by an infinite loop in
+ the rust protover code. Fixes bug 25250, bugfix on 0.3.3.1-alpha.
+ Also tracked as TROVE-2018-003.
+
+ o Code simplification and refactoring:
+ - Update the "rust dependencies" submodule to be a project-level
+ repository, rather than a user repository. Closes ticket 25323.
+
+
+Changes in version 0.3.2.10 - 2018-03-03
+ Tor 0.3.2.10 is the second stable release in the 0.3.2 series. It
+ backports a number of bugfixes, including important fixes for security
+ issues.
+
+ It includes an important security fix for a remote crash attack
+ against directory authorities, tracked as TROVE-2018-001.
+
+ Additionally, it backports a fix for a bug whose severity we have
+ upgraded: Bug 24700, which was fixed in 0.3.3.2-alpha, can be remotely
+ triggered in order to crash relays with a use-after-free pattern. As
+ such, we are now tracking that bug as TROVE-2018-002 and
+ CVE-2018-0491, and backporting it to earlier releases. This bug
+ affected versions 0.3.2.1-alpha through 0.3.2.9, as well as version
+ 0.3.3.1-alpha.
+
+ This release also backports our new system for improved resistance to
+ denial-of-service attacks against relays.
+
+ This release also fixes several minor bugs and annoyances from
+ earlier releases.
+
+ Relays running 0.3.2.x SHOULD upgrade to one of the versions released
+ today, for the fix to TROVE-2018-002. Directory authorities should
+ also upgrade. (Relays on earlier versions might want to update too for
+ the DoS mitigations.)
+
+ o Major bugfixes (denial-of-service, directory authority, backport from 0.3.3.3-alpha):
+ - Fix a protocol-list handling bug that could be used to remotely crash
+ directory authorities with a null-pointer exception. Fixes bug 25074;
+ bugfix on 0.2.9.4-alpha. Also tracked as TROVE-2018-001 and
+ CVE-2018-0490.
+
+ o Major bugfixes (scheduler, KIST, denial-of-service, backport from 0.3.3.2-alpha):
+ - Avoid adding the same channel twice in the KIST scheduler pending
+ list, which could lead to remote denial-of-service use-after-free
+ attacks against relays. Fixes bug 24700; bugfix on 0.3.2.1-alpha.
+
+ o Major features (denial-of-service mitigation, backport from 0.3.3.2-alpha):
+ - Give relays some defenses against the recent network overload. We
+ start with three defenses (default parameters in parentheses).
+ First: if a single client address makes too many concurrent
+ connections (>100), hang up on further connections. Second: if a
+ single client address makes circuits too quickly (more than 3 per
+ second, with an allowed burst of 90) while also having too many
+ connections open (3), refuse new create cells for the next while
+ (1-2 hours). Third: if a client asks to establish a rendezvous
+ point to you directly, ignore the request. These defenses can be
+ manually controlled by new torrc options, but relays will also
+ take guidance from consensus parameters, so there's no need to
+ configure anything manually. Implements ticket 24902.
+
+ o Major bugfixes (onion services, retry behavior, backport from 0.3.3.1-alpha):
+ - Fix an "off by 2" error in counting rendezvous failures on the
+ onion service side. While we thought we would stop the rendezvous
+ attempt after one failed circuit, we were actually making three
+ circuit attempts before giving up. Now switch to a default of 2,
+ and allow the consensus parameter "hs_service_max_rdv_failures" to
+ override. Fixes bug 24895; bugfix on 0.0.6.
+ - New-style (v3) onion services now obey the "max rendezvous circuit
+ attempts" logic. Previously they would make as many rendezvous
+ circuit attempts as they could fit in the MAX_REND_TIMEOUT second
+ window before giving up. Fixes bug 24894; bugfix on 0.3.2.1-alpha.
+
+ o Major bugfixes (protocol versions, backport from 0.3.3.2-alpha):
+ - Add Link protocol version 5 to the supported protocols list. Fixes
+ bug 25070; bugfix on 0.3.1.1-alpha.
+
+ o Major bugfixes (relay, backport from 0.3.3.1-alpha):
+ - Fix a set of false positives where relays would consider
+ connections to other relays as being client-only connections (and
+ thus e.g. deserving different link padding schemes) if those
+ relays fell out of the consensus briefly. Now we look only at the
+ initial handshake and whether the connection authenticated as a
+ relay. Fixes bug 24898; bugfix on 0.3.1.1-alpha.
+
+ o Major bugfixes (scheduler, consensus, backport from 0.3.3.2-alpha):
+ - The scheduler subsystem was failing to promptly notice changes in
+ consensus parameters, making it harder to switch schedulers
+ network-wide. Fixes bug 24975; bugfix on 0.3.2.1-alpha.
+
+ o Minor features (denial-of-service avoidance, backport from 0.3.3.2-alpha):
+ - Make our OOM handler aware of the geoip client history cache so it
+ doesn't fill up the memory. This check is important for IPv6 and
+ our DoS mitigation subsystem. Closes ticket 25122.
+
+ o Minor features (compatibility, OpenSSL, backport from 0.3.3.3-alpha):
+ - Tor will now support TLS1.3 once OpenSSL 1.1.1 is released.
+ Previous versions of Tor would not have worked with OpenSSL 1.1.1,
+ since they neither disabled TLS 1.3 nor enabled any of the
+ ciphersuites it requires. Now we enable the TLS 1.3 ciphersuites.
+ Closes ticket 24978.
+
+ o Minor features (geoip):
+ - Update geoip and geoip6 to the February 7 2018 Maxmind GeoLite2
+ Country database.
+
+ o Minor features (logging, diagnostic, backport from 0.3.3.2-alpha):
+ - When logging a failure to check a hidden service's certificate,
+ also log what the problem with the certificate was. Diagnostic
+ for ticket 24972.
+
+ o Minor bugfix (channel connection, backport from 0.3.3.2-alpha):
+ - Use the actual observed address of an incoming relay connection,
+ not the canonical address of the relay from its descriptor, when
+ making decisions about how to handle the incoming connection.
+ Fixes bug 24952; bugfix on 0.2.4.11-alpha. Patch by "ffmancera".
+
+ o Minor bugfixes (denial-of-service, backport from 0.3.3.3-alpha):
+ - Fix a possible crash on malformed consensus. If a consensus had
+ contained an unparseable protocol line, it could have made clients
+ and relays crash with a null-pointer exception. To exploit this
+ issue, however, an attacker would need to be able to subvert the
+ directory authority system. Fixes bug 25251; bugfix on
+ 0.2.9.4-alpha. Also tracked as TROVE-2018-004.
+
+ o Minor bugfix (directory authority, backport from 0.3.3.2-alpha):
+ - Directory authorities, when refusing a descriptor from a rejected
+ relay, now explicitly tell the relay (in its logs) to set a valid
+ ContactInfo address and contact the bad-relays@ mailing list.
+ Fixes bug 25170; bugfix on 0.2.9.1.
+
+ o Minor bugfixes (build, rust, backport from 0.3.3.1-alpha):
+ - When building with Rust on OSX, link against libresolv, to work
+ around the issue at https://github.com/rust-lang/rust/issues/46797.
+ Fixes bug 24652; bugfix on 0.3.1.1-alpha.
+
+ o Minor bugfixes (onion services, backport from 0.3.3.2-alpha):
+ - Remove a BUG() statement when a client fetches an onion descriptor
+ that has a lower revision counter than the one in its cache. This
+ can happen in normal circumstances due to HSDir desync. Fixes bug
+ 24976; bugfix on 0.3.2.1-alpha.
+
+ o Minor bugfixes (logging, backport from 0.3.3.2-alpha):
+ - Don't treat inability to store a cached consensus object as a bug:
+ it can happen normally when we are out of disk space. Fixes bug
+ 24859; bugfix on 0.3.1.1-alpha.
+
+ o Minor bugfixes (performance, fragile-hardening, backport from 0.3.3.1-alpha):
+ - Improve the performance of our consensus-diff application code
+ when Tor is built with the --enable-fragile-hardening option set.
+ Fixes bug 24826; bugfix on 0.3.1.1-alpha.
+
+ o Minor bugfixes (OSX, backport from 0.3.3.1-alpha):
+ - Don't exit the Tor process if setrlimit() fails to change the file
+ limit (which can happen sometimes on some versions of OSX). Fixes
+ bug 21074; bugfix on 0.0.9pre5.
+
+ o Minor bugfixes (spec conformance, backport from 0.3.3.3-alpha):
+ - Forbid "-0" as a protocol version. Fixes part of bug 25249; bugfix on
+ 0.2.9.4-alpha.
+ - Forbid UINT32_MAX as a protocol version. Fixes part of bug 25249;
+ bugfix on 0.2.9.4-alpha.
+
+ o Minor bugfixes (testing, backport from 0.3.3.1-alpha):
+ - Fix a memory leak in the scheduler/loop_kist unit test. Fixes bug
+ 25005; bugfix on 0.3.2.7-rc.
+
+ o Minor bugfixes (v3 onion services, backport from 0.3.3.2-alpha):
+ - Look at the "HSRend" protocol version, not the "HSDir" protocol
+ version, when deciding whether a consensus entry can support the
+ v3 onion service protocol as a rendezvous point. Fixes bug 25105;
+ bugfix on 0.3.2.1-alpha.
+
+ o Code simplification and refactoring (backport from 0.3.3.3-alpha):
+ - Update the "rust dependencies" submodule to be a project-level
+ repository, rather than a user repository. Closes ticket 25323.
+
+ o Documentation (backport from 0.3.3.1-alpha)
+ - Document that operators who run more than one relay or bridge are
+ expected to set MyFamily and ContactInfo correctly. Closes
+ ticket 24526.
+
+
+Changes in version 0.3.1.10 - 2018-03-03
+ Tor 0.3.1.10 backports a number of bugfixes, including important fixes for
+ security issues.
+
+ It includes an important security fix for a remote crash attack
+ against directory authorities, tracked as TROVE-2018-001.
+
+ This release also backports our new system for improved resistance to
+ denial-of-service attacks against relays.
+
+ This release also fixes several minor bugs and annoyances from
+ earlier releases.
+
+ All directory authorities should upgrade to one of the versions
+ released today. Relays running 0.3.1.x may wish to update to one of
+ the versions released today, for the DoS mitigations.
+
+ Please note: according to our release calendar, Tor 0.3.1 will no
+ longer be supported after 1 July 2018. If you will be running Tor
+ after that date, you should make sure to plan to upgrade to the latest
+ stable version, or downgrade to 0.2.9 (which will receive long-term
+ support).
+
+ o Major bugfixes (denial-of-service, directory authority, backport from 0.3.3.3-alpha):
+ - Fix a protocol-list handling bug that could be used to remotely crash
+ directory authorities with a null-pointer exception. Fixes bug 25074;
+ bugfix on 0.2.9.4-alpha. Also tracked as TROVE-2018-001 and
+ CVE-2018-0490.
+
+ o Major features (denial-of-service mitigation, backport from 0.3.3.2-alpha):
+ - Give relays some defenses against the recent network overload. We
+ start with three defenses (default parameters in parentheses).
+ First: if a single client address makes too many concurrent
+ connections (>100), hang up on further connections. Second: if a
+ single client address makes circuits too quickly (more than 3 per
+ second, with an allowed burst of 90) while also having too many
+ connections open (3), refuse new create cells for the next while
+ (1-2 hours). Third: if a client asks to establish a rendezvous
+ point to you directly, ignore the request. These defenses can be
+ manually controlled by new torrc options, but relays will also
+ take guidance from consensus parameters, so there's no need to
+ configure anything manually. Implements ticket 24902.
+
+ o Minor features (linux seccomp2 sandbox, backport from 0.3.2.5-alpha):
+ - Update the sandbox rules so that they should now work correctly
+ with Glibc 2.26. Closes ticket 24315.
+
+ o Major bugfixes (onion services, retry behavior, backport from 0.3.3.1-alpha):
+ - Fix an "off by 2" error in counting rendezvous failures on the
+ onion service side. While we thought we would stop the rendezvous
+ attempt after one failed circuit, we were actually making three
+ circuit attempts before giving up. Now switch to a default of 2,
+ and allow the consensus parameter "hs_service_max_rdv_failures" to
+ override. Fixes bug 24895; bugfix on 0.0.6.
+
+ o Major bugfixes (protocol versions, backport from 0.3.3.2-alpha):
+ - Add Link protocol version 5 to the supported protocols list. Fixes
+ bug 25070; bugfix on 0.3.1.1-alpha.
+
+ o Major bugfixes (relay, backport from 0.3.3.1-alpha):
+ - Fix a set of false positives where relays would consider
+ connections to other relays as being client-only connections (and
+ thus e.g. deserving different link padding schemes) if those
+ relays fell out of the consensus briefly. Now we look only at the
+ initial handshake and whether the connection authenticated as a
+ relay. Fixes bug 24898; bugfix on 0.3.1.1-alpha.
+
+ o Minor features (denial-of-service avoidance, backport from 0.3.3.2-alpha):
+ - Make our OOM handler aware of the geoip client history cache so it
+ doesn't fill up the memory. This check is important for IPv6 and
+ our DoS mitigation subsystem. Closes ticket 25122.
+
+ o Minor feature (relay statistics, backport from 0.3.2.6-alpha):
+ - Change relay bandwidth reporting stats interval from 4 hours to 24
+ hours in order to reduce the efficiency of guard discovery
+ attacks. Fixes ticket 23856.
+
+ o Minor features (compatibility, OpenSSL, backport from 0.3.3.3-alpha):
+ - Tor will now support TLS1.3 once OpenSSL 1.1.1 is released.
+ Previous versions of Tor would not have worked with OpenSSL 1.1.1,
+ since they neither disabled TLS 1.3 nor enabled any of the
+ ciphersuites it requires. Now we enable the TLS 1.3 ciphersuites.
+ Closes ticket 24978.
+
+ o Minor features (fallback directory mirrors, backport from 0.3.2.9):
+ - The fallback directory list has been re-generated based on the
+ current status of the network. Tor uses fallback directories to
+ bootstrap when it doesn't yet have up-to-date directory
+ information. Closes ticket 24801.
+ - Make the default DirAuthorityFallbackRate 0.1, so that clients
+ prefer to bootstrap from fallback directory mirrors. This is a
+ follow-up to 24679, which removed weights from the default
+ fallbacks. Implements ticket 24681.
+
+ o Minor features (geoip):
+ - Update geoip and geoip6 to the February 7 2018 Maxmind GeoLite2
+ Country database.
+
+ o Minor bugfix (channel connection, backport from 0.3.3.2-alpha):
+ - Use the actual observed address of an incoming relay connection,
+ not the canonical address of the relay from its descriptor, when
+ making decisions about how to handle the incoming connection.
+ Fixes bug 24952; bugfix on 0.2.4.11-alpha. Patch by "ffmancera".
+
+ o Minor bugfix (directory authority, backport from 0.3.3.2-alpha):
+ - Directory authorities, when refusing a descriptor from a rejected
+ relay, now explicitly tell the relay (in its logs) to set a valid
+ ContactInfo address and contact the bad-relays@ mailing list.
+ Fixes bug 25170; bugfix on 0.2.9.1.
+
+ o Minor bugfixes (address selection, backport from 0.3.2.9):
+ - When the fascist_firewall_choose_address_ functions don't find a
+ reachable address, set the returned address to the null address
+ and port. This is a precautionary measure, because some callers do
+ not check the return value. Fixes bug 24736; bugfix
+ on 0.2.8.2-alpha.
+
+ o Major bugfixes (bootstrapping, backport from 0.3.2.5-alpha):
+ - Fetch descriptors aggressively whenever we lack enough to build
+ circuits, regardless of how many descriptors we are missing.
+ Previously, we would delay launching the fetch when we had fewer
+ than 15 missing descriptors, even if some of those descriptors
+ were blocking circuits from building. Fixes bug 23985; bugfix on
+ 0.1.1.11-alpha. The effects of this bug became worse in
+ 0.3.0.3-alpha, when we began treating missing descriptors from our
+ primary guards as a reason to delay circuits.
+ - Don't try fetching microdescriptors from relays that have failed
+ to deliver them in the past. Fixes bug 23817; bugfix
+ on 0.3.0.1-alpha.
+
+ o Minor bugfixes (compilation, backport from 0.3.2.7-rc):
+ - Fix a signed/unsigned comparison warning introduced by our fix to
+ TROVE-2017-009. Fixes bug 24480; bugfix on 0.2.5.16.
+
+ o Minor bugfixes (control port, linux seccomp2 sandbox, backport from 0.3.2.5-alpha):
+ - Avoid a crash when attempting to use the seccomp2 sandbox together
+ with the OwningControllerProcess feature. Fixes bug 24198; bugfix
+ on 0.2.5.1-alpha.
+
+ o Minor bugfixes (denial-of-service, backport from 0.3.3.3-alpha):
+ - Fix a possible crash on malformed consensus. If a consensus had
+ contained an unparseable protocol line, it could have made clients
+ and relays crash with a null-pointer exception. To exploit this
+ issue, however, an attacker would need to be able to subvert the
+ directory authority system. Fixes bug 25251; bugfix on
+ 0.2.9.4-alpha. Also tracked as TROVE-2018-004.
+
+ o Minor bugfixes (directory cache, backport from 0.3.2.5-alpha):
+ - Recover better from empty or corrupt files in the consensus cache
+ directory. Fixes bug 24099; bugfix on 0.3.1.1-alpha.
+ - When a consensus diff calculation is only partially successful,
+ only record the successful parts as having succeeded. Partial
+ success can happen if (for example) one compression method fails
+ but the others succeed. Previously we misrecorded all the
+ calculations as having succeeded, which would later cause a
+ nonfatal assertion failure. Fixes bug 24086; bugfix
+ on 0.3.1.1-alpha.
+
+ o Minor bugfixes (entry guards, backport from 0.3.2.3-alpha):
+ - Tor now updates its guard state when it reads a consensus
+ regardless of whether it's missing descriptors. That makes tor use
+ its primary guards to fetch descriptors in some edge cases where
+ it would previously have used fallback directories. Fixes bug
+ 23862; bugfix on 0.3.0.1-alpha.
+
+ o Minor bugfixes (logging, backport from 0.3.3.2-alpha):
+ - Don't treat inability to store a cached consensus object as a bug:
+ it can happen normally when we are out of disk space. Fixes bug
+ 24859; bugfix on 0.3.1.1-alpha.
+
+ o Minor bugfixes (memory usage, backport from 0.3.2.8-rc):
+ - When queuing DESTROY cells on a channel, only queue the circuit-id
+ and reason fields: not the entire 514-byte cell. This fix should
+ help mitigate any bugs or attacks that fill up these queues, and
+ free more RAM for other uses. Fixes bug 24666; bugfix
+ on 0.2.5.1-alpha.
+
+ o Minor bugfixes (network layer, backport from 0.3.2.5-alpha):
+ - When closing a connection via close_connection_immediately(), we
+ mark it as "not blocked on bandwidth", to prevent later calls from
+ trying to unblock it, and give it permission to read. This fixes a
+ backtrace warning that can happen on relays under various
+ circumstances. Fixes bug 24167; bugfix on 0.1.0.1-rc.
+
+ o Minor bugfixes (path selection, backport from 0.3.2.4-alpha):
+ - When selecting relays by bandwidth, avoid a rounding error that
+ could sometimes cause load to be imbalanced incorrectly.
+ Previously, we would always round upwards; now, we round towards
+ the nearest integer. This had the biggest effect when a relay's
+ weight adjustments should have given it weight 0, but it got
+ weight 1 instead. Fixes bug 23318; bugfix on 0.2.4.3-alpha.
+ - When calculating the fraction of nodes that have descriptors, and
+ all nodes in the network have zero bandwidths, count the number of
+ nodes instead. Fixes bug 23318; bugfix on 0.2.4.10-alpha.
+ - Actually log the total bandwidth in compute_weighted_bandwidths().
+ Fixes bug 24170; bugfix on 0.2.4.3-alpha.
+
+ o Minor bugfixes (performance, fragile-hardening, backport from 0.3.3.1-alpha):
+ - Improve the performance of our consensus-diff application code
+ when Tor is built with the --enable-fragile-hardening option set.
+ Fixes bug 24826; bugfix on 0.3.1.1-alpha.
+
+ o Minor bugfixes (OSX, backport from 0.3.3.1-alpha):
+ - Don't exit the Tor process if setrlimit() fails to change the file
+ limit (which can happen sometimes on some versions of OSX). Fixes
+ bug 21074; bugfix on 0.0.9pre5.
+
+ o Minor bugfixes (portability, msvc, backport from 0.3.2.9):
+ - Fix a bug in the bit-counting parts of our timing-wheel code on
+ MSVC. (Note that MSVC is still not a supported build platform, due
+ to cyptographic timing channel risks.) Fixes bug 24633; bugfix
+ on 0.2.9.1-alpha.
+
+ o Minor bugfixes (relay, partial backport):
+ - Make the internal channel_is_client() function look at what sort
+ of connection handshake the other side used, rather than whether
+ the other side ever sent a create_fast cell to us. Backports part
+ of the fixes from bugs 22805 and 24898.
+
+ o Minor bugfixes (spec conformance, backport from 0.3.3.3-alpha):
+ - Forbid "-0" as a protocol version. Fixes part of bug 25249; bugfix on
+ 0.2.9.4-alpha.
+ - Forbid UINT32_MAX as a protocol version. Fixes part of bug 25249;
+ bugfix on 0.2.9.4-alpha.
+
+ o Code simplification and refactoring (backport from 0.3.3.3-alpha):
+ - Update the "rust dependencies" submodule to be a project-level
+ repository, rather than a user repository. Closes ticket 25323.
+
+
+Changes in version 0.2.9.15 - 2018-03-03
+ Tor 0.2.9.15 backports important security and stability bugfixes from
+ later Tor releases.
+
+ It includes an important security fix for a remote crash attack
+ against directory authorities, tracked as TROVE-2018-001.
+
+ This release also backports our new system for improved resistance to
+ denial-of-service attacks against relays.
+
+ This release also fixes several minor bugs and annoyances from
+ earlier releases.
+
+ All directory authorities should upgrade to one of the versions
+ released today. Relays running 0.2.9.x may wish to update to one of
+ the versions released today, for the DoS mitigations.
+
+ o Major bugfixes (denial-of-service, directory authority, backport from 0.3.3.3-alpha):
+ - Fix a protocol-list handling bug that could be used to remotely crash
+ directory authorities with a null-pointer exception. Fixes bug 25074;
+ bugfix on 0.2.9.4-alpha. Also tracked as TROVE-2018-001 and
+ CVE-2018-0490.
+
+ o Major features (denial-of-service mitigation):
+ - Give relays some defenses against the recent network overload. We
+ start with three defenses (default parameters in parentheses).
+ First: if a single client address makes too many concurrent
+ connections (>100), hang up on further connections. Second: if a
+ single client address makes circuits too quickly (more than 3 per
+ second, with an allowed burst of 90) while also having too many
+ connections open (3), refuse new create cells for the next while
+ (1-2 hours). Third: if a client asks to establish a rendezvous
+ point to you directly, ignore the request. These defenses can be
+ manually controlled by new torrc options, but relays will also
+ take guidance from consensus parameters, so there's no need to
+ configure anything manually. Implements ticket 24902.
+
+ o Major bugfixes (bootstrapping):
+ - Fetch descriptors aggressively whenever we lack enough to build
+ circuits, regardless of how many descriptors we are missing.
+ Previously, we would delay launching the fetch when we had fewer
+ than 15 missing descriptors, even if some of those descriptors
+ were blocking circuits from building. Fixes bug 23985; bugfix on
+ 0.1.1.11-alpha. The effects of this bug became worse in
+ 0.3.0.3-alpha, when we began treating missing descriptors from our
+ primary guards as a reason to delay circuits.
+
+ o Major bugfixes (onion services, retry behavior):
+ - Fix an "off by 2" error in counting rendezvous failures on the
+ onion service side. While we thought we would stop the rendezvous
+ attempt after one failed circuit, we were actually making three
+ circuit attempts before giving up. Now switch to a default of 2,
+ and allow the consensus parameter "hs_service_max_rdv_failures" to
+ override. Fixes bug 24895; bugfix on 0.0.6.
+
+ o Minor feature (relay statistics):
+ - Change relay bandwidth reporting stats interval from 4 hours to 24
+ hours in order to reduce the efficiency of guard discovery
+ attacks. Fixes ticket 23856.
+
+ o Minor features (compatibility, OpenSSL):
+ - Tor will now support TLS1.3 once OpenSSL 1.1.1 is released.
+ Previous versions of Tor would not have worked with OpenSSL 1.1.1,
+ since they neither disabled TLS 1.3 nor enabled any of the
+ ciphersuites it requires. Now we enable the TLS 1.3 ciphersuites.
+ Closes ticket 24978.
+
+ o Minor features (denial-of-service avoidance):
+ - Make our OOM handler aware of the geoip client history cache so it
+ doesn't fill up the memory. This check is important for IPv6 and
+ our DoS mitigation subsystem. Closes ticket 25122.
+
+ o Minor features (fallback directory mirrors):
+ - The fallback directory list has been re-generated based on the
+ current status of the network. Tor uses fallback directories to
+ bootstrap when it doesn't yet have up-to-date directory
+ information. Closes ticket 24801.
+ - Make the default DirAuthorityFallbackRate 0.1, so that clients
+ prefer to bootstrap from fallback directory mirrors. This is a
+ follow-up to 24679, which removed weights from the default
+ fallbacks. Implements ticket 24681.
+
+ o Minor features (geoip):
+ - Update geoip and geoip6 to the February 7 2018 Maxmind GeoLite2
+ Country database.
+
+ o Minor features (linux seccomp2 sandbox):
+ - Update the sandbox rules so that they should now work correctly
+ with Glibc 2.26. Closes ticket 24315.
+
+ o Minor bugfix (channel connection):
+ - Use the actual observed address of an incoming relay connection,
+ not the canonical address of the relay from its descriptor, when
+ making decisions about how to handle the incoming connection.
+ Fixes bug 24952; bugfix on 0.2.4.11-alpha. Patch by "ffmancera".
+
+ o Minor bugfix (directory authority):
+ - Directory authorities, when refusing a descriptor from a rejected
+ relay, now explicitly tell the relay (in its logs) to set a valid
+ ContactInfo address and contact the bad-relays@ mailing list.
+ Fixes bug 25170; bugfix on 0.2.9.1.
+
+ o Minor bugfixes (address selection):
+ - When the fascist_firewall_choose_address_ functions don't find a
+ reachable address, set the returned address to the null address
+ and port. This is a precautionary measure, because some callers do
+ not check the return value. Fixes bug 24736; bugfix
+ on 0.2.8.2-alpha.
+
+ o Minor bugfixes (compilation):
+ - Fix a signed/unsigned comparison warning introduced by our fix to
+ TROVE-2017-009. Fixes bug 24480; bugfix on 0.2.5.16.
+
+ o Minor bugfixes (control port, linux seccomp2 sandbox):
+ - Avoid a crash when attempting to use the seccomp2 sandbox together
+ with the OwningControllerProcess feature. Fixes bug 24198; bugfix
+ on 0.2.5.1-alpha.
+
+ o Minor bugfixes (denial-of-service, backport from 0.3.3.3-alpha):
+ - Fix a possible crash on malformed consensus. If a consensus had
+ contained an unparseable protocol line, it could have made clients
+ and relays crash with a null-pointer exception. To exploit this
+ issue, however, an attacker would need to be able to subvert the
+ directory authority system. Fixes bug 25251; bugfix on
+ 0.2.9.4-alpha. Also tracked as TROVE-2018-004.
+
+ o Minor bugfixes (memory usage):
+ - When queuing DESTROY cells on a channel, only queue the circuit-id
+ and reason fields: not the entire 514-byte cell. This fix should
+ help mitigate any bugs or attacks that fill up these queues, and
+ free more RAM for other uses. Fixes bug 24666; bugfix
+ on 0.2.5.1-alpha.
+
+ o Minor bugfixes (network layer):
+ - When closing a connection via close_connection_immediately(), we
+ mark it as "not blocked on bandwidth", to prevent later calls from
+ trying to unblock it, and give it permission to read. This fixes a
+ backtrace warning that can happen on relays under various
+ circumstances. Fixes bug 24167; bugfix on 0.1.0.1-rc.
+
+ o Minor bugfixes (OSX):
+ - Don't exit the Tor process if setrlimit() fails to change the file
+ limit (which can happen sometimes on some versions of OSX). Fixes
+ bug 21074; bugfix on 0.0.9pre5.
+
+ o Minor bugfixes (path selection):
+ - When selecting relays by bandwidth, avoid a rounding error that
+ could sometimes cause load to be imbalanced incorrectly.
+ Previously, we would always round upwards; now, we round towards
+ the nearest integer. This had the biggest effect when a relay's
+ weight adjustments should have given it weight 0, but it got
+ weight 1 instead. Fixes bug 23318; bugfix on 0.2.4.3-alpha.
+ - When calculating the fraction of nodes that have descriptors, and
+ all nodes in the network have zero bandwidths, count the number of
+ nodes instead. Fixes bug 23318; bugfix on 0.2.4.10-alpha.
+ - Actually log the total bandwidth in compute_weighted_bandwidths().
+ Fixes bug 24170; bugfix on 0.2.4.3-alpha.
+
+ o Minor bugfixes (portability, msvc):
+ - Fix a bug in the bit-counting parts of our timing-wheel code on
+ MSVC. (Note that MSVC is still not a supported build platform, due
+ to cryptographic timing channel risks.) Fixes bug 24633; bugfix
+ on 0.2.9.1-alpha.
+
+ o Minor bugfixes (relay):
+ - Make the internal channel_is_client() function look at what sort
+ of connection handshake the other side used, rather than whether
+ the other side ever sent a create_fast cell to us. Backports part
+ of the fixes from bugs 22805 and 24898.
+
+ o Minor bugfixes (spec conformance, backport from 0.3.3.3-alpha):
+ - Forbid "-0" as a protocol version. Fixes part of bug 25249; bugfix on
+ 0.2.9.4-alpha.
+ - Forbid UINT32_MAX as a protocol version. Fixes part of bug 25249;
+ bugfix on 0.2.9.4-alpha.
+
+
Changes in version 0.3.3.2-alpha - 2018-02-10
Tor 0.3.3.2-alpha is the second alpha in the 0.3.3.x series. It
introduces a mechanism to handle the high loads that many relay
diff --git a/ReleaseNotes b/ReleaseNotes
index 6c31d8ab0c..93ff6d6ff6 100644
--- a/ReleaseNotes
+++ b/ReleaseNotes
@@ -2,6 +2,586 @@ This document summarizes new features and bugfixes in each stable release
of Tor. If you want to see more detailed descriptions of the changes in
each development snapshot, see the ChangeLog file.
+Changes in version 0.3.2.10 - 2018-03-03
+ Tor 0.3.2.10 is the second stable release in the 0.3.2 series. It
+ backports a number of bugfixes, including important fixes for security
+ issues.
+
+ It includes an important security fix for a remote crash attack
+ against directory authorities, tracked as TROVE-2018-001.
+
+ Additionally, it backports a fix for a bug whose severity we have
+ upgraded: Bug 24700, which was fixed in 0.3.3.2-alpha, can be remotely
+ triggered in order to crash relays with a use-after-free pattern. As
+ such, we are now tracking that bug as TROVE-2018-002 and
+ CVE-2018-0491, and backporting it to earlier releases. This bug
+ affected versions 0.3.2.1-alpha through 0.3.2.9, as well as version
+ 0.3.3.1-alpha.
+
+ This release also backports our new system for improved resistance to
+ denial-of-service attacks against relays.
+
+ This release also fixes several minor bugs and annoyances from
+ earlier releases.
+
+ Relays running 0.3.2.x SHOULD upgrade to one of the versions released
+ today, for the fix to TROVE-2018-002. Directory authorities should
+ also upgrade. (Relays on earlier versions might want to update too for
+ the DoS mitigations.)
+
+ o Major bugfixes (denial-of-service, directory authority, backport from 0.3.3.3-alpha):
+ - Fix a protocol-list handling bug that could be used to remotely crash
+ directory authorities with a null-pointer exception. Fixes bug 25074;
+ bugfix on 0.2.9.4-alpha. Also tracked as TROVE-2018-001 and
+ CVE-2018-0490.
+
+ o Major bugfixes (scheduler, KIST, denial-of-service, backport from 0.3.3.2-alpha):
+ - Avoid adding the same channel twice in the KIST scheduler pending
+ list, which could lead to remote denial-of-service use-after-free
+ attacks against relays. Fixes bug 24700; bugfix on 0.3.2.1-alpha.
+
+ o Major features (denial-of-service mitigation, backport from 0.3.3.2-alpha):
+ - Give relays some defenses against the recent network overload. We
+ start with three defenses (default parameters in parentheses).
+ First: if a single client address makes too many concurrent
+ connections (>100), hang up on further connections. Second: if a
+ single client address makes circuits too quickly (more than 3 per
+ second, with an allowed burst of 90) while also having too many
+ connections open (3), refuse new create cells for the next while
+ (1-2 hours). Third: if a client asks to establish a rendezvous
+ point to you directly, ignore the request. These defenses can be
+ manually controlled by new torrc options, but relays will also
+ take guidance from consensus parameters, so there's no need to
+ configure anything manually. Implements ticket 24902.
+
+ o Major bugfixes (onion services, retry behavior, backport from 0.3.3.1-alpha):
+ - Fix an "off by 2" error in counting rendezvous failures on the
+ onion service side. While we thought we would stop the rendezvous
+ attempt after one failed circuit, we were actually making three
+ circuit attempts before giving up. Now switch to a default of 2,
+ and allow the consensus parameter "hs_service_max_rdv_failures" to
+ override. Fixes bug 24895; bugfix on 0.0.6.
+ - New-style (v3) onion services now obey the "max rendezvous circuit
+ attempts" logic. Previously they would make as many rendezvous
+ circuit attempts as they could fit in the MAX_REND_TIMEOUT second
+ window before giving up. Fixes bug 24894; bugfix on 0.3.2.1-alpha.
+
+ o Major bugfixes (protocol versions, backport from 0.3.3.2-alpha):
+ - Add Link protocol version 5 to the supported protocols list. Fixes
+ bug 25070; bugfix on 0.3.1.1-alpha.
+
+ o Major bugfixes (relay, backport from 0.3.3.1-alpha):
+ - Fix a set of false positives where relays would consider
+ connections to other relays as being client-only connections (and
+ thus e.g. deserving different link padding schemes) if those
+ relays fell out of the consensus briefly. Now we look only at the
+ initial handshake and whether the connection authenticated as a
+ relay. Fixes bug 24898; bugfix on 0.3.1.1-alpha.
+
+ o Major bugfixes (scheduler, consensus, backport from 0.3.3.2-alpha):
+ - The scheduler subsystem was failing to promptly notice changes in
+ consensus parameters, making it harder to switch schedulers
+ network-wide. Fixes bug 24975; bugfix on 0.3.2.1-alpha.
+
+ o Minor features (denial-of-service avoidance, backport from 0.3.3.2-alpha):
+ - Make our OOM handler aware of the geoip client history cache so it
+ doesn't fill up the memory. This check is important for IPv6 and
+ our DoS mitigation subsystem. Closes ticket 25122.
+
+ o Minor features (compatibility, OpenSSL, backport from 0.3.3.3-alpha):
+ - Tor will now support TLS1.3 once OpenSSL 1.1.1 is released.
+ Previous versions of Tor would not have worked with OpenSSL 1.1.1,
+ since they neither disabled TLS 1.3 nor enabled any of the
+ ciphersuites it requires. Now we enable the TLS 1.3 ciphersuites.
+ Closes ticket 24978.
+
+ o Minor features (geoip):
+ - Update geoip and geoip6 to the February 7 2018 Maxmind GeoLite2
+ Country database.
+
+ o Minor features (logging, diagnostic, backport from 0.3.3.2-alpha):
+ - When logging a failure to check a hidden service's certificate,
+ also log what the problem with the certificate was. Diagnostic
+ for ticket 24972.
+
+ o Minor bugfix (channel connection, backport from 0.3.3.2-alpha):
+ - Use the actual observed address of an incoming relay connection,
+ not the canonical address of the relay from its descriptor, when
+ making decisions about how to handle the incoming connection.
+ Fixes bug 24952; bugfix on 0.2.4.11-alpha. Patch by "ffmancera".
+
+ o Minor bugfixes (denial-of-service, backport from 0.3.3.3-alpha):
+ - Fix a possible crash on malformed consensus. If a consensus had
+ contained an unparseable protocol line, it could have made clients
+ and relays crash with a null-pointer exception. To exploit this
+ issue, however, an attacker would need to be able to subvert the
+ directory authority system. Fixes bug 25251; bugfix on
+ 0.2.9.4-alpha. Also tracked as TROVE-2018-004.
+
+ o Minor bugfix (directory authority, backport from 0.3.3.2-alpha):
+ - Directory authorities, when refusing a descriptor from a rejected
+ relay, now explicitly tell the relay (in its logs) to set a valid
+ ContactInfo address and contact the bad-relays@ mailing list.
+ Fixes bug 25170; bugfix on 0.2.9.1.
+
+ o Minor bugfixes (build, rust, backport from 0.3.3.1-alpha):
+ - When building with Rust on OSX, link against libresolv, to work
+ around the issue at https://github.com/rust-lang/rust/issues/46797.
+ Fixes bug 24652; bugfix on 0.3.1.1-alpha.
+
+ o Minor bugfixes (onion services, backport from 0.3.3.2-alpha):
+ - Remove a BUG() statement when a client fetches an onion descriptor
+ that has a lower revision counter than the one in its cache. This
+ can happen in normal circumstances due to HSDir desync. Fixes bug
+ 24976; bugfix on 0.3.2.1-alpha.
+
+ o Minor bugfixes (logging, backport from 0.3.3.2-alpha):
+ - Don't treat inability to store a cached consensus object as a bug:
+ it can happen normally when we are out of disk space. Fixes bug
+ 24859; bugfix on 0.3.1.1-alpha.
+
+ o Minor bugfixes (performance, fragile-hardening, backport from 0.3.3.1-alpha):
+ - Improve the performance of our consensus-diff application code
+ when Tor is built with the --enable-fragile-hardening option set.
+ Fixes bug 24826; bugfix on 0.3.1.1-alpha.
+
+ o Minor bugfixes (OSX, backport from 0.3.3.1-alpha):
+ - Don't exit the Tor process if setrlimit() fails to change the file
+ limit (which can happen sometimes on some versions of OSX). Fixes
+ bug 21074; bugfix on 0.0.9pre5.
+
+ o Minor bugfixes (spec conformance, backport from 0.3.3.3-alpha):
+ - Forbid "-0" as a protocol version. Fixes part of bug 25249; bugfix on
+ 0.2.9.4-alpha.
+ - Forbid UINT32_MAX as a protocol version. Fixes part of bug 25249;
+ bugfix on 0.2.9.4-alpha.
+
+ o Minor bugfixes (testing, backport from 0.3.3.1-alpha):
+ - Fix a memory leak in the scheduler/loop_kist unit test. Fixes bug
+ 25005; bugfix on 0.3.2.7-rc.
+
+ o Minor bugfixes (v3 onion services, backport from 0.3.3.2-alpha):
+ - Look at the "HSRend" protocol version, not the "HSDir" protocol
+ version, when deciding whether a consensus entry can support the
+ v3 onion service protocol as a rendezvous point. Fixes bug 25105;
+ bugfix on 0.3.2.1-alpha.
+
+ o Code simplification and refactoring (backport from 0.3.3.3-alpha):
+ - Update the "rust dependencies" submodule to be a project-level
+ repository, rather than a user repository. Closes ticket 25323.
+
+ o Documentation (backport from 0.3.3.1-alpha)
+ - Document that operators who run more than one relay or bridge are
+ expected to set MyFamily and ContactInfo correctly. Closes
+ ticket 24526.
+
+
+Changes in version 0.3.1.10 - 2018-03-03
+ Tor 0.3.1.10 backports a number of bugfixes, including important fixes for
+ security issues.
+
+ It includes an important security fix for a remote crash attack
+ against directory authorities, tracked as TROVE-2018-001.
+
+ This release also backports our new system for improved resistance to
+ denial-of-service attacks against relays.
+
+ This release also fixes several minor bugs and annoyances from
+ earlier releases.
+
+ All directory authorities should upgrade to one of the versions
+ released today. Relays running 0.3.1.x may wish to update to one of
+ the versions released today, for the DoS mitigations.
+
+ Please note: according to our release calendar, Tor 0.3.1 will no
+ longer be supported after 1 July 2018. If you will be running Tor
+ after that date, you should make sure to plan to upgrade to the latest
+ stable version, or downgrade to 0.2.9 (which will receive long-term
+ support).
+
+ o Major bugfixes (denial-of-service, directory authority, backport from 0.3.3.3-alpha):
+ - Fix a protocol-list handling bug that could be used to remotely crash
+ directory authorities with a null-pointer exception. Fixes bug 25074;
+ bugfix on 0.2.9.4-alpha. Also tracked as TROVE-2018-001 and
+ CVE-2018-0490.
+
+ o Major features (denial-of-service mitigation, backport from 0.3.3.2-alpha):
+ - Give relays some defenses against the recent network overload. We
+ start with three defenses (default parameters in parentheses).
+ First: if a single client address makes too many concurrent
+ connections (>100), hang up on further connections. Second: if a
+ single client address makes circuits too quickly (more than 3 per
+ second, with an allowed burst of 90) while also having too many
+ connections open (3), refuse new create cells for the next while
+ (1-2 hours). Third: if a client asks to establish a rendezvous
+ point to you directly, ignore the request. These defenses can be
+ manually controlled by new torrc options, but relays will also
+ take guidance from consensus parameters, so there's no need to
+ configure anything manually. Implements ticket 24902.
+
+ o Minor features (linux seccomp2 sandbox, backport from 0.3.2.5-alpha):
+ - Update the sandbox rules so that they should now work correctly
+ with Glibc 2.26. Closes ticket 24315.
+
+ o Major bugfixes (onion services, retry behavior, backport from 0.3.3.1-alpha):
+ - Fix an "off by 2" error in counting rendezvous failures on the
+ onion service side. While we thought we would stop the rendezvous
+ attempt after one failed circuit, we were actually making three
+ circuit attempts before giving up. Now switch to a default of 2,
+ and allow the consensus parameter "hs_service_max_rdv_failures" to
+ override. Fixes bug 24895; bugfix on 0.0.6.
+
+ o Major bugfixes (protocol versions, backport from 0.3.3.2-alpha):
+ - Add Link protocol version 5 to the supported protocols list. Fixes
+ bug 25070; bugfix on 0.3.1.1-alpha.
+
+ o Major bugfixes (relay, backport from 0.3.3.1-alpha):
+ - Fix a set of false positives where relays would consider
+ connections to other relays as being client-only connections (and
+ thus e.g. deserving different link padding schemes) if those
+ relays fell out of the consensus briefly. Now we look only at the
+ initial handshake and whether the connection authenticated as a
+ relay. Fixes bug 24898; bugfix on 0.3.1.1-alpha.
+
+ o Minor features (denial-of-service avoidance, backport from 0.3.3.2-alpha):
+ - Make our OOM handler aware of the geoip client history cache so it
+ doesn't fill up the memory. This check is important for IPv6 and
+ our DoS mitigation subsystem. Closes ticket 25122.
+
+ o Minor feature (relay statistics, backport from 0.3.2.6-alpha):
+ - Change relay bandwidth reporting stats interval from 4 hours to 24
+ hours in order to reduce the efficiency of guard discovery
+ attacks. Fixes ticket 23856.
+
+ o Minor features (compatibility, OpenSSL, backport from 0.3.3.3-alpha):
+ - Tor will now support TLS1.3 once OpenSSL 1.1.1 is released.
+ Previous versions of Tor would not have worked with OpenSSL 1.1.1,
+ since they neither disabled TLS 1.3 nor enabled any of the
+ ciphersuites it requires. Now we enable the TLS 1.3 ciphersuites.
+ Closes ticket 24978.
+
+ o Minor features (fallback directory mirrors, backport from 0.3.2.9):
+ - The fallback directory list has been re-generated based on the
+ current status of the network. Tor uses fallback directories to
+ bootstrap when it doesn't yet have up-to-date directory
+ information. Closes ticket 24801.
+ - Make the default DirAuthorityFallbackRate 0.1, so that clients
+ prefer to bootstrap from fallback directory mirrors. This is a
+ follow-up to 24679, which removed weights from the default
+ fallbacks. Implements ticket 24681.
+
+ o Minor features (geoip):
+ - Update geoip and geoip6 to the February 7 2018 Maxmind GeoLite2
+ Country database.
+
+ o Minor bugfix (channel connection, backport from 0.3.3.2-alpha):
+ - Use the actual observed address of an incoming relay connection,
+ not the canonical address of the relay from its descriptor, when
+ making decisions about how to handle the incoming connection.
+ Fixes bug 24952; bugfix on 0.2.4.11-alpha. Patch by "ffmancera".
+
+ o Minor bugfix (directory authority, backport from 0.3.3.2-alpha):
+ - Directory authorities, when refusing a descriptor from a rejected
+ relay, now explicitly tell the relay (in its logs) to set a valid
+ ContactInfo address and contact the bad-relays@ mailing list.
+ Fixes bug 25170; bugfix on 0.2.9.1.
+
+ o Minor bugfixes (address selection, backport from 0.3.2.9):
+ - When the fascist_firewall_choose_address_ functions don't find a
+ reachable address, set the returned address to the null address
+ and port. This is a precautionary measure, because some callers do
+ not check the return value. Fixes bug 24736; bugfix
+ on 0.2.8.2-alpha.
+
+ o Major bugfixes (bootstrapping, backport from 0.3.2.5-alpha):
+ - Fetch descriptors aggressively whenever we lack enough to build
+ circuits, regardless of how many descriptors we are missing.
+ Previously, we would delay launching the fetch when we had fewer
+ than 15 missing descriptors, even if some of those descriptors
+ were blocking circuits from building. Fixes bug 23985; bugfix on
+ 0.1.1.11-alpha. The effects of this bug became worse in
+ 0.3.0.3-alpha, when we began treating missing descriptors from our
+ primary guards as a reason to delay circuits.
+ - Don't try fetching microdescriptors from relays that have failed
+ to deliver them in the past. Fixes bug 23817; bugfix
+ on 0.3.0.1-alpha.
+
+ o Minor bugfixes (compilation, backport from 0.3.2.7-rc):
+ - Fix a signed/unsigned comparison warning introduced by our fix to
+ TROVE-2017-009. Fixes bug 24480; bugfix on 0.2.5.16.
+
+ o Minor bugfixes (control port, linux seccomp2 sandbox, backport from 0.3.2.5-alpha):
+ - Avoid a crash when attempting to use the seccomp2 sandbox together
+ with the OwningControllerProcess feature. Fixes bug 24198; bugfix
+ on 0.2.5.1-alpha.
+
+ o Minor bugfixes (denial-of-service, backport from 0.3.3.3-alpha):
+ - Fix a possible crash on malformed consensus. If a consensus had
+ contained an unparseable protocol line, it could have made clients
+ and relays crash with a null-pointer exception. To exploit this
+ issue, however, an attacker would need to be able to subvert the
+ directory authority system. Fixes bug 25251; bugfix on
+ 0.2.9.4-alpha. Also tracked as TROVE-2018-004.
+
+ o Minor bugfixes (directory cache, backport from 0.3.2.5-alpha):
+ - Recover better from empty or corrupt files in the consensus cache
+ directory. Fixes bug 24099; bugfix on 0.3.1.1-alpha.
+ - When a consensus diff calculation is only partially successful,
+ only record the successful parts as having succeeded. Partial
+ success can happen if (for example) one compression method fails
+ but the others succeed. Previously we misrecorded all the
+ calculations as having succeeded, which would later cause a
+ nonfatal assertion failure. Fixes bug 24086; bugfix
+ on 0.3.1.1-alpha.
+
+ o Minor bugfixes (entry guards, backport from 0.3.2.3-alpha):
+ - Tor now updates its guard state when it reads a consensus
+ regardless of whether it's missing descriptors. That makes tor use
+ its primary guards to fetch descriptors in some edge cases where
+ it would previously have used fallback directories. Fixes bug
+ 23862; bugfix on 0.3.0.1-alpha.
+
+ o Minor bugfixes (logging, backport from 0.3.3.2-alpha):
+ - Don't treat inability to store a cached consensus object as a bug:
+ it can happen normally when we are out of disk space. Fixes bug
+ 24859; bugfix on 0.3.1.1-alpha.
+
+ o Minor bugfixes (memory usage, backport from 0.3.2.8-rc):
+ - When queuing DESTROY cells on a channel, only queue the circuit-id
+ and reason fields: not the entire 514-byte cell. This fix should
+ help mitigate any bugs or attacks that fill up these queues, and
+ free more RAM for other uses. Fixes bug 24666; bugfix
+ on 0.2.5.1-alpha.
+
+ o Minor bugfixes (network layer, backport from 0.3.2.5-alpha):
+ - When closing a connection via close_connection_immediately(), we
+ mark it as "not blocked on bandwidth", to prevent later calls from
+ trying to unblock it, and give it permission to read. This fixes a
+ backtrace warning that can happen on relays under various
+ circumstances. Fixes bug 24167; bugfix on 0.1.0.1-rc.
+
+ o Minor bugfixes (path selection, backport from 0.3.2.4-alpha):
+ - When selecting relays by bandwidth, avoid a rounding error that
+ could sometimes cause load to be imbalanced incorrectly.
+ Previously, we would always round upwards; now, we round towards
+ the nearest integer. This had the biggest effect when a relay's
+ weight adjustments should have given it weight 0, but it got
+ weight 1 instead. Fixes bug 23318; bugfix on 0.2.4.3-alpha.
+ - When calculating the fraction of nodes that have descriptors, and
+ all nodes in the network have zero bandwidths, count the number of
+ nodes instead. Fixes bug 23318; bugfix on 0.2.4.10-alpha.
+ - Actually log the total bandwidth in compute_weighted_bandwidths().
+ Fixes bug 24170; bugfix on 0.2.4.3-alpha.
+
+ o Minor bugfixes (performance, fragile-hardening, backport from 0.3.3.1-alpha):
+ - Improve the performance of our consensus-diff application code
+ when Tor is built with the --enable-fragile-hardening option set.
+ Fixes bug 24826; bugfix on 0.3.1.1-alpha.
+
+ o Minor bugfixes (OSX, backport from 0.3.3.1-alpha):
+ - Don't exit the Tor process if setrlimit() fails to change the file
+ limit (which can happen sometimes on some versions of OSX). Fixes
+ bug 21074; bugfix on 0.0.9pre5.
+
+ o Minor bugfixes (portability, msvc, backport from 0.3.2.9):
+ - Fix a bug in the bit-counting parts of our timing-wheel code on
+ MSVC. (Note that MSVC is still not a supported build platform, due
+ to cyptographic timing channel risks.) Fixes bug 24633; bugfix
+ on 0.2.9.1-alpha.
+
+ o Minor bugfixes (relay, partial backport):
+ - Make the internal channel_is_client() function look at what sort
+ of connection handshake the other side used, rather than whether
+ the other side ever sent a create_fast cell to us. Backports part
+ of the fixes from bugs 22805 and 24898.
+
+ o Minor bugfixes (spec conformance, backport from 0.3.3.3-alpha):
+ - Forbid "-0" as a protocol version. Fixes part of bug 25249; bugfix on
+ 0.2.9.4-alpha.
+ - Forbid UINT32_MAX as a protocol version. Fixes part of bug 25249;
+ bugfix on 0.2.9.4-alpha.
+
+ o Code simplification and refactoring (backport from 0.3.3.3-alpha):
+ - Update the "rust dependencies" submodule to be a project-level
+ repository, rather than a user repository. Closes ticket 25323.
+
+Changes in version 0.2.9.15 - 2018-03-03
+ Tor 0.2.9.15 backports important security and stability bugfixes from
+ later Tor releases.
+
+ It includes an important security fix for a remote crash attack
+ against directory authorities, tracked as TROVE-2018-001.
+
+ This release also backports our new system for improved resistance to
+ denial-of-service attacks against relays.
+
+ This release also fixes several minor bugs and annoyances from
+ earlier releases.
+
+ All directory authorities should upgrade to one of the versions
+ released today. Relays running 0.2.9.x may wish to update to one of
+ the versions released today, for the DoS mitigations.
+
+ o Major bugfixes (denial-of-service, directory authority, backport from 0.3.3.3-alpha):
+ - Fix a protocol-list handling bug that could be used to remotely crash
+ directory authorities with a null-pointer exception. Fixes bug 25074;
+ bugfix on 0.2.9.4-alpha. Also tracked as TROVE-2018-001 and
+ CVE-2018-0490.
+
+ o Major features (denial-of-service mitigation):
+ - Give relays some defenses against the recent network overload. We
+ start with three defenses (default parameters in parentheses).
+ First: if a single client address makes too many concurrent
+ connections (>100), hang up on further connections. Second: if a
+ single client address makes circuits too quickly (more than 3 per
+ second, with an allowed burst of 90) while also having too many
+ connections open (3), refuse new create cells for the next while
+ (1-2 hours). Third: if a client asks to establish a rendezvous
+ point to you directly, ignore the request. These defenses can be
+ manually controlled by new torrc options, but relays will also
+ take guidance from consensus parameters, so there's no need to
+ configure anything manually. Implements ticket 24902.
+
+ o Major bugfixes (bootstrapping):
+ - Fetch descriptors aggressively whenever we lack enough to build
+ circuits, regardless of how many descriptors we are missing.
+ Previously, we would delay launching the fetch when we had fewer
+ than 15 missing descriptors, even if some of those descriptors
+ were blocking circuits from building. Fixes bug 23985; bugfix on
+ 0.1.1.11-alpha. The effects of this bug became worse in
+ 0.3.0.3-alpha, when we began treating missing descriptors from our
+ primary guards as a reason to delay circuits.
+
+ o Major bugfixes (onion services, retry behavior):
+ - Fix an "off by 2" error in counting rendezvous failures on the
+ onion service side. While we thought we would stop the rendezvous
+ attempt after one failed circuit, we were actually making three
+ circuit attempts before giving up. Now switch to a default of 2,
+ and allow the consensus parameter "hs_service_max_rdv_failures" to
+ override. Fixes bug 24895; bugfix on 0.0.6.
+
+ o Minor feature (relay statistics):
+ - Change relay bandwidth reporting stats interval from 4 hours to 24
+ hours in order to reduce the efficiency of guard discovery
+ attacks. Fixes ticket 23856.
+
+ o Minor features (compatibility, OpenSSL):
+ - Tor will now support TLS1.3 once OpenSSL 1.1.1 is released.
+ Previous versions of Tor would not have worked with OpenSSL 1.1.1,
+ since they neither disabled TLS 1.3 nor enabled any of the
+ ciphersuites it requires. Now we enable the TLS 1.3 ciphersuites.
+ Closes ticket 24978.
+
+ o Minor features (denial-of-service avoidance):
+ - Make our OOM handler aware of the geoip client history cache so it
+ doesn't fill up the memory. This check is important for IPv6 and
+ our DoS mitigation subsystem. Closes ticket 25122.
+
+ o Minor features (fallback directory mirrors):
+ - The fallback directory list has been re-generated based on the
+ current status of the network. Tor uses fallback directories to
+ bootstrap when it doesn't yet have up-to-date directory
+ information. Closes ticket 24801.
+ - Make the default DirAuthorityFallbackRate 0.1, so that clients
+ prefer to bootstrap from fallback directory mirrors. This is a
+ follow-up to 24679, which removed weights from the default
+ fallbacks. Implements ticket 24681.
+
+ o Minor features (geoip):
+ - Update geoip and geoip6 to the February 7 2018 Maxmind GeoLite2
+ Country database.
+
+ o Minor features (linux seccomp2 sandbox):
+ - Update the sandbox rules so that they should now work correctly
+ with Glibc 2.26. Closes ticket 24315.
+
+ o Minor bugfix (channel connection):
+ - Use the actual observed address of an incoming relay connection,
+ not the canonical address of the relay from its descriptor, when
+ making decisions about how to handle the incoming connection.
+ Fixes bug 24952; bugfix on 0.2.4.11-alpha. Patch by "ffmancera".
+
+ o Minor bugfix (directory authority):
+ - Directory authorities, when refusing a descriptor from a rejected
+ relay, now explicitly tell the relay (in its logs) to set a valid
+ ContactInfo address and contact the bad-relays@ mailing list.
+ Fixes bug 25170; bugfix on 0.2.9.1.
+
+ o Minor bugfixes (address selection):
+ - When the fascist_firewall_choose_address_ functions don't find a
+ reachable address, set the returned address to the null address
+ and port. This is a precautionary measure, because some callers do
+ not check the return value. Fixes bug 24736; bugfix
+ on 0.2.8.2-alpha.
+
+ o Minor bugfixes (compilation):
+ - Fix a signed/unsigned comparison warning introduced by our fix to
+ TROVE-2017-009. Fixes bug 24480; bugfix on 0.2.5.16.
+
+ o Minor bugfixes (control port, linux seccomp2 sandbox):
+ - Avoid a crash when attempting to use the seccomp2 sandbox together
+ with the OwningControllerProcess feature. Fixes bug 24198; bugfix
+ on 0.2.5.1-alpha.
+
+ o Minor bugfixes (denial-of-service, backport from 0.3.3.3-alpha):
+ - Fix a possible crash on malformed consensus. If a consensus had
+ contained an unparseable protocol line, it could have made clients
+ and relays crash with a null-pointer exception. To exploit this
+ issue, however, an attacker would need to be able to subvert the
+ directory authority system. Fixes bug 25251; bugfix on
+ 0.2.9.4-alpha. Also tracked as TROVE-2018-004.
+
+ o Minor bugfixes (memory usage):
+ - When queuing DESTROY cells on a channel, only queue the circuit-id
+ and reason fields: not the entire 514-byte cell. This fix should
+ help mitigate any bugs or attacks that fill up these queues, and
+ free more RAM for other uses. Fixes bug 24666; bugfix
+ on 0.2.5.1-alpha.
+
+ o Minor bugfixes (network layer):
+ - When closing a connection via close_connection_immediately(), we
+ mark it as "not blocked on bandwidth", to prevent later calls from
+ trying to unblock it, and give it permission to read. This fixes a
+ backtrace warning that can happen on relays under various
+ circumstances. Fixes bug 24167; bugfix on 0.1.0.1-rc.
+
+ o Minor bugfixes (OSX):
+ - Don't exit the Tor process if setrlimit() fails to change the file
+ limit (which can happen sometimes on some versions of OSX). Fixes
+ bug 21074; bugfix on 0.0.9pre5.
+
+ o Minor bugfixes (path selection):
+ - When selecting relays by bandwidth, avoid a rounding error that
+ could sometimes cause load to be imbalanced incorrectly.
+ Previously, we would always round upwards; now, we round towards
+ the nearest integer. This had the biggest effect when a relay's
+ weight adjustments should have given it weight 0, but it got
+ weight 1 instead. Fixes bug 23318; bugfix on 0.2.4.3-alpha.
+ - When calculating the fraction of nodes that have descriptors, and
+ all nodes in the network have zero bandwidths, count the number of
+ nodes instead. Fixes bug 23318; bugfix on 0.2.4.10-alpha.
+ - Actually log the total bandwidth in compute_weighted_bandwidths().
+ Fixes bug 24170; bugfix on 0.2.4.3-alpha.
+
+ o Minor bugfixes (portability, msvc):
+ - Fix a bug in the bit-counting parts of our timing-wheel code on
+ MSVC. (Note that MSVC is still not a supported build platform, due
+ to cryptographic timing channel risks.) Fixes bug 24633; bugfix
+ on 0.2.9.1-alpha.
+
+ o Minor bugfixes (relay):
+ - Make the internal channel_is_client() function look at what sort
+ of connection handshake the other side used, rather than whether
+ the other side ever sent a create_fast cell to us. Backports part
+ of the fixes from bugs 22805 and 24898.
+
+ o Minor bugfixes (spec conformance, backport from 0.3.3.3-alpha):
+ - Forbid "-0" as a protocol version. Fixes part of bug 25249; bugfix on
+ 0.2.9.4-alpha.
+ - Forbid UINT32_MAX as a protocol version. Fixes part of bug 25249;
+ bugfix on 0.2.9.4-alpha.
+
+
Changes in version 0.3.2.9 - 2018-01-09
Tor 0.3.2.9 is the first stable release in the 0.3.2 series.
diff --git a/changes/18105 b/changes/18105
new file mode 100644
index 0000000000..87e6e61d2f
--- /dev/null
+++ b/changes/18105
@@ -0,0 +1,4 @@
+ o Code simplification and refactoring:
+ - Introduce a function to call getsockname() and return
+ tor_addr_t, to save a little complexity throughout the codebase.
+ Closes ticket 18105.
diff --git a/changes/bug18918 b/changes/bug18918
new file mode 100644
index 0000000000..c939168f49
--- /dev/null
+++ b/changes/bug18918
@@ -0,0 +1,6 @@
+ o Code simplification and refactoring:
+ - In order to make the OR and dir checking function in router.c less
+ confusing we renamed some functions and consider_testing_reachability()
+ has been splitted into router_should_check_reachability() and
+ router_do_reachability_checks(). Also we improved the documentation in
+ some functions. Closes ticket 18918.
diff --git a/changes/bug20887 b/changes/bug20887
new file mode 100644
index 0000000000..5d4e4ed233
--- /dev/null
+++ b/changes/bug20887
@@ -0,0 +1,4 @@
+ o Minor bugfixes (freebsd):
+ - In have_enough_mem_for_dircache(), the variable DIRCACHE_MIN_MEM_MB
+ does not stringify on FreeBSD, so we switch to tor_asprintf(). Fixes
+ bug 20887; bugfix on 0.2.8.1-alpha. Patch by Neel Chauhan.
diff --git a/changes/bug23909 b/changes/bug23909
new file mode 100644
index 0000000000..6b84e711e7
--- /dev/null
+++ b/changes/bug23909
@@ -0,0 +1,4 @@
+ o Minor features (directory authority):
+ - Directory authorities now open their key-pinning files as O_SYNC,
+ to prevent themselves from accidentally writing partial lines.
+ Closes ticket 23909.
diff --git a/changes/bug24484 b/changes/bug24484
new file mode 100644
index 0000000000..35a2044923
--- /dev/null
+++ b/changes/bug24484
@@ -0,0 +1,4 @@
+ o Code simplification and refactoring:
+ - Since Tor requires C99, remove our old workaround code for libc
+ implementations where free(NULL) doesn't work. Closes ticket 24484.
+
diff --git a/changes/bug24769 b/changes/bug24769
deleted file mode 100644
index 2893e0ff07..0000000000
--- a/changes/bug24769
+++ /dev/null
@@ -1,7 +0,0 @@
- o Minor bugfixes (performance):
- - Reduce the number of circuits that can be opened at once during the
- circuit build timeout phase. This is done by increasing the idle timeout
- to 3 minutes, and lowering the maximum number of concurrent learning
- circuits to 10. Fixes bug 24769; bugfix on 0.3.1.1-alpha.
-
-
diff --git a/changes/bug24914 b/changes/bug24914
new file mode 100644
index 0000000000..ea441fd38c
--- /dev/null
+++ b/changes/bug24914
@@ -0,0 +1,3 @@
+ o Minor features (performance):
+ - Avoid a needless call to malloc() when processing an incoming
+ relay cell. Closes ticket 24914.
diff --git a/changes/bug24978 b/changes/bug24978
deleted file mode 100644
index 5dc45c7442..0000000000
--- a/changes/bug24978
+++ /dev/null
@@ -1,7 +0,0 @@
- o Minor features (compatibility, OpenSSL):
- - Tor will now support TLS1.3 once OpenSSL 1.1.1 is released.
- Previous versions of Tor would not have worked with OpenSSL
- 1.1.1, since they neither disabled TLS 1.3 nor enabled any of the
- ciphersuites it requires. Here we enable the TLS 1.3 ciphersuites.
- Closes ticket 24978.
-
diff --git a/changes/bug25120 b/changes/bug25120
deleted file mode 100644
index 7215756ef3..0000000000
--- a/changes/bug25120
+++ /dev/null
@@ -1,4 +0,0 @@
- o Minor features (logging):
- - Clarify the log messages produced when getrandom() or a related
- entropy-generation mechanism gives an error. Closes ticket
- 25120.
diff --git a/changes/bug25223 b/changes/bug25223
deleted file mode 100644
index fdd5563500..0000000000
--- a/changes/bug25223
+++ /dev/null
@@ -1,4 +0,0 @@
- o Minor bugfixes (DoS mitigation):
- - Make sure we don't modify consensus parameters if we aren't a public
- relay when a new consensus arrives. Fixes bug 25223; bugfix on
- 0.3.3.2-alpha.
diff --git a/changes/bug25415 b/changes/bug25415
new file mode 100644
index 0000000000..ec851aee8d
--- /dev/null
+++ b/changes/bug25415
@@ -0,0 +1,4 @@
+ o Major bugfixes (directory authority):
+ - Avoid a crash when testing router reachability on a router that could
+ have an ed25519 ID, but which does not. Fixes bug 25415; bugfix on
+ 0.3.3.2-alpha.
diff --git a/changes/feature25150 b/changes/feature25150
new file mode 100644
index 0000000000..eb65327a8d
--- /dev/null
+++ b/changes/feature25150
@@ -0,0 +1,4 @@
+ o Minor features (performance, allocation):
+ - Avoid a needless malloc()/free() pair every time we handle an ntor
+ handshake. Closes ticket 25150.
+
diff --git a/changes/ticket23873 b/changes/ticket23873
new file mode 100644
index 0000000000..ffe65e5ed4
--- /dev/null
+++ b/changes/ticket23873
@@ -0,0 +1,6 @@
+ o Code simplification and refactoring:
+ - We remove the return value of node_get_prim_orport() and
+ node_get_prim_dirport(), and introduce node_get_prim_orport()
+ in node_ipv6_or_preferred() and node_ipv6_dir_preferred() in
+ order to check for a null address. Closes ticket 23873. Patch
+ by Neel Chauhan.
diff --git a/changes/ticket24343 b/changes/ticket24343
deleted file mode 100644
index e62d65eb54..0000000000
--- a/changes/ticket24343
+++ /dev/null
@@ -1,6 +0,0 @@
- o Minor bugfixes (man page, SocksPort):
- - Remove dead code about the old "SocksSockets" option. To do so, the
- SocksSocketsGroupWritable option has been renamed to
- UnixSockssGroupWritable which does the same exact thing. The old option
- is still usable but will warn that it is deprecated. Fixes bug 24343;
- bugfix on 0.2.6.3.
diff --git a/changes/ticket24714 b/changes/ticket24714
new file mode 100644
index 0000000000..60353abec9
--- /dev/null
+++ b/changes/ticket24714
@@ -0,0 +1,6 @@
+ o Code simplification and refactoring:
+ - Rename two fields of connection_t struct.
+ timestamp_lastwritten is renamed to timestamp_last_write_allowed and
+ timestamp_lastread is renamed to timestamp_last_read_allowed.
+ Closes ticket 24714, patch by "valentecaio".
+
diff --git a/changes/ticket25071 b/changes/ticket25071
deleted file mode 100644
index 5e2917e10b..0000000000
--- a/changes/ticket25071
+++ /dev/null
@@ -1,4 +0,0 @@
- o Minor features (testing):
- - Add a "make test-rust" target to run the rust tests only.
- Closes ticket 25071.
-
diff --git a/changes/ticket25081 b/changes/ticket25081
new file mode 100644
index 0000000000..b6e6c2a5a6
--- /dev/null
+++ b/changes/ticket25081
@@ -0,0 +1,5 @@
+ o Code simplification and refactoring:
+ - Remove extern declaration of stats_n_seconds_working variable from main,
+ protecting its accesses with get_uptime() and reset_uptime() functions.
+ Closes ticket 25081, patch by “valentecaio”.
+
diff --git a/changes/ticket25162 b/changes/ticket25162
new file mode 100644
index 0000000000..37019a7f8f
--- /dev/null
+++ b/changes/ticket25162
@@ -0,0 +1,6 @@
+ o Minor features (compression, zstd):
+ - When running with zstd, Tor now considers using advanced functions that
+ the zstd maintainers have labeled as potentially unstable. To
+ prevent breakage, Tor will only use this functionality when
+ the runtime version of the zstd library matches the version
+ with which it were compiled. Closes ticket 25162.
diff --git a/changes/ticket25202 b/changes/ticket25202
deleted file mode 100644
index ba64abad7b..0000000000
--- a/changes/ticket25202
+++ /dev/null
@@ -1,4 +0,0 @@
- o Minor bugfixes (DoS mitigation):
- - Add extra safety checks when refilling the circuit creation bucket to
- ensure we never set a value that is above the allowed burst. Fixes
- bug 25202; bugfix on 0.3.3.2-alpha.
diff --git a/changes/ticket25261 b/changes/ticket25261
new file mode 100644
index 0000000000..604a09d975
--- /dev/null
+++ b/changes/ticket25261
@@ -0,0 +1,3 @@
+ o Minor bugfix (Multiple includes):
+ - Fixed multiple includes of trasports.h in src/or/connection.c
+ Fixes bug 25261; bugfix on 0.2.5.1-alpha.
diff --git a/changes/ticket25268 b/changes/ticket25268
new file mode 100644
index 0000000000..e444984dc4
--- /dev/null
+++ b/changes/ticket25268
@@ -0,0 +1,7 @@
+ o Removed features:
+ - The old "round-robin" circuit multiplexer (circuitmux)
+ implementation has been removed, along with a fairly large set of
+ code that existed to support it. It has not been the default
+ circuitmux since we introduced the "EWMA" circuitmux in 0.2.4.x,
+ but it still required an unreasonable amount of memory and CPU.
+ Closes ticket 25268.
diff --git a/changes/ticket25323 b/changes/ticket25323
deleted file mode 100644
index 836825de5d..0000000000
--- a/changes/ticket25323
+++ /dev/null
@@ -1,4 +0,0 @@
- o Code simplification and refactoring:
- - Update the "rust dependencies" submodule to be an project-level
- repository, rather than a user repository. Closes ticket 25323.
-
diff --git a/changes/ticket4187 b/changes/ticket4187
new file mode 100644
index 0000000000..c5f795b1a6
--- /dev/null
+++ b/changes/ticket4187
@@ -0,0 +1,3 @@
+ o Minor bugfixes (directory client):
+ - When unverified-consensus is verified, rename it to cached-consenus.
+ Fixes bug 4187; bugfix on 0.2.0.3-alpha.
diff --git a/changes/ticket6236 b/changes/ticket6236
new file mode 100644
index 0000000000..9dea07e696
--- /dev/null
+++ b/changes/ticket6236
@@ -0,0 +1,4 @@
+ o Minor bugfixes (Duplicate code):
+ - Remove duplicate code in parse_{c,s}method_line and bootstrap
+ their functionalities into a single function. Fixes
+ bug 6236; bugfix on 0.2.3.6-alpha.
diff --git a/configure.ac b/configure.ac
index 6c6add1876..0b9733cdb9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@ dnl Copyright (c) 2007-2017, The Tor Project, Inc.
dnl See LICENSE for licensing information
AC_PREREQ([2.63])
-AC_INIT([tor],[0.3.3.3-alpha-dev])
+AC_INIT([tor],[0.3.4.0-alpha-dev])
AC_CONFIG_SRCDIR([src/or/main.c])
AC_CONFIG_MACRO_DIR([m4])
@@ -61,6 +61,8 @@ AC_ARG_ENABLE(cargo-online-mode,
AS_HELP_STRING(--enable-cargo-online-mode, [Allow cargo to make network requests to fetch crates. For builds with rust only.]))
AC_ARG_ENABLE(restart-debugging,
AS_HELP_STRING(--enable-restart-debugging, [Build Tor with support for debugging in-process restart. Developers only.]))
+AC_ARG_ENABLE(zstd-advanced-apis,
+ AS_HELP_STRING(--disable-zstd-advanced-apis, [Build without support for zstd's "static-only" APIs.]))
if test "x$enable_coverage" != "xyes" -a "x$enable_asserts_in_tests" = "xno" ; then
AC_MSG_ERROR([Can't disable assertions outside of coverage build])
@@ -114,6 +116,10 @@ if test "$enable_restart_debugging" = "yes"; then
[Defined if we're building with support for in-process restart debugging.])
fi
+if test "$enable_zstd_advanced_apis" != "no"; then
+ AC_DEFINE(ENABLE_ZSTD_ADVANCED_APIS, 1,
+ [Defined if we're going to try to use zstd's "static-only" APIs.])
+fi
# systemd support
if test "x$enable_systemd" = "xno"; then
@@ -615,6 +621,21 @@ fi
AM_CONDITIONAL(BUILD_READPASSPHRASE_C,
test "x$ac_cv_func_readpassphrase" = "xno" && test "$bwin32" = "false")
+AC_MSG_CHECKING([whether free(NULL) works])
+AC_RUN_IFELSE([AC_LANG_PROGRAM([
+ #include <stdlib.h>
+], [
+char *p = NULL;
+free(p);
+])],
+[free_null_ok=true; AC_MSG_RESULT(yes)],
+[free_null_ok=false; AC_MSG_RESULT(no)],
+[free_null_ok=cross; AC_MSG_RESULT(cross)])
+
+if test "$free_null_ok" = "false"; then
+ AC_MSG_ERROR([Your libc implementation doesn't allow free(NULL), as required by C99.])
+fi
+
dnl ------------------------------------------------------
dnl Where do you live, libevent? And how do we call you?
@@ -835,6 +856,10 @@ AC_CHECK_MEMBERS([SSL.state], , ,
[#include <openssl/ssl.h>
])
+AC_CHECK_SIZEOF(SHA_CTX, , [AC_INCLUDES_DEFAULT()
+#include <openssl/sha.h>
+])
+
dnl Define the set of checks for KIST scheduler support.
AC_DEFUN([CHECK_KIST_SUPPORT],[
dnl KIST needs struct tcp_info and for certain members to exist.
@@ -953,6 +978,16 @@ if test "x$have_zstd" = "xyes"; then
AC_DEFINE(HAVE_ZSTD,1,[Have Zstd])
TOR_ZSTD_CFLAGS="${ZSTD_CFLAGS}"
TOR_ZSTD_LIBS="${ZSTD_LIBS}"
+
+ dnl now check for zstd functions
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="$LIBS $ZSTD_LIBS"
+ CFLAGS="$CFLAGS $ZSTD_CFLAGS"
+ AC_CHECK_FUNCS(ZSTD_estimateCStreamSize \
+ ZSTD_estimateDCtxSize)
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
fi
AC_SUBST(TOR_ZSTD_CFLAGS)
AC_SUBST(TOR_ZSTD_LIBS)
diff --git a/contrib/win32build/tor-mingw.nsi.in b/contrib/win32build/tor-mingw.nsi.in
index 0e037da453..dfcb0644dc 100644
--- a/contrib/win32build/tor-mingw.nsi.in
+++ b/contrib/win32build/tor-mingw.nsi.in
@@ -8,7 +8,7 @@
!include "LogicLib.nsh"
!include "FileFunc.nsh"
!insertmacro GetParameters
-!define VERSION "0.3.3.3-alpha-dev"
+!define VERSION "0.3.4.0-alpha-dev"
!define INSTALLER "tor-${VERSION}-win32.exe"
!define WEBSITE "https://www.torproject.org/"
!define LICENSE "LICENSE"
diff --git a/doc/HACKING/CodingStandardsRust.md b/doc/HACKING/CodingStandardsRust.md
index d0b17c1604..731a7bb85e 100644
--- a/doc/HACKING/CodingStandardsRust.md
+++ b/doc/HACKING/CodingStandardsRust.md
@@ -284,12 +284,26 @@ Here are some additional bits of advice and rules:
}
}
-3. Pass only integer types and bytes over the boundary
+3. Pass only C-compatible primitive types and bytes over the boundary
- The only non-integer type which may cross the FFI boundary is
+ Rust's C-compatible primitive types are integers and floats.
+ These types are declared in the [libc crate](https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu/libc/index.html#types).
+ Most Rust objects have different [representations](https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu/libc/index.html#types)
+ in C and Rust, so they can't be passed using FFI.
+
+ Tor currently uses the following Rust primitive types from libc for FFI:
+ * defined-size integers: `uint32_t`
+ * native-sized integers: `c_int`
+ * native-sized floats: `c_double`
+ * native-sized raw pointers: `* c_void`, `* c_char`, `** c_char`
+
+ TODO: C smartlist to Stringlist conversion using FFI
+
+ The only non-primitive type which may cross the FFI boundary is
bytes, e.g. `&[u8]`. This SHOULD be done on the Rust side by
- passing a pointer (`*mut libc::c_char`) and a length
- (`libc::size_t`).
+ passing a pointer (`*mut libc::c_char`). The length can be passed
+ explicitly (`libc::size_t`), or the string can be NUL-byte terminated
+ C string.
One might be tempted to do this via doing
`CString::new("blah").unwrap().into_raw()`. This has several problems:
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index 8ecc4175d1..9fb95c8bc6 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -311,7 +311,9 @@ GENERAL OPTIONS
other than controller connections, and we close (and don't reattempt)
any outbound
connections. Controllers sometimes use this option to avoid using
- the network until Tor is fully configured. (Default: 0)
+ the network until Tor is fully configured. Tor will make still certain
+ network-related calls (like DNS lookups) as a part of its configuration
+ process, even if DisableNetwork is set. (Default: 0)
[[ConstrainedSockets]] **ConstrainedSockets** **0**|**1**::
If set, Tor will tell the kernel to attempt to shrink the buffers for all
@@ -778,17 +780,15 @@ GENERAL OPTIONS
This is useful when running on flash memory or other media that support
only a limited number of writes. (Default: 0)
-[[CircuitPriorityHalflife]] **CircuitPriorityHalflife** __NUM1__::
+[[CircuitPriorityHalflife]] **CircuitPriorityHalflife** __NUM__::
If this value is set, we override the default algorithm for choosing which
- circuit's cell to deliver or relay next. When the value is 0, we
- round-robin between the active circuits on a connection, delivering one
- cell from each in turn. When the value is positive, we prefer delivering
- cells from whichever connection has the lowest weighted cell count, where
- cells are weighted exponentially according to the supplied
- CircuitPriorityHalflife value (in seconds). If this option is not set at
- all, we use the behavior recommended in the current consensus
- networkstatus. This is an advanced option; you generally shouldn't have
- to mess with it. (Default: not set)
+ circuit's cell to deliver or relay next. It is delivered first to the
+ circuit that has the lowest weighted cell count, where cells are weighted
+ exponentially according to this value (in seconds). If the value is -1, it
+ is taken from the consensus if possible else it will fallback to the
+ default value of 30. Minimum: 1, Maximum: 2147483647. This can be defined
+ as a float value. This is an advanced option; you generally shouldn't have
+ to mess with it. (Default: -1)
[[CountPrivateBandwidth]] **CountPrivateBandwidth** **0**|**1**::
If this option is set, then Tor's rate-limiting applies not only to
@@ -1396,7 +1396,7 @@ The following options are useful only for clients (that is, if
[[HTTPTunnelPort]] **HTTPTunnelPort** \['address':]__port__|**auto** [_isolation flags_]::
Open this port to listen for proxy connections using the "HTTP CONNECT"
- protocol instead of SOCKS. Set this to 0
+ protocol instead of SOCKS. Set this to
0 if you don't want to allow "HTTP CONNECT" connections. Set the port
to "auto" to have Tor pick a port for you. This directive can be
specified multiple times to bind to multiple addresses/ports. See
@@ -1436,7 +1436,7 @@ The following options are useful only for clients (that is, if
Set this to "default", or leave it unconfigured, to use regular IPTables
on Linux, or to use pf +rdr-to+ rules on *BSD systems. +
+
- (Default: "default".)
+ (Default: "default")
[[NATDPort]] **NATDPort** \['address':]__port__|**auto** [_isolation flags_]::
Open this port to listen for connections from old versions of ipfw (as
@@ -1729,7 +1729,7 @@ The following options are useful only for clients (that is, if
prevent your Tor client from bootstrapping. If this option is negative,
Tor will use a default value chosen by the directory authorities. If the
directory authorities do not choose a value, Tor will default to 0.6.
- (Default: -1.)
+ (Default: -1)
[[ClientBootstrapConsensusAuthorityDownloadSchedule]] **ClientBootstrapConsensusAuthorityDownloadSchedule** __N__,__N__,__...__::
Schedule for when clients should download consensuses from authorities
@@ -1887,7 +1887,7 @@ is non-zero):
If you want to use a reduced exit policy rather than the default exit
policy, set "ReducedExitPolicy 1". If you want to _replace_ the default
exit policy with your custom exit policy, end your exit policy with either
- a reject *:* or an accept *:*. Otherwise, you’re _augmenting_ (prepending
+ a reject *:* or an accept *:*. Otherwise, you're _augmenting_ (prepending
to) the default or reduced exit policy. +
+
The default exit policy is:
@@ -2258,7 +2258,8 @@ is non-zero):
sent and received by this relay, in addition to total cell counts.
These statistics are rounded, and omitted if traffic is low. This
information is important for load balancing decisions related to padding.
- (Default: 1)
+ If ExtraInfoStatistics is enabled, it will be published
+ as a part of extra-info document. (Default: 1)
[[DirReqStatistics]] **DirReqStatistics** **0**|**1**::
Relays and bridges only.
diff --git a/src/common/address.c b/src/common/address.c
index a2f4c93b91..ca263425f0 100644
--- a/src/common/address.c
+++ b/src/common/address.c
@@ -1697,7 +1697,7 @@ get_interface_address6_via_udp_socket_hack,(int severity,
sa_family_t family,
tor_addr_t *addr))
{
- struct sockaddr_storage my_addr, target_addr;
+ struct sockaddr_storage target_addr;
int sock=-1, r=-1;
socklen_t addr_len;
@@ -1740,21 +1740,19 @@ get_interface_address6_via_udp_socket_hack,(int severity,
goto err;
}
- if (tor_getsockname(sock,(struct sockaddr*)&my_addr, &addr_len)) {
+ if (tor_addr_from_getsockname(addr, sock) < 0) {
int e = tor_socket_errno(sock);
log_fn(severity, LD_NET, "getsockname() to determine interface failed: %s",
tor_socket_strerror(e));
goto err;
}
- if (tor_addr_from_sockaddr(addr, (struct sockaddr*)&my_addr, NULL) == 0) {
- if (tor_addr_is_loopback(addr) || tor_addr_is_multicast(addr)) {
- log_fn(severity, LD_NET, "Address that we determined via UDP socket"
- " magic is unsuitable for public comms.");
- } else {
- r=0;
- }
- }
+ if (tor_addr_is_loopback(addr) || tor_addr_is_multicast(addr)) {
+ log_fn(severity, LD_NET, "Address that we determined via UDP socket"
+ " magic is unsuitable for public comms.");
+ } else {
+ r=0;
+ }
err:
if (sock >= 0)
diff --git a/src/common/buffers.h b/src/common/buffers.h
index 22a5f7bfa3..4275152de2 100644
--- a/src/common/buffers.h
+++ b/src/common/buffers.h
@@ -13,7 +13,6 @@
#define TOR_BUFFERS_H
#include "compat.h"
-#include "compat.h"
#include "torint.h"
#include "testsupport.h"
diff --git a/src/common/compat.c b/src/common/compat.c
index 4cb346dfa5..e8916c8d1f 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -100,7 +100,6 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt)
/* Only use the linux prctl; the IRIX prctl is totally different */
#include <sys/prctl.h>
#elif defined(__APPLE__)
-#include <sys/types.h>
#include <sys/ptrace.h>
#endif /* defined(HAVE_SYS_PRCTL_H) && defined(__linux__) || ... */
@@ -1392,6 +1391,24 @@ tor_getsockname,(tor_socket_t sock, struct sockaddr *address,
return getsockname(sock, address, address_len);
}
+/**
+ * Find the local address associated with the socket <b>sock</b>, and
+ * place it in *<b>addr_out</b>. Return 0 on success, -1 on failure.
+ *
+ * (As tor_getsockname, but instead places the result in a tor_addr_t.) */
+int
+tor_addr_from_getsockname(tor_addr_t *addr_out, tor_socket_t sock)
+{
+ struct sockaddr_storage ss;
+ socklen_t ss_len = sizeof(ss);
+ memset(&ss, 0, sizeof(ss));
+
+ if (tor_getsockname(sock, (struct sockaddr *) &ss, &ss_len) < 0)
+ return -1;
+
+ return tor_addr_from_sockaddr(addr_out, (struct sockaddr *)&ss, NULL);
+}
+
/** Turn <b>socket</b> into a nonblocking socket. Return 0 on success, -1
* on failure.
*/
diff --git a/src/common/compat.h b/src/common/compat.h
index 93301feda0..f7932c914a 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -510,6 +510,8 @@ int get_n_open_sockets(void);
MOCK_DECL(int,
tor_getsockname,(tor_socket_t socket, struct sockaddr *address,
socklen_t *address_len));
+struct tor_addr_t;
+int tor_addr_from_getsockname(struct tor_addr_t *addr_out, tor_socket_t sock);
#define tor_socket_send(s, buf, len, flags) send(s, buf, len, flags)
#define tor_socket_recv(s, buf, len, flags) recv(s, buf, len, flags)
diff --git a/src/common/compat_winthreads.c b/src/common/compat_winthreads.c
index 5f7ec94c23..7021344f6e 100644
--- a/src/common/compat_winthreads.c
+++ b/src/common/compat_winthreads.c
@@ -18,7 +18,6 @@
#include "util.h"
#include "container.h"
#include "torlog.h"
-#include <process.h>
/* This value is more or less total cargo-cult */
#define SPIN_COUNT 2000
diff --git a/src/common/compress.c b/src/common/compress.c
index 47c93cf6a9..cb1549f1aa 100644
--- a/src/common/compress.c
+++ b/src/common/compress.c
@@ -663,3 +663,13 @@ tor_compress_init(void)
tor_zstd_init();
}
+/** Warn if we had any problems while setting up our compression libraries.
+ *
+ * (This isn't part of tor_compress_init, since the logs aren't set up yet.)
+ */
+void
+tor_compress_log_init_warnings(void)
+{
+ tor_zstd_warn_if_version_mismatched();
+}
+
diff --git a/src/common/compress.h b/src/common/compress.h
index 952102bf97..65d63a4386 100644
--- a/src/common/compress.h
+++ b/src/common/compress.h
@@ -87,6 +87,7 @@ void tor_compress_free_(tor_compress_state_t *state);
size_t tor_compress_state_size(const tor_compress_state_t *state);
void tor_compress_init(void);
+void tor_compress_log_init_warnings(void);
#endif /* !defined(TOR_COMPRESS_H) */
diff --git a/src/common/compress_zstd.c b/src/common/compress_zstd.c
index 0db87d61b7..4024f5594d 100644
--- a/src/common/compress_zstd.c
+++ b/src/common/compress_zstd.c
@@ -18,6 +18,13 @@
#include "compress.h"
#include "compress_zstd.h"
+#ifdef ENABLE_ZSTD_ADVANCED_APIS
+/* This is a lie, but we make sure it doesn't get us in trouble by wrapping
+ * all invocations of zstd's static-only functions in a check to make sure
+ * that the compile-time version matches the run-time version. */
+#define ZSTD_STATIC_LINKING_ONLY
+#endif
+
#ifdef HAVE_ZSTD
#include <zstd.h>
#endif
@@ -51,21 +58,31 @@ tor_zstd_method_supported(void)
#endif
}
+#ifdef HAVE_ZSTD
+/** Format a zstd version number as a string in <b>buf</b>. */
+static void
+tor_zstd_format_version(char *buf, size_t buflen, unsigned version_number)
+{
+ tor_snprintf(buf, buflen,
+ "%u.%u.%u",
+ version_number / 10000 % 100,
+ version_number / 100 % 100,
+ version_number % 100);
+}
+#endif
+
+#define VERSION_STR_MAX_LEN 16 /* more than enough space for 99.99.99 */
+
/** Return a string representation of the version of the currently running
* version of libzstd. Returns NULL if Zstandard is unsupported. */
const char *
tor_zstd_get_version_str(void)
{
#ifdef HAVE_ZSTD
- static char version_str[16];
- size_t version_number;
+ static char version_str[VERSION_STR_MAX_LEN];
- version_number = ZSTD_versionNumber();
- tor_snprintf(version_str, sizeof(version_str),
- "%d.%d.%d",
- (int) version_number / 10000 % 100,
- (int) version_number / 100 % 100,
- (int) version_number % 100);
+ tor_zstd_format_version(version_str, sizeof(version_str),
+ ZSTD_versionNumber());
return version_str;
#else /* !(defined(HAVE_ZSTD)) */
@@ -85,6 +102,26 @@ tor_zstd_get_header_version_str(void)
#endif
}
+#ifdef TOR_UNIT_TESTS
+static int static_apis_disable_for_testing = 0;
+#endif
+
+/** Return true iff we can use the "static-only" APIs. */
+int
+tor_zstd_can_use_static_apis(void)
+{
+#if defined(ZSTD_STATIC_LINKING_ONLY) && defined(HAVE_ZSTD)
+#ifdef TOR_UNIT_TESTS
+ if (static_apis_disable_for_testing) {
+ return 0;
+ }
+#endif
+ return (ZSTD_VERSION_NUMBER == ZSTD_versionNumber());
+#else
+ return 0;
+#endif
+}
+
/** Internal Zstandard state for incremental compression/decompression.
* The body of this struct is not exposed. */
struct tor_zstd_compress_state_t {
@@ -112,9 +149,11 @@ struct tor_zstd_compress_state_t {
#ifdef HAVE_ZSTD
/** Return an approximate number of bytes stored in memory to hold the
- * Zstandard compression/decompression state. */
+ * Zstandard compression/decompression state. This is a fake estimate
+ * based on inspecting the zstd source: tor_zstd_state_size_precalc() is
+ * more accurate when it's allowed to use "static-only" functions */
static size_t
-tor_zstd_state_size_precalc(int compress, int preset)
+tor_zstd_state_size_precalc_fake(int compress, int preset)
{
tor_assert(preset > 0);
@@ -171,6 +210,28 @@ tor_zstd_state_size_precalc(int compress, int preset)
return memory_usage;
}
+
+/** Return an approximate number of bytes stored in memory to hold the
+ * Zstandard compression/decompression state. */
+static size_t
+tor_zstd_state_size_precalc(int compress, int preset)
+{
+#ifdef ZSTD_STATIC_LINKING_ONLY
+ if (tor_zstd_can_use_static_apis()) {
+ if (compress) {
+#ifdef HAVE_ZSTD_ESTIMATECSTREAMSIZE
+ return ZSTD_estimateCStreamSize(preset);
+#endif
+ } else {
+#ifdef HAVE_ZSTD_ESTIMATEDCTXSIZE
+ /* Could use DStream, but that takes a windowSize. */
+ return ZSTD_estimateDCtxSize();
+#endif
+ }
+ }
+#endif
+ return tor_zstd_state_size_precalc_fake(compress, preset);
+}
#endif /* defined(HAVE_ZSTD) */
/** Construct and return a tor_zstd_compress_state_t object using
@@ -440,3 +501,34 @@ tor_zstd_init(void)
atomic_counter_init(&total_zstd_allocation);
}
+/** Warn if the header and library versions don't match. */
+void
+tor_zstd_warn_if_version_mismatched(void)
+{
+#if defined(HAVE_ZSTD) && defined(ENABLE_ZSTD_ADVANCED_APIS)
+ if (! tor_zstd_can_use_static_apis()) {
+ char header_version[VERSION_STR_MAX_LEN];
+ char runtime_version[VERSION_STR_MAX_LEN];
+ tor_zstd_format_version(header_version, sizeof(header_version),
+ ZSTD_VERSION_NUMBER);
+ tor_zstd_format_version(runtime_version, sizeof(runtime_version),
+ ZSTD_versionNumber());
+
+ log_warn(LD_GENERAL,
+ "Tor was compiled with zstd %s, but is running with zstd %s. "
+ "For safety, we'll avoid using advanced zstd functionality.",
+ header_version, runtime_version);
+ }
+#endif
+}
+
+#ifdef TOR_UNIT_TESTS
+/** Testing only: disable usage of static-only APIs, so we can make sure that
+ * we still work without them. */
+void
+tor_zstd_set_static_apis_disabled_for_testing(int disabled)
+{
+ static_apis_disable_for_testing = disabled;
+}
+#endif
+
diff --git a/src/common/compress_zstd.h b/src/common/compress_zstd.h
index 9bca24ded7..bd42cf65ce 100644
--- a/src/common/compress_zstd.h
+++ b/src/common/compress_zstd.h
@@ -17,6 +17,8 @@ const char *tor_zstd_get_version_str(void);
const char *tor_zstd_get_header_version_str(void);
+int tor_zstd_can_use_static_apis(void);
+
/** Internal state for an incremental Zstandard compression/decompression. */
typedef struct tor_zstd_compress_state_t tor_zstd_compress_state_t;
@@ -41,6 +43,11 @@ size_t tor_zstd_compress_state_size(const tor_zstd_compress_state_t *state);
size_t tor_zstd_get_total_allocation(void);
void tor_zstd_init(void);
+void tor_zstd_warn_if_version_mismatched(void);
+
+#ifdef TOR_UNIT_TESTS
+void tor_zstd_set_static_apis_disabled_for_testing(int disabled);
+#endif
#endif /* !defined(TOR_COMPRESS_ZSTD_H) */
diff --git a/src/common/crypto.c b/src/common/crypto.c
index d85aca4004..ade8b0191f 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -970,6 +970,7 @@ crypto_digest_alloc_bytes(digest_algorithm_t alg)
/* Gives the length of crypto_digest_t through the end of the field 'd' */
#define END_OF_FIELD(f) (offsetof(crypto_digest_t, f) + \
STRUCT_FIELD_SIZE(crypto_digest_t, f))
+
switch (alg) {
case DIGEST_SHA1:
return END_OF_FIELD(d.sha1);
@@ -1155,6 +1156,29 @@ crypto_digest_dup(const crypto_digest_t *digest)
return tor_memdup(digest, alloc_bytes);
}
+/** Temporarily save the state of <b>digest</b> in <b>checkpoint</b>.
+ * Asserts that <b>digest</b> is a SHA1 digest object.
+ */
+void
+crypto_digest_checkpoint(crypto_digest_checkpoint_t *checkpoint,
+ const crypto_digest_t *digest)
+{
+ const size_t bytes = crypto_digest_alloc_bytes(digest->algorithm);
+ tor_assert(bytes <= sizeof(checkpoint->mem));
+ memcpy(checkpoint->mem, digest, bytes);
+}
+
+/** Restore the state of <b>digest</b> from <b>checkpoint</b>.
+ * Asserts that <b>digest</b> is a SHA1 digest object. Requires that the
+ * state was previously stored with crypto_digest_checkpoint() */
+void
+crypto_digest_restore(crypto_digest_t *digest,
+ const crypto_digest_checkpoint_t *checkpoint)
+{
+ const size_t bytes = crypto_digest_alloc_bytes(digest->algorithm);
+ memcpy(digest, checkpoint->mem, bytes);
+}
+
/** Replace the state of the digest object <b>into</b> with the state
* of the digest object <b>from</b>. Requires that 'into' and 'from'
* have the same digest type.
diff --git a/src/common/crypto.h b/src/common/crypto.h
index a9c8837b9e..015c5fcfe7 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -90,6 +90,13 @@ typedef struct crypto_digest_t crypto_digest_t;
typedef struct crypto_xof_t crypto_xof_t;
typedef struct crypto_dh_t crypto_dh_t;
+#define DIGEST_CHECKPOINT_BYTES (SIZEOF_VOID_P + 512)
+/** Structure used to temporarily save the a digest object. Only implemented
+ * for SHA1 digest for now. */
+typedef struct crypto_digest_checkpoint_t {
+ uint8_t mem[DIGEST_CHECKPOINT_BYTES];
+} crypto_digest_checkpoint_t;
+
/* global state */
int crypto_early_init(void) ATTR_WUR;
int crypto_global_init(int hardwareAccel,
@@ -178,6 +185,10 @@ void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data,
void crypto_digest_get_digest(crypto_digest_t *digest,
char *out, size_t out_len);
crypto_digest_t *crypto_digest_dup(const crypto_digest_t *digest);
+void crypto_digest_checkpoint(crypto_digest_checkpoint_t *checkpoint,
+ const crypto_digest_t *digest);
+void crypto_digest_restore(crypto_digest_t *digest,
+ const crypto_digest_checkpoint_t *checkpoint);
void crypto_digest_assign(crypto_digest_t *into,
const crypto_digest_t *from);
void crypto_hmac_sha256(char *hmac_out,
diff --git a/src/common/util.h b/src/common/util.h
index 2ee0ea28cd..653c154aba 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -73,9 +73,9 @@ extern int dmalloc_free(const char *file, const int line, void *pnt,
} \
STMT_END
#else /* !(defined(USE_DMALLOC)) */
-/** Release memory allocated by tor_malloc, tor_realloc, tor_strdup, etc.
- * Unlike the free() function, tor_free() will still work on NULL pointers,
- * and it sets the pointer value to NULL after freeing it.
+/** Release memory allocated by tor_malloc, tor_realloc, tor_strdup,
+ * etc. Unlike the free() function, the tor_free() macro sets the
+ * pointer value to NULL after freeing it.
*
* This is a macro. If you need a function pointer to release memory from
* tor_malloc(), use tor_free_().
@@ -88,17 +88,13 @@ extern int dmalloc_free(const char *file, const int line, void *pnt,
#ifdef __GNUC__
#define tor_free(p) STMT_BEGIN \
typeof(&(p)) tor_free__tmpvar = &(p); \
- if (PREDICT_LIKELY((*tor_free__tmpvar)!=NULL)) { \
- raw_free(*tor_free__tmpvar); \
- *tor_free__tmpvar=NULL; \
- } \
+ raw_free(*tor_free__tmpvar); \
+ *tor_free__tmpvar=NULL; \
STMT_END
#else
#define tor_free(p) STMT_BEGIN \
- if (PREDICT_LIKELY((p)!=NULL)) { \
- raw_free(p); \
- (p)=NULL; \
- } \
+ raw_free(p); \
+ (p)=NULL; \
STMT_END
#endif
#endif /* defined(USE_DMALLOC) */
diff --git a/src/or/channel.c b/src/or/channel.c
index ff1cfde2ad..a9483ee021 100644
--- a/src/or/channel.c
+++ b/src/or/channel.c
@@ -2109,21 +2109,6 @@ channel_listener_dumpstats(int severity)
}
/**
- * Set the cmux policy on all active channels.
- */
-void
-channel_set_cmux_policy_everywhere(circuitmux_policy_t *pol)
-{
- if (!active_channels) return;
-
- SMARTLIST_FOREACH_BEGIN(active_channels, channel_t *, curr) {
- if (curr->cmux) {
- circuitmux_set_policy(curr->cmux, pol);
- }
- } SMARTLIST_FOREACH_END(curr);
-}
-
-/**
* Clean up channels.
*
* This gets called periodically from run_scheduled_events() in main.c;
diff --git a/src/or/channel.h b/src/or/channel.h
index 0af5aed414..6cf8cd7f72 100644
--- a/src/or/channel.h
+++ b/src/or/channel.h
@@ -422,9 +422,6 @@ void channel_free_all(void);
void channel_dumpstats(int severity);
void channel_listener_dumpstats(int severity);
-/* Set the cmux policy on all active channels */
-void channel_set_cmux_policy_everywhere(circuitmux_policy_t *pol);
-
#ifdef TOR_CHANNEL_INTERNAL_
#ifdef CHANNEL_PRIVATE_
diff --git a/src/or/channeltls.c b/src/or/channeltls.c
index 9000703b01..54d94f6109 100644
--- a/src/or/channeltls.c
+++ b/src/or/channeltls.c
@@ -160,9 +160,8 @@ channel_tls_common_init(channel_tls_t *tlschan)
chan->write_var_cell = channel_tls_write_var_cell_method;
chan->cmux = circuitmux_alloc();
- if (cell_ewma_enabled()) {
- circuitmux_set_policy(chan->cmux, &ewma_policy);
- }
+ /* We only have one policy for now so always set it to EWMA. */
+ circuitmux_set_policy(chan->cmux, &ewma_policy);
}
/**
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 8fe6ba0e60..b3b543348c 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -1055,7 +1055,7 @@ circuit_build_no_more_hops(origin_circuit_t *circ)
clear_broken_connection_map(1);
if (server_mode(options) && !check_whether_orport_reachable(options)) {
inform_testing_reachability();
- consider_testing_reachability(1, 1);
+ router_do_reachability_checks(1, 1);
}
}
@@ -1611,7 +1611,7 @@ onionskin_answer(or_circuit_t *circ,
* rend_service_launch_establish_intro())
*
* - We are a router testing its own reachabiity
- * (CIRCUIT_PURPOSE_TESTING, via consider_testing_reachability())
+ * (CIRCUIT_PURPOSE_TESTING, via router_do_reachability_checks())
*
* onion_pick_cpath_exit() bypasses us (by not calling
* new_route_len()) in the one-hop tunnel case, so we don't need to
@@ -2866,8 +2866,10 @@ extend_info_from_node(const node_t *node, int for_direct_connect)
valid_addr = fascist_firewall_choose_address_node(node,
FIREWALL_OR_CONNECTION,
0, &ap);
- else
- valid_addr = !node_get_prim_orport(node, &ap);
+ else {
+ node_get_prim_orport(node, &ap);
+ valid_addr = tor_addr_port_is_valid_ap(&ap, 0);
+ }
if (valid_addr)
log_debug(LD_CIRC, "using %s for %s",
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 29ad9a8ee5..00726ca986 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -403,9 +403,6 @@ circuit_set_p_circid_chan(or_circuit_t *or_circ, circid_t id,
circuit_set_circid_chan_helper(circ, CELL_DIRECTION_IN, id, chan);
if (chan) {
- tor_assert(bool_eq(or_circ->p_chan_cells.n,
- or_circ->next_active_on_p_chan));
-
chan->timestamp_last_had_circuits = approx_time();
}
@@ -428,8 +425,6 @@ circuit_set_n_circid_chan(circuit_t *circ, circid_t id,
circuit_set_circid_chan_helper(circ, CELL_DIRECTION_OUT, id, chan);
if (chan) {
- tor_assert(bool_eq(circ->n_chan_cells.n, circ->next_active_on_n_chan));
-
chan->timestamp_last_had_circuits = approx_time();
}
diff --git a/src/or/circuitmux.c b/src/or/circuitmux.c
index fe3d8f1332..f9f5faa057 100644
--- a/src/or/circuitmux.c
+++ b/src/or/circuitmux.c
@@ -114,13 +114,6 @@ struct circuitmux_s {
*/
chanid_circid_muxinfo_map_t *chanid_circid_map;
- /*
- * Double-linked ring of circuits with queued cells waiting for room to
- * free up on this connection's outbuf. Every time we pull cells from
- * a circuit, we advance this pointer to the next circuit in the ring.
- */
- struct circuit_t *active_circuits_head, *active_circuits_tail;
-
/** List of queued destroy cells */
destroy_cell_queue_t destroy_cell_queue;
/** Boolean: True iff the last cell to circuitmux_get_first_active_circuit
@@ -177,17 +170,6 @@ struct chanid_circid_muxinfo_t {
};
/*
- * Internal-use #defines
- */
-
-#ifdef CMUX_PARANOIA
-#define circuitmux_assert_okay_paranoid(cmux) \
- circuitmux_assert_okay(cmux)
-#else
-#define circuitmux_assert_okay_paranoid(cmux)
-#endif /* defined(CMUX_PARANOIA) */
-
-/*
* Static function declarations
*/
@@ -199,21 +181,9 @@ chanid_circid_entry_hash(chanid_circid_muxinfo_t *a);
static chanid_circid_muxinfo_t *
circuitmux_find_map_entry(circuitmux_t *cmux, circuit_t *circ);
static void
-circuitmux_make_circuit_active(circuitmux_t *cmux, circuit_t *circ,
- cell_direction_t direction);
+circuitmux_make_circuit_active(circuitmux_t *cmux, circuit_t *circ);
static void
-circuitmux_make_circuit_inactive(circuitmux_t *cmux, circuit_t *circ,
- cell_direction_t direction);
-static inline void
-circuitmux_move_active_circ_to_tail(circuitmux_t *cmux, circuit_t *circ,
- cell_direction_t direction);
-static inline circuit_t **
-circuitmux_next_active_circ_p(circuitmux_t *cmux, circuit_t *circ);
-static inline circuit_t **
-circuitmux_prev_active_circ_p(circuitmux_t *cmux, circuit_t *circ);
-static void circuitmux_assert_okay_pass_one(circuitmux_t *cmux);
-static void circuitmux_assert_okay_pass_two(circuitmux_t *cmux);
-static void circuitmux_assert_okay_pass_three(circuitmux_t *cmux);
+circuitmux_make_circuit_inactive(circuitmux_t *cmux, circuit_t *circ);
/* Static global variables */
@@ -223,119 +193,6 @@ static int64_t global_destroy_ctr = 0;
/* Function definitions */
/**
- * Linked list helpers
- */
-
-/**
- * Move an active circuit to the tail of the cmux's active circuits list;
- * used by circuitmux_notify_xmit_cells().
- */
-
-static inline void
-circuitmux_move_active_circ_to_tail(circuitmux_t *cmux, circuit_t *circ,
- cell_direction_t direction)
-{
- circuit_t **next_p = NULL, **prev_p = NULL;
- circuit_t **next_prev = NULL, **prev_next = NULL;
- circuit_t **tail_next = NULL;
- or_circuit_t *or_circ = NULL;
-
- tor_assert(cmux);
- tor_assert(circ);
-
- circuitmux_assert_okay_paranoid(cmux);
-
- /* Figure out our next_p and prev_p for this cmux/direction */
- if (direction) {
- if (direction == CELL_DIRECTION_OUT) {
- tor_assert(circ->n_mux == cmux);
- next_p = &(circ->next_active_on_n_chan);
- prev_p = &(circ->prev_active_on_n_chan);
- } else {
- or_circ = TO_OR_CIRCUIT(circ);
- tor_assert(or_circ->p_mux == cmux);
- next_p = &(or_circ->next_active_on_p_chan);
- prev_p = &(or_circ->prev_active_on_p_chan);
- }
- } else {
- if (circ->n_mux == cmux) {
- next_p = &(circ->next_active_on_n_chan);
- prev_p = &(circ->prev_active_on_n_chan);
- } else {
- or_circ = TO_OR_CIRCUIT(circ);
- tor_assert(or_circ->p_mux == cmux);
- next_p = &(or_circ->next_active_on_p_chan);
- prev_p = &(or_circ->prev_active_on_p_chan);
- }
- }
- tor_assert(next_p);
- tor_assert(prev_p);
-
- /* Check if this really is an active circuit */
- if ((*next_p == NULL && *prev_p == NULL) &&
- !(circ == cmux->active_circuits_head ||
- circ == cmux->active_circuits_tail)) {
- /* Not active, no-op */
- return;
- }
-
- /* Check if this is already the tail */
- if (circ == cmux->active_circuits_tail) return;
-
- /* Okay, we have to move it; figure out next_prev and prev_next */
- if (*next_p) next_prev = circuitmux_prev_active_circ_p(cmux, *next_p);
- if (*prev_p) prev_next = circuitmux_next_active_circ_p(cmux, *prev_p);
- /* Adjust the previous node's next pointer, if any */
- if (prev_next) *prev_next = *next_p;
- /* Otherwise, we were the head */
- else cmux->active_circuits_head = *next_p;
- /* Adjust the next node's previous pointer, if any */
- if (next_prev) *next_prev = *prev_p;
- /* We're out of the list; now re-attach at the tail */
- /* Adjust our next and prev pointers */
- *next_p = NULL;
- *prev_p = cmux->active_circuits_tail;
- /* Set the next pointer of the tail, or the head if none */
- if (cmux->active_circuits_tail) {
- tail_next = circuitmux_next_active_circ_p(cmux,
- cmux->active_circuits_tail);
- *tail_next = circ;
- } else {
- cmux->active_circuits_head = circ;
- }
- /* Set the tail to this circuit */
- cmux->active_circuits_tail = circ;
-
- circuitmux_assert_okay_paranoid(cmux);
-}
-
-static inline circuit_t **
-circuitmux_next_active_circ_p(circuitmux_t *cmux, circuit_t *circ)
-{
- tor_assert(cmux);
- tor_assert(circ);
-
- if (circ->n_mux == cmux) return &(circ->next_active_on_n_chan);
- else {
- tor_assert(TO_OR_CIRCUIT(circ)->p_mux == cmux);
- return &(TO_OR_CIRCUIT(circ)->next_active_on_p_chan);
- }
-}
-
-static inline circuit_t **
-circuitmux_prev_active_circ_p(circuitmux_t *cmux, circuit_t *circ)
-{
- tor_assert(cmux);
- tor_assert(circ);
-
- if (circ->n_mux == cmux) return &(circ->prev_active_on_n_chan);
- else {
- tor_assert(TO_OR_CIRCUIT(circ)->p_mux == cmux);
- return &(TO_OR_CIRCUIT(circ)->prev_active_on_p_chan);
- }
-}
-
-/**
* Helper for chanid_circid_cell_count_map_t hash table: compare the channel
* ID and circuit ID for a and b, and return less than, equal to, or greater
* than zero appropriately.
@@ -406,11 +263,6 @@ circuitmux_detach_all_circuits(circuitmux_t *cmux, smartlist_t *detached_out)
circuit_t *circ = NULL;
tor_assert(cmux);
- /*
- * Don't circuitmux_assert_okay_paranoid() here; this gets called when
- * channels are being freed and have already been unregistered, so
- * the channel ID lookups it does will fail.
- */
i = HT_START(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
while (i) {
@@ -435,7 +287,7 @@ circuitmux_detach_all_circuits(circuitmux_t *cmux, smartlist_t *detached_out)
*/
if (to_remove->muxinfo.cell_count > 0) {
- circuitmux_make_circuit_inactive(cmux, circ, CELL_DIRECTION_OUT);
+ circuitmux_make_circuit_inactive(cmux, circ);
}
/* Clear n_mux */
@@ -450,7 +302,7 @@ circuitmux_detach_all_circuits(circuitmux_t *cmux, smartlist_t *detached_out)
*/
if (to_remove->muxinfo.cell_count > 0) {
- circuitmux_make_circuit_inactive(cmux, circ, CELL_DIRECTION_IN);
+ circuitmux_make_circuit_inactive(cmux, circ);
}
/*
@@ -606,9 +458,7 @@ circuitmux_clear_policy(circuitmux_t *cmux)
tor_assert(cmux);
/* Internally, this is just setting policy to NULL */
- if (cmux->policy) {
- circuitmux_set_policy(cmux, NULL);
- }
+ circuitmux_set_policy(cmux, NULL);
}
/**
@@ -944,7 +794,6 @@ circuitmux_attach_circuit,(circuitmux_t *cmux, circuit_t *circ,
tor_assert(circ);
tor_assert(direction == CELL_DIRECTION_IN ||
direction == CELL_DIRECTION_OUT);
- circuitmux_assert_okay_paranoid(cmux);
/*
* Figure out which channel we're using, and get the circuit's current
@@ -1002,10 +851,10 @@ circuitmux_attach_circuit,(circuitmux_t *cmux, circuit_t *circ,
*/
if (hashent->muxinfo.cell_count > 0 && cell_count == 0) {
--(cmux->n_active_circuits);
- circuitmux_make_circuit_inactive(cmux, circ, direction);
+ circuitmux_make_circuit_inactive(cmux, circ);
} else if (hashent->muxinfo.cell_count == 0 && cell_count > 0) {
++(cmux->n_active_circuits);
- circuitmux_make_circuit_active(cmux, circ, direction);
+ circuitmux_make_circuit_active(cmux, circ);
}
cmux->n_cells -= hashent->muxinfo.cell_count;
cmux->n_cells += cell_count;
@@ -1033,7 +882,7 @@ circuitmux_attach_circuit,(circuitmux_t *cmux, circuit_t *circ,
hashent->muxinfo.cell_count = cell_count;
hashent->muxinfo.direction = direction;
/* Allocate policy specific circuit data if we need it */
- if (cmux->policy && cmux->policy->alloc_circ_data) {
+ if (cmux->policy->alloc_circ_data) {
/* Assert that we have the means to free policy-specific data */
tor_assert(cmux->policy->free_circ_data);
/* Allocate it */
@@ -1053,25 +902,14 @@ circuitmux_attach_circuit,(circuitmux_t *cmux, circuit_t *circ,
if (direction == CELL_DIRECTION_OUT) circ->n_mux = cmux;
else TO_OR_CIRCUIT(circ)->p_mux = cmux;
- /* Make sure the next/prev pointers are NULL */
- if (direction == CELL_DIRECTION_OUT) {
- circ->next_active_on_n_chan = NULL;
- circ->prev_active_on_n_chan = NULL;
- } else {
- TO_OR_CIRCUIT(circ)->next_active_on_p_chan = NULL;
- TO_OR_CIRCUIT(circ)->prev_active_on_p_chan = NULL;
- }
-
/* Update counters */
++(cmux->n_circuits);
if (cell_count > 0) {
++(cmux->n_active_circuits);
- circuitmux_make_circuit_active(cmux, circ, direction);
+ circuitmux_make_circuit_active(cmux, circ);
}
cmux->n_cells += cell_count;
}
-
- circuitmux_assert_okay_paranoid(cmux);
}
/**
@@ -1095,7 +933,6 @@ circuitmux_detach_circuit,(circuitmux_t *cmux, circuit_t *circ))
tor_assert(cmux);
tor_assert(cmux->chanid_circid_map);
tor_assert(circ);
- circuitmux_assert_okay_paranoid(cmux);
/* See if we have it for n_chan/n_circ_id */
if (circ->n_chan) {
@@ -1133,7 +970,7 @@ circuitmux_detach_circuit,(circuitmux_t *cmux, circuit_t *circ))
if (hashent->muxinfo.cell_count > 0) {
--(cmux->n_active_circuits);
/* This does policy notifies, so comes before freeing policy data */
- circuitmux_make_circuit_inactive(cmux, circ, last_searched_direction);
+ circuitmux_make_circuit_inactive(cmux, circ);
}
cmux->n_cells -= hashent->muxinfo.cell_count;
@@ -1162,8 +999,6 @@ circuitmux_detach_circuit,(circuitmux_t *cmux, circuit_t *circ))
/* Free the hash entry */
tor_free(hashent);
}
-
- circuitmux_assert_okay_paranoid(cmux);
}
/**
@@ -1172,94 +1007,22 @@ circuitmux_detach_circuit,(circuitmux_t *cmux, circuit_t *circ))
*/
static void
-circuitmux_make_circuit_active(circuitmux_t *cmux, circuit_t *circ,
- cell_direction_t direction)
+circuitmux_make_circuit_active(circuitmux_t *cmux, circuit_t *circ)
{
- circuit_t **next_active = NULL, **prev_active = NULL, **next_prev = NULL;
- circuitmux_t *circuit_cmux = NULL;
- chanid_circid_muxinfo_t *hashent = NULL;
- channel_t *chan = NULL;
- circid_t circ_id;
- int already_active;
-
tor_assert(cmux);
+ tor_assert(cmux->policy);
tor_assert(circ);
- tor_assert(direction == CELL_DIRECTION_OUT ||
- direction == CELL_DIRECTION_IN);
- /*
- * Don't circuitmux_assert_okay_paranoid(cmux) here because the cell count
- * already got changed and we have to update the list for it to be consistent
- * again.
- */
-
- /* Get the right set of active list links for this direction */
- if (direction == CELL_DIRECTION_OUT) {
- next_active = &(circ->next_active_on_n_chan);
- prev_active = &(circ->prev_active_on_n_chan);
- circuit_cmux = circ->n_mux;
- chan = circ->n_chan;
- circ_id = circ->n_circ_id;
- } else {
- next_active = &(TO_OR_CIRCUIT(circ)->next_active_on_p_chan);
- prev_active = &(TO_OR_CIRCUIT(circ)->prev_active_on_p_chan);
- circuit_cmux = TO_OR_CIRCUIT(circ)->p_mux;
- chan = TO_OR_CIRCUIT(circ)->p_chan;
- circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
- }
-
- /* Assert that it is attached to this mux and a channel */
- tor_assert(cmux == circuit_cmux);
- tor_assert(chan != NULL);
-
- /*
- * Check if the circuit really was inactive; if it's active, at least one
- * of the next_active and prev_active pointers will not be NULL, or this
- * circuit will be either the head or tail of the list for this cmux.
- */
- already_active = (*prev_active != NULL || *next_active != NULL ||
- cmux->active_circuits_head == circ ||
- cmux->active_circuits_tail == circ);
-
- /* If we're already active, log a warning and finish */
- if (already_active) {
- log_warn(LD_CIRC,
- "Circuit %u on channel " U64_FORMAT " was already active",
- (unsigned)circ_id, U64_PRINTF_ARG(chan->global_identifier));
- return;
- }
-
- /*
- * This is going at the head of the list; if the old head is not NULL,
- * then its prev pointer should point to this.
- */
- *next_active = cmux->active_circuits_head; /* Next is old head */
- *prev_active = NULL; /* Prev is NULL (this will be the head) */
- if (cmux->active_circuits_head) {
- /* The list had an old head; update its prev pointer */
- next_prev =
- circuitmux_prev_active_circ_p(cmux, cmux->active_circuits_head);
- tor_assert(next_prev);
- *next_prev = circ;
- } else {
- /* The list was empty; this becomes the tail as well */
- cmux->active_circuits_tail = circ;
- }
- /* This becomes the new head of the list */
- cmux->active_circuits_head = circ;
/* Policy-specific notification */
- if (cmux->policy &&
- cmux->policy->notify_circ_active) {
+ if (cmux->policy->notify_circ_active) {
/* Okay, we need to check the circuit for policy data now */
- hashent = circuitmux_find_map_entry(cmux, circ);
+ chanid_circid_muxinfo_t *hashent = circuitmux_find_map_entry(cmux, circ);
/* We should have found something */
tor_assert(hashent);
/* Notify */
cmux->policy->notify_circ_active(cmux, cmux->policy_data,
circ, hashent->muxinfo.policy_data);
}
-
- circuitmux_assert_okay_paranoid(cmux);
}
/**
@@ -1268,112 +1031,22 @@ circuitmux_make_circuit_active(circuitmux_t *cmux, circuit_t *circ,
*/
static void
-circuitmux_make_circuit_inactive(circuitmux_t *cmux, circuit_t *circ,
- cell_direction_t direction)
+circuitmux_make_circuit_inactive(circuitmux_t *cmux, circuit_t *circ)
{
- circuit_t **next_active = NULL, **prev_active = NULL;
- circuit_t **next_prev = NULL, **prev_next = NULL;
- circuitmux_t *circuit_cmux = NULL;
- chanid_circid_muxinfo_t *hashent = NULL;
- channel_t *chan = NULL;
- circid_t circ_id;
- int already_inactive;
-
tor_assert(cmux);
+ tor_assert(cmux->policy);
tor_assert(circ);
- tor_assert(direction == CELL_DIRECTION_OUT ||
- direction == CELL_DIRECTION_IN);
- /*
- * Don't circuitmux_assert_okay_paranoid(cmux) here because the cell count
- * already got changed and we have to update the list for it to be consistent
- * again.
- */
-
- /* Get the right set of active list links for this direction */
- if (direction == CELL_DIRECTION_OUT) {
- next_active = &(circ->next_active_on_n_chan);
- prev_active = &(circ->prev_active_on_n_chan);
- circuit_cmux = circ->n_mux;
- chan = circ->n_chan;
- circ_id = circ->n_circ_id;
- } else {
- next_active = &(TO_OR_CIRCUIT(circ)->next_active_on_p_chan);
- prev_active = &(TO_OR_CIRCUIT(circ)->prev_active_on_p_chan);
- circuit_cmux = TO_OR_CIRCUIT(circ)->p_mux;
- chan = TO_OR_CIRCUIT(circ)->p_chan;
- circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
- }
-
- /* Assert that it is attached to this mux and a channel */
- tor_assert(cmux == circuit_cmux);
- tor_assert(chan != NULL);
-
- /*
- * Check if the circuit really was active; if it's inactive, the
- * next_active and prev_active pointers will be NULL and this circuit
- * will not be the head or tail of the list for this cmux.
- */
- already_inactive = (*prev_active == NULL && *next_active == NULL &&
- cmux->active_circuits_head != circ &&
- cmux->active_circuits_tail != circ);
-
- /* If we're already inactive, log a warning and finish */
- if (already_inactive) {
- log_warn(LD_CIRC,
- "Circuit %d on channel " U64_FORMAT " was already inactive",
- (unsigned)circ_id, U64_PRINTF_ARG(chan->global_identifier));
- return;
- }
-
- /* Remove from the list; first get next_prev and prev_next */
- if (*next_active) {
- /*
- * If there's a next circuit, its previous circuit becomes this
- * circuit's previous circuit.
- */
- next_prev = circuitmux_prev_active_circ_p(cmux, *next_active);
- } else {
- /* Else, the tail becomes this circuit's previous circuit */
- next_prev = &(cmux->active_circuits_tail);
- }
-
- /* Got next_prev, now prev_next */
- if (*prev_active) {
- /*
- * If there's a previous circuit, its next circuit becomes this circuit's
- * next circuit.
- */
- prev_next = circuitmux_next_active_circ_p(cmux, *prev_active);
- } else {
- /* Else, the head becomes this circuit's next circuit */
- prev_next = &(cmux->active_circuits_head);
- }
-
- /* Assert that we got sensible values for the next/prev pointers */
- tor_assert(next_prev != NULL);
- tor_assert(prev_next != NULL);
-
- /* Update the next/prev pointers - this removes circ from the list */
- *next_prev = *prev_active;
- *prev_next = *next_active;
-
- /* Now null out prev_active/next_active */
- *prev_active = NULL;
- *next_active = NULL;
/* Policy-specific notification */
- if (cmux->policy &&
- cmux->policy->notify_circ_inactive) {
+ if (cmux->policy->notify_circ_inactive) {
/* Okay, we need to check the circuit for policy data now */
- hashent = circuitmux_find_map_entry(cmux, circ);
+ chanid_circid_muxinfo_t *hashent = circuitmux_find_map_entry(cmux, circ);
/* We should have found something */
tor_assert(hashent);
/* Notify */
cmux->policy->notify_circ_inactive(cmux, cmux->policy_data,
circ, hashent->muxinfo.policy_data);
}
-
- circuitmux_assert_okay_paranoid(cmux);
}
/**
@@ -1400,8 +1073,6 @@ circuitmux_set_num_cells(circuitmux_t *cmux, circuit_t *circ,
tor_assert(cmux);
tor_assert(circ);
- circuitmux_assert_okay_paranoid(cmux);
-
/* Search for this circuit's entry */
hashent = circuitmux_find_map_entry(cmux, circ);
/* Assert that we found one */
@@ -1412,7 +1083,7 @@ circuitmux_set_num_cells(circuitmux_t *cmux, circuit_t *circ,
cmux->n_cells += n_cells;
/* Do we need to notify a cmux policy? */
- if (cmux->policy && cmux->policy->notify_set_n_cells) {
+ if (cmux->policy->notify_set_n_cells) {
/* Call notify_set_n_cells */
cmux->policy->notify_set_n_cells(cmux,
cmux->policy_data,
@@ -1428,21 +1099,15 @@ circuitmux_set_num_cells(circuitmux_t *cmux, circuit_t *circ,
if (hashent->muxinfo.cell_count > 0 && n_cells == 0) {
--(cmux->n_active_circuits);
hashent->muxinfo.cell_count = n_cells;
- circuitmux_make_circuit_inactive(cmux, circ, hashent->muxinfo.direction);
+ circuitmux_make_circuit_inactive(cmux, circ);
/* Is the old cell count == 0 and the new cell count > 0 ? */
} else if (hashent->muxinfo.cell_count == 0 && n_cells > 0) {
++(cmux->n_active_circuits);
hashent->muxinfo.cell_count = n_cells;
- circuitmux_make_circuit_active(cmux, circ, hashent->muxinfo.direction);
+ circuitmux_make_circuit_active(cmux, circ);
} else {
- /*
- * Update the entry cell count like this so we can put a
- * circuitmux_assert_okay_paranoid inside make_circuit_(in)active() too.
- */
hashent->muxinfo.cell_count = n_cells;
}
-
- circuitmux_assert_okay_paranoid(cmux);
}
/*
@@ -1468,6 +1133,9 @@ circuitmux_get_first_active_circuit(circuitmux_t *cmux,
circuit_t *circ = NULL;
tor_assert(cmux);
+ tor_assert(cmux->policy);
+ /* This callback is mandatory. */
+ tor_assert(cmux->policy->pick_active_circuit);
tor_assert(destroy_queue_out);
*destroy_queue_out = NULL;
@@ -1486,14 +1154,7 @@ circuitmux_get_first_active_circuit(circuitmux_t *cmux,
/* We also must have a cell available for this to be the case */
tor_assert(cmux->n_cells > 0);
/* Do we have a policy-provided circuit selector? */
- if (cmux->policy && cmux->policy->pick_active_circuit) {
- circ = cmux->policy->pick_active_circuit(cmux, cmux->policy_data);
- }
- /* Fall back on the head of the active circuits list */
- if (!circ) {
- tor_assert(cmux->active_circuits_head);
- circ = cmux->active_circuits_head;
- }
+ circ = cmux->policy->pick_active_circuit(cmux, cmux->policy_data);
cmux->last_cell_was_destroy = 0;
} else {
tor_assert(cmux->n_cells == 0);
@@ -1517,7 +1178,6 @@ circuitmux_notify_xmit_cells(circuitmux_t *cmux, circuit_t *circ,
tor_assert(cmux);
tor_assert(circ);
- circuitmux_assert_okay_paranoid(cmux);
if (n_cells == 0) return;
@@ -1544,17 +1204,11 @@ circuitmux_notify_xmit_cells(circuitmux_t *cmux, circuit_t *circ,
/* Adjust the mux cell counter */
cmux->n_cells -= n_cells;
- /* If we aren't making it inactive later, move it to the tail of the list */
- if (!becomes_inactive) {
- circuitmux_move_active_circ_to_tail(cmux, circ,
- hashent->muxinfo.direction);
- }
-
/*
* We call notify_xmit_cells() before making the circuit inactive if needed,
* so the policy can always count on this coming in on an active circuit.
*/
- if (cmux->policy && cmux->policy->notify_xmit_cells) {
+ if (cmux->policy->notify_xmit_cells) {
cmux->policy->notify_xmit_cells(cmux, cmux->policy_data, circ,
hashent->muxinfo.policy_data,
n_cells);
@@ -1566,10 +1220,8 @@ circuitmux_notify_xmit_cells(circuitmux_t *cmux, circuit_t *circ,
*/
if (becomes_inactive) {
--(cmux->n_active_circuits);
- circuitmux_make_circuit_inactive(cmux, circ, hashent->muxinfo.direction);
+ circuitmux_make_circuit_inactive(cmux, circ);
}
-
- circuitmux_assert_okay_paranoid(cmux);
}
/**
@@ -1592,282 +1244,6 @@ circuitmux_notify_xmit_destroy(circuitmux_t *cmux)
I64_PRINTF_ARG(global_destroy_ctr));
}
-/*
- * Circuitmux consistency checking assertions
- */
-
-/**
- * Check that circuitmux data structures are consistent and fail with an
- * assert if not.
- */
-
-void
-circuitmux_assert_okay(circuitmux_t *cmux)
-{
- tor_assert(cmux);
-
- /*
- * Pass 1: iterate the hash table; for each entry:
- * a) Check that the circuit has this cmux for n_mux or p_mux
- * b) If the cell_count is > 0, set the mark bit; otherwise clear it
- * c) Also check activeness (cell_count > 0 should be active)
- * d) Count the number of circuits, active circuits and queued cells
- * and at the end check that they match the counters in the cmux.
- *
- * Pass 2: iterate the active circuits list; for each entry,
- * make sure the circuit is attached to this mux and appears
- * in the hash table. Make sure the mark bit is 1, and clear
- * it in the hash table entry. Consistency-check the linked
- * list pointers.
- *
- * Pass 3: iterate the hash table again; assert if any active circuits
- * (mark bit set to 1) are discovered that weren't cleared in pass 2
- * (don't appear in the linked list).
- */
-
- circuitmux_assert_okay_pass_one(cmux);
- circuitmux_assert_okay_pass_two(cmux);
- circuitmux_assert_okay_pass_three(cmux);
-}
-
-/**
- * Do the first pass of circuitmux_assert_okay(); see the comment in that
- * function.
- */
-
-static void
-circuitmux_assert_okay_pass_one(circuitmux_t *cmux)
-{
- chanid_circid_muxinfo_t **i = NULL;
- uint64_t chan_id;
- channel_t *chan;
- circid_t circ_id;
- circuit_t *circ;
- or_circuit_t *or_circ;
- circuit_t **next_p, **prev_p;
- unsigned int n_circuits, n_active_circuits, n_cells;
-
- tor_assert(cmux);
- tor_assert(cmux->chanid_circid_map);
-
- /* Reset the counters */
- n_circuits = n_active_circuits = n_cells = 0;
- /* Start iterating the hash table */
- i = HT_START(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
- while (i) {
- /* Assert that the hash table entry isn't null */
- tor_assert(*i);
-
- /* Get the channel and circuit id */
- chan_id = (*i)->chan_id;
- circ_id = (*i)->circ_id;
-
- /* Find the channel and circuit, assert that they exist */
- chan = channel_find_by_global_id(chan_id);
- tor_assert(chan);
- circ = circuit_get_by_circid_channel_even_if_marked(circ_id, chan);
- tor_assert(circ);
-
- /* Assert that we know which direction this is going */
- tor_assert((*i)->muxinfo.direction == CELL_DIRECTION_OUT ||
- (*i)->muxinfo.direction == CELL_DIRECTION_IN);
-
- if ((*i)->muxinfo.direction == CELL_DIRECTION_OUT) {
- /* We should be n_mux on this circuit */
- tor_assert(cmux == circ->n_mux);
- tor_assert(chan == circ->n_chan);
- /* Get next and prev for next test */
- next_p = &(circ->next_active_on_n_chan);
- prev_p = &(circ->prev_active_on_n_chan);
- } else {
- /* This should be an or_circuit_t and we should be p_mux */
- or_circ = TO_OR_CIRCUIT(circ);
- tor_assert(cmux == or_circ->p_mux);
- tor_assert(chan == or_circ->p_chan);
- /* Get next and prev for next test */
- next_p = &(or_circ->next_active_on_p_chan);
- prev_p = &(or_circ->prev_active_on_p_chan);
- }
-
- /*
- * Should this circuit be active? I.e., does the mux know about > 0
- * cells on it?
- */
- const int circ_is_active = ((*i)->muxinfo.cell_count > 0);
-
- /* It should be in the linked list iff it's active */
- if (circ_is_active) {
- /* Either we have a next link or we are the tail */
- tor_assert(*next_p || (circ == cmux->active_circuits_tail));
- /* Either we have a prev link or we are the head */
- tor_assert(*prev_p || (circ == cmux->active_circuits_head));
- /* Increment the active circuits counter */
- ++n_active_circuits;
- } else {
- /* Shouldn't be in list, so no next or prev link */
- tor_assert(!(*next_p));
- tor_assert(!(*prev_p));
- /* And can't be head or tail */
- tor_assert(circ != cmux->active_circuits_head);
- tor_assert(circ != cmux->active_circuits_tail);
- }
-
- /* Increment the circuits counter */
- ++n_circuits;
- /* Adjust the cell counter */
- n_cells += (*i)->muxinfo.cell_count;
-
- /* Set the mark bit to circ_is_active */
- (*i)->muxinfo.mark = circ_is_active;
-
- /* Advance to the next entry */
- i = HT_NEXT(chanid_circid_muxinfo_map, cmux->chanid_circid_map, i);
- }
-
- /* Now check the counters */
- tor_assert(n_cells == cmux->n_cells);
- tor_assert(n_circuits == cmux->n_circuits);
- tor_assert(n_active_circuits == cmux->n_active_circuits);
-}
-
-/**
- * Do the second pass of circuitmux_assert_okay(); see the comment in that
- * function.
- */
-
-static void
-circuitmux_assert_okay_pass_two(circuitmux_t *cmux)
-{
- circuit_t *curr_circ, *prev_circ = NULL, *next_circ;
- or_circuit_t *curr_or_circ;
- uint64_t curr_chan_id;
- circid_t curr_circ_id;
- circuit_t **next_p, **prev_p;
- channel_t *chan;
- unsigned int n_active_circuits = 0;
- chanid_circid_muxinfo_t search, *hashent = NULL;
-
- tor_assert(cmux);
- tor_assert(cmux->chanid_circid_map);
-
- /*
- * Walk the linked list of active circuits in cmux; keep track of the
- * previous circuit seen for consistency checking purposes. Count them
- * to make sure the number in the linked list matches
- * cmux->n_active_circuits.
- */
- curr_circ = cmux->active_circuits_head;
- while (curr_circ) {
- /* Reset some things */
- chan = NULL;
- curr_or_circ = NULL;
- next_circ = NULL;
- next_p = prev_p = NULL;
- cell_direction_t direction;
-
- /* Figure out if this is n_mux or p_mux */
- if (cmux == curr_circ->n_mux) {
- /* Get next_p and prev_p */
- next_p = &(curr_circ->next_active_on_n_chan);
- prev_p = &(curr_circ->prev_active_on_n_chan);
- /* Get the channel */
- chan = curr_circ->n_chan;
- /* Get the circuit id */
- curr_circ_id = curr_circ->n_circ_id;
- /* Remember the direction */
- direction = CELL_DIRECTION_OUT;
- } else {
- /* We must be p_mux and this must be an or_circuit_t */
- curr_or_circ = TO_OR_CIRCUIT(curr_circ);
- tor_assert(cmux == curr_or_circ->p_mux);
- /* Get next_p and prev_p */
- next_p = &(curr_or_circ->next_active_on_p_chan);
- prev_p = &(curr_or_circ->prev_active_on_p_chan);
- /* Get the channel */
- chan = curr_or_circ->p_chan;
- /* Get the circuit id */
- curr_circ_id = curr_or_circ->p_circ_id;
- /* Remember the direction */
- direction = CELL_DIRECTION_IN;
- }
-
- /* Assert that we got a channel and get the channel ID */
- tor_assert(chan);
- curr_chan_id = chan->global_identifier;
-
- /* Assert that prev_p points to last circuit we saw */
- tor_assert(*prev_p == prev_circ);
- /* If that's NULL, assert that we are the head */
- if (!(*prev_p)) tor_assert(curr_circ == cmux->active_circuits_head);
-
- /* Get the next circuit */
- next_circ = *next_p;
- /* If it's NULL, assert that we are the tail */
- if (!(*next_p)) tor_assert(curr_circ == cmux->active_circuits_tail);
-
- /* Now find the hash table entry for this circuit */
- search.chan_id = curr_chan_id;
- search.circ_id = curr_circ_id;
- hashent = HT_FIND(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
- &search);
-
- /* Assert that we have one */
- tor_assert(hashent);
-
- /* Assert that the direction matches */
- tor_assert(direction == hashent->muxinfo.direction);
-
- /* Assert that the hash entry got marked in pass one */
- tor_assert(hashent->muxinfo.mark);
-
- /* Clear the mark */
- hashent->muxinfo.mark = 0;
-
- /* Increment the counter */
- ++n_active_circuits;
-
- /* Advance to the next active circuit and update prev_circ */
- prev_circ = curr_circ;
- curr_circ = next_circ;
- }
-
- /* Assert that the counter matches the cmux */
- tor_assert(n_active_circuits == cmux->n_active_circuits);
-}
-
-/**
- * Do the third pass of circuitmux_assert_okay(); see the comment in that
- * function.
- */
-
-static void
-circuitmux_assert_okay_pass_three(circuitmux_t *cmux)
-{
- chanid_circid_muxinfo_t **i = NULL;
-
- tor_assert(cmux);
- tor_assert(cmux->chanid_circid_map);
-
- /* Start iterating the hash table */
- i = HT_START(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
-
- /* Advance through each entry */
- while (i) {
- /* Assert that it isn't null */
- tor_assert(*i);
-
- /*
- * Assert that this entry is not marked - i.e., that either we didn't
- * think it should be active in pass one or we saw it in the active
- * circuits linked list.
- */
- tor_assert(!((*i)->muxinfo.mark));
-
- /* Advance to the next entry */
- i = HT_NEXT(chanid_circid_muxinfo_map, cmux->chanid_circid_map, i);
- }
-}
-
/*DOCDOC */
void
circuitmux_append_destroy_cell(channel_t *chan,
diff --git a/src/or/circuitmux_ewma.c b/src/or/circuitmux_ewma.c
index fde2d22a89..b2ace8a9fa 100644
--- a/src/or/circuitmux_ewma.c
+++ b/src/or/circuitmux_ewma.c
@@ -223,8 +223,6 @@ ewma_cmp_cmux(circuitmux_t *cmux_1, circuitmux_policy_data_t *pol_data_1,
* has value ewma_scale_factor ** N.)
*/
static double ewma_scale_factor = 0.1;
-/* DOCDOC ewma_enabled */
-static int ewma_enabled = 0;
/*** EWMA circuitmux_policy_t method table ***/
@@ -243,6 +241,13 @@ circuitmux_policy_t ewma_policy = {
/*** EWMA method implementations using the below EWMA helper functions ***/
+/** Compute and return the current cell_ewma tick. */
+static inline unsigned int
+cell_ewma_get_tick(void)
+{
+ return ((unsigned)approx_time() / EWMA_TICK_LEN);
+}
+
/**
* Allocate an ewma_policy_data_t and upcast it to a circuitmux_policy_data_t;
* this is called when setting the policy on a circuitmux_t to ewma_policy.
@@ -612,59 +617,79 @@ cell_ewma_tick_from_timeval(const struct timeval *now,
return res;
}
-/** Tell the caller whether ewma_enabled is set */
-int
-cell_ewma_enabled(void)
+/* Default value for the CircuitPriorityHalflifeMsec consensus parameter in
+ * msec. */
+#define CMUX_PRIORITY_HALFLIFE_MSEC_DEFAULT 30000
+/* Minimum and maximum value for the CircuitPriorityHalflifeMsec consensus
+ * parameter. */
+#define CMUX_PRIORITY_HALFLIFE_MSEC_MIN 1
+#define CMUX_PRIORITY_HALFLIFE_MSEC_MAX INT32_MAX
+
+/* Return the value of the circuit priority halflife from the options if
+ * available or else from the consensus (in that order). If none can be found,
+ * a default value is returned.
+ *
+ * The source_msg points to a string describing from where the value was
+ * picked so it can be used for logging. */
+static double
+get_circuit_priority_halflife(const or_options_t *options,
+ const networkstatus_t *consensus,
+ const char **source_msg)
{
- return ewma_enabled;
-}
+ int32_t halflife_ms;
+ double halflife;
+ /* Compute the default value now. We might need it. */
+ double halflife_default =
+ ((double) CMUX_PRIORITY_HALFLIFE_MSEC_DEFAULT) / 1000.0;
-/** Compute and return the current cell_ewma tick. */
-unsigned int
-cell_ewma_get_tick(void)
-{
- return ((unsigned)approx_time() / EWMA_TICK_LEN);
+ /* Try to get it from configuration file first. */
+ if (options && options->CircuitPriorityHalflife < EPSILON) {
+ halflife = options->CircuitPriorityHalflife;
+ *source_msg = "CircuitPriorityHalflife in configuration";
+ goto end;
+ }
+
+ /* Try to get the msec value from the consensus. */
+ halflife_ms = networkstatus_get_param(consensus,
+ "CircuitPriorityHalflifeMsec",
+ CMUX_PRIORITY_HALFLIFE_MSEC_DEFAULT,
+ CMUX_PRIORITY_HALFLIFE_MSEC_MIN,
+ CMUX_PRIORITY_HALFLIFE_MSEC_MAX);
+ halflife = ((double) halflife_ms) / 1000.0;
+ *source_msg = "CircuitPriorityHalflifeMsec in consensus";
+
+ end:
+ /* We should never go below the EPSILON else we would consider it disabled
+ * and we can't have that. */
+ if (halflife < EPSILON) {
+ log_warn(LD_CONFIG, "CircuitPriorityHalflife is too small (%f). "
+ "Adjusting to the smallest value allowed: %f.",
+ halflife, halflife_default);
+ halflife = halflife_default;
+ }
+ return halflife;
}
/** Adjust the global cell scale factor based on <b>options</b> */
void
-cell_ewma_set_scale_factor(const or_options_t *options,
- const networkstatus_t *consensus)
+cmux_ewma_set_options(const or_options_t *options,
+ const networkstatus_t *consensus)
{
- int32_t halflife_ms;
double halflife;
const char *source;
- if (options && options->CircuitPriorityHalflife >= -EPSILON) {
- halflife = options->CircuitPriorityHalflife;
- source = "CircuitPriorityHalflife in configuration";
- } else if (consensus && (halflife_ms = networkstatus_get_param(
- consensus, "CircuitPriorityHalflifeMsec",
- -1, -1, INT32_MAX)) >= 0) {
- halflife = ((double)halflife_ms)/1000.0;
- source = "CircuitPriorityHalflifeMsec in consensus";
- } else {
- halflife = EWMA_DEFAULT_HALFLIFE;
- source = "Default value";
- }
- if (halflife <= EPSILON) {
- /* The cell EWMA algorithm is disabled. */
- ewma_scale_factor = 0.1;
- ewma_enabled = 0;
- log_info(LD_OR,
- "Disabled cell_ewma algorithm because of value in %s",
- source);
- } else {
- /* convert halflife into halflife-per-tick. */
- halflife /= EWMA_TICK_LEN;
- /* compute per-tick scale factor. */
- ewma_scale_factor = exp( LOG_ONEHALF / halflife );
- ewma_enabled = 1;
- log_info(LD_OR,
- "Enabled cell_ewma algorithm because of value in %s; "
- "scale factor is %f per %d seconds",
- source, ewma_scale_factor, EWMA_TICK_LEN);
- }
+ /* Both options and consensus can be NULL. This assures us to either get a
+ * valid configured value or the default one. */
+ halflife = get_circuit_priority_halflife(options, consensus, &source);
+
+ /* convert halflife into halflife-per-tick. */
+ halflife /= EWMA_TICK_LEN;
+ /* compute per-tick scale factor. */
+ ewma_scale_factor = exp( LOG_ONEHALF / halflife );
+ log_info(LD_OR,
+ "Enabled cell_ewma algorithm because of value in %s; "
+ "scale factor is %f per %d seconds",
+ source, ewma_scale_factor, EWMA_TICK_LEN);
}
/** Return the multiplier necessary to convert the value of a cell sent in
diff --git a/src/or/circuitmux_ewma.h b/src/or/circuitmux_ewma.h
index 8f4e57865e..2ef8c2586d 100644
--- a/src/or/circuitmux_ewma.h
+++ b/src/or/circuitmux_ewma.h
@@ -12,13 +12,12 @@
#include "or.h"
#include "circuitmux.h"
+/* The public EWMA policy callbacks object. */
extern circuitmux_policy_t ewma_policy;
/* Externally visible EWMA functions */
-int cell_ewma_enabled(void);
-unsigned int cell_ewma_get_tick(void);
-void cell_ewma_set_scale_factor(const or_options_t *options,
- const networkstatus_t *consensus);
+void cmux_ewma_set_options(const or_options_t *options,
+ const networkstatus_t *consensus);
#endif /* !defined(TOR_CIRCUITMUX_EWMA_H) */
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index bc9c4bccbd..8d388cc2c6 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -55,7 +55,6 @@
#include "rephist.h"
#include "router.h"
#include "routerlist.h"
-#include "config.h"
static void circuit_expire_old_circuits_clientside(void);
static void circuit_increment_failure_count(void);
@@ -1632,7 +1631,7 @@ circuit_testing_opened(origin_circuit_t *circ)
router_perform_bandwidth_test(NUM_PARALLEL_TESTING_CIRCS, time(NULL));
have_performed_bandwidth_test = 1;
} else
- consider_testing_reachability(1, 0);
+ router_do_reachability_checks(1, 0);
}
/** A testing circuit has failed to build. Take whatever stats we want. */
@@ -2584,7 +2583,7 @@ link_apconn_to_circ(entry_connection_t *apconn, origin_circuit_t *circ,
log_debug(LD_APP|LD_CIRC, "attaching new conn to circ. n_circ_id %u.",
(unsigned)circ->base_.n_circ_id);
/* reset it, so we can measure circ timeouts */
- ENTRY_TO_CONN(apconn)->timestamp_lastread = time(NULL);
+ ENTRY_TO_CONN(apconn)->timestamp_last_read_allowed = time(NULL);
ENTRY_TO_EDGE_CONN(apconn)->next_stream = circ->p_streams;
ENTRY_TO_EDGE_CONN(apconn)->on_circuit = TO_CIRCUIT(circ);
/* assert_connection_ok(conn, time(NULL)); */
diff --git a/src/or/config.c b/src/or/config.c
index 685884fb84..212c6c6b94 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -264,7 +264,7 @@ static config_var_t option_vars_[] = {
OBSOLETE("CircuitIdleTimeout"),
V(CircuitsAvailableTimeout, INTERVAL, "0"),
V(CircuitStreamTimeout, INTERVAL, "0"),
- V(CircuitPriorityHalflife, DOUBLE, "-100.0"), /*negative:'Use default'*/
+ V(CircuitPriorityHalflife, DOUBLE, "-1.0"), /*negative:'Use default'*/
V(ClientDNSRejectInternalAddresses, BOOL,"1"),
V(ClientOnly, BOOL, "0"),
V(ClientPreferIPv6ORPort, AUTOBOOL, "auto"),
@@ -1791,7 +1791,6 @@ options_act(const or_options_t *old_options)
char *msg=NULL;
const int transition_affects_workers =
old_options && options_transition_affects_workers(old_options, options);
- int old_ewma_enabled;
const int transition_affects_guards =
old_options && options_transition_affects_guards(old_options, options);
@@ -2065,16 +2064,8 @@ options_act(const or_options_t *old_options)
if (accounting_is_enabled(options))
configure_accounting(time(NULL));
- old_ewma_enabled = cell_ewma_enabled();
/* Change the cell EWMA settings */
- cell_ewma_set_scale_factor(options, networkstatus_get_latest_consensus());
- /* If we just enabled ewma, set the cmux policy on all active channels */
- if (cell_ewma_enabled() && !old_ewma_enabled) {
- channel_set_cmux_policy_everywhere(&ewma_policy);
- } else if (!cell_ewma_enabled() && old_ewma_enabled) {
- /* Turn it off everywhere */
- channel_set_cmux_policy_everywhere(NULL);
- }
+ cmux_ewma_set_options(options, networkstatus_get_latest_consensus());
/* Update the BridgePassword's hashed version as needed. We store this as a
* digest so that we can do side-channel-proof comparisons on it.
@@ -4634,15 +4625,14 @@ have_enough_mem_for_dircache(const or_options_t *options, size_t total_mem,
if (options->DirCache) {
if (total_mem < DIRCACHE_MIN_MEM_BYTES) {
if (options->BridgeRelay) {
- *msg = tor_strdup("Running a Bridge with less than "
- STRINGIFY(DIRCACHE_MIN_MEM_MB) " MB of memory is not "
- "recommended.");
+ tor_asprintf(msg, "Running a Bridge with less than %d MB of memory "
+ "is not recommended.", DIRCACHE_MIN_MEM_MB);
} else {
- *msg = tor_strdup("Being a directory cache (default) with less than "
- STRINGIFY(DIRCACHE_MIN_MEM_MB) " MB of memory is not "
- "recommended and may consume most of the available "
- "resources, consider disabling this functionality by "
- "setting the DirCache option to 0.");
+ tor_asprintf(msg, "Being a directory cache (default) with less than "
+ "%d MB of memory is not recommended and may consume "
+ "most of the available resources. Consider disabling "
+ "this functionality by setting the DirCache option "
+ "to 0.", DIRCACHE_MIN_MEM_MB);
}
}
} else {
diff --git a/src/or/connection.c b/src/or/connection.c
index 2a6b10763e..5532551cfe 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -101,7 +101,6 @@
#include "transports.h"
#include "routerparse.h"
#include "sandbox.h"
-#include "transports.h"
#ifdef HAVE_PWD_H
#include <pwd.h>
@@ -460,8 +459,8 @@ connection_init(time_t now, connection_t *conn, int type, int socket_family)
}
conn->timestamp_created = now;
- conn->timestamp_lastread = now;
- conn->timestamp_lastwritten = now;
+ conn->timestamp_last_read_allowed = now;
+ conn->timestamp_last_write_allowed = now;
}
/** Create a link between <b>conn_a</b> and <b>conn_b</b>. */
@@ -859,7 +858,7 @@ connection_mark_for_close_internal_, (connection_t *conn,
/* in case we're going to be held-open-til-flushed, reset
* the number of seconds since last successful write, so
* we get our whole 15 seconds */
- conn->timestamp_lastwritten = time(NULL);
+ conn->timestamp_last_write_allowed = time(NULL);
}
/** Find each connection that has hold_open_until_flushed set to
@@ -881,7 +880,7 @@ connection_expire_held_open(void)
*/
if (conn->hold_open_until_flushed) {
tor_assert(conn->marked_for_close);
- if (now - conn->timestamp_lastwritten >= 15) {
+ if (now - conn->timestamp_last_write_allowed >= 15) {
int severity;
if (conn->type == CONN_TYPE_EXIT ||
(conn->type == CONN_TYPE_DIR &&
@@ -1259,15 +1258,12 @@ connection_listener_new(const struct sockaddr *listensockaddr,
gotPort = usePort;
} else {
tor_addr_t addr2;
- struct sockaddr_storage ss;
- socklen_t ss_len=sizeof(ss);
- if (getsockname(s, (struct sockaddr*)&ss, &ss_len)<0) {
+ if (tor_addr_from_getsockname(&addr2, s)<0) {
log_warn(LD_NET, "getsockname() couldn't learn address for %s: %s",
conn_type_to_string(type),
tor_socket_strerror(tor_socket_errno(s)));
gotPort = 0;
}
- tor_addr_from_sockaddr(&addr2, (struct sockaddr*)&ss, &gotPort);
}
#ifdef HAVE_SYS_UN_H
/*
@@ -3418,7 +3414,7 @@ connection_handle_read_impl(connection_t *conn)
if (conn->marked_for_close)
return 0; /* do nothing */
- conn->timestamp_lastread = approx_time();
+ conn->timestamp_last_read_allowed = approx_time();
switch (conn->type) {
case CONN_TYPE_OR_LISTENER:
@@ -3819,7 +3815,7 @@ update_send_buffer_size(tor_socket_t sock)
* when libevent tells us that conn wants to write, or below
* from connection_buf_add() when an entire TLS record is ready.
*
- * Update <b>conn</b>-\>timestamp_lastwritten to now, and call flush_buf
+ * Update <b>conn</b>-\>timestamp_last_write_allowed to now, and call flush_buf
* or flush_buf_tls appropriately. If it succeeds and there are no more
* more bytes on <b>conn</b>-\>outbuf, then call connection_finished_flushing
* on it too.
@@ -3852,7 +3848,7 @@ connection_handle_write_impl(connection_t *conn, int force)
return 0;
}
- conn->timestamp_lastwritten = now;
+ conn->timestamp_last_write_allowed = now;
/* Sometimes, "writable" means "connected". */
if (connection_state_is_connecting(conn)) {
@@ -4528,8 +4524,6 @@ alloc_http_authenticator(const char *authenticator)
static void
client_check_address_changed(tor_socket_t sock)
{
- struct sockaddr_storage out_sockaddr;
- socklen_t out_addr_len = (socklen_t) sizeof(out_sockaddr);
tor_addr_t out_addr, iface_addr;
tor_addr_t **last_interface_ip_ptr;
sa_family_t family;
@@ -4537,13 +4531,12 @@ client_check_address_changed(tor_socket_t sock)
if (!outgoing_addrs)
outgoing_addrs = smartlist_new();
- if (getsockname(sock, (struct sockaddr*)&out_sockaddr, &out_addr_len)<0) {
+ if (tor_addr_from_getsockname(&out_addr, sock) < 0) {
int e = tor_socket_errno(sock);
log_warn(LD_NET, "getsockname() to check for address change failed: %s",
tor_socket_strerror(e));
return;
}
- tor_addr_from_sockaddr(&out_addr, (struct sockaddr*)&out_sockaddr, NULL);
family = tor_addr_family(&out_addr);
if (family == AF_INET)
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index a47f044e08..948c8722bf 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -739,7 +739,7 @@ connection_ap_expire_beginning(void)
/* if it's an internal linked connection, don't yell its status. */
severity = (tor_addr_is_null(&base_conn->addr) && !base_conn->port)
? LOG_INFO : LOG_NOTICE;
- seconds_idle = (int)( now - base_conn->timestamp_lastread );
+ seconds_idle = (int)( now - base_conn->timestamp_last_read_allowed );
seconds_since_born = (int)( now - base_conn->timestamp_created );
if (base_conn->state == AP_CONN_STATE_OPEN)
@@ -825,7 +825,7 @@ connection_ap_expire_beginning(void)
mark_circuit_unusable_for_new_conns(TO_ORIGIN_CIRCUIT(circ));
/* give our stream another 'cutoff' seconds to try */
- conn->base_.timestamp_lastread += cutoff;
+ conn->base_.timestamp_last_read_allowed += cutoff;
if (entry_conn->num_socks_retries < 250) /* avoid overflow */
entry_conn->num_socks_retries++;
/* move it back into 'pending' state, and try to attach. */
@@ -1135,7 +1135,7 @@ connection_ap_detach_retriable(entry_connection_t *conn,
int reason)
{
control_event_stream_status(conn, STREAM_EVENT_FAILED_RETRIABLE, reason);
- ENTRY_TO_CONN(conn)->timestamp_lastread = time(NULL);
+ ENTRY_TO_CONN(conn)->timestamp_last_read_allowed = time(NULL);
/* Roll back path bias use state so that we probe the circuit
* if nothing else succeeds on it */
diff --git a/src/or/control.c b/src/or/control.c
index 6ac2dcb3db..7786e16481 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -7599,6 +7599,9 @@ control_free_all(void)
tor_event_free(flush_queued_events_event);
flush_queued_events_event = NULL;
}
+ bootstrap_percent = BOOTSTRAP_STATUS_UNDEF;
+ notice_bootstrap_percent = 0;
+ bootstrap_problems = 0;
}
#ifdef TOR_UNIT_TESTS
diff --git a/src/or/directory.c b/src/or/directory.c
index 29d091af38..c419b61d02 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -2437,7 +2437,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
* and the date header. (We used to check now-date_header, but that's
* inaccurate if we spend a lot of time downloading.)
*/
- apparent_skew = conn->base_.timestamp_lastwritten - date_header;
+ apparent_skew = conn->base_.timestamp_last_write_allowed - date_header;
if (labs(apparent_skew)>ALLOW_DIRECTORY_TIME_SKEW) {
int trusted = router_digest_is_trusted_dir(conn->identity_digest);
clock_skew_warning(TO_CONN(conn), apparent_skew, trusted, LD_HTTP,
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 0f47a83986..7a693b9d43 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -1423,7 +1423,7 @@ dirserv_thinks_router_is_hs_dir(const routerinfo_t *router,
* tests aren't instant. If we haven't been running long enough,
* trust the relay. */
- if (stats_n_seconds_working >
+ if (get_uptime() >
get_options()->MinUptimeHidServDirectoryV2 * 1.1)
uptime = MIN(rep_hist_get_uptime(router->cache_info.identity_digest, now),
real_uptime(router, now));
@@ -3392,7 +3392,8 @@ dirserv_single_reachability_test(time_t now, routerinfo_t *router)
tor_assert(node);
if (options->AuthDirTestEd25519LinkKeys &&
- node_supports_ed25519_link_authentication(node, 1)) {
+ node_supports_ed25519_link_authentication(node, 1) &&
+ router->cache_info.signing_key_cert) {
ed_id_key = &router->cache_info.signing_key_cert->signing_key;
} else {
ed_id_key = NULL;
diff --git a/src/or/hibernate.c b/src/or/hibernate.c
index 4dc35f68d0..7261cf8002 100644
--- a/src/or/hibernate.c
+++ b/src/or/hibernate.c
@@ -866,7 +866,7 @@ hibernate_end(hibernate_state_t new_state)
hibernate_state = new_state;
hibernate_end_time = 0; /* no longer hibernating */
- stats_n_seconds_working = 0; /* reset published uptime */
+ reset_uptime(); /* reset published uptime */
}
/** A wrapper around hibernate_begin, for when we get SIGINT. */
diff --git a/src/or/hs_client.c b/src/or/hs_client.c
index d3978f22f0..20963cd453 100644
--- a/src/or/hs_client.c
+++ b/src/or/hs_client.c
@@ -17,7 +17,6 @@
#include "hs_descriptor.h"
#include "hs_cache.h"
#include "hs_cell.h"
-#include "hs_ident.h"
#include "config.h"
#include "directory.h"
#include "hs_client.h"
@@ -29,7 +28,6 @@
#include "connection.h"
#include "nodelist.h"
#include "circpathbias.h"
-#include "connection.h"
#include "hs_ntor.h"
#include "circuitbuild.h"
#include "networkstatus.h"
@@ -1439,8 +1437,8 @@ hs_client_desc_has_arrived(const hs_ident_dir_conn_t *ident)
* connection is considered "fresh" and can continue without being closed
* too early. */
base_conn->timestamp_created = now;
- base_conn->timestamp_lastread = now;
- base_conn->timestamp_lastwritten = now;
+ base_conn->timestamp_last_read_allowed = now;
+ base_conn->timestamp_last_write_allowed = now;
/* Change connection's state into waiting for a circuit. */
base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
diff --git a/src/or/hs_common.c b/src/or/hs_common.c
index 6d97c8775c..aa34b0e8fb 100644
--- a/src/or/hs_common.c
+++ b/src/or/hs_common.c
@@ -28,7 +28,6 @@
#include "rendservice.h"
#include "routerset.h"
#include "router.h"
-#include "routerset.h"
#include "shared_random.h"
#include "shared_random_state.h"
diff --git a/src/or/hs_intropoint.c b/src/or/hs_intropoint.c
index 8c6453e6fd..3274e8e9c0 100644
--- a/src/or/hs_intropoint.c
+++ b/src/or/hs_intropoint.c
@@ -12,7 +12,6 @@
#include "config.h"
#include "circuitlist.h"
#include "circuituse.h"
-#include "config.h"
#include "relay.h"
#include "rendmid.h"
#include "rephist.h"
diff --git a/src/or/hs_service.c b/src/or/hs_service.c
index 8ae00df48e..220d3f5157 100644
--- a/src/or/hs_service.c
+++ b/src/or/hs_service.c
@@ -31,7 +31,6 @@
#include "hs_common.h"
#include "hs_config.h"
#include "hs_control.h"
-#include "hs_circuit.h"
#include "hs_descriptor.h"
#include "hs_ident.h"
#include "hs_intropoint.h"
diff --git a/src/or/keypin.c b/src/or/keypin.c
index 1698dc184f..52bdff816c 100644
--- a/src/or/keypin.c
+++ b/src/or/keypin.c
@@ -289,8 +289,10 @@ static int keypin_journal_fd = -1;
int
keypin_open_journal(const char *fname)
{
- /* O_SYNC ??*/
- int fd = tor_open_cloexec(fname, O_WRONLY|O_CREAT|O_BINARY, 0600);
+#ifndef O_SYNC
+#define O_SYNC 0
+#endif
+ int fd = tor_open_cloexec(fname, O_WRONLY|O_CREAT|O_BINARY|O_SYNC, 0600);
if (fd < 0)
goto err;
@@ -417,10 +419,11 @@ keypin_load_journal_impl(const char *data, size_t size)
++n_entries;
}
- int severity = (n_corrupt_lines || n_duplicates) ? LOG_WARN : LOG_INFO;
+ int severity = (n_corrupt_lines || n_duplicates) ? LOG_NOTICE : LOG_INFO;
tor_log(severity, LD_DIRSERV,
"Loaded %d entries from keypin journal. "
- "Found %d corrupt lines, %d duplicates, and %d conflicts.",
+ "Found %d corrupt lines (ignored), %d duplicates (harmless), "
+ "and %d conflicts (resolved in favor or more recent entry).",
n_entries, n_corrupt_lines, n_duplicates, n_conflicts);
return 0;
diff --git a/src/or/main.c b/src/or/main.c
index d1f0044095..65340751ef 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -179,7 +179,7 @@ static uint64_t stats_n_bytes_written = 0;
/** What time did this process start up? */
time_t time_of_process_start = 0;
/** How many seconds have we been running? */
-long stats_n_seconds_working = 0;
+static long stats_n_seconds_working = 0;
/** How many times have we returned from the main loop successfully? */
static uint64_t stats_n_main_loop_successes = 0;
/** How many times have we received an error from the main loop? */
@@ -1008,7 +1008,8 @@ conn_close_if_marked(int i)
LOG_FN_CONN(conn, (LOG_INFO,LD_NET,
"Holding conn (fd %d) open for more flushing.",
(int)conn->s));
- conn->timestamp_lastwritten = now; /* reset so we can flush more */
+ conn->timestamp_last_write_allowed = now; /* reset so we can flush
+ * more */
} else if (sz == 0) {
/* Also, retval==0. If we get here, we didn't want to write anything
* (because of rate-limiting) and we didn't. */
@@ -1094,7 +1095,7 @@ directory_all_unreachable(time_t now)
{
(void)now;
- stats_n_seconds_working=0; /* reset it */
+ reset_uptime(); /* reset it */
if (!directory_all_unreachable_cb_event) {
directory_all_unreachable_cb_event =
@@ -1143,7 +1144,7 @@ directory_info_has_arrived(time_t now, int from_cache, int suppress_logs)
if (server_mode(options) && !net_is_disabled() && !from_cache &&
(have_completed_a_circuit() || !any_predicted_circuits(now)))
- consider_testing_reachability(1, 1);
+ router_do_reachability_checks(1, 1);
}
/** Perform regular maintenance tasks for a single connection. This
@@ -1159,7 +1160,7 @@ run_connection_housekeeping(int i, time_t now)
channel_t *chan = NULL;
int have_any_circuits;
int past_keepalive =
- now >= conn->timestamp_lastwritten + options->KeepalivePeriod;
+ now >= conn->timestamp_last_write_allowed + options->KeepalivePeriod;
if (conn->outbuf && !connection_get_outbuf_len(conn) &&
conn->type == CONN_TYPE_OR)
@@ -1174,10 +1175,10 @@ run_connection_housekeeping(int i, time_t now)
* if a server or received if a client) for 5 min */
if (conn->type == CONN_TYPE_DIR &&
((DIR_CONN_IS_SERVER(conn) &&
- conn->timestamp_lastwritten
+ conn->timestamp_last_write_allowed
+ options->TestingDirConnectionMaxStall < now) ||
(!DIR_CONN_IS_SERVER(conn) &&
- conn->timestamp_lastread
+ conn->timestamp_last_read_allowed
+ options->TestingDirConnectionMaxStall < now))) {
log_info(LD_DIR,"Expiring wedged directory conn (fd %d, purpose %d)",
(int)conn->s, conn->purpose);
@@ -1253,13 +1254,14 @@ run_connection_housekeeping(int i, time_t now)
connection_or_close_normally(TO_OR_CONN(conn), 0);
} else if (
now >= or_conn->timestamp_lastempty + options->KeepalivePeriod*10 &&
- now >= conn->timestamp_lastwritten + options->KeepalivePeriod*10) {
+ now >=
+ conn->timestamp_last_write_allowed + options->KeepalivePeriod*10) {
log_fn(LOG_PROTOCOL_WARN,LD_PROTOCOL,
"Expiring stuck OR connection to fd %d (%s:%d). (%d bytes to "
"flush; %d seconds since last write)",
(int)conn->s, conn->address, conn->port,
(int)connection_get_outbuf_len(conn),
- (int)(now-conn->timestamp_lastwritten));
+ (int)(now-conn->timestamp_last_write_allowed));
connection_or_close_normally(TO_OR_CONN(conn), 0);
} else if (past_keepalive && !connection_get_outbuf_len(conn)) {
/* send a padding cell */
@@ -1473,6 +1475,7 @@ teardown_periodic_events(void)
for (i = 0; periodic_events[i].name; ++i) {
periodic_event_destroy(&periodic_events[i]);
}
+ periodic_events_initialized = 0;
}
/**
@@ -1940,14 +1943,14 @@ reset_padding_counts_callback(time_t now, const or_options_t *options)
return REPHIST_CELL_PADDING_COUNTS_INTERVAL;
}
+static int should_init_bridge_stats = 1;
+
/**
* Periodic callback: Write bridge statistics to disk if appropriate.
*/
static int
record_bridge_stats_callback(time_t now, const or_options_t *options)
{
- static int should_init_bridge_stats = 1;
-
/* 1h. Check whether we should write bridge statistics to disk.
*/
if (should_record_bridge_info(options)) {
@@ -2062,8 +2065,8 @@ check_for_reachability_bw_callback(time_t now, const or_options_t *options)
if (server_mode(options) &&
(have_completed_a_circuit() || !any_predicted_circuits(now)) &&
!net_is_disabled()) {
- if (stats_n_seconds_working < TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) {
- consider_testing_reachability(1, dirport_reachability_count==0);
+ if (get_uptime() < TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) {
+ router_do_reachability_checks(1, dirport_reachability_count==0);
if (++dirport_reachability_count > 5)
dirport_reachability_count = 0;
return 1;
@@ -2140,6 +2143,8 @@ expire_old_ciruits_serverside_callback(time_t now, const or_options_t *options)
return 11;
}
+static int dns_honesty_first_time = 1;
+
/**
* Periodic event: if we're an exit, see if our DNS server is telling us
* obvious lies.
@@ -2155,10 +2160,9 @@ check_dns_honesty_callback(time_t now, const or_options_t *options)
router_my_exit_policy_is_reject_star())
return PERIODIC_EVENT_NO_UPDATE;
- static int first_time = 1;
- if (first_time) {
+ if (dns_honesty_first_time) {
/* Don't launch right when we start */
- first_time = 0;
+ dns_honesty_first_time = 0;
return crypto_rand_int_range(60, 180);
}
@@ -2209,6 +2213,8 @@ check_fw_helper_app_callback(time_t now, const or_options_t *options)
return PORT_FORWARDING_CHECK_INTERVAL;
}
+static int heartbeat_callback_first_time = 1;
+
/**
* Periodic callback: write the heartbeat message in the logs.
*
@@ -2218,16 +2224,14 @@ check_fw_helper_app_callback(time_t now, const or_options_t *options)
static int
heartbeat_callback(time_t now, const or_options_t *options)
{
- static int first = 1;
-
/* Check if heartbeat is disabled */
if (!options->HeartbeatPeriod) {
return PERIODIC_EVENT_NO_UPDATE;
}
/* Skip the first one. */
- if (first) {
- first = 0;
+ if (heartbeat_callback_first_time) {
+ heartbeat_callback_first_time = 0;
return options->HeartbeatPeriod;
}
@@ -2279,6 +2283,8 @@ hs_service_callback(time_t now, const or_options_t *options)
static periodic_timer_t *second_timer = NULL;
/** Number of libevent errors in the last second: we die if we get too many. */
static int n_libevent_errors = 0;
+/** Last time that second_elapsed_callback was called. */
+static time_t current_second = 0;
/** Libevent callback: invoked once every second. */
static void
@@ -2287,7 +2293,6 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
/* XXXX This could be sensibly refactored into multiple callbacks, and we
* could use Libevent's timers for this rather than checking the current
* time against a bunch of timeouts every second. */
- static time_t current_second = 0;
time_t now;
size_t bytes_written;
size_t bytes_read;
@@ -2319,8 +2324,8 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
!net_is_disabled() &&
seconds_elapsed > 0 &&
have_completed_a_circuit() &&
- stats_n_seconds_working / TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT !=
- (stats_n_seconds_working+seconds_elapsed) /
+ get_uptime() / TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT !=
+ (get_uptime()+seconds_elapsed) /
TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) {
/* every 20 minutes, check and complain if necessary */
const routerinfo_t *me = router_get_my_routerinfo();
@@ -2382,12 +2387,14 @@ systemd_watchdog_callback(periodic_timer_t *timer, void *arg)
/** Timer: used to invoke refill_callback(). */
static periodic_timer_t *refill_timer = NULL;
+/** Millisecond when refall_callback was last invoked. */
+static struct timeval refill_timer_current_millisecond;
+
/** Libevent callback: invoked periodically to refill token buckets
* and count r/w bytes. */
static void
refill_callback(periodic_timer_t *timer, void *arg)
{
- static struct timeval current_millisecond;
struct timeval now;
size_t bytes_written;
@@ -2403,12 +2410,13 @@ refill_callback(periodic_timer_t *timer, void *arg)
tor_gettimeofday(&now);
/* If this is our first time, no time has passed. */
- if (current_millisecond.tv_sec) {
- long mdiff = tv_mdiff(&current_millisecond, &now);
+ if (refill_timer_current_millisecond.tv_sec) {
+ long mdiff = tv_mdiff(&refill_timer_current_millisecond, &now);
if (mdiff > INT_MAX)
mdiff = INT_MAX;
milliseconds_elapsed = (int)mdiff;
- seconds_rolled_over = (int)(now.tv_sec - current_millisecond.tv_sec);
+ seconds_rolled_over = (int)(now.tv_sec -
+ refill_timer_current_millisecond.tv_sec);
}
bytes_written = stats_prev_global_write_bucket - global_write_bucket;
@@ -2425,7 +2433,8 @@ refill_callback(periodic_timer_t *timer, void *arg)
stats_prev_global_read_bucket = global_read_bucket;
stats_prev_global_write_bucket = global_write_bucket;
- current_millisecond = now; /* remember what time it is, for next time */
+ /* remember what time it is, for next time */
+ refill_timer_current_millisecond = now;
}
#ifndef _WIN32
@@ -2464,9 +2473,9 @@ ip_address_changed(int at_interface)
}
} else {
if (server) {
- if (stats_n_seconds_working > UPTIME_CUTOFF_FOR_NEW_BANDWIDTH_TEST)
+ if (get_uptime() > UPTIME_CUTOFF_FOR_NEW_BANDWIDTH_TEST)
reset_bandwidth_test();
- stats_n_seconds_working = 0;
+ reset_uptime();
router_reset_reachability();
}
}
@@ -3004,6 +3013,13 @@ get_uptime,(void))
return stats_n_seconds_working;
}
+/** Reset Tor's uptime. */
+MOCK_IMPL(void,
+reset_uptime,(void))
+{
+ stats_n_seconds_working = 0;
+}
+
/**
* Write current memory usage information to the log.
*/
@@ -3047,13 +3063,13 @@ dumpstats(int severity)
i,
(int)connection_get_inbuf_len(conn),
(int)buf_allocation(conn->inbuf),
- (int)(now - conn->timestamp_lastread));
+ (int)(now - conn->timestamp_last_read_allowed));
tor_log(severity,LD_GENERAL,
"Conn %d: %d bytes waiting on outbuf "
"(len %d, last written %d secs ago)",i,
(int)connection_get_outbuf_len(conn),
(int)buf_allocation(conn->outbuf),
- (int)(now - conn->timestamp_lastwritten));
+ (int)(now - conn->timestamp_last_write_allowed));
if (conn->type == CONN_TYPE_OR) {
or_connection_t *or_conn = TO_OR_CONN(conn);
if (or_conn->tls) {
@@ -3323,6 +3339,8 @@ tor_init(int argc, char *argv[])
if (strstr(version, "alpha") || strstr(version, "beta"))
log_notice(LD_GENERAL, "This version is not a stable Tor release. "
"Expect more bugs than usual.");
+
+ tor_compress_log_init_warnings();
}
#ifdef HAVE_RUST
@@ -3512,6 +3530,31 @@ tor_free_all(int postfork)
tor_event_free(shutdown_did_not_work_event);
tor_event_free(initialize_periodic_events_event);
+#ifdef HAVE_SYSTEMD_209
+ periodic_timer_free(systemd_watchdog_timer);
+#endif
+
+ global_read_bucket = global_write_bucket = 0;
+ global_relayed_read_bucket = global_relayed_write_bucket = 0;
+ stats_prev_global_read_bucket = stats_prev_global_write_bucket = 0;
+ stats_prev_n_read = stats_prev_n_written = 0;
+ stats_n_bytes_read = stats_n_bytes_written = 0;
+ time_of_process_start = 0;
+ time_of_last_signewnym = 0;
+ signewnym_is_pending = 0;
+ newnym_epoch = 0;
+ called_loop_once = 0;
+ main_loop_should_exit = 0;
+ main_loop_exit_value = 0;
+ can_complete_circuits = 0;
+ quiet_level = 0;
+ should_init_bridge_stats = 1;
+ dns_honesty_first_time = 1;
+ heartbeat_callback_first_time = 1;
+ n_libevent_errors = 0;
+ current_second = 0;
+ memset(&refill_timer_current_millisecond, 0, sizeof(struct timeval));
+
if (!postfork) {
release_lockfile();
}
diff --git a/src/or/main.h b/src/or/main.h
index c49d216f4e..f01506fcea 100644
--- a/src/or/main.h
+++ b/src/or/main.h
@@ -63,6 +63,7 @@ void reschedule_descriptor_update_check(void);
void reschedule_directory_downloads(void);
MOCK_DECL(long,get_uptime,(void));
+MOCK_DECL(void,reset_uptime,(void));
unsigned get_signewnym_epoch(void);
@@ -87,7 +88,6 @@ uint64_t get_main_loop_error_count(void);
uint64_t get_main_loop_idle_count(void);
extern time_t time_of_process_start;
-extern long stats_n_seconds_working;
extern int quiet_level;
extern int global_read_bucket;
extern int global_write_bucket;
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 7777473f11..72b96753cb 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -237,7 +237,7 @@ router_reload_consensus_networkstatus(void)
s = networkstatus_read_cached_consensus_impl(flav, flavor, 1);
if (s) {
if (networkstatus_set_current_consensus(s, flavor,
- flags|NSSET_WAS_WAITING_FOR_CERTS,
+ flags | NSSET_WAS_WAITING_FOR_CERTS,
NULL)) {
log_info(LD_FS, "Couldn't load unverified consensus %s networkstatus "
"from cache", flavor);
@@ -1768,7 +1768,6 @@ networkstatus_set_current_consensus(const char *consensus,
consensus_waiting_for_certs_t *waiting = NULL;
time_t current_valid_after = 0;
int free_consensus = 1; /* Free 'c' at the end of the function */
- int old_ewma_enabled;
int checked_protocols_already = 0;
if (flav < 0) {
@@ -1917,6 +1916,15 @@ networkstatus_set_current_consensus(const char *consensus,
}
}
+ /* Signatures from the consensus are verified */
+ if (from_cache && was_waiting_for_certs) {
+ /* We check if the consensus is loaded from disk cache and that it
+ * it is an unverified consensus. If it is unverified, rename it to
+ * cached-*-consensus since it has been verified. */
+ log_info(LD_DIR, "Unverified consensus signatures verified.");
+ tor_rename(unverified_fname, consensus_fname);
+ }
+
if (!from_cache && flav == usable_consensus_flavor())
control_event_client_status(LOG_NOTICE, "CONSENSUS_ARRIVED");
@@ -1992,17 +2000,8 @@ networkstatus_set_current_consensus(const char *consensus,
/* XXXXNM Microdescs: needs a non-ns variant. ???? NM*/
update_consensus_networkstatus_fetch_time(now);
- /* Update ewma and adjust policy if needed; first cache the old value */
- old_ewma_enabled = cell_ewma_enabled();
/* Change the cell EWMA settings */
- cell_ewma_set_scale_factor(options, c);
- /* If we just enabled ewma, set the cmux policy on all active channels */
- if (cell_ewma_enabled() && !old_ewma_enabled) {
- channel_set_cmux_policy_everywhere(&ewma_policy);
- } else if (!cell_ewma_enabled() && old_ewma_enabled) {
- /* Turn it off everywhere */
- channel_set_cmux_policy_everywhere(NULL);
- }
+ cmux_ewma_set_options(options, c);
/* XXXX this call might be unnecessary here: can changing the
* current consensus really alter our view of any OR's rate limits? */
diff --git a/src/or/nodelist.c b/src/or/nodelist.c
index 391b31d683..40b56f3d1d 100644
--- a/src/or/nodelist.c
+++ b/src/or/nodelist.c
@@ -1456,9 +1456,11 @@ node_ipv6_or_preferred(const node_t *node)
/* XX/teor - node->ipv6_preferred is set from
* fascist_firewall_prefer_ipv6_orport() each time the consensus is loaded.
*/
+ node_get_prim_orport(node, &ipv4_addr);
if (!fascist_firewall_use_ipv6(options)) {
return 0;
- } else if (node->ipv6_preferred || node_get_prim_orport(node, &ipv4_addr)) {
+ } else if (node->ipv6_preferred ||
+ !tor_addr_port_is_valid_ap(&ipv4_addr, 0)) {
return node_has_ipv6_orport(node);
}
return 0;
@@ -1469,14 +1471,12 @@ node_ipv6_or_preferred(const node_t *node)
if (r && tor_addr_port_is_valid_ipv4h((r)->addr, (r)->port_field, 0)) { \
tor_addr_from_ipv4h(&(ap_out)->addr, (r)->addr); \
(ap_out)->port = (r)->port_field; \
- return 0; \
} \
STMT_END
-/** Copy the primary (IPv4) OR port (IP address and TCP port) for
- * <b>node</b> into *<b>ap_out</b>. Return 0 if a valid address and
- * port was copied, else return non-zero.*/
-int
+/** Copy the primary (IPv4) OR port (IP address and TCP port) for <b>node</b>
+ * into *<b>ap_out</b>. */
+void
node_get_prim_orport(const node_t *node, tor_addr_port_t *ap_out)
{
node_assert_ok(node);
@@ -1493,8 +1493,6 @@ node_get_prim_orport(const node_t *node, tor_addr_port_t *ap_out)
RETURN_IPV4_AP(node->ri, or_port, ap_out);
RETURN_IPV4_AP(node->rs, or_port, ap_out);
/* Microdescriptors only have an IPv6 address */
-
- return -1;
}
/** Copy the preferred OR port (IP address and TCP port) for
@@ -1566,19 +1564,19 @@ node_ipv6_dir_preferred(const node_t *node)
* so we can't use it to determine DirPort IPv6 preference.
* This means that bridge clients will use IPv4 DirPorts by default.
*/
+ node_get_prim_dirport(node, &ipv4_addr);
if (!fascist_firewall_use_ipv6(options)) {
return 0;
- } else if (node_get_prim_dirport(node, &ipv4_addr)
+ } else if (!tor_addr_port_is_valid_ap(&ipv4_addr, 0)
|| fascist_firewall_prefer_ipv6_dirport(get_options())) {
return node_has_ipv6_dirport(node);
}
return 0;
}
-/** Copy the primary (IPv4) Dir port (IP address and TCP port) for
- * <b>node</b> into *<b>ap_out</b>. Return 0 if a valid address and
- * port was copied, else return non-zero.*/
-int
+/** Copy the primary (IPv4) Dir port (IP address and TCP port) for <b>node</b>
+ * into *<b>ap_out</b>. */
+void
node_get_prim_dirport(const node_t *node, tor_addr_port_t *ap_out)
{
node_assert_ok(node);
@@ -1590,8 +1588,6 @@ node_get_prim_dirport(const node_t *node, tor_addr_port_t *ap_out)
RETURN_IPV4_AP(node->ri, dir_port, ap_out);
RETURN_IPV4_AP(node->rs, dir_port, ap_out);
/* Microdescriptors only have an IPv6 address */
-
- return -1;
}
#undef RETURN_IPV4_AP
diff --git a/src/or/nodelist.h b/src/or/nodelist.h
index dc20eaf0a5..ff26c8cc76 100644
--- a/src/or/nodelist.h
+++ b/src/or/nodelist.h
@@ -77,11 +77,11 @@ int node_has_ipv6_dirport(const node_t *node);
/* Deprecated - use node_ipv6_or_preferred or node_ipv6_dir_preferred */
#define node_ipv6_preferred(node) node_ipv6_or_preferred(node)
int node_ipv6_or_preferred(const node_t *node);
-int node_get_prim_orport(const node_t *node, tor_addr_port_t *ap_out);
+void node_get_prim_orport(const node_t *node, tor_addr_port_t *ap_out);
void node_get_pref_orport(const node_t *node, tor_addr_port_t *ap_out);
void node_get_pref_ipv6_orport(const node_t *node, tor_addr_port_t *ap_out);
int node_ipv6_dir_preferred(const node_t *node);
-int node_get_prim_dirport(const node_t *node, tor_addr_port_t *ap_out);
+void node_get_prim_dirport(const node_t *node, tor_addr_port_t *ap_out);
void node_get_pref_dirport(const node_t *node, tor_addr_port_t *ap_out);
void node_get_pref_ipv6_dirport(const node_t *node, tor_addr_port_t *ap_out);
int node_has_curve25519_onion_key(const node_t *node);
diff --git a/src/or/onion.c b/src/or/onion.c
index bd80c2f503..0c88c4d7ee 100644
--- a/src/or/onion.c
+++ b/src/or/onion.c
@@ -521,6 +521,11 @@ onion_skin_create(int type,
return r;
}
+/* This is the maximum value for keys_out_len passed to
+ * onion_skin_server_handshake, plus 16. We can make it bigger if needed:
+ * It just defines how many bytes to stack-allocate. */
+#define MAX_KEYS_TMP_LEN 128
+
/** Perform the second (server-side) step of a circuit-creation handshake of
* type <b>type</b>, responding to the client request in <b>onion_skin</b>
* using the keys in <b>keys</b>. On success, write our response into
@@ -563,20 +568,21 @@ onion_skin_server_handshake(int type,
return -1;
{
size_t keys_tmp_len = keys_out_len + DIGEST_LEN;
- uint8_t *keys_tmp = tor_malloc(keys_out_len + DIGEST_LEN);
+ tor_assert(keys_tmp_len <= MAX_KEYS_TMP_LEN);
+ uint8_t keys_tmp[MAX_KEYS_TMP_LEN];
if (onion_skin_ntor_server_handshake(
onion_skin, keys->curve25519_key_map,
keys->junk_keypair,
keys->my_identity,
reply_out, keys_tmp, keys_tmp_len)<0) {
- tor_free(keys_tmp);
+ /* no need to memwipe here, since the output will never be used */
return -1;
}
+
memcpy(keys_out, keys_tmp, keys_out_len);
memcpy(rend_nonce_out, keys_tmp+keys_out_len, DIGEST_LEN);
- memwipe(keys_tmp, 0, keys_tmp_len);
- tor_free(keys_tmp);
+ memwipe(keys_tmp, 0, sizeof(keys_tmp));
r = NTOR_REPLY_LEN;
}
break;
diff --git a/src/or/or.h b/src/or/or.h
index 2397f66511..6ff5902da5 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1361,10 +1361,10 @@ typedef struct connection_t {
* connection. */
size_t outbuf_flushlen; /**< How much data should we try to flush from the
* outbuf? */
- time_t timestamp_lastread; /**< When was the last time libevent said we could
- * read? */
- time_t timestamp_lastwritten; /**< When was the last time libevent said we
- * could write? */
+ time_t timestamp_last_read_allowed; /**< When was the last time libevent said
+ * we could read? */
+ time_t timestamp_last_write_allowed; /**< When was the last time libevent
+ * said we could write? */
time_t timestamp_created; /**< When was this connection_t created? */
@@ -3162,15 +3162,6 @@ typedef struct circuit_t {
/** Index in smartlist of all circuits (global_circuitlist). */
int global_circuitlist_idx;
- /** Next circuit in the doubly-linked ring of circuits waiting to add
- * cells to n_conn. NULL if we have no cells pending, or if we're not
- * linked to an OR connection. */
- struct circuit_t *next_active_on_n_chan;
- /** Previous circuit in the doubly-linked ring of circuits waiting to add
- * cells to n_conn. NULL if we have no cells pending, or if we're not
- * linked to an OR connection. */
- struct circuit_t *prev_active_on_n_chan;
-
/** Various statistics about cells being added to or removed from this
* circuit's queues; used only if CELL_STATS events are enabled and
* cleared after being sent to control port. */
@@ -3450,14 +3441,6 @@ struct onion_queue_t;
typedef struct or_circuit_t {
circuit_t base_;
- /** Next circuit in the doubly-linked ring of circuits waiting to add
- * cells to p_chan. NULL if we have no cells pending, or if we're not
- * linked to an OR connection. */
- struct circuit_t *next_active_on_p_chan;
- /** Previous circuit in the doubly-linked ring of circuits waiting to add
- * cells to p_chan. NULL if we have no cells pending, or if we're not
- * linked to an OR connection. */
- struct circuit_t *prev_active_on_p_chan;
/** Pointer to an entry on the onion queue, if this circuit is waiting for a
* chance to give an onionskin to a cpuworker. Used only in onion.c */
struct onion_queue_t *onionqueue_entry;
diff --git a/src/or/relay.c b/src/or/relay.c
index 506b7eccb3..5dc9d9445b 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -151,9 +151,9 @@ relay_digest_matches(crypto_digest_t *digest, cell_t *cell)
{
uint32_t received_integrity, calculated_integrity;
relay_header_t rh;
- crypto_digest_t *backup_digest=NULL;
+ crypto_digest_checkpoint_t backup_digest;
- backup_digest = crypto_digest_dup(digest);
+ crypto_digest_checkpoint(&backup_digest, digest);
relay_header_unpack(&rh, cell->payload);
memcpy(&received_integrity, rh.integrity, 4);
@@ -167,19 +167,21 @@ relay_digest_matches(crypto_digest_t *digest, cell_t *cell)
crypto_digest_add_bytes(digest, (char*) cell->payload, CELL_PAYLOAD_SIZE);
crypto_digest_get_digest(digest, (char*) &calculated_integrity, 4);
+ int rv = 1;
+
if (calculated_integrity != received_integrity) {
// log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing.");
// (%d vs %d).", received_integrity, calculated_integrity);
/* restore digest to its old form */
- crypto_digest_assign(digest, backup_digest);
+ crypto_digest_restore(digest, &backup_digest);
/* restore the relay header */
memcpy(rh.integrity, &received_integrity, 4);
relay_header_pack(cell->payload, &rh);
- crypto_digest_free(backup_digest);
- return 0;
+ rv = 0;
}
- crypto_digest_free(backup_digest);
- return 1;
+
+ memwipe(&backup_digest, 0, sizeof(backup_digest));
+ return rv;
}
/** Apply <b>cipher</b> to CELL_PAYLOAD_SIZE bytes of <b>in</b>
@@ -1449,7 +1451,7 @@ connection_edge_process_relay_cell_not_open(
"after %d seconds.",
(unsigned)circ->n_circ_id,
rh->stream_id,
- (int)(time(NULL) - conn->base_.timestamp_lastread));
+ (int)(time(NULL) - conn->base_.timestamp_last_read_allowed));
if (connected_cell_parse(rh, cell, &addr, &ttl) < 0) {
log_fn(LOG_PROTOCOL_WARN, LD_APP,
"Got a badly formatted connected cell. Closing.");
@@ -2397,13 +2399,6 @@ circuit_consider_sending_sendme(circuit_t *circ, crypt_path_t *layer_hint)
}
}
-#ifdef ACTIVE_CIRCUITS_PARANOIA
-#define assert_cmux_ok_paranoid(chan) \
- assert_circuit_mux_okay(chan)
-#else
-#define assert_cmux_ok_paranoid(chan)
-#endif /* defined(ACTIVE_CIRCUITS_PARANOIA) */
-
/** The total number of cells we have allocated. */
static size_t total_cells_allocated = 0;
@@ -2691,16 +2686,12 @@ update_circuit_on_cmux_(circuit_t *circ, cell_direction_t direction,
}
tor_assert(circuitmux_attached_circuit_direction(cmux, circ) == direction);
- assert_cmux_ok_paranoid(chan);
-
/* Update the number of cells we have for the circuit mux */
if (direction == CELL_DIRECTION_OUT) {
circuitmux_set_num_cells(cmux, circ, circ->n_chan_cells.n);
} else {
circuitmux_set_num_cells(cmux, circ, or_circ->p_chan_cells.n);
}
-
- assert_cmux_ok_paranoid(chan);
}
/** Remove all circuits from the cmux on <b>chan</b>.
@@ -2845,7 +2836,6 @@ channel_flush_from_first_active_circuit, (channel_t *chan, int max))
}
/* If it returns NULL, no cells left to send */
if (!circ) break;
- assert_cmux_ok_paranoid(chan);
if (circ->n_chan == chan) {
queue = &circ->n_chan_cells;
@@ -2949,8 +2939,6 @@ channel_flush_from_first_active_circuit, (channel_t *chan, int max))
}
/* Okay, we're done sending now */
- assert_cmux_ok_paranoid(chan);
-
return n_flushed;
}
@@ -3101,17 +3089,6 @@ circuit_clear_cell_queue(circuit_t *circ, channel_t *chan)
update_circuit_on_cmux(circ, direction);
}
-/** Fail with an assert if the circuit mux on chan is corrupt
- */
-void
-assert_circuit_mux_okay(channel_t *chan)
-{
- tor_assert(chan);
- tor_assert(chan->cmux);
-
- circuitmux_assert_okay(chan->cmux);
-}
-
/** Return 1 if we shouldn't restart reading on this circuit, even if
* we get a SENDME. Else return 0.
*/
diff --git a/src/or/relay.h b/src/or/relay.h
index f0fa7e9870..ecc67e0b32 100644
--- a/src/or/relay.h
+++ b/src/or/relay.h
@@ -76,7 +76,6 @@ void destroy_cell_queue_append(destroy_cell_queue_t *queue,
void channel_unlink_all_circuits(channel_t *chan, smartlist_t *detached_out);
MOCK_DECL(int, channel_flush_from_first_active_circuit,
(channel_t *chan, int max));
-void assert_circuit_mux_okay(channel_t *chan);
void update_circuit_on_cmux_(circuit_t *circ, cell_direction_t direction,
const char *file, int lineno);
#define update_circuit_on_cmux(circ, direction) \
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index 57815815b9..9a1b97c6d6 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -915,8 +915,8 @@ rend_client_desc_trynow(const char *query)
/* restart their timeout values, so they get a fair shake at
* connecting to the hidden service. */
base_conn->timestamp_created = now;
- base_conn->timestamp_lastread = now;
- base_conn->timestamp_lastwritten = now;
+ base_conn->timestamp_last_read_allowed = now;
+ base_conn->timestamp_last_write_allowed = now;
connection_ap_mark_as_pending_circuit(conn);
} else { /* 404, or fetch didn't get that far */
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 43494692cb..ac3e9f502e 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -86,7 +86,6 @@
#include "ht.h"
#include "channelpadding.h"
-#include "channelpadding.h"
#include "connection_or.h"
static void bw_arrays_init(void);
diff --git a/src/or/router.c b/src/or/router.c
index 9c053cad46..991c7138c8 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -1227,7 +1227,8 @@ check_whether_dirport_reachable(const or_options_t *options)
/* XXX Should this be increased? */
#define MIN_BW_TO_ADVERTISE_DIRSERVER 51200
-/** Return true iff we have enough configured bandwidth to cache directory
+/** Return true iff we have enough configured bandwidth to advertise or
+ * automatically provide directory services from cache directory
* information. */
static int
router_has_bandwidth_to_be_dirserver(const or_options_t *options)
@@ -1250,7 +1251,7 @@ router_has_bandwidth_to_be_dirserver(const or_options_t *options)
* MIN_BW_TO_ADVERTISE_DIRSERVER, don't bother trying to serve requests.
*/
static int
-router_should_be_directory_server(const or_options_t *options, int dir_port)
+router_should_be_dirserver(const or_options_t *options, int dir_port)
{
static int advertising=1; /* start out assuming we will advertise */
int new_choice=1;
@@ -1355,7 +1356,7 @@ decide_to_advertise_dir_impl(const or_options_t *options,
/* Part two: consider config options that could make us choose to
* publish or not publish that the user might find surprising. */
- return router_should_be_directory_server(options, dir_port);
+ return router_should_be_dirserver(options, dir_port);
}
/** Front-end to decide_to_advertise_dir_impl(): return 0 if we don't want to
@@ -1363,7 +1364,7 @@ decide_to_advertise_dir_impl(const or_options_t *options,
* DirPort we want to advertise.
*/
static int
-decide_to_advertise_dirport(const or_options_t *options, uint16_t dir_port)
+router_should_advertise_dirport(const or_options_t *options, uint16_t dir_port)
{
/* supports_tunnelled_dir_requests is not relevant, pass 0 */
return decide_to_advertise_dir_impl(options, dir_port, 0) ? dir_port : 0;
@@ -1373,7 +1374,7 @@ decide_to_advertise_dirport(const or_options_t *options, uint16_t dir_port)
* advertise the fact that we support begindir requests, else return 1.
*/
static int
-decide_to_advertise_begindir(const or_options_t *options,
+router_should_advertise_begindir(const or_options_t *options,
int supports_tunnelled_dir_requests)
{
/* dir_port is not relevant, pass 0 */
@@ -1406,26 +1407,17 @@ extend_info_from_router(const routerinfo_t *r)
&ap.addr, ap.port);
}
-/** Some time has passed, or we just got new directory information.
- * See if we currently believe our ORPort or DirPort to be
- * unreachable. If so, launch a new test for it.
- *
- * For ORPort, we simply try making a circuit that ends at ourselves.
- * Success is noticed in onionskin_answer().
- *
- * For DirPort, we make a connection via Tor to our DirPort and ask
- * for our own server descriptor.
- * Success is noticed in connection_dir_client_reached_eof().
+/**See if we currently believe our ORPort or DirPort to be
+ * unreachable. If so, return 1 else return 0.
*/
-void
-consider_testing_reachability(int test_or, int test_dir)
+static int
+router_should_check_reachability(int test_or, int test_dir)
{
const routerinfo_t *me = router_get_my_routerinfo();
const or_options_t *options = get_options();
- int orport_reachable = check_whether_orport_reachable(options);
- tor_addr_t addr;
+
if (!me)
- return;
+ return 0;
if (routerset_contains_router(options->ExcludeNodes, me, -1) &&
options->StrictNodes) {
@@ -1440,43 +1432,66 @@ consider_testing_reachability(int test_or, int test_dir)
"We cannot learn whether we are usable, and will not "
"be able to advertise ourself.");
}
- return;
+ return 0;
}
+ return 1;
+}
+
+/** Some time has passed, or we just got new directory information.
+ * See if we currently believe our ORPort or DirPort to be
+ * unreachable. If so, launch a new test for it.
+ *
+ * For ORPort, we simply try making a circuit that ends at ourselves.
+ * Success is noticed in onionskin_answer().
+ *
+ * For DirPort, we make a connection via Tor to our DirPort and ask
+ * for our own server descriptor.
+ * Success is noticed in connection_dir_client_reached_eof().
+ */
+void
+router_do_reachability_checks(int test_or, int test_dir)
+{
+ const routerinfo_t *me = router_get_my_routerinfo();
+ const or_options_t *options = get_options();
+ int orport_reachable = check_whether_orport_reachable(options);
+ tor_addr_t addr;
+
+ if (router_should_check_reachability(test_or, test_dir)) {
+ if (test_or && (!orport_reachable || !circuit_enough_testing_circs())) {
+ extend_info_t *ei = extend_info_from_router(me);
+ /* XXX IPv6 self testing */
+ log_info(LD_CIRC, "Testing %s of my ORPort: %s:%d.",
+ !orport_reachable ? "reachability" : "bandwidth",
+ fmt_addr32(me->addr), me->or_port);
+ circuit_launch_by_extend_info(CIRCUIT_PURPOSE_TESTING, ei,
+ CIRCLAUNCH_NEED_CAPACITY|CIRCLAUNCH_IS_INTERNAL);
+ extend_info_free(ei);
+ }
- if (test_or && (!orport_reachable || !circuit_enough_testing_circs())) {
- extend_info_t *ei = extend_info_from_router(me);
/* XXX IPv6 self testing */
- log_info(LD_CIRC, "Testing %s of my ORPort: %s:%d.",
- !orport_reachable ? "reachability" : "bandwidth",
- fmt_addr32(me->addr), me->or_port);
- circuit_launch_by_extend_info(CIRCUIT_PURPOSE_TESTING, ei,
- CIRCLAUNCH_NEED_CAPACITY|CIRCLAUNCH_IS_INTERNAL);
- extend_info_free(ei);
- }
-
- /* XXX IPv6 self testing */
- tor_addr_from_ipv4h(&addr, me->addr);
- if (test_dir && !check_whether_dirport_reachable(options) &&
- !connection_get_by_type_addr_port_purpose(
- CONN_TYPE_DIR, &addr, me->dir_port,
- DIR_PURPOSE_FETCH_SERVERDESC)) {
- tor_addr_port_t my_orport, my_dirport;
- memcpy(&my_orport.addr, &addr, sizeof(addr));
- memcpy(&my_dirport.addr, &addr, sizeof(addr));
- my_orport.port = me->or_port;
- my_dirport.port = me->dir_port;
- /* ask myself, via tor, for my server descriptor. */
- directory_request_t *req =
- directory_request_new(DIR_PURPOSE_FETCH_SERVERDESC);
- directory_request_set_or_addr_port(req, &my_orport);
- directory_request_set_dir_addr_port(req, &my_dirport);
- directory_request_set_directory_id_digest(req,
+ tor_addr_from_ipv4h(&addr, me->addr);
+ if (test_dir && !check_whether_dirport_reachable(options) &&
+ !connection_get_by_type_addr_port_purpose(
+ CONN_TYPE_DIR, &addr, me->dir_port,
+ DIR_PURPOSE_FETCH_SERVERDESC)) {
+ tor_addr_port_t my_orport, my_dirport;
+ memcpy(&my_orport.addr, &addr, sizeof(addr));
+ memcpy(&my_dirport.addr, &addr, sizeof(addr));
+ my_orport.port = me->or_port;
+ my_dirport.port = me->dir_port;
+ /* ask myself, via tor, for my server descriptor. */
+ directory_request_t *req =
+ directory_request_new(DIR_PURPOSE_FETCH_SERVERDESC);
+ directory_request_set_or_addr_port(req, &my_orport);
+ directory_request_set_dir_addr_port(req, &my_dirport);
+ directory_request_set_directory_id_digest(req,
me->cache_info.identity_digest);
- // ask via an anon circuit, connecting to our dirport.
- directory_request_set_indirection(req, DIRIND_ANON_DIRPORT);
- directory_request_set_resource(req, "authority.z");
- directory_initiate_request(req);
- directory_request_free(req);
+ // ask via an anon circuit, connecting to our dirport.
+ directory_request_set_indirection(req, DIRIND_ANON_DIRPORT);
+ directory_request_set_resource(req, "authority.z");
+ directory_initiate_request(req);
+ directory_request_free(req);
+ }
}
}
@@ -1521,7 +1536,7 @@ router_dirport_found_reachable(void)
&& check_whether_orport_reachable(options) ?
" Publishing server descriptor." : "");
can_reach_dir_port = 1;
- if (decide_to_advertise_dirport(options, me->dir_port)) {
+ if (router_should_advertise_dirport(options, me->dir_port)) {
mark_my_descriptor_dirty("DirPort found reachable");
/* This is a significant enough change to upload immediately,
* at least in a test network */
@@ -2915,14 +2930,14 @@ router_dump_router_to_string(routerinfo_t *router,
router->nickname,
address,
router->or_port,
- decide_to_advertise_dirport(options, router->dir_port),
+ router_should_advertise_dirport(options, router->dir_port),
ed_cert_line ? ed_cert_line : "",
extra_or_address ? extra_or_address : "",
router->platform,
proto_line,
published,
fingerprint,
- stats_n_seconds_working,
+ get_uptime(),
(int) router->bandwidthrate,
(int) router->bandwidthburst,
(int) router->bandwidthcapacity,
@@ -2989,7 +3004,7 @@ router_dump_router_to_string(routerinfo_t *router,
tor_free(p6);
}
- if (decide_to_advertise_begindir(options,
+ if (router_should_advertise_begindir(options,
router->supports_tunnelled_dir_requests)) {
smartlist_add_strdup(chunks, "tunnelled-dir-server\n");
}
diff --git a/src/or/router.h b/src/or/router.h
index 696e983662..7f50308956 100644
--- a/src/or/router.h
+++ b/src/or/router.h
@@ -47,7 +47,7 @@ int init_keys_client(void);
int check_whether_orport_reachable(const or_options_t *options);
int check_whether_dirport_reachable(const or_options_t *options);
int dir_server_mode(const or_options_t *options);
-void consider_testing_reachability(int test_or, int test_dir);
+void router_do_reachability_checks(int test_or, int test_dir);
void router_orport_found_reachable(void);
void router_dirport_found_reachable(void);
void router_perform_bandwidth_test(int num_circs, time_t now);
diff --git a/src/or/status.c b/src/or/status.c
index 4f7be164b1..4c497739e8 100644
--- a/src/or/status.c
+++ b/src/or/status.c
@@ -25,7 +25,6 @@
#include "main.h"
#include "rephist.h"
#include "hibernate.h"
-#include "rephist.h"
#include "statefile.h"
#include "hs_stats.h"
#include "hs_service.h"
diff --git a/src/or/transports.c b/src/or/transports.c
index b08dcd1613..5cbf1ddbc1 100644
--- a/src/or/transports.c
+++ b/src/or/transports.c
@@ -1025,48 +1025,71 @@ parse_method_error(const char *line, int is_server)
line+strlen(error)+1);
}
-/** Parses an SMETHOD <b>line</b> and if well-formed it registers the
- * new transport in <b>mp</b>. */
-STATIC int
-parse_smethod_line(const char *line, managed_proxy_t *mp)
+/** A helper for parse_{c,s}method_line(), bootstraps its
+ * functionalities. If <b>is_smethod</b> is true then the
+ * the line to parse is a SMETHOD line otherwise it is a
+ * CMETHOD line*/
+static int
+parse_method_line_helper(const char *line,
+ managed_proxy_t *mp,
+ int is_smethod)
{
+ int item_index = 0;
int r;
- smartlist_t *items = NULL;
- char *method_name=NULL;
+ char *transport_name=NULL;
char *args_string=NULL;
char *addrport=NULL;
- tor_addr_t tor_addr;
+ int socks_ver=PROXY_NONE;
char *address=NULL;
uint16_t port = 0;
+ const char *method_str = is_smethod ? PROTO_SMETHOD : PROTO_CMETHOD;
+ const int min_args_count = is_smethod ? 3 : 4;
+
+ tor_addr_t tor_addr;
transport_t *transport=NULL;
+ smartlist_t *items= smartlist_new();
- items = smartlist_new();
smartlist_split_string(items, line, NULL,
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
- if (smartlist_len(items) < 3) {
- log_warn(LD_CONFIG, "Server managed proxy sent us a SMETHOD line "
- "with too few arguments.");
+ if (smartlist_len(items) < min_args_count) {
+ log_warn(LD_CONFIG, "Managed proxy sent us a %s line "
+ "with too few arguments.", method_str);
goto err;
}
- /* Example of legit SMETHOD line:
- SMETHOD obfs2 0.0.0.0:25612 ARGS:secret=supersekrit,key=superkey */
-
- tor_assert(!strcmp(smartlist_get(items,0),PROTO_SMETHOD));
+ tor_assert(!strcmp(smartlist_get(items, item_index),method_str));
+ ++item_index;
- method_name = smartlist_get(items,1);
- if (!string_is_C_identifier(method_name)) {
+ transport_name = smartlist_get(items,item_index);
+ ++item_index;
+ if (!string_is_C_identifier(transport_name)) {
log_warn(LD_CONFIG, "Transport name is not a C identifier (%s).",
- method_name);
+ transport_name);
goto err;
}
- addrport = smartlist_get(items, 2);
+ /** Check for the proxy method sent to us in CMETHOD line. */
+ if (!is_smethod) {
+ const char *socks_ver_str = smartlist_get(items,item_index);
+ ++item_index;
+
+ if (!strcmp(socks_ver_str,"socks4")) {
+ socks_ver = PROXY_SOCKS4;
+ } else if (!strcmp(socks_ver_str,"socks5")) {
+ socks_ver = PROXY_SOCKS5;
+ } else {
+ log_warn(LD_CONFIG, "Client managed proxy sent us a proxy protocol "
+ "we don't recognize. (%s)", socks_ver_str);
+ goto err;
+ }
+ }
+
+ addrport = smartlist_get(items, item_index);
+ ++item_index;
if (tor_addr_port_split(LOG_WARN, addrport, &address, &port)<0) {
- log_warn(LD_CONFIG, "Error parsing transport "
- "address '%s'", addrport);
+ log_warn(LD_CONFIG, "Error parsing transport address '%s'", addrport);
goto err;
}
@@ -1081,10 +1104,11 @@ parse_smethod_line(const char *line, managed_proxy_t *mp)
goto err;
}
- if (smartlist_len(items) > 3) {
+ /** Check for options in the SMETHOD line. */
+ if (is_smethod && smartlist_len(items) > min_args_count) {
/* Seems like there are also some [options] in the SMETHOD line.
Let's see if we can parse them. */
- char *options_string = smartlist_get(items, 3);
+ char *options_string = smartlist_get(items, item_index);
log_debug(LD_CONFIG, "Got options_string: %s", options_string);
if (!strcmpstart(options_string, "ARGS:")) {
args_string = options_string+strlen("ARGS:");
@@ -1092,15 +1116,20 @@ parse_smethod_line(const char *line, managed_proxy_t *mp)
}
}
- transport = transport_new(&tor_addr, port, method_name,
- PROXY_NONE, args_string);
+ transport = transport_new(&tor_addr, port, transport_name,
+ socks_ver, args_string);
smartlist_add(mp->transports, transport);
- /* For now, notify the user so that they know where the server
- transport is listening. */
- log_info(LD_CONFIG, "Server transport %s at %s:%d.",
- method_name, address, (int)port);
+ /** Logs info about line parsing success for client or server */
+ if (is_smethod) {
+ log_info(LD_CONFIG, "Server transport %s at %s:%d.",
+ transport_name, address, (int)port);
+ } else {
+ log_info(LD_CONFIG, "Transport %s at %s:%d with SOCKS %d. "
+ "Attached to managed proxy.",
+ transport_name, address, (int)port, socks_ver);
+ }
r=0;
goto done;
@@ -1115,93 +1144,24 @@ parse_smethod_line(const char *line, managed_proxy_t *mp)
return r;
}
+/** Parses an SMETHOD <b>line</b> and if well-formed it registers the
+ * new transport in <b>mp</b>. */
+STATIC int
+parse_smethod_line(const char *line, managed_proxy_t *mp)
+{
+ /* Example of legit SMETHOD line:
+ SMETHOD obfs2 0.0.0.0:25612 ARGS:secret=supersekrit,key=superkey */
+ return parse_method_line_helper(line, mp, 1);
+}
+
/** Parses a CMETHOD <b>line</b>, and if well-formed it registers
* the new transport in <b>mp</b>. */
STATIC int
parse_cmethod_line(const char *line, managed_proxy_t *mp)
{
- int r;
- smartlist_t *items = NULL;
-
- char *method_name=NULL;
-
- char *socks_ver_str=NULL;
- int socks_ver=PROXY_NONE;
-
- char *addrport=NULL;
- tor_addr_t tor_addr;
- char *address=NULL;
- uint16_t port = 0;
-
- transport_t *transport=NULL;
-
- items = smartlist_new();
- smartlist_split_string(items, line, NULL,
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
- if (smartlist_len(items) < 4) {
- log_warn(LD_CONFIG, "Client managed proxy sent us a CMETHOD line "
- "with too few arguments.");
- goto err;
- }
-
- tor_assert(!strcmp(smartlist_get(items,0),PROTO_CMETHOD));
-
- method_name = smartlist_get(items,1);
- if (!string_is_C_identifier(method_name)) {
- log_warn(LD_CONFIG, "Transport name is not a C identifier (%s).",
- method_name);
- goto err;
- }
-
- socks_ver_str = smartlist_get(items,2);
-
- if (!strcmp(socks_ver_str,"socks4")) {
- socks_ver = PROXY_SOCKS4;
- } else if (!strcmp(socks_ver_str,"socks5")) {
- socks_ver = PROXY_SOCKS5;
- } else {
- log_warn(LD_CONFIG, "Client managed proxy sent us a proxy protocol "
- "we don't recognize. (%s)", socks_ver_str);
- goto err;
- }
-
- addrport = smartlist_get(items, 3);
- if (tor_addr_port_split(LOG_WARN, addrport, &address, &port)<0) {
- log_warn(LD_CONFIG, "Error parsing transport "
- "address '%s'", addrport);
- goto err;
- }
-
- if (!port) {
- log_warn(LD_CONFIG,
- "Transport address '%s' has no port.", addrport);
- goto err;
- }
-
- if (tor_addr_parse(&tor_addr, address) < 0) {
- log_warn(LD_CONFIG, "Error parsing transport address '%s'", address);
- goto err;
- }
-
- transport = transport_new(&tor_addr, port, method_name, socks_ver, NULL);
-
- smartlist_add(mp->transports, transport);
-
- log_info(LD_CONFIG, "Transport %s at %s:%d with SOCKS %d. "
- "Attached to managed proxy.",
- method_name, address, (int)port, socks_ver);
-
- r=0;
- goto done;
-
- err:
- r = -1;
-
- done:
- SMARTLIST_FOREACH(items, char*, s, tor_free(s));
- smartlist_free(items);
- tor_free(address);
- return r;
+ /* Example of legit CMETHOD line:
+ CMETHOD obfs2 socks5 127.0.0.1:35713 */
+ return parse_method_line_helper(line, mp, 0);
}
/** Parses an PROXY-ERROR <b>line</b> and warns the user accordingly. */
diff --git a/src/rust/protover/ffi.rs b/src/rust/protover/ffi.rs
index 2ee0286ecf..e4cf0a7e88 100644
--- a/src/rust/protover/ffi.rs
+++ b/src/rust/protover/ffi.rs
@@ -12,9 +12,6 @@ use std::ffi::CString;
use protover::*;
use smartlist::*;
use tor_allocate::allocate_and_copy_string;
-use tor_util::strings::byte_slice_is_c_like;
-use tor_util::strings::empty_static_cstr;
-
/// Translate C enums to Rust Proto enums, using the integer value of the C
/// enum to map to its associated Rust enum
@@ -143,18 +140,7 @@ pub extern "C" fn protocol_list_supports_protocol_or_later(
pub extern "C" fn protover_get_supported_protocols() -> *const c_char {
let supported: &'static CStr;
- // If we're going to pass it to C, there cannot be any intermediate NUL
- // bytes. An assert is okay here, since changing the const byte slice
- // in protover.rs to contain a NUL byte somewhere in the middle would be a
- // programming error.
- assert!(byte_slice_is_c_like(SUPPORTED_PROTOCOLS));
-
- // It's okay to unwrap the result of this function because
- // we can see that the bytes we're passing into it 1) are valid UTF-8,
- // 2) have no intermediate NUL bytes, and 3) are terminated with a NUL
- // byte.
- supported = CStr::from_bytes_with_nul(SUPPORTED_PROTOCOLS).unwrap();
-
+ supported = get_supported_protocols_cstr();
supported.as_ptr()
}
@@ -202,10 +188,9 @@ pub extern "C" fn protover_is_supported_here(
#[no_mangle]
pub extern "C" fn protover_compute_for_old_tor(version: *const c_char) -> *const c_char {
let supported: &'static CStr;
- let elder_protocols: &'static [u8];
let empty: &'static CStr;
- empty = empty_static_cstr();
+ empty = cstr!("");
if version.is_null() {
return empty.as_ptr();
@@ -220,19 +205,6 @@ pub extern "C" fn protover_compute_for_old_tor(version: *const c_char) -> *const
Err(_) => return empty.as_ptr(),
};
- elder_protocols = compute_for_old_tor(&version);
-
- // If we're going to pass it to C, there cannot be any intermediate NUL
- // bytes. An assert is okay here, since changing the const byte slice
- // in protover.rs to contain a NUL byte somewhere in the middle would be a
- // programming error.
- assert!(byte_slice_is_c_like(elder_protocols));
-
- // It's okay to unwrap the result of this function because
- // we can see that the bytes we're passing into it 1) are valid UTF-8,
- // 2) have no intermediate NUL bytes, and 3) are terminated with a NUL
- // byte.
- supported = CStr::from_bytes_with_nul(elder_protocols).unwrap_or(empty);
-
+ supported = compute_for_old_tor(&version);
supported.as_ptr()
}
diff --git a/src/rust/protover/lib.rs b/src/rust/protover/lib.rs
index fe8c0f9bb2..8e80fcef4c 100644
--- a/src/rust/protover/lib.rs
+++ b/src/rust/protover/lib.rs
@@ -26,6 +26,7 @@ extern crate libc;
extern crate smartlist;
extern crate external;
extern crate tor_allocate;
+#[macro_use]
extern crate tor_util;
mod protover;
diff --git a/src/rust/protover/protover.rs b/src/rust/protover/protover.rs
index e5dc69b9a0..03776411ca 100644
--- a/src/rust/protover/protover.rs
+++ b/src/rust/protover/protover.rs
@@ -5,14 +5,13 @@ use external::c_tor_version_as_new_as;
use std::str;
use std::str::FromStr;
+use std::ffi::CStr;
use std::fmt;
use std::collections::{HashMap, HashSet};
use std::ops::Range;
use std::string::String;
use std::u32;
-use tor_util::strings::NUL_BYTE;
-
/// The first version of Tor that included "proto" entries in its descriptors.
/// Authorities should use this to decide whether to guess proto lines.
///
@@ -26,30 +25,6 @@ const FIRST_TOR_VERSION_TO_ADVERTISE_PROTOCOLS: &'static str = "0.2.9.3-alpha";
/// C_RUST_COUPLED: src/or/protover.c `MAX_PROTOCOLS_TO_EXPAND`
const MAX_PROTOCOLS_TO_EXPAND: usize = (1<<16);
-/// Currently supported protocols and their versions, as a byte-slice.
-///
-/// # Warning
-///
-/// This byte-slice ends in a NUL byte. This is so that we can directly convert
-/// it to an `&'static CStr` in the FFI code, in order to hand the static string
-/// to C in a way that is compatible with C static strings.
-///
-/// Rust code which wishes to accesses this string should use
-/// `protover::get_supported_protocols()` instead.
-///
-/// C_RUST_COUPLED: src/or/protover.c `protover_get_supported_protocols`
-pub(crate) const SUPPORTED_PROTOCOLS: &'static [u8] =
- b"Cons=1-2 \
- Desc=1-2 \
- DirCache=1-2 \
- HSDir=1-2 \
- HSIntro=3-4 \
- HSRend=1-2 \
- Link=1-5 \
- LinkAuth=1,3 \
- Microdesc=1-2 \
- Relay=1-2\0";
-
/// Known subprotocols in Tor. Indicates which subprotocol a relay supports.
///
/// C_RUST_COUPLED: src/or/protover.h `protocol_type_t`
@@ -97,21 +72,51 @@ impl FromStr for Proto {
}
}
-/// Get the string representation of current supported protocols
+/// Get a CStr representation of current supported protocols, for
+/// passing to C, or for converting to a `&str` for Rust.
///
/// # Returns
///
-/// A `String` whose value is the existing protocols supported by tor.
+/// An `&'static CStr` whose value is the existing protocols supported by tor.
/// Returned data is in the format as follows:
///
/// "HSDir=1-1 LinkAuth=1"
///
-pub fn get_supported_protocols() -> &'static str {
- // The `len() - 1` is to remove the NUL byte.
- // The `unwrap` is safe becauase we SUPPORTED_PROTOCOLS is under
- // our control.
- str::from_utf8(&SUPPORTED_PROTOCOLS[..SUPPORTED_PROTOCOLS.len() - 1])
- .unwrap_or("")
+/// # Note
+///
+/// Rust code can use the `&'static CStr` as a normal `&'a str` by
+/// calling `protover::get_supported_protocols`.
+///
+// C_RUST_COUPLED: src/or/protover.c `protover_get_supported_protocols`
+pub(crate) fn get_supported_protocols_cstr() -> &'static CStr {
+ cstr!("Cons=1-2 \
+ Desc=1-2 \
+ DirCache=1-2 \
+ HSDir=1-2 \
+ HSIntro=3-4 \
+ HSRend=1-2 \
+ Link=1-5 \
+ LinkAuth=1,3 \
+ Microdesc=1-2 \
+ Relay=1-2")
+}
+
+/// Get a string representation of current supported protocols.
+///
+/// # Returns
+///
+/// An `&'a str` whose value is the existing protocols supported by tor.
+/// Returned data is in the format as follows:
+///
+/// "HSDir=1-1 LinkAuth=1"
+pub fn get_supported_protocols<'a>() -> &'a str {
+ let supported_cstr: &'static CStr = get_supported_protocols_cstr();
+ let supported: &str = match supported_cstr.to_str() {
+ Ok(x) => x,
+ Err(_) => "",
+ };
+
+ supported
}
pub struct SupportedProtocols(HashMap<Proto, Versions>);
@@ -754,7 +759,7 @@ pub fn is_supported_here(proto: Proto, vers: Version) -> bool {
///
/// # Returns
///
-/// A `&'static [u8]` encoding a list of protocol names and supported
+/// A `&'static CStr` encoding a list of protocol names and supported
/// versions. The string takes the following format:
///
/// "HSDir=1-1 LinkAuth=1"
@@ -763,27 +768,29 @@ pub fn is_supported_here(proto: Proto, vers: Version) -> bool {
/// only for tor versions older than FIRST_TOR_VERSION_TO_ADVERTISE_PROTOCOLS.
///
/// C_RUST_COUPLED: src/rust/protover.c `compute_for_old_tor`
-pub fn compute_for_old_tor(version: &str) -> &'static [u8] {
+pub fn compute_for_old_tor(version: &str) -> &'static CStr {
+ let empty: &'static CStr = cstr!("");
+
if c_tor_version_as_new_as(version, FIRST_TOR_VERSION_TO_ADVERTISE_PROTOCOLS) {
- return NUL_BYTE;
+ return empty;
}
if c_tor_version_as_new_as(version, "0.2.9.1-alpha") {
- return b"Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1-2 \
- Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2\0";
+ return cstr!("Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1-2 \
+ Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2");
}
if c_tor_version_as_new_as(version, "0.2.7.5") {
- return b"Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 \
- Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2\0";
+ return cstr!("Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 \
+ Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2");
}
if c_tor_version_as_new_as(version, "0.2.4.19") {
- return b"Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 \
- Link=1-4 LinkAuth=1 Microdesc=1 Relay=1-2\0";
+ return cstr!("Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 \
+ Link=1-4 LinkAuth=1 Microdesc=1 Relay=1-2");
}
- NUL_BYTE
+ empty
}
#[cfg(test)]
diff --git a/src/rust/tor_util/strings.rs b/src/rust/tor_util/strings.rs
index 9321ce4f85..505191d913 100644
--- a/src/rust/tor_util/strings.rs
+++ b/src/rust/tor_util/strings.rs
@@ -3,80 +3,138 @@
//! Utilities for working with static strings.
-use std::ffi::CStr;
-
-/// A byte-array containing a single NUL byte (`b"\0"`).
-pub const NUL_BYTE: &'static [u8] = b"\0";
-
-/// Determine if a byte slice is a C-like string.
-///
-/// These checks guarantee that:
-///
-/// 1. there are no intermediate NUL bytes
-/// 2. the last byte *is* a NUL byte
+/// Create a `CStr` from a literal byte slice, appending a NUL byte to it first.
///
/// # Warning
///
-/// This function does _not_ guarantee that the bytes represent any valid
-/// encoding such as ASCII or UTF-8.
+/// The literal byte slice which is taken as an argument *MUST NOT* have any NUL
+/// bytes (`b"\0"`) in it, anywhere, or else an empty string will be returned
+/// (`CStr::from_bytes_with_nul_unchecked(b"\0")`) so as to avoid `panic!()`ing.
///
/// # Examples
///
/// ```
-/// # use tor_util::strings::byte_slice_is_c_like;
-/// #
-/// let bytes: &[u8] = b"foo bar baz";
+/// #[macro_use]
+/// extern crate tor_util;
///
-/// assert!(byte_slice_is_c_like(&bytes) == false);
+/// use std::ffi::CStr;
///
-/// let bytes: &[u8] = b"foo\0bar baz";
+/// # fn do_test() -> Result<&'static CStr, &'static str> {
+/// let message: &'static str = "This is a test of the tsunami warning system.";
+/// let tuesday: &'static CStr;
+/// let original: &str;
///
-/// assert!(byte_slice_is_c_like(&bytes) == false);
+/// tuesday = cstr!("This is a test of the tsunami warning system.");
+/// original = tuesday.to_str().or(Err("Couldn't unwrap CStr!"))?;
///
-/// let bytes: &[u8] = b"foo bar baz\0";
+/// assert!(original == message);
+/// #
+/// # Ok(tuesday)
+/// # }
+/// # fn main() {
+/// # do_test(); // so that we can use the ? operator in the test
+/// # }
+/// ```
+/// It is also possible to pass several string literals to this macro. They
+/// will be concatenated together in the order of the arguments, unmodified,
+/// before finally being suffixed with a NUL byte:
///
-/// assert!(byte_slice_is_c_like(&bytes) == true);
/// ```
-pub fn byte_slice_is_c_like(bytes: &[u8]) -> bool {
- if !bytes[..bytes.len() - 1].contains(&0x00) && bytes[bytes.len() - 1] == 0x00 {
- return true;
- }
- false
-}
-
-/// Get a static `CStr` containing a single `NUL_BYTE`.
+/// #[macro_use]
+/// extern crate tor_util;
+/// #
+/// # use std::ffi::CStr;
+/// #
+/// # fn do_test() -> Result<&'static CStr, &'static str> {
///
-/// # Examples
+/// let quux: &'static CStr = cstr!("foo", "bar", "baz");
+/// let orig: &'static str = quux.to_str().or(Err("Couldn't unwrap CStr!"))?;
///
-/// When used as follows in a Rust FFI function, which could be called
-/// from C:
+/// assert!(orig == "foobarbaz");
+/// # Ok(quux)
+/// # }
+/// # fn main() {
+/// # do_test(); // so that we can use the ? operator in the test
+/// # }
+/// ```
+/// This is useful for passing static strings to C from Rust FFI code. To do so
+/// so, use the `.as_ptr()` method on the resulting `&'static CStr` to convert
+/// it to the Rust equivalent of a C `const char*`:
///
/// ```
-/// # extern crate libc;
-/// # extern crate tor_util;
-/// #
-/// # use tor_util::strings::empty_static_cstr;
-/// use libc::c_char;
+/// #[macro_use]
+/// extern crate tor_util;
+///
/// use std::ffi::CStr;
+/// use std::os::raw::c_char;
///
-/// pub extern "C" fn give_c_code_an_empty_static_string() -> *const c_char {
-/// let empty: &'static CStr = empty_static_cstr();
+/// pub extern "C" fn give_static_borrowed_string_to_c() -> *const c_char {
+/// let hello: &'static CStr = cstr!("Hello, language my parents wrote.");
///
-/// empty.as_ptr()
+/// hello.as_ptr()
/// }
-///
/// # fn main() {
-/// # give_c_code_an_empty_static_string();
+/// # let greetings = give_static_borrowed_string_to_c();
/// # }
/// ```
+/// Note that the C code this static borrowed string is passed to *MUST NOT*
+/// attempt to free the memory for the string.
+///
+/// # Note
+///
+/// An unfortunate limitation of the rustc compiler (as of 1.25.0-nightly), is
+/// that the first example above compiles, but if we were to change the
+/// assignment of `tuesday` as follows, it will fail to compile, because Rust
+/// macros are expanded at parse time, and at parse time there is no symbol
+/// table available.
///
-/// This equates to an "empty" `const char*` static string in C.
-pub fn empty_static_cstr() -> &'static CStr {
- let empty: &'static CStr;
+/// ```ignore
+/// tuesday = cstr!(message);
+/// ```
+/// with the error message `error: expected a literal`.
+///
+/// # Returns
+///
+/// If the string literals passed as arguments contain no NUL bytes anywhere,
+/// then an `&'static CStr` containing the (concatenated) bytes of the string
+/// literal(s) passed as arguments, with a NUL byte appended, is returned.
+/// Otherwise, an `&'static CStr` containing a single NUL byte is returned (an
+/// "empty" string in C).
+#[macro_export]
+macro_rules! cstr {
+ ($($bytes:expr),*) => (
+ ::std::ffi::CStr::from_bytes_with_nul(
+ concat!($($bytes),*, "\0").as_bytes()
+ ).unwrap_or(
+ unsafe{
+ ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"\0")
+ }
+ )
+ )
+}
+
+#[cfg(test)]
+mod test {
+ use std::ffi::CStr;
+
+ #[test]
+ fn cstr_macro() {
+ let _: &'static CStr = cstr!("boo");
+ }
+
+ #[test]
+ fn cstr_macro_multi_input() {
+ let quux: &'static CStr = cstr!("foo", "bar", "baz");
- unsafe {
- empty = CStr::from_bytes_with_nul_unchecked(NUL_BYTE);
+ assert!(quux.to_str().unwrap() == "foobarbaz");
}
- empty
+ #[test]
+ fn cstr_macro_bad_input() {
+ let waving: &'static CStr = cstr!("waving not drowning o/");
+ let drowning: &'static CStr = cstr!("\0 drowning not waving");
+
+ assert!(waving.to_str().unwrap() == "waving not drowning o/");
+ assert!(drowning.to_str().unwrap() == "")
+ }
}
diff --git a/src/test/test_channel.c b/src/test/test_channel.c
index bdc9d32f78..812ec6c1ac 100644
--- a/src/test/test_channel.c
+++ b/src/test/test_channel.c
@@ -281,6 +281,7 @@ new_fake_channel(void)
chan->state = CHANNEL_STATE_OPEN;
chan->cmux = circuitmux_alloc();
+ circuitmux_set_policy(chan->cmux, &ewma_policy);
return chan;
}
@@ -575,15 +576,13 @@ test_channel_outbound_cell(void *arg)
channel_register(chan);
tt_int_op(chan->registered, OP_EQ, 1);
/* Set EWMA policy so we can pick it when flushing. */
- channel_set_cmux_policy_everywhere(&ewma_policy);
+ circuitmux_set_policy(chan->cmux, &ewma_policy);
tt_ptr_op(circuitmux_get_policy(chan->cmux), OP_EQ, &ewma_policy);
/* Register circuit to the channel circid map which will attach the circuit
* to the channel's cmux as well. */
circuit_set_n_circid_chan(TO_CIRCUIT(circ), 42, chan);
tt_int_op(channel_num_circuits(chan), OP_EQ, 1);
- tt_assert(!TO_CIRCUIT(circ)->next_active_on_n_chan);
- tt_assert(!TO_CIRCUIT(circ)->prev_active_on_n_chan);
/* Test the cmux state. */
tt_ptr_op(TO_CIRCUIT(circ)->n_mux, OP_EQ, chan->cmux);
tt_int_op(circuitmux_is_circuit_attached(chan->cmux, TO_CIRCUIT(circ)),
diff --git a/src/test/test_circuitlist.c b/src/test/test_circuitlist.c
index d170009a9c..3794ffc2c6 100644
--- a/src/test/test_circuitlist.c
+++ b/src/test/test_circuitlist.c
@@ -9,6 +9,7 @@
#include "channel.h"
#include "circuitbuild.h"
#include "circuitlist.h"
+#include "circuitmux_ewma.h"
#include "hs_circuitmap.h"
#include "test.h"
#include "log_test_helpers.h"
diff --git a/src/test/test_circuitmux.c b/src/test/test_circuitmux.c
index 854f725054..75b7a0ea47 100644
--- a/src/test/test_circuitmux.c
+++ b/src/test/test_circuitmux.c
@@ -7,6 +7,7 @@
#include "or.h"
#include "channel.h"
#include "circuitmux.h"
+#include "circuitmux_ewma.h"
#include "relay.h"
#include "scheduler.h"
#include "test.h"
@@ -45,6 +46,7 @@ test_cmux_destroy_cell_queue(void *arg)
cmux = circuitmux_alloc();
tt_assert(cmux);
ch = new_fake_channel();
+ circuitmux_set_policy(cmux, &ewma_policy);
ch->has_queued_writes = has_queued_writes;
ch->wide_circ_ids = 1;
diff --git a/src/test/test_config.c b/src/test/test_config.c
index d42335de38..3729c8aabb 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -20,7 +20,6 @@
#include "connection_edge.h"
#include "test.h"
#include "util.h"
-#include "address.h"
#include "connection_or.h"
#include "control.h"
#include "cpuworker.h"
@@ -42,9 +41,6 @@
#include "routerlist.h"
#include "routerset.h"
#include "statefile.h"
-#include "test.h"
-#include "transports.h"
-#include "util.h"
#include "test_helpers.h"
diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c
index ca64dce5fe..71faf70af2 100644
--- a/src/test/test_dir_handle_get.c
+++ b/src/test/test_dir_handle_get.c
@@ -16,7 +16,6 @@
#include "directory.h"
#include "test.h"
#include "compress.h"
-#include "connection.h"
#include "rendcommon.h"
#include "rendcache.h"
#include "router.h"
diff --git a/src/test/test_helpers.c b/src/test/test_helpers.c
index 0da9cf64d0..ab453d3bdc 100644
--- a/src/test/test_helpers.c
+++ b/src/test/test_helpers.c
@@ -33,7 +33,6 @@ DISABLE_GCC_WARNING(overlength-strings)
* at large. */
#endif
#include "test_descriptors.inc"
-#include "or.h"
#include "circuitlist.h"
#ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS
ENABLE_GCC_WARNING(overlength-strings)
diff --git a/src/test/test_hs_intropoint.c b/src/test/test_hs_intropoint.c
index 55dfafbeac..fe3236c331 100644
--- a/src/test/test_hs_intropoint.c
+++ b/src/test/test_hs_intropoint.c
@@ -14,7 +14,6 @@
#include "test.h"
#include "log_test_helpers.h"
#include "crypto.h"
-#include "log_test_helpers.h"
#include "or.h"
#include "circuitlist.h"
diff --git a/src/test/test_util.c b/src/test/test_util.c
index b67fad58e3..5f77f303a7 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -16,6 +16,7 @@
#include "memarea.h"
#include "util_process.h"
#include "log_test_helpers.h"
+#include "compress_zstd.h"
#ifdef HAVE_PWD_H
#include <pwd.h>
@@ -2396,6 +2397,37 @@ test_util_compress_stream_impl(compress_method_t method,
tor_free(buf3);
}
+/** Setup function for compression tests: handles x-zstd:nostatic
+ */
+static void *
+compression_test_setup(const struct testcase_t *testcase)
+{
+ tor_assert(testcase->setup_data);
+ tor_assert(testcase->setup_data != (void*)TT_SKIP);
+ const char *methodname = testcase->setup_data;
+
+ if (!strcmp(methodname, "x-zstd:nostatic")) {
+ methodname = "x-zstd";
+ tor_zstd_set_static_apis_disabled_for_testing(1);
+ }
+
+ return (void *)methodname;
+}
+
+/** Cleanup for compression tests: disables nostatic */
+static int
+compression_test_cleanup(const struct testcase_t *testcase, void *ptr)
+{
+ (void)testcase;
+ (void)ptr;
+ tor_zstd_set_static_apis_disabled_for_testing(0);
+ return 1;
+}
+
+static const struct testcase_setup_t compress_setup = {
+ compression_test_setup, compression_test_cleanup
+};
+
/** Run unit tests for compression functions */
static void
test_util_compress(void *arg)
@@ -6095,22 +6127,22 @@ test_util_get_unquoted_path(void *arg)
{ #name, test_util_ ## name, flags, NULL, NULL }
#define COMPRESS(name, identifier) \
- { "compress/" #name, test_util_compress, 0, &passthrough_setup, \
+ { "compress/" #name, test_util_compress, 0, &compress_setup, \
(char*)(identifier) }
#define COMPRESS_CONCAT(name, identifier) \
{ "compress_concat/" #name, test_util_decompress_concatenated, 0, \
- &passthrough_setup, \
+ &compress_setup, \
(char*)(identifier) }
#define COMPRESS_JUNK(name, identifier) \
{ "compress_junk/" #name, test_util_decompress_junk, 0, \
- &passthrough_setup, \
+ &compress_setup, \
(char*)(identifier) }
#define COMPRESS_DOS(name, identifier) \
{ "compress_dos/" #name, test_util_decompress_dos, 0, \
- &passthrough_setup, \
+ &compress_setup, \
(char*)(identifier) }
#ifdef _WIN32
@@ -6141,11 +6173,13 @@ struct testcase_t util_tests[] = {
COMPRESS(gzip, "gzip"),
COMPRESS(lzma, "x-tor-lzma"),
COMPRESS(zstd, "x-zstd"),
+ COMPRESS(zstd_nostatic, "x-zstd:nostatic"),
COMPRESS(none, "identity"),
COMPRESS_CONCAT(zlib, "deflate"),
COMPRESS_CONCAT(gzip, "gzip"),
COMPRESS_CONCAT(lzma, "x-tor-lzma"),
COMPRESS_CONCAT(zstd, "x-zstd"),
+ COMPRESS_CONCAT(zstd_nostatic, "x-zstd:nostatic"),
COMPRESS_CONCAT(none, "identity"),
COMPRESS_JUNK(zlib, "deflate"),
COMPRESS_JUNK(gzip, "gzip"),
@@ -6154,6 +6188,7 @@ struct testcase_t util_tests[] = {
COMPRESS_DOS(gzip, "gzip"),
COMPRESS_DOS(lzma, "x-tor-lzma"),
COMPRESS_DOS(zstd, "x-zstd"),
+ COMPRESS_DOS(zstd_nostatic, "x-zstd:nostatic"),
UTIL_TEST(gzip_compression_bomb, TT_FORK),
UTIL_LEGACY(datadir),
UTIL_LEGACY(memarea),
diff --git a/src/test/testing_common.c b/src/test/testing_common.c
index 52729147b2..b9b36d96d0 100644
--- a/src/test/testing_common.c
+++ b/src/test/testing_common.c
@@ -29,8 +29,6 @@
#include <dirent.h>
#endif /* defined(_WIN32) */
-#include "or.h"
-
#ifdef USE_DMALLOC
#include <dmalloc.h>
#include "main.h"
diff --git a/src/tools/tor-gencert.c b/src/tools/tor-gencert.c
index fb7465c0eb..0e7fc79e6f 100644
--- a/src/tools/tor-gencert.c
+++ b/src/tools/tor-gencert.c
@@ -36,7 +36,6 @@ ENABLE_GCC_WARNING(redundant-decls)
#include <assert.h>
#endif
-#include "compat.h"
#include "util.h"
#include "torlog.h"
#include "crypto.h"
diff --git a/src/win32/orconfig.h b/src/win32/orconfig.h
index 8b4da1df75..238e0f6962 100644
--- a/src/win32/orconfig.h
+++ b/src/win32/orconfig.h
@@ -218,7 +218,7 @@
#define USING_TWOS_COMPLEMENT
/* Version number of package */
-#define VERSION "0.3.3.3-alpha-dev"
+#define VERSION "0.3.4.0-alpha-dev"