routerlist: Choose nodes that can initiate IPv6 extends

Part of 33226.
This commit is contained in:
teor 2020-05-11 17:00:25 +10:00
parent 9e7f51e469
commit 1c1faf586a
5 changed files with 50 additions and 30 deletions

View File

@ -1796,12 +1796,13 @@ pick_restricted_middle_node(router_crn_flags_t flags,
/* Add all running nodes to all_live_nodes */
router_add_running_nodes_to_smartlist(all_live_nodes,
(flags & CRN_NEED_UPTIME) != 0,
(flags & CRN_NEED_CAPACITY) != 0,
(flags & CRN_NEED_GUARD) != 0,
(flags & CRN_NEED_DESC) != 0,
(flags & CRN_PREF_ADDR) != 0,
(flags & CRN_DIRECT_CONN) != 0);
(flags & CRN_NEED_UPTIME) != 0,
(flags & CRN_NEED_CAPACITY) != 0,
(flags & CRN_NEED_GUARD) != 0,
(flags & CRN_NEED_DESC) != 0,
(flags & CRN_PREF_ADDR) != 0,
(flags & CRN_DIRECT_CONN) != 0,
(flags & CRN_INITIATE_IPV6_EXTEND) != 0);
/* Filter all_live_nodes to only add live *and* whitelisted middles
* to the list whitelisted_live_middles. */
@ -2306,6 +2307,10 @@ choose_good_middle_server(uint8_t purpose,
flags |= CRN_NEED_UPTIME;
if (state->need_capacity)
flags |= CRN_NEED_CAPACITY;
/* Picking the second-last node. (The last node is the relay doing the
* self-test.) */
if (state->is_ipv6_selftest && cur_len == state->desired_path_len - 2)
flags |= CRN_INITIATE_IPV6_EXTEND;
/** If a hidden service circuit wants a specific middle node, pin it. */
if (middle_node_must_be_vanguard(options, purpose, cur_len)) {

View File

@ -930,25 +930,33 @@ nodelist_subtract(smartlist_t *sl, const smartlist_t *excluded)
bitarray_free(excluded_idx);
}
/** Return a random running node from the nodelist. Never
* pick a node that is in
* <b>excludedsmartlist</b>, or which matches <b>excludedset</b>,
* even if they are the only nodes available.
* If <b>CRN_NEED_UPTIME</b> is set in flags and any router has more than
* a minimum uptime, return one of those.
* If <b>CRN_NEED_CAPACITY</b> is set in flags, weight your choice by the
* advertised capacity of each router.
* If <b>CRN_NEED_GUARD</b> is set in flags, consider only Guard routers.
* If <b>CRN_WEIGHT_AS_EXIT</b> is set in flags, we weight bandwidths as if
* picking an exit node, otherwise we weight bandwidths for picking a relay
* node (that is, possibly discounting exit nodes).
* If <b>CRN_NEED_DESC</b> is set in flags, we only consider nodes that
* have a routerinfo or microdescriptor -- that is, enough info to be
* used to build a circuit.
* If <b>CRN_PREF_ADDR</b> is set in flags, we only consider nodes that
* have an address that is preferred by the ClientPreferIPv6ORPort setting
* (regardless of this flag, we exclude nodes that aren't allowed by the
* firewall, including ClientUseIPv4 0 and fascist_firewall_use_ipv6() == 0).
/** Return a random running node from the nodelist. Never pick a node that is
* in <b>excludedsmartlist</b>, or which matches <b>excludedset</b>, even if
* they are the only nodes available.
*
* If the following <b>flags</b> are set:
* - <b>CRN_NEED_UPTIME</b>: if any router has more than a minimum uptime,
* return one of those;
* - <b>CRN_NEED_CAPACITY</b>: weight your choice by the advertised capacity
* of each router;
* - <b>CRN_NEED_GUARD</b>: only consider Guard routers;
* - <b>CRN_WEIGHT_AS_EXIT</b>: we weight bandwidths as if picking an exit
* node, otherwise we weight bandwidths for
* picking a relay node (that is, possibly
* discounting exit nodes);
* - <b>CRN_NEED_DESC</b>: only consider nodes that have a routerinfo or
* microdescriptor -- that is, enough info to be
* used to build a circuit;
* - <b>CRN_DIRECT_CONN</b>: only consider nodes that are suitable for direct
* connections. Check ReachableAddresses,
* ClientUseIPv4 0, and
* fascist_firewall_use_ipv6() == 0);
* - <b>CRN_PREF_ADDR</b>: only consider nodes that have an address that is
* preferred by the ClientPreferIPv6ORPort setting.
* - <b>CRN_RENDEZVOUS_V3</b>: only consider nodes that can become v3 onion
* service rendezvous points.
* - <b>CRN_INITIATE_IPV6_EXTEND</b>: only consider routers than can initiate
* IPv6 extends.
*/
const node_t *
router_choose_random_node(smartlist_t *excludedsmartlist,
@ -963,6 +971,7 @@ router_choose_random_node(smartlist_t *excludedsmartlist,
const int pref_addr = (flags & CRN_PREF_ADDR) != 0;
const int direct_conn = (flags & CRN_DIRECT_CONN) != 0;
const int rendezvous_v3 = (flags & CRN_RENDEZVOUS_V3) != 0;
const bool initiate_ipv6_extend = (flags & CRN_INITIATE_IPV6_EXTEND) != 0;
const smartlist_t *node_list = nodelist_get_list();
smartlist_t *sl=smartlist_new(),
@ -997,7 +1006,7 @@ router_choose_random_node(smartlist_t *excludedsmartlist,
router_add_running_nodes_to_smartlist(sl, need_uptime, need_capacity,
need_guard, need_desc, pref_addr,
direct_conn);
direct_conn, initiate_ipv6_extend);
log_debug(LD_CIRC,
"We found %d running nodes.",
smartlist_len(sl));

View File

@ -28,6 +28,8 @@ typedef enum router_crn_flags_t {
/* On clients, only provide nodes with HSRend >= 2 protocol version which
* is required for hidden service version >= 3. */
CRN_RENDEZVOUS_V3 = 1<<9,
/* On clients, only provide nodes that can initiate IPv6 extends. */
CRN_INITIATE_IPV6_EXTEND = 1<<10,
} router_crn_flags_t;
/** Possible ways to weight routers when choosing one randomly. See

View File

@ -512,13 +512,15 @@ routers_have_same_or_addrs(const routerinfo_t *r1, const routerinfo_t *r2)
}
/** Add every suitable node from our nodelist to <b>sl</b>, so that
* we can pick a node for a circuit.
* we can pick a node for a circuit. See router_choose_random_node()
* for details.
*/
void
router_add_running_nodes_to_smartlist(smartlist_t *sl, int need_uptime,
int need_capacity, int need_guard,
int need_desc, int pref_addr,
int direct_conn)
int direct_conn,
bool initiate_ipv6_extend)
{
const int check_reach = !router_or_conn_should_skip_reachable_address_check(
get_options(),
@ -545,7 +547,8 @@ router_add_running_nodes_to_smartlist(smartlist_t *sl, int need_uptime,
FIREWALL_OR_CONNECTION,
pref_addr))
continue;
if (initiate_ipv6_extend && !node_supports_initiating_ipv6_extends(node))
continue;
smartlist_add(sl, (void *)node);
} SMARTLIST_FOREACH_END(node);
}

View File

@ -61,7 +61,8 @@ int routers_have_same_or_addrs(const routerinfo_t *r1, const routerinfo_t *r2);
void router_add_running_nodes_to_smartlist(smartlist_t *sl, int need_uptime,
int need_capacity, int need_guard,
int need_desc, int pref_addr,
int direct_conn);
int direct_conn,
bool initiate_ipv6_extend);
const routerinfo_t *routerlist_find_my_routerinfo(void);
uint32_t router_get_advertised_bandwidth(const routerinfo_t *router);