summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml3
-rw-r--r--changes/bug271993
-rw-r--r--changes/bug282697
-rw-r--r--changes/bug296135
-rw-r--r--changes/bug301515
-rw-r--r--changes/diagnostic_28223_redux4
-rw-r--r--changes/ticket278213
-rw-r--r--changes/ticket300334
-rw-r--r--changes/ticket300515
-rw-r--r--changes/ticket301143
-rw-r--r--changes/ticket301174
-rw-r--r--changes/ticket301493
-rw-r--r--changes/ticket301764
-rw-r--r--changes/ticket302342
-rw-r--r--doc/tor.1.txt18
-rwxr-xr-xscripts/git/git-pull-all.sh18
-rwxr-xr-xscripts/git/pre-commit.git-hook8
-rwxr-xr-xscripts/git/pre-push.git-hook13
-rw-r--r--scripts/maint/practracker/exceptions.txt8
-rw-r--r--src/config/torrc.sample.in6
-rw-r--r--src/core/or/connection_edge.c27
-rw-r--r--src/core/or/policies.c20
-rw-r--r--src/feature/client/circpathbias.c4
-rw-r--r--src/feature/dirparse/microdesc_parse.c17
-rw-r--r--src/feature/hs/hs_client.c2
-rw-r--r--src/feature/hs/hs_common.c23
-rw-r--r--src/feature/hs/hs_common.h3
-rw-r--r--src/feature/nodelist/microdesc.c28
-rw-r--r--src/feature/nodelist/node_select.c1
-rw-r--r--src/feature/relay/onion_queue.c10
-rw-r--r--src/feature/rend/rendclient.c9
-rw-r--r--src/lib/fdio/fdio.c4
-rw-r--r--src/lib/math/prob_distr.h2
-rw-r--r--src/lib/smartlist_core/smartlist_core.c2
-rw-r--r--src/rust/Cargo.toml11
-rwxr-xr-xsrc/test/test-network.sh34
-rw-r--r--src/test/test_containers.c4
-rw-r--r--src/test/test_hs.c10
-rw-r--r--src/tools/tor-resolve.c1
39 files changed, 269 insertions, 69 deletions
diff --git a/.travis.yml b/.travis.yml
index bda1f323e5..8e258aef26 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -216,7 +216,7 @@ script:
## We run `make check` because that's what https://jenkins.torproject.org does.
- if [[ "$DISTCHECK" == "" && "$TEST_STEM" == "" ]]; then make check; fi
## Diagnostic for bug 29437: kill stem if it hangs for 15 minutes
- - if [[ "$TEST_STEM" != "" ]]; then timelimit -p -t 540 -T 30 make src/app/tor test-stem; fi
+ - if [[ "$TEST_STEM" != "" ]]; then make src/app/tor; timelimit -p -t 540 -s USR1 -T 30 -S ABRT python3 "$STEM_SOURCE_DIR"/run_tests.py --tor src/app/tor --integ --log notice --target RUN_ALL; fi
- if [[ "$DISTCHECK" != "" && "$TEST_STEM" == "" ]]; then make distcheck DISTCHECK_CONFIGURE_FLAGS="$CONFIGURE_FLAGS"; fi
## If this build was one that produced coverage, upload it.
- if [[ "$COVERAGE_OPTIONS" != "" ]]; then coveralls -b . --exclude src/test --exclude src/trunnel --gcov-options '\-p' || echo "Coverage failed"; fi
@@ -230,6 +230,7 @@ after_failure:
## `make distcheck` puts it somewhere different.
- if [[ "$DISTCHECK" != "" ]]; then make show-distdir-testlog || echo "make failed"; fi
- if [[ "$DISTCHECK" != "" ]]; then make show-distdir-core || echo "make failed"; fi
+ - if [[ "$TEST_STEM" != "" ]]; then cat "$STEM_SOURCE_DIR"/test/data/tor_log || echo "cat failed"; fi
before_cache:
## Delete all gcov files.
diff --git a/changes/bug27199 b/changes/bug27199
new file mode 100644
index 0000000000..f9d2a422f9
--- /dev/null
+++ b/changes/bug27199
@@ -0,0 +1,3 @@
+ o Minor bugfixes (rust):
+ - Abort on panic in all build profiles, instead of potentially unwinding
+ into C code. Fixes bug 27199; bugfix on 0.3.3.1-alpha.
diff --git a/changes/bug28269 b/changes/bug28269
new file mode 100644
index 0000000000..bdfe9e1aae
--- /dev/null
+++ b/changes/bug28269
@@ -0,0 +1,7 @@
+ o Minor bugfixes (onion services):
+ - If we are launching repeated HSFETCH queries and are rate-limited,
+ we introduce a new controller response QUERY_RATE_LIMITED instead
+ of QUERY_NO_HSDIR, while keeping the latter for when onion service
+ directories are missing a descriptor. Previously, we returned
+ QUERY_NO_HSDIR for both cases. Fixes bug 28269; bugfix on
+ 0.3.1.1-alpha. Patch by Neel Chauhan
diff --git a/changes/bug29613 b/changes/bug29613
new file mode 100644
index 0000000000..e966973255
--- /dev/null
+++ b/changes/bug29613
@@ -0,0 +1,5 @@
+ o Minor bugfixes (relay):
+ - If we are are a relay and have IPv6Exit to 1 while ExitRelay is
+ auto, we act as if ExitRelay is 1. Previously, we ignored IPv6Exit
+ if ExitRelay was 0 or auto. Fixes bug 29613; bugfix on 0.3.5.1-alpha.
+ Patch by Neel Chauhan.
diff --git a/changes/bug30151 b/changes/bug30151
new file mode 100644
index 0000000000..8ac9a320a0
--- /dev/null
+++ b/changes/bug30151
@@ -0,0 +1,5 @@
+ o Minor bugfixes (tor-resolve):
+ - Fix a memory leak in tor-resolve that could happen if Tor gave it a
+ malformed SOCKS response. (Memory leaks in tor-resolve don't actually
+ matter, but it's good to fix them anyway.) Fixes bug 30151; bugfix on
+ 0.4.0.1-alpha.
diff --git a/changes/diagnostic_28223_redux b/changes/diagnostic_28223_redux
new file mode 100644
index 0000000000..0d7499832e
--- /dev/null
+++ b/changes/diagnostic_28223_redux
@@ -0,0 +1,4 @@
+ o Minor features (diagnostic):
+ - Add more diagnostic log messages in an attempt to solve
+ the issue of NUL bytes appearing in a microdescriptor cache.
+ Related to ticket 28223.
diff --git a/changes/ticket27821 b/changes/ticket27821
new file mode 100644
index 0000000000..158f308fbf
--- /dev/null
+++ b/changes/ticket27821
@@ -0,0 +1,3 @@
+ o Minor features (HTTP tunnel):
+ - Return an informative web page when the HTTPTunnelPort is used as an
+ HTTP proxy. Closes ticket 27821, patch by "eighthave".
diff --git a/changes/ticket30033 b/changes/ticket30033
new file mode 100644
index 0000000000..3f66d049c8
--- /dev/null
+++ b/changes/ticket30033
@@ -0,0 +1,4 @@
+ o Minor features (developer tooling):
+ - Call pre-commit git hook from pre-push hook to make sure we're
+ running documentation and code style checks before pushing to remote
+ git repository. Implements feature 30033.
diff --git a/changes/ticket30051 b/changes/ticket30051
new file mode 100644
index 0000000000..87b6d7611f
--- /dev/null
+++ b/changes/ticket30051
@@ -0,0 +1,5 @@
+ o Minor features (developer tooling):
+ - Call practracker from pre-push and pre-commit git hooks to let a
+ developer know if they made any code style violations in their last
+ commit. This should help preventing code style violations appearing
+ upstream. Closes ticket 30051.
diff --git a/changes/ticket30114 b/changes/ticket30114
new file mode 100644
index 0000000000..a80f7f4dcf
--- /dev/null
+++ b/changes/ticket30114
@@ -0,0 +1,3 @@
+ o Minor features (git scripts):
+ - In git-pull-all.sh, also fetch the latest tor-github pull requests.
+ Implements ticket 30114.
diff --git a/changes/ticket30117 b/changes/ticket30117
new file mode 100644
index 0000000000..5b6e6dabf7
--- /dev/null
+++ b/changes/ticket30117
@@ -0,0 +1,4 @@
+ o Testing (continuous integration):
+ - In Travis, tell timelimit to use stem's backtrace signals. And launch
+ python directly from timelimit, so python receives the signals from
+ timelimit, rather than make. Closes ticket 30117.
diff --git a/changes/ticket30149 b/changes/ticket30149
new file mode 100644
index 0000000000..a21687ac2f
--- /dev/null
+++ b/changes/ticket30149
@@ -0,0 +1,3 @@
+ o Code simplification and refactoring:
+ - Add several assertions in an attempt to fix some Coverity warnings.
+ Closes ticket 30149.
diff --git a/changes/ticket30176 b/changes/ticket30176
new file mode 100644
index 0000000000..da23760ce5
--- /dev/null
+++ b/changes/ticket30176
@@ -0,0 +1,4 @@
+ o Minor features (defense in depth):
+ - In smartlist_remove_keeporder(), set any pointers that become
+ unused to NULL, in case a bug causes them to be used later. Closes
+ ticket 30176. Patch from Tobias Stoeckmann.
diff --git a/changes/ticket30234 b/changes/ticket30234
new file mode 100644
index 0000000000..5a0076bad2
--- /dev/null
+++ b/changes/ticket30234
@@ -0,0 +1,2 @@
+ o Testing (continuous integration):
+ - In Travis, show stem's tor log after failure. Closes ticket 30234.
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index f992172405..cbbc3515bb 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -1935,13 +1935,14 @@ is non-zero):
exit according to the ExitPolicy option, the ReducedExitPolicy option,
or the default ExitPolicy (if no other exit policy option is specified). +
+
- If ExitRelay is set to 0, no traffic is allowed to
- exit, and the ExitPolicy and ReducedExitPolicy options are ignored. +
+ If ExitRelay is set to 0, no traffic is allowed to exit, and the
+ ExitPolicy, ReducedExitPolicy, and IPv6Exit options are ignored. +
+
- If ExitRelay is set to "auto", then Tor checks the ExitPolicy and
- ReducedExitPolicy options. If either is set, Tor behaves as if ExitRelay
- were set to 1. If neither exit policy option is set, Tor behaves as if
- ExitRelay were set to 0. (Default: auto)
+ If ExitRelay is set to "auto", then Tor checks the ExitPolicy,
+ ReducedExitPolicy, and IPv6Exit options. If at least one of these options
+ is set, Tor behaves as if ExitRelay were set to 1. If none of these exit
+ policy options are set, Tor behaves as if ExitRelay were set to 0.
+ (Default: auto)
[[ExitPolicy]] **ExitPolicy** __policy__,__policy__,__...__::
Set an exit policy for this server. Each policy is of the form
@@ -2136,8 +2137,9 @@ is non-zero):
(Default: 0)
[[IPv6Exit]] **IPv6Exit** **0**|**1**::
- If set, and we are an exit node, allow clients to use us for IPv6
- traffic. (Default: 0)
+ If set, and we are an exit node, allow clients to use us for IPv6 traffic.
+ When this option is set and ExitRelay is auto, we act as if ExitRelay
+ is 1. (Default: 0)
[[MaxOnionQueueDelay]] **MaxOnionQueueDelay** __NUM__ [**msec**|**second**]::
If we have more onionskins queued for processing than we can process in
diff --git a/scripts/git/git-pull-all.sh b/scripts/git/git-pull-all.sh
index 0a4898a111..5d1d58e4bf 100755
--- a/scripts/git/git-pull-all.sh
+++ b/scripts/git/git-pull-all.sh
@@ -174,6 +174,19 @@ function fetch_origin
fi
}
+# Fetch tor-github pull requests. No arguments.
+function fetch_tor_github
+{
+ local cmd="git fetch tor-github"
+ printf " %s Fetching tor-github..." "$MARKER"
+ if [ $DRY_RUN -eq 0 ]; then
+ msg=$( eval "$cmd" 2>&1 )
+ validate_ret $? "$msg"
+ else
+ printf "\\n %s\\n" "${IWTH}$cmd${CNRM}"
+ fi
+}
+
###############
# Entry point #
###############
@@ -188,8 +201,11 @@ while getopts "n" opt; do
esac
done
-# First, fetch the origin.
+# First, fetch tor-github.
goto_repo "$ORIGIN_PATH"
+fetch_tor_github
+
+# Then, fetch the origin.
fetch_origin
# Go over all configured worktree.
diff --git a/scripts/git/pre-commit.git-hook b/scripts/git/pre-commit.git-hook
index 65fa99f4c4..b285776c04 100755
--- a/scripts/git/pre-commit.git-hook
+++ b/scripts/git/pre-commit.git-hook
@@ -12,7 +12,7 @@ cd "$workdir" || exit 1
set -e
-if [ ! -z "ls ./changes/*" ]; then
+if [ -n "$(ls ./changes/)" ]; then
python scripts/maint/lintChanges.py ./changes/*
fi
@@ -26,7 +26,7 @@ if [ -d src/lib ]; then
src/test/*.[ch] \
src/test/*/*.[ch] \
src/tools/*.[ch]
-elif [ -d src/common]; then
+elif [ -d src/common ]; then
# This was the layout before 0.3.5
perl scripts/maint/checkSpace.pl -C \
src/common/*/*.[ch] \
@@ -39,3 +39,7 @@ fi
if test -e scripts/maint/checkIncludes.py; then
python scripts/maint/checkIncludes.py
fi
+
+if [ -e scripts/maint/practracker/practracker.py ]; then
+ python3 ./scripts/maint/practracker/practracker.py "$workdir"
+fi
diff --git a/scripts/git/pre-push.git-hook b/scripts/git/pre-push.git-hook
index e7a72efa08..740180d6f6 100755
--- a/scripts/git/pre-push.git-hook
+++ b/scripts/git/pre-push.git-hook
@@ -27,6 +27,19 @@ ref_is_upstream_branch() {
fi
}
+workdir=$(git rev-parse --show-toplevel)
+if [ -x "$workdir/.git/hooks/pre-commit" ]; then
+ if ! "$workdir"/.git/hooks/pre-commit; then
+ exit 1
+ fi
+fi
+
+if [ -e scripts/maint/practracker/practracker.py ]; then
+ if ! python3 ./scripts/maint/practracker/practracker.py "$workdir"; then
+ exit 1
+ fi
+fi
+
# shellcheck disable=SC2034
while read -r local_ref local_sha remote_ref remote_sha
do
diff --git a/scripts/maint/practracker/exceptions.txt b/scripts/maint/practracker/exceptions.txt
index 7d03bf27d6..1992c563ac 100644
--- a/scripts/maint/practracker/exceptions.txt
+++ b/scripts/maint/practracker/exceptions.txt
@@ -102,7 +102,7 @@ problem function-size /src/core/or/circuituse.c:circuit_get_open_circ_or_launch(
problem function-size /src/core/or/circuituse.c:connection_ap_handshake_attach_circuit() 244
problem function-size /src/core/or/command.c:command_process_create_cell() 156
problem function-size /src/core/or/command.c:command_process_relay_cell() 132
-problem file-size /src/core/or/connection_edge.c 4550
+problem file-size /src/core/or/connection_edge.c 4575
problem include-count /src/core/or/connection_edge.c 64
problem function-size /src/core/or/connection_edge.c:connection_ap_expire_beginning() 117
problem function-size /src/core/or/connection_edge.c:connection_ap_handshake_rewrite() 192
@@ -117,7 +117,7 @@ problem include-count /src/core/or/connection_or.c 51
problem function-size /src/core/or/connection_or.c:connection_or_group_set_badness_() 105
problem function-size /src/core/or/connection_or.c:connection_or_client_learned_peer_id() 144
problem function-size /src/core/or/connection_or.c:connection_or_compute_authenticate_cell_body() 235
-problem file-size /src/core/or/policies.c 3163
+problem file-size /src/core/or/policies.c 3171
problem function-size /src/core/or/policies.c:policy_summarize() 107
problem function-size /src/core/or/protover.c:protover_all_supported() 116
problem file-size /src/core/or/relay.c 3173
@@ -187,7 +187,7 @@ problem function-size /src/feature/dirclient/dirclient.c:handle_response_fetch_c
problem function-size /src/feature/dircommon/consdiff.c:gen_ed_diff() 204
problem function-size /src/feature/dircommon/consdiff.c:apply_ed_diff() 159
problem function-size /src/feature/dirparse/authcert_parse.c:authority_cert_parse_from_string() 182
-problem function-size /src/feature/dirparse/microdesc_parse.c:microdescs_parse_from_string() 154
+problem function-size /src/feature/dirparse/microdesc_parse.c:microdescs_parse_from_string() 169
problem function-size /src/feature/dirparse/ns_parse.c:routerstatus_parse_entry_from_string() 286
problem function-size /src/feature/dirparse/ns_parse.c:networkstatus_verify_bw_weights() 389
problem function-size /src/feature/dirparse/ns_parse.c:networkstatus_parse_vote_from_string() 638
@@ -218,7 +218,7 @@ problem include-count /src/feature/nodelist/networkstatus.c 61
problem function-size /src/feature/nodelist/networkstatus.c:networkstatus_check_consensus_signature() 176
problem function-size /src/feature/nodelist/networkstatus.c:networkstatus_set_current_consensus() 293
problem function-size /src/feature/nodelist/node_select.c:router_pick_directory_server_impl() 123
-problem function-size /src/feature/nodelist/node_select.c:compute_weighted_bandwidths() 205
+problem function-size /src/feature/nodelist/node_select.c:compute_weighted_bandwidths() 206
problem function-size /src/feature/nodelist/node_select.c:router_pick_trusteddirserver_impl() 114
problem function-size /src/feature/nodelist/nodelist.c:compute_frac_paths_available() 193
problem file-size /src/feature/nodelist/routerlist.c 3234
diff --git a/src/config/torrc.sample.in b/src/config/torrc.sample.in
index c2ae707e93..9d514e6bda 100644
--- a/src/config/torrc.sample.in
+++ b/src/config/torrc.sample.in
@@ -174,13 +174,11 @@
## Uncomment this if you want your relay to be an exit, with the default
## exit policy (or whatever exit policy you set below).
-## (If ReducedExitPolicy or ExitPolicy are set, relays are exits.
-## If neither exit policy option is set, relays are non-exits.)
+## (If ReducedExitPolicy, ExitPolicy, or IPv6Exit are set, relays are exits.
+## If none of these options are set, relays are non-exits.)
#ExitRelay 1
## Uncomment this if you want your relay to allow IPv6 exit traffic.
-## You must also set ExitRelay, ReducedExitPolicy, or ExitPolicy to make your
-## relay into an exit.
## (Relays do not allow any exit traffic by default.)
#IPv6Exit 1
diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c
index 071a8c91ed..33ba723971 100644
--- a/src/core/or/connection_edge.c
+++ b/src/core/or/connection_edge.c
@@ -2810,6 +2810,31 @@ connection_ap_process_natd(entry_connection_t *conn)
return connection_ap_rewrite_and_attach_if_allowed(conn, NULL, NULL);
}
+static const char HTTP_CONNECT_IS_NOT_AN_HTTP_PROXY_MSG[] =
+ "HTTP/1.0 405 Method Not Allowed\r\n"
+ "Content-Type: text/html; charset=iso-8859-1\r\n\r\n"
+ "<html>\n"
+ "<head>\n"
+ "<title>This is an HTTP CONNECT tunnel, not an full HTTP Proxy</title>\n"
+ "</head>\n"
+ "<body>\n"
+ "<h1>This is an HTTP CONNECT tunnel, not an HTTP proxy.</h1>\n"
+ "<p>\n"
+ "It appears you have configured your web browser to use this Tor port as\n"
+ "an HTTP proxy.\n"
+ "</p><p>\n"
+ "This is not correct: This port is configured as a CONNECT tunnel, not\n"
+ "an HTTP proxy. Please configure your client accordingly. You can also\n"
+ "use HTTPS, then the client should automatically use HTTP CONNECT."
+ "</p>\n"
+ "<p>\n"
+ "See <a href=\"https://www.torproject.org/documentation.html\">"
+ "https://www.torproject.org/documentation.html</a> for more "
+ "information.\n"
+ "</p>\n"
+ "</body>\n"
+ "</html>\n";
+
/** Called on an HTTP CONNECT entry connection when some bytes have arrived,
* but we have not yet received a full HTTP CONNECT request. Try to parse an
* HTTP CONNECT request from the connection's inbuf. On success, set up the
@@ -2850,7 +2875,7 @@ connection_ap_process_http_connect(entry_connection_t *conn)
tor_assert(command);
tor_assert(addrport);
if (strcasecmp(command, "connect")) {
- errmsg = "HTTP/1.0 405 Method Not Allowed\r\n\r\n";
+ errmsg = HTTP_CONNECT_IS_NOT_AN_HTTP_PROXY_MSG;
goto err;
}
diff --git a/src/core/or/policies.c b/src/core/or/policies.c
index a6d66d36de..f59894ea8f 100644
--- a/src/core/or/policies.c
+++ b/src/core/or/policies.c
@@ -1164,6 +1164,15 @@ authdir_policy_badexit_address(uint32_t addr, uint16_t port)
#define REJECT(arg) \
STMT_BEGIN *msg = tor_strdup(arg); goto err; STMT_END
+/** Check <b>or_options</b> to determine whether or not we are using the
+ * default options for exit policy. Return true if so, false otherwise. */
+static int
+policy_using_default_exit_options(const or_options_t *or_options)
+{
+ return (or_options->ExitPolicy == NULL && or_options->ExitRelay == -1 &&
+ or_options->ReducedExitPolicy == 0 && or_options->IPv6Exit == 0);
+}
+
/** Config helper: If there's any problem with the policy configuration
* options in <b>options</b>, return -1 and set <b>msg</b> to a newly
* allocated description of the error. Else return 0. */
@@ -1182,9 +1191,8 @@ validate_addr_policies(const or_options_t *options, char **msg)
static int warned_about_nonexit = 0;
- if (public_server_mode(options) &&
- !warned_about_nonexit && options->ExitPolicy == NULL &&
- options->ExitRelay == -1 && options->ReducedExitPolicy == 0) {
+ if (public_server_mode(options) && !warned_about_nonexit &&
+ policy_using_default_exit_options(options)) {
warned_about_nonexit = 1;
log_notice(LD_CONFIG, "By default, Tor does not run as an exit relay. "
"If you want to be an exit relay, "
@@ -2141,9 +2149,9 @@ policies_parse_exit_policy_from_options(const or_options_t *or_options,
int rv = 0;
/* Short-circuit for non-exit relays, or for relays where we didn't specify
- * ExitPolicy or ReducedExitPolicy and ExitRelay is auto. */
- if (or_options->ExitRelay == 0 || (or_options->ExitPolicy == NULL &&
- or_options->ExitRelay == -1 && or_options->ReducedExitPolicy == 0)) {
+ * ExitPolicy or ReducedExitPolicy or IPv6Exit and ExitRelay is auto. */
+ if (or_options->ExitRelay == 0 ||
+ policy_using_default_exit_options(or_options)) {
append_exit_policy_string(result, "reject *4:*");
append_exit_policy_string(result, "reject *6:*");
return 0;
diff --git a/src/feature/client/circpathbias.c b/src/feature/client/circpathbias.c
index 1743ab5a81..e6af649ba7 100644
--- a/src/feature/client/circpathbias.c
+++ b/src/feature/client/circpathbias.c
@@ -176,6 +176,7 @@ pathbias_get_scale_threshold(const or_options_t *options)
static double
pathbias_get_scale_ratio(const or_options_t *options)
{
+ (void) options;
/*
* The scale factor is the denominator for our scaling
* of circuit counts for our path bias window.
@@ -185,7 +186,8 @@ pathbias_get_scale_ratio(const or_options_t *options)
*/
int denominator = networkstatus_get_param(NULL, "pb_scalefactor",
2, 2, INT32_MAX);
- (void) options;
+ tor_assert(denominator > 0);
+
/**
* The mult factor is the numerator for our scaling
* of circuit counts for our path bias window. It
diff --git a/src/feature/dirparse/microdesc_parse.c b/src/feature/dirparse/microdesc_parse.c
index 3b11e65ca0..22cc1e272e 100644
--- a/src/feature/dirparse/microdesc_parse.c
+++ b/src/feature/dirparse/microdesc_parse.c
@@ -160,7 +160,22 @@ microdescs_parse_from_string(const char *s, const char *eos,
if (tokenize_string(area, s, start_of_next_microdesc, tokens,
microdesc_token_table, flags)) {
- log_warn(LD_DIR, "Unparseable microdescriptor");
+ const char *location;
+ switch (where) {
+ case SAVED_NOWHERE:
+ location = "download or generated string";
+ break;
+ case SAVED_IN_CACHE:
+ location = "cache";
+ break;
+ case SAVED_IN_JOURNAL:
+ location = "journal";
+ break;
+ default:
+ location = "unknown location";
+ break;
+ }
+ log_warn(LD_DIR, "Unparseable microdescriptor found in %s", location);
goto next;
}
diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c
index 38b9646c17..7aec6d80bb 100644
--- a/src/feature/hs/hs_client.c
+++ b/src/feature/hs/hs_client.c
@@ -424,7 +424,7 @@ pick_hsdir_v3(const ed25519_public_key_t *onion_identity_pk)
/* Pick an HSDir from the responsible ones. The ownership of
* responsible_hsdirs is given to this function so no need to free it. */
- hsdir_rs = hs_pick_hsdir(responsible_hsdirs, base64_blinded_pubkey);
+ hsdir_rs = hs_pick_hsdir(responsible_hsdirs, base64_blinded_pubkey, NULL);
return hsdir_rs;
}
diff --git a/src/feature/hs/hs_common.c b/src/feature/hs/hs_common.c
index b2227432d2..d4736c2862 100644
--- a/src/feature/hs/hs_common.c
+++ b/src/feature/hs/hs_common.c
@@ -1589,20 +1589,25 @@ hs_purge_last_hid_serv_requests(void)
/** Given the list of responsible HSDirs in <b>responsible_dirs</b>, pick the
* one that we should use to fetch a descriptor right now. Take into account
* previous failed attempts at fetching this descriptor from HSDirs using the
- * string identifier <b>req_key_str</b>.
+ * string identifier <b>req_key_str</b>. We return whether we are rate limited
+ * into *<b>is_rate_limited_out</b> if it is not NULL.
*
* Steals ownership of <b>responsible_dirs</b>.
*
* Return the routerstatus of the chosen HSDir if successful, otherwise return
* NULL if no HSDirs are worth trying right now. */
routerstatus_t *
-hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str)
+hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str,
+ bool *is_rate_limited_out)
{
smartlist_t *usable_responsible_dirs = smartlist_new();
const or_options_t *options = get_options();
routerstatus_t *hs_dir;
time_t now = time(NULL);
int excluded_some;
+ bool rate_limited = false;
+ int rate_limited_count = 0;
+ int responsible_dirs_count = smartlist_len(responsible_dirs);
tor_assert(req_key_str);
@@ -1622,6 +1627,7 @@ hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str)
if (last + hs_hsdir_requery_period(options) >= now ||
!node || !node_has_preferred_descriptor(node, 0)) {
SMARTLIST_DEL_CURRENT(responsible_dirs, dir);
+ rate_limited_count++;
continue;
}
if (!routerset_contains_node(options->ExcludeNodes, node)) {
@@ -1629,6 +1635,10 @@ hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str)
}
} SMARTLIST_FOREACH_END(dir);
+ if (rate_limited_count > 0 || responsible_dirs_count > 0) {
+ rate_limited = rate_limited_count == responsible_dirs_count;
+ }
+
excluded_some =
smartlist_len(usable_responsible_dirs) < smartlist_len(responsible_dirs);
@@ -1640,9 +1650,10 @@ hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str)
smartlist_free(responsible_dirs);
smartlist_free(usable_responsible_dirs);
if (!hs_dir) {
+ const char *warn_str = (rate_limited) ? "we are rate limited." :
+ "we requested them all recently without success";
log_info(LD_REND, "Could not pick one of the responsible hidden "
- "service directories, because we requested them all "
- "recently without success.");
+ "service directories, because %s.", warn_str);
if (options->StrictNodes && excluded_some) {
log_warn(LD_REND, "Could not pick a hidden service directory for the "
"requested hidden service: they are all either down or "
@@ -1654,6 +1665,10 @@ hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str)
hs_lookup_last_hid_serv_request(hs_dir, req_key_str, now, 1);
}
+ if (is_rate_limited_out != NULL) {
+ *is_rate_limited_out = rate_limited;
+ }
+
return hs_dir;
}
diff --git a/src/feature/hs/hs_common.h b/src/feature/hs/hs_common.h
index abf39fa431..3009780d90 100644
--- a/src/feature/hs/hs_common.h
+++ b/src/feature/hs/hs_common.h
@@ -241,7 +241,8 @@ void hs_get_responsible_hsdirs(const struct ed25519_public_key_t *blinded_pk,
int use_second_hsdir_index,
int for_fetching, smartlist_t *responsible_dirs);
routerstatus_t *hs_pick_hsdir(smartlist_t *responsible_dirs,
- const char *req_key_str);
+ const char *req_key_str,
+ bool *is_rate_limited_out);
time_t hs_hsdir_requery_period(const or_options_t *options);
time_t hs_lookup_last_hid_serv_request(routerstatus_t *hs_dir,
diff --git a/src/feature/nodelist/microdesc.c b/src/feature/nodelist/microdesc.c
index b4f05b63a0..36922561a0 100644
--- a/src/feature/nodelist/microdesc.c
+++ b/src/feature/nodelist/microdesc.c
@@ -70,6 +70,8 @@ struct microdesc_cache_t {
};
static microdesc_cache_t *get_microdesc_cache_noload(void);
+static void warn_if_nul_found(const char *inp, size_t len, int64_t offset,
+ const char *activity);
/** Helper: computes a hash of <b>md</b> to place it in a hash table. */
static inline unsigned int
@@ -223,6 +225,8 @@ dump_microdescriptor(int fd, microdesc_t *md, size_t *annotation_len_out)
}
md->off = tor_fd_getpos(fd);
+ warn_if_nul_found(md->body, md->bodylen, (int64_t) md->off,
+ "dumping a microdescriptor");
written = write_all_to_fd(fd, md->body, md->bodylen);
if (written != (ssize_t)md->bodylen) {
written = written < 0 ? 0 : written;
@@ -482,6 +486,27 @@ microdesc_cache_clear(microdesc_cache_t *cache)
cache->bytes_dropped = 0;
}
+static void
+warn_if_nul_found(const char *inp, size_t len, int64_t offset,
+ const char *activity)
+{
+ const char *nul_found = memchr(inp, 0, len);
+ if (BUG(nul_found)) {
+ log_warn(LD_BUG, "Found unexpected NUL while %s, offset %"PRId64
+ "at position %"TOR_PRIuSZ"/%"TOR_PRIuSZ".",
+ activity, offset, (nul_found - inp), len);
+ const char *start_excerpt_at, *eos = inp + len;
+ if ((nul_found - inp) >= 16)
+ start_excerpt_at = nul_found - 16;
+ else
+ start_excerpt_at = inp;
+ size_t excerpt_len = MIN(32, eos - start_excerpt_at);
+ char tmp[65];
+ base16_encode(tmp, sizeof(tmp), start_excerpt_at, excerpt_len);
+ log_warn(LD_BUG, " surrounding string: %s", tmp);
+ }
+}
+
/** Reload the contents of <b>cache</b> from disk. If it is empty, load it
* for the first time. Return 0 on success, -1 on failure. */
int
@@ -499,6 +524,7 @@ microdesc_cache_reload(microdesc_cache_t *cache)
mm = cache->cache_content = tor_mmap_file(cache->cache_fname);
if (mm) {
+ warn_if_nul_found(mm->data, mm->size, 0, "scanning microdesc cache");
added = microdescs_add_to_cache(cache, mm->data, mm->data+mm->size,
SAVED_IN_CACHE, 0, -1, NULL);
if (added) {
@@ -511,6 +537,8 @@ microdesc_cache_reload(microdesc_cache_t *cache)
RFTS_IGNORE_MISSING, &st);
if (journal_content) {
cache->journal_len = (size_t) st.st_size;
+ warn_if_nul_found(journal_content, cache->journal_len, 0,
+ "reading microdesc journal");
added = microdescs_add_to_cache(cache, journal_content,
journal_content+st.st_size,
SAVED_IN_JOURNAL, 0, -1, NULL);
diff --git a/src/feature/nodelist/node_select.c b/src/feature/nodelist/node_select.c
index e31abb247f..93ddb066d4 100644
--- a/src/feature/nodelist/node_select.c
+++ b/src/feature/nodelist/node_select.c
@@ -585,6 +585,7 @@ compute_weighted_bandwidths(const smartlist_t *sl,
}
weight_scale = networkstatus_get_weight_scale_param(NULL);
+ tor_assert(weight_scale >= 1);
if (rule == WEIGHT_FOR_GUARD) {
Wg = networkstatus_get_bw_weight(NULL, "Wgg", -1);
diff --git a/src/feature/relay/onion_queue.c b/src/feature/relay/onion_queue.c
index 696905cf5e..c37745cf33 100644
--- a/src/feature/relay/onion_queue.c
+++ b/src/feature/relay/onion_queue.c
@@ -212,10 +212,12 @@ num_ntors_per_tap(void)
#define MIN_NUM_NTORS_PER_TAP 1
#define MAX_NUM_NTORS_PER_TAP 100000
- return networkstatus_get_param(NULL, "NumNTorsPerTAP",
- DEFAULT_NUM_NTORS_PER_TAP,
- MIN_NUM_NTORS_PER_TAP,
- MAX_NUM_NTORS_PER_TAP);
+ int result = networkstatus_get_param(NULL, "NumNTorsPerTAP",
+ DEFAULT_NUM_NTORS_PER_TAP,
+ MIN_NUM_NTORS_PER_TAP,
+ MAX_NUM_NTORS_PER_TAP);
+ tor_assert(result > 0);
+ return result;
}
/** Choose which onion queue we'll pull from next. If one is empty choose
diff --git a/src/feature/rend/rendclient.c b/src/feature/rend/rendclient.c
index 5a8b234544..f84d221b1a 100644
--- a/src/feature/rend/rendclient.c
+++ b/src/feature/rend/rendclient.c
@@ -469,16 +469,19 @@ directory_get_from_hs_dir(const char *desc_id,
/* Automatically pick an hs dir if none given. */
if (!rs_hsdir) {
+ bool rate_limited = false;
+
/* Determine responsible dirs. Even if we can't get all we want, work with
* the ones we have. If it's empty, we'll notice in hs_pick_hsdir(). */
smartlist_t *responsible_dirs = smartlist_new();
hid_serv_get_responsible_directories(responsible_dirs, desc_id);
- hs_dir = hs_pick_hsdir(responsible_dirs, desc_id_base32);
+ hs_dir = hs_pick_hsdir(responsible_dirs, desc_id_base32, &rate_limited);
if (!hs_dir) {
/* No suitable hs dir can be found, stop right now. */
- control_event_hsv2_descriptor_failed(rend_query, NULL,
- "QUERY_NO_HSDIR");
+ const char *query_response = (rate_limited) ? "QUERY_RATE_LIMITED" :
+ "QUERY_NO_HSDIR";
+ control_event_hsv2_descriptor_failed(rend_query, NULL, query_response);
control_event_hs_descriptor_content(rend_data_get_address(rend_query),
desc_id_base32, NULL, NULL);
return 0;
diff --git a/src/lib/fdio/fdio.c b/src/lib/fdio/fdio.c
index 6c87af791d..078af6a9ba 100644
--- a/src/lib/fdio/fdio.c
+++ b/src/lib/fdio/fdio.c
@@ -17,12 +17,16 @@
#ifdef _WIN32
#include <windows.h>
#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
#include "lib/fdio/fdio.h"
#include "lib/cc/torint.h"
#include "lib/err/torerr.h"
#include <stdlib.h>
+#include <stdio.h>
/** @{ */
/** Some old versions of Unix didn't define constants for these values,
diff --git a/src/lib/math/prob_distr.h b/src/lib/math/prob_distr.h
index 2eb935e4a8..8fccf8d015 100644
--- a/src/lib/math/prob_distr.h
+++ b/src/lib/math/prob_distr.h
@@ -53,7 +53,7 @@ struct dist {
* We define this conditionally to suppress false positives from
* Coverity, which gets confused by the sizeof business.
*/
-#ifdef __COVERITY___
+#ifdef __COVERITY__
#define TYPE_CHECK_OBJ(OPS, OBJ, TYPE) 0
#else
#define TYPE_CHECK_OBJ(OPS, OBJ, TYPE) \
diff --git a/src/lib/smartlist_core/smartlist_core.c b/src/lib/smartlist_core/smartlist_core.c
index 5947e76271..6b0a305a93 100644
--- a/src/lib/smartlist_core/smartlist_core.c
+++ b/src/lib/smartlist_core/smartlist_core.c
@@ -177,6 +177,8 @@ smartlist_remove_keeporder(smartlist_t *sl, const void *element)
sl->list[i++] = sl->list[j];
}
}
+ memset(sl->list + sl->num_used, 0,
+ sizeof(void *) * (num_used_orig - sl->num_used));
}
/** If <b>sl</b> is nonempty, remove and return the final element. Otherwise,
diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml
index 83f9629660..de8693ea33 100644
--- a/src/rust/Cargo.toml
+++ b/src/rust/Cargo.toml
@@ -10,6 +10,17 @@ members = [
"tor_util",
]
+# Can remove panic="abort" when this issue is fixed:
+# https://github.com/rust-lang/rust/issues/52652
+[profile.dev]
+panic = "abort"
+
[profile.release]
debug = true
panic = "abort"
+
+[profile.test]
+panic = "abort"
+
+[profile.bench]
+panic = "abort"
diff --git a/src/test/test-network.sh b/src/test/test-network.sh
index 4d56e83806..5ef995f1a4 100755
--- a/src/test/test-network.sh
+++ b/src/test/test-network.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/bin/sh
# This script calls the equivalent script in chutney/tools
@@ -18,32 +18,14 @@ ECHO="${ECHO:-echo}"
# Output is prefixed with the name of the script
myname=$(basename "$0")
-# Save the arguments before we destroy them
-# This might not preserve arguments with spaces in them
-ORIGINAL_ARGS=( "$@" )
-
# We need to find CHUTNEY_PATH, so that we can call the version of this script
# in chutney/tools with the same arguments. We also need to respect --quiet.
-until [ -z "$1" ]
-do
- case "$1" in
- --chutney-path)
- CHUTNEY_PATH="$2"
- shift
- ;;
- --tor-path)
- TOR_DIR="$2"
- shift
- ;;
- --quiet)
- ECHO=true
- ;;
- *)
- # maybe chutney's test-network.sh can handle it
- ;;
- esac
- shift
-done
+CHUTNEY_PATH=$(echo "$@" | awk -F '--chutney-path ' '{sub(" .*","",$2); print $2}')
+TOR_DIR=$(echo "$@" | awk -F '--tor-dir ' '{sub(" .*","",$2); print $2}')
+
+if echo "$@" | grep -e "--quiet" > /dev/null; then
+ ECHO=true
+fi
# optional: $TOR_DIR is the tor build directory
# it's used to find the location of tor binaries
@@ -99,7 +81,7 @@ if [ -d "$CHUTNEY_PATH" ] && [ -x "$TEST_NETWORK" ]; then
# this may fail if some arguments have spaces in them
# if so, set CHUTNEY_PATH before calling test-network.sh, and spaces
# will be handled correctly
- exec "$TEST_NETWORK" "${ORIGINAL_ARGS[@]}" # $ORIGINAL_ARGS
+ exec "$TEST_NETWORK" "$@"
else
$ECHO "$myname: Could not find tools/test-network.sh in CHUTNEY_PATH."
$ECHO "$myname: Please update your chutney using 'git pull'."
diff --git a/src/test/test_containers.c b/src/test/test_containers.c
index 7892a08853..67ba457975 100644
--- a/src/test/test_containers.c
+++ b/src/test/test_containers.c
@@ -1006,6 +1006,10 @@ test_container_smartlist_remove(void *arg)
tt_ptr_op(smartlist_get(sl, 1), OP_EQ, &array[2]);
tt_ptr_op(smartlist_get(sl, 2), OP_EQ, &array[1]);
tt_ptr_op(smartlist_get(sl, 3), OP_EQ, &array[2]);
+ /* Ordinary code should never look at this pointer; we're doing it here
+ * to make sure that we really cleared the pointer we removed.
+ */
+ tt_ptr_op(sl->list[4], OP_EQ, NULL);
done:
smartlist_free(sl);
diff --git a/src/test/test_hs.c b/src/test/test_hs.c
index aeb3387471..5d3327c777 100644
--- a/src/test/test_hs.c
+++ b/src/test/test_hs.c
@@ -323,6 +323,16 @@ test_hs_desc_event(void *arg)
tt_str_op(received_msg,OP_EQ, expected_msg);
tor_free(received_msg);
+ /* test HSDir rate limited */
+ rend_query.auth_type = REND_NO_AUTH;
+ control_event_hsv2_descriptor_failed(&rend_query.base_, NULL,
+ "QUERY_RATE_LIMITED");
+ expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" NO_AUTH " \
+ "UNKNOWN REASON=QUERY_RATE_LIMITED\r\n";
+ tt_assert(received_msg);
+ tt_str_op(received_msg,OP_EQ, expected_msg);
+ tor_free(received_msg);
+
/* Test invalid content with no HSDir fingerprint. */
char *exp_msg;
control_event_hs_descriptor_content(rend_query.onion_address,
diff --git a/src/tools/tor-resolve.c b/src/tools/tor-resolve.c
index 98b3a4a74c..5d97696c18 100644
--- a/src/tools/tor-resolve.c
+++ b/src/tools/tor-resolve.c
@@ -424,6 +424,7 @@ do_resolve(const char *hostname,
if (parsed < 2) {
log_err(LD_NET, "Failed to parse SOCKS5 method selection "
"message");
+ socks5_server_method_free(m);
goto err;
}