mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 13:13:44 +01:00
Add an address_set to the nodelist.
This set is rebuilt whenever a consensus arrives. In between consensuses, it is add-only.
This commit is contained in:
parent
0640da4269
commit
6892d32921
@ -14,6 +14,7 @@
|
||||
|
||||
#include "or.h"
|
||||
#include "address.h"
|
||||
#include "address_set.h"
|
||||
#include "config.h"
|
||||
#include "control.h"
|
||||
#include "dirserv.h"
|
||||
@ -52,6 +53,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
|
||||
@ -63,6 +65,8 @@ typedef struct nodelist_t {
|
||||
/* Hash table to map from node ID digest to node. */
|
||||
HT_HEAD(nodelist_map, node_t) nodes_by_id;
|
||||
|
||||
/* Set of addresses that belong to nodes we believe in. */
|
||||
address_set_t *node_addrs;
|
||||
} nodelist_t;
|
||||
|
||||
static inline unsigned int
|
||||
@ -150,6 +154,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.
|
||||
@ -188,6 +236,8 @@ nodelist_set_routerinfo(routerinfo_t *ri, routerinfo_t **ri_old_out)
|
||||
dirserv_set_node_flags_from_authoritative_status(node, status);
|
||||
}
|
||||
|
||||
node_add_to_address_set(node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -219,6 +269,9 @@ nodelist_add_microdesc(microdesc_t *md)
|
||||
node->md = md;
|
||||
md->held_by_nodes++;
|
||||
}
|
||||
|
||||
node_add_to_address_set(node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -240,6 +293,11 @@ 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) * 2;
|
||||
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;
|
||||
@ -278,6 +336,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
|
||||
@ -430,6 +493,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);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,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);
|
||||
|
Loading…
Reference in New Issue
Block a user