summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2021-02-03 08:51:36 -0500
committerDavid Goulet <dgoulet@torproject.org>2021-02-03 08:51:36 -0500
commitbf80465d86832c6ae2faf582d5ada18371b51370 (patch)
treeb95d65befeed6af10c51f3847988d70c39af8fcc
parenta5b4ee2a01128a97e5b9ec8f50b975a5aaf40551 (diff)
parent98590621bb49cbecd601085f7e03697f8783ff7b (diff)
downloadtor-bf80465d86832c6ae2faf582d5ada18371b51370.tar.gz
tor-bf80465d86832c6ae2faf582d5ada18371b51370.zip
Merge branch 'maint-0.3.5' into release-0.3.5
-rw-r--r--src/core/or/connection_edge.c12
-rw-r--r--src/feature/nodelist/nodelist.c8
2 files changed, 18 insertions, 2 deletions
diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c
index f9a9bbdb73..b40fa3e567 100644
--- a/src/core/or/connection_edge.c
+++ b/src/core/or/connection_edge.c
@@ -4003,6 +4003,15 @@ my_exit_policy_rejects(const tor_addr_t *addr,
return 0;
}
+/** Return true iff the consensus allows network reentry. The default value is
+ * false if the parameter is not found. */
+static bool
+network_reentry_is_allowed(void)
+{
+ /* Default is false, re-entry is not allowed. */
+ return !!networkstatus_get_param(NULL, "allow-network-reentry", 0, 0, 1);
+}
+
/** Connect to conn's specified addr and port. If it worked, conn
* has now been added to the connection_array.
*
@@ -4040,6 +4049,8 @@ connection_exit_connect(edge_connection_t *edge_conn)
* infinite-length circuits (see "A Practical Congestion Attack on Tor Using
* Long Paths", Usenix Security 2009). See also ticket 2667.
*
+ * Skip this if the network reentry is allowed (known from the consensus).
+ *
* The TORPROTOCOL reason is used instead of EXITPOLICY so client do NOT
* attempt to retry connecting onto another circuit that will also fail
* bringing considerable more load on the network if so.
@@ -4050,6 +4061,7 @@ connection_exit_connect(edge_connection_t *edge_conn)
* reason that makes the client retry results in much worst consequences in
* case of an attack so this is a small price to pay. */
if (!connection_edge_is_rendezvous_stream(edge_conn) &&
+ !network_reentry_is_allowed() &&
nodelist_reentry_probably_contains(&conn->addr, conn->port)) {
log_info(LD_EXIT, "%s:%d tried to connect back to a known relay address. "
"Closing.", escaped_safe_str_client(conn->address),
diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c
index 9d553ce1f5..22b93762e7 100644
--- a/src/feature/nodelist/nodelist.c
+++ b/src/feature/nodelist/nodelist.c
@@ -672,8 +672,12 @@ nodelist_set_consensus(networkstatus_t *ns)
address_set_free(the_nodelist->node_addrs);
addr_port_set_free(the_nodelist->reentry_set);
the_nodelist->node_addrs = address_set_new(estimated_addresses);
- /* Times two here is for both the ORPort and DirPort. */
- the_nodelist->reentry_set = addr_port_set_new(estimated_addresses * 2);
+ /* Times two here is for both the ORPort and DirPort. We double it again in
+ * order to minimize as much as possible the false positive when looking up
+ * this set. Reason is that Exit streams that are legitimate but end up a
+ * false positive against this set will thus be considered reentry and be
+ * rejected which means a bad UX. */
+ the_nodelist->reentry_set = addr_port_set_new(estimated_addresses * 2 * 2);
SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, routerstatus_t *, rs) {
node_t *node = node_get_or_create(rs->identity_digest);