aboutsummaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-02-09 12:08:12 -0500
committerNick Mathewson <nickm@torproject.org>2018-02-09 12:08:12 -0500
commitabdf2a6f7f400bf7769b701c79b51e51f1cc9e55 (patch)
tree98a3ca09c057afef4f4ac1e2152bc9c33669319a /src/or
parentd9826b0a30f42754dc5764ce02c7b0271d996c92 (diff)
parent1a4fc9cddf27595db6f5da981a557f768fa32f66 (diff)
downloadtor-abdf2a6f7f400bf7769b701c79b51e51f1cc9e55.tar.gz
tor-abdf2a6f7f400bf7769b701c79b51e51f1cc9e55.zip
Merge remote-tracking branch 'dgoulet/ticket24902_029_05'
Diffstat (limited to 'src/or')
-rw-r--r--src/or/dos.c9
-rw-r--r--src/or/nodelist.c78
-rw-r--r--src/or/nodelist.h3
3 files changed, 90 insertions, 0 deletions
diff --git a/src/or/dos.c b/src/or/dos.c
index 88f1351a3f..9e8a7a9abe 100644
--- a/src/or/dos.c
+++ b/src/or/dos.c
@@ -14,6 +14,7 @@
#include "geoip.h"
#include "main.h"
#include "networkstatus.h"
+#include "nodelist.h"
#include "router.h"
#include "dos.h"
@@ -664,6 +665,14 @@ dos_new_client_conn(or_connection_t *or_conn)
goto end;
}
+ /* We ignore any known address meaning an address of a known relay. The
+ * reason to do so is because network reentry is possible where a client
+ * connection comes from an Exit node. Even when we'll fix reentry, this is
+ * a robust defense to keep in place. */
+ if (nodelist_probably_contains_address(&or_conn->real_addr)) {
+ goto end;
+ }
+
/* We are only interested in client connection from the geoip cache. */
entry = geoip_lookup_client(&or_conn->real_addr, NULL,
GEOIP_CLIENT_CONNECT);
diff --git a/src/or/nodelist.c b/src/or/nodelist.c
index 17a50ca862..391b31d683 100644
--- a/src/or/nodelist.c
+++ b/src/or/nodelist.c
@@ -42,6 +42,7 @@
#include "or.h"
#include "address.h"
+#include "address_set.h"
#include "config.h"
#include "control.h"
#include "dirserv.h"
@@ -87,6 +88,7 @@ static void count_usable_descriptors(int *num_present,
static void update_router_have_minimum_dir_info(void);
static double get_frac_paths_needed_for_circs(const or_options_t *options,
const networkstatus_t *ns);
+static void node_add_to_address_set(const node_t *node);
/** A nodelist_t holds a node_t object for every router we're "willing to use
* for something". Specifically, it should hold a node_t for every node that
@@ -105,6 +107,9 @@ typedef struct nodelist_t {
* you should add it to this map with node_add_to_ed25519_map().
*/
HT_HEAD(nodelist_ed_map, node_t) nodes_by_ed_id;
+
+ /* Set of addresses that belong to nodes we believe in. */
+ address_set_t *node_addrs;
} nodelist_t;
static inline unsigned int
@@ -381,6 +386,50 @@ node_addrs_changed(node_t *node)
node->country = -1;
}
+/** Add all address information about <b>node</b> to the current address
+ * set (if there is one).
+ */
+static void
+node_add_to_address_set(const node_t *node)
+{
+ if (!the_nodelist || !the_nodelist->node_addrs)
+ return;
+
+ /* These various address sources can be redundant, but it's likely faster
+ * to add them all than to compare them all for equality. */
+
+ if (node->rs) {
+ if (node->rs->addr)
+ address_set_add_ipv4h(the_nodelist->node_addrs, node->rs->addr);
+ if (!tor_addr_is_null(&node->rs->ipv6_addr))
+ address_set_add(the_nodelist->node_addrs, &node->rs->ipv6_addr);
+ }
+ if (node->ri) {
+ if (node->ri->addr)
+ address_set_add_ipv4h(the_nodelist->node_addrs, node->ri->addr);
+ if (!tor_addr_is_null(&node->ri->ipv6_addr))
+ address_set_add(the_nodelist->node_addrs, &node->ri->ipv6_addr);
+ }
+ if (node->md) {
+ if (!tor_addr_is_null(&node->md->ipv6_addr))
+ address_set_add(the_nodelist->node_addrs, &node->md->ipv6_addr);
+ }
+}
+
+/** Return true if <b>addr</b> is the address of some node in the nodelist.
+ * If not, probably return false. */
+int
+nodelist_probably_contains_address(const tor_addr_t *addr)
+{
+ if (BUG(!addr))
+ return 0;
+
+ if (!the_nodelist || !the_nodelist->node_addrs)
+ return 0;
+
+ return address_set_probably_contains(the_nodelist->node_addrs, addr);
+}
+
/** Add <b>ri</b> to an appropriate node in the nodelist. If we replace an
* old routerinfo, and <b>ri_old_out</b> is not NULL, set *<b>ri_old_out</b>
* to the previous routerinfo.
@@ -431,6 +480,8 @@ nodelist_set_routerinfo(routerinfo_t *ri, routerinfo_t **ri_old_out)
networkstatus_get_latest_consensus());
}
+ node_add_to_address_set(node);
+
return node;
}
@@ -472,9 +523,22 @@ nodelist_add_microdesc(microdesc_t *md)
node_add_to_ed25519_map(node);
}
+ node_add_to_address_set(node);
+
return node;
}
+/* Default value. */
+#define ESTIMATED_ADDRESS_PER_NODE 2
+
+/* Return the estimated number of address per node_t. This is used for the
+ * size of the bloom filter in the nodelist (node_addrs). */
+MOCK_IMPL(int,
+get_estimated_address_per_node, (void))
+{
+ return ESTIMATED_ADDRESS_PER_NODE;
+}
+
/** Tell the nodelist that the current usable consensus is <b>ns</b>.
* This makes the nodelist change all of the routerstatus entries for
* the nodes, drop nodes that no longer have enough info to get used,
@@ -493,6 +557,12 @@ nodelist_set_consensus(networkstatus_t *ns)
SMARTLIST_FOREACH(the_nodelist->nodes, node_t *, node,
node->rs = NULL);
+ /* Conservatively estimate that every node will have 2 addresses. */
+ const int estimated_addresses = smartlist_len(ns->routerstatus_list) *
+ get_estimated_address_per_node();
+ address_set_free(the_nodelist->node_addrs);
+ the_nodelist->node_addrs = address_set_new(estimated_addresses);
+
SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, routerstatus_t *, rs) {
node_t *node = node_get_or_create(rs->identity_digest);
node->rs = rs;
@@ -536,6 +606,11 @@ nodelist_set_consensus(networkstatus_t *ns)
nodelist_purge();
+ /* Now add all the nodes we have to the address set. */
+ SMARTLIST_FOREACH_BEGIN(the_nodelist->nodes, node_t *, node) {
+ node_add_to_address_set(node);
+ } SMARTLIST_FOREACH_END(node);
+
if (! authdir) {
SMARTLIST_FOREACH_BEGIN(the_nodelist->nodes, node_t *, node) {
/* We have no routerstatus for this router. Clear flags so we can skip
@@ -694,6 +769,9 @@ nodelist_free_all(void)
smartlist_free(the_nodelist->nodes);
+ address_set_free(the_nodelist->node_addrs);
+ the_nodelist->node_addrs = NULL;
+
tor_free(the_nodelist);
}
diff --git a/src/or/nodelist.h b/src/or/nodelist.h
index 0abdcd6045..dc20eaf0a5 100644
--- a/src/or/nodelist.h
+++ b/src/or/nodelist.h
@@ -29,6 +29,7 @@ const node_t *node_get_by_hex_id(const char *identity_digest,
node_t *nodelist_set_routerinfo(routerinfo_t *ri, routerinfo_t **ri_old_out);
node_t *nodelist_add_microdesc(microdesc_t *md);
void nodelist_set_consensus(networkstatus_t *ns);
+int nodelist_probably_contains_address(const tor_addr_t *addr);
void nodelist_remove_microdesc(const char *identity_digest, microdesc_t *md);
void nodelist_remove_routerinfo(routerinfo_t *ri);
@@ -154,5 +155,7 @@ node_set_hsdir_index(node_t *node, const networkstatus_t *ns);
#endif /* defined(NODELIST_PRIVATE) */
+MOCK_DECL(int, get_estimated_address_per_node, (void));
+
#endif /* !defined(TOR_NODELIST_H) */