diff options
author | David Goulet <dgoulet@torproject.org> | 2021-01-29 14:54:21 -0500 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2021-01-29 14:54:21 -0500 |
commit | b2434d30d2c1071f01d9331752fc7d357169332f (patch) | |
tree | fe4b908fc6cfb88c7f0d869f20d4d6a32484c794 /src/feature/nodelist | |
parent | ea380162025d392803a96d331c8dc64bef56f2e7 (diff) | |
parent | 705fd37875c4acd61037da6a2680678ae128e4a4 (diff) | |
download | tor-b2434d30d2c1071f01d9331752fc7d357169332f.tar.gz tor-b2434d30d2c1071f01d9331752fc7d357169332f.zip |
Merge branch 'tor-gitlab/mr/285' into ticket2667_044_01
Diffstat (limited to 'src/feature/nodelist')
-rw-r--r-- | src/feature/nodelist/dirlist.c | 11 | ||||
-rw-r--r-- | src/feature/nodelist/nodelist.c | 87 | ||||
-rw-r--r-- | src/feature/nodelist/nodelist.h | 6 |
3 files changed, 74 insertions, 30 deletions
diff --git a/src/feature/nodelist/dirlist.c b/src/feature/nodelist/dirlist.c index 33d1bfc4d0..4317491043 100644 --- a/src/feature/nodelist/dirlist.c +++ b/src/feature/nodelist/dirlist.c @@ -55,13 +55,18 @@ static smartlist_t *fallback_dir_servers = NULL; static void add_trusted_dir_to_nodelist_addr_set(const dir_server_t *dir) { + tor_addr_t tmp_addr; + tor_assert(dir); tor_assert(dir->is_authority); - /* Add IPv4 and then IPv6 if applicable. */ - nodelist_add_addr4_to_address_set(dir->addr); + /* Add IPv4 and then IPv6 if applicable. For authorities, we add the ORPort + * and DirPort so re-entry into the network back to them is not possible. */ + tor_addr_from_ipv4h(&tmp_addr, dir->addr); + nodelist_add_addr_to_address_set(&tmp_addr, dir->or_port, dir->dir_port); if (!tor_addr_is_null(&dir->ipv6_addr)) { - nodelist_add_addr6_to_address_set(&dir->ipv6_addr); + /* IPv6 DirPort is not a thing yet for authorities. */ + nodelist_add_addr_to_address_set(&dir->ipv6_addr, dir->ipv6_orport, 0); } } diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c index 6ee1d11cae..94c2730028 100644 --- a/src/feature/nodelist/nodelist.c +++ b/src/feature/nodelist/nodelist.c @@ -135,6 +135,10 @@ typedef struct nodelist_t { /* Set of addresses that belong to nodes we believe in. */ address_set_t *node_addrs; + /* Set of addresses + port that belong to nodes we know and that we don't + * allow network re-entry towards them. */ + addr_port_set_t *reentry_set; + /* The valid-after time of the last live consensus that initialized the * nodelist. We use this to detect outdated nodelists that need to be * rebuilt using a newer consensus. */ @@ -447,49 +451,62 @@ node_addrs_changed(node_t *node) static void node_add_to_address_set(const node_t *node) { - if (!the_nodelist || !the_nodelist->node_addrs) + tor_addr_t tmp_addr; + + if (!the_nodelist || + !the_nodelist->node_addrs || !the_nodelist->reentry_set) return; - /* These various address sources can be redundant, but it's likely faster - * to add them all than to compare them all for equality. */ + /* These various address sources can be redundant, but it's likely faster to + * add them all than to compare them all for equality. + * + * For relays, we only add the ORPort in the addr+port set since we want to + * allow re-entry into the network to the DirPort so the self reachability + * test succeeds and thus the 0 value for the DirPort. */ if (node->rs) { - if (node->rs->addr) - nodelist_add_addr4_to_address_set(node->rs->addr); + if (node->rs->addr) { + tor_addr_from_ipv4h(&tmp_addr, node->rs->addr); + nodelist_add_addr_to_address_set(&tmp_addr, node->rs->or_port, 0); + } if (!tor_addr_is_null(&node->rs->ipv6_addr)) - nodelist_add_addr6_to_address_set(&node->rs->ipv6_addr); + nodelist_add_addr_to_address_set(&node->rs->ipv6_addr, + node->rs->ipv6_orport, 0); } if (node->ri) { - if (node->ri->addr) - nodelist_add_addr4_to_address_set(node->ri->addr); + if (node->ri->addr) { + tor_addr_from_ipv4h(&tmp_addr, node->ri->addr); + nodelist_add_addr_to_address_set(&tmp_addr, node->ri->or_port, 0); + } if (!tor_addr_is_null(&node->ri->ipv6_addr)) - nodelist_add_addr6_to_address_set(&node->ri->ipv6_addr); + nodelist_add_addr_to_address_set(&node->ri->ipv6_addr, + node->ri->ipv6_orport, 0); } if (node->md) { if (!tor_addr_is_null(&node->md->ipv6_addr)) - nodelist_add_addr6_to_address_set(&node->md->ipv6_addr); + nodelist_add_addr_to_address_set(&node->md->ipv6_addr, + node->md->ipv6_orport, 0); } } -/** Add the given v4 address into the nodelist address set. */ +/** Add the given address into the nodelist address set. */ void -nodelist_add_addr4_to_address_set(const uint32_t addr) +nodelist_add_addr_to_address_set(const tor_addr_t *addr, + uint16_t or_port, uint16_t dir_port) { - if (!the_nodelist || !the_nodelist->node_addrs || addr == 0) { - return; - } - address_set_add_ipv4h(the_nodelist->node_addrs, addr); -} - -/** Add the given v6 address into the nodelist address set. */ -void -nodelist_add_addr6_to_address_set(const tor_addr_t *addr) -{ - if (BUG(!addr) || tor_addr_is_null(addr) || tor_addr_is_v4(addr) || - !the_nodelist || !the_nodelist->node_addrs) { + if (BUG(!addr) || tor_addr_is_null(addr) || + (!tor_addr_is_v4(addr) && tor_addr_family(addr) != AF_INET6) || + !the_nodelist || !the_nodelist->node_addrs || + !the_nodelist->reentry_set) { return; } address_set_add(the_nodelist->node_addrs, addr); + if (or_port != 0) { + addr_port_set_add(the_nodelist->reentry_set, addr, or_port); + } + if (dir_port != 0) { + addr_port_set_add(the_nodelist->reentry_set, addr, dir_port); + } } /** Return true if <b>addr</b> is the address of some node in the nodelist. @@ -506,6 +523,21 @@ nodelist_probably_contains_address(const tor_addr_t *addr) return address_set_probably_contains(the_nodelist->node_addrs, addr); } +/** Return true if <b>addr</b> is the address of some node in the nodelist and + * corresponds also to the given port. If not, probably return false. */ +bool +nodelist_reentry_probably_contains(const tor_addr_t *addr, uint16_t port) +{ + if (BUG(!addr) || BUG(!port)) + return false; + + if (!the_nodelist || !the_nodelist->reentry_set) + return false; + + return addr_port_set_probably_contains(the_nodelist->reentry_set, + addr, port); +} + /** 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. @@ -637,10 +669,13 @@ nodelist_set_consensus(networkstatus_t *ns) * v6). Then we add the number of configured trusted authorities we have. */ int estimated_addresses = smartlist_len(ns->routerstatus_list) * get_estimated_address_per_node(); - estimated_addresses += (get_n_authorities(V3_DIRINFO & BRIDGE_DIRINFO) * + estimated_addresses += (get_n_authorities(V3_DIRINFO | BRIDGE_DIRINFO) * get_estimated_address_per_node()); 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); SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, routerstatus_t *, rs) { node_t *node = node_get_or_create(rs->identity_digest); @@ -867,6 +902,8 @@ nodelist_free_all(void) address_set_free(the_nodelist->node_addrs); the_nodelist->node_addrs = NULL; + addr_port_set_free(the_nodelist->reentry_set); + the_nodelist->reentry_set = NULL; tor_free(the_nodelist); } diff --git a/src/feature/nodelist/nodelist.h b/src/feature/nodelist/nodelist.h index 57ab2d5913..2964185e1a 100644 --- a/src/feature/nodelist/nodelist.h +++ b/src/feature/nodelist/nodelist.h @@ -35,8 +35,10 @@ node_t *nodelist_add_microdesc(microdesc_t *md); void nodelist_set_consensus(networkstatus_t *ns); void nodelist_ensure_freshness(networkstatus_t *ns); int nodelist_probably_contains_address(const tor_addr_t *addr); -void nodelist_add_addr4_to_address_set(const uint32_t addr); -void nodelist_add_addr6_to_address_set(const tor_addr_t *addr); +bool nodelist_reentry_probably_contains(const tor_addr_t *addr, + uint16_t port); +void nodelist_add_addr_to_address_set(const tor_addr_t *addr, + uint16_t or_port, uint16_t dir_port); void nodelist_remove_microdesc(const char *identity_digest, microdesc_t *md); void nodelist_remove_routerinfo(routerinfo_t *ri); |