diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-02-09 12:08:12 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-02-09 12:08:12 -0500 |
commit | abdf2a6f7f400bf7769b701c79b51e51f1cc9e55 (patch) | |
tree | 98a3ca09c057afef4f4ac1e2152bc9c33669319a /src/or | |
parent | d9826b0a30f42754dc5764ce02c7b0271d996c92 (diff) | |
parent | 1a4fc9cddf27595db6f5da981a557f768fa32f66 (diff) | |
download | tor-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.c | 9 | ||||
-rw-r--r-- | src/or/nodelist.c | 78 | ||||
-rw-r--r-- | src/or/nodelist.h | 3 |
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) */ |