mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 23:53:32 +01:00
nodelist: Stop recursing in router_choose_random_node()
Instead, call out to a helper function, repeating the call if needed. Avoids duplicating exclusions for: * the current relay's family, and * any exclusions specified by the caller. Part of 34200.
This commit is contained in:
parent
2ea1692c20
commit
3f7f976d48
@ -930,47 +930,25 @@ nodelist_subtract(smartlist_t *sl, const smartlist_t *excluded)
|
|||||||
bitarray_free(excluded_idx);
|
bitarray_free(excluded_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return a random running node from the nodelist. Never pick a node that is
|
/* Node selection helper for router_choose_random_node().
|
||||||
* in <b>excludedsmartlist</b>, or which matches <b>excludedset</b>, even if
|
|
||||||
* they are the only nodes available.
|
|
||||||
*
|
*
|
||||||
* <b>flags</b> is a set of CRN_* flags, see
|
* Populates a node list based on <b>flags</b>, ignoring nodes in
|
||||||
* router_add_running_nodes_to_smartlist() for details.
|
* <b>excludednodes</b> and <b>excludedset</b>. Chooses the node based on
|
||||||
*/
|
* <b>rule</b>. */
|
||||||
const node_t *
|
static const node_t *
|
||||||
router_choose_random_node(smartlist_t *excludedsmartlist,
|
router_choose_random_node_helper(smartlist_t *excludednodes,
|
||||||
routerset_t *excludedset,
|
routerset_t *excludedset,
|
||||||
router_crn_flags_t flags)
|
router_crn_flags_t flags,
|
||||||
|
bandwidth_weight_rule_t rule)
|
||||||
{
|
{
|
||||||
/* A limited set of flags, used for weighting and fallback node selection.
|
smartlist_t *sl=smartlist_new();
|
||||||
*/
|
|
||||||
const int need_uptime = (flags & CRN_NEED_UPTIME) != 0;
|
|
||||||
const int need_capacity = (flags & CRN_NEED_CAPACITY) != 0;
|
|
||||||
const int need_guard = (flags & CRN_NEED_GUARD) != 0;
|
|
||||||
const int pref_addr = (flags & CRN_PREF_ADDR) != 0;
|
|
||||||
|
|
||||||
smartlist_t *sl=smartlist_new(),
|
|
||||||
*excludednodes=smartlist_new();
|
|
||||||
const node_t *choice = NULL;
|
const node_t *choice = NULL;
|
||||||
const routerinfo_t *r;
|
|
||||||
bandwidth_weight_rule_t rule;
|
|
||||||
|
|
||||||
rule = (need_guard ? WEIGHT_FOR_GUARD : WEIGHT_FOR_MID);
|
|
||||||
|
|
||||||
/* If the node_t is not found we won't be to exclude ourself but we
|
|
||||||
* won't be able to pick ourself in router_choose_random_node() so
|
|
||||||
* this is fine to at least try with our routerinfo_t object. */
|
|
||||||
if ((r = router_get_my_routerinfo()))
|
|
||||||
routerlist_add_node_and_family(excludednodes, r);
|
|
||||||
|
|
||||||
router_add_running_nodes_to_smartlist(sl, flags);
|
router_add_running_nodes_to_smartlist(sl, flags);
|
||||||
log_debug(LD_CIRC,
|
log_debug(LD_CIRC,
|
||||||
"We found %d running nodes.",
|
"We found %d running nodes.",
|
||||||
smartlist_len(sl));
|
smartlist_len(sl));
|
||||||
|
|
||||||
if (excludedsmartlist) {
|
|
||||||
smartlist_add_all(excludednodes, excludedsmartlist);
|
|
||||||
}
|
|
||||||
nodelist_subtract(sl, excludednodes);
|
nodelist_subtract(sl, excludednodes);
|
||||||
|
|
||||||
if (excludedset) {
|
if (excludedset) {
|
||||||
@ -984,8 +962,53 @@ router_choose_random_node(smartlist_t *excludedsmartlist,
|
|||||||
choice = node_sl_choose_by_bandwidth(sl, rule);
|
choice = node_sl_choose_by_bandwidth(sl, rule);
|
||||||
|
|
||||||
smartlist_free(sl);
|
smartlist_free(sl);
|
||||||
|
|
||||||
|
return choice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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.
|
||||||
|
*
|
||||||
|
* <b>flags</b> is a set of CRN_* flags, see
|
||||||
|
* router_add_running_nodes_to_smartlist() for details.
|
||||||
|
*/
|
||||||
|
const node_t *
|
||||||
|
router_choose_random_node(smartlist_t *excludedsmartlist,
|
||||||
|
routerset_t *excludedset,
|
||||||
|
router_crn_flags_t flags)
|
||||||
|
{
|
||||||
|
/* A limited set of flags, used for fallback node selection.
|
||||||
|
*/
|
||||||
|
const int need_uptime = (flags & CRN_NEED_UPTIME) != 0;
|
||||||
|
const int need_capacity = (flags & CRN_NEED_CAPACITY) != 0;
|
||||||
|
const int need_guard = (flags & CRN_NEED_GUARD) != 0;
|
||||||
|
const int pref_addr = (flags & CRN_PREF_ADDR) != 0;
|
||||||
|
|
||||||
|
smartlist_t *excludednodes=smartlist_new();
|
||||||
|
const node_t *choice = NULL;
|
||||||
|
const routerinfo_t *r;
|
||||||
|
bandwidth_weight_rule_t rule;
|
||||||
|
|
||||||
|
rule = (need_guard ? WEIGHT_FOR_GUARD : WEIGHT_FOR_MID);
|
||||||
|
|
||||||
|
/* If the node_t is not found we won't be to exclude ourself but we
|
||||||
|
* won't be able to pick ourself in router_choose_random_node() so
|
||||||
|
* this is fine to at least try with our routerinfo_t object. */
|
||||||
|
if ((r = router_get_my_routerinfo()))
|
||||||
|
routerlist_add_node_and_family(excludednodes, r);
|
||||||
|
|
||||||
|
if (excludedsmartlist) {
|
||||||
|
smartlist_add_all(excludednodes, excludedsmartlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
choice = router_choose_random_node_helper(excludednodes,
|
||||||
|
excludedset,
|
||||||
|
flags,
|
||||||
|
rule);
|
||||||
|
|
||||||
if (!choice && (need_uptime || need_capacity || need_guard || pref_addr)) {
|
if (!choice && (need_uptime || need_capacity || need_guard || pref_addr)) {
|
||||||
/* try once more -- recurse but with fewer restrictions. */
|
/* try once more, with fewer restrictions. */
|
||||||
log_info(LD_CIRC,
|
log_info(LD_CIRC,
|
||||||
"We couldn't find any live%s%s%s%s routers; falling back "
|
"We couldn't find any live%s%s%s%s routers; falling back "
|
||||||
"to list of all routers.",
|
"to list of all routers.",
|
||||||
@ -995,8 +1018,10 @@ router_choose_random_node(smartlist_t *excludedsmartlist,
|
|||||||
pref_addr?", preferred address":"");
|
pref_addr?", preferred address":"");
|
||||||
flags &= ~ (CRN_NEED_UPTIME|CRN_NEED_CAPACITY|CRN_NEED_GUARD|
|
flags &= ~ (CRN_NEED_UPTIME|CRN_NEED_CAPACITY|CRN_NEED_GUARD|
|
||||||
CRN_PREF_ADDR);
|
CRN_PREF_ADDR);
|
||||||
choice = router_choose_random_node(
|
choice = router_choose_random_node_helper(excludednodes,
|
||||||
excludedsmartlist, excludedset, flags);
|
excludedset,
|
||||||
|
flags,
|
||||||
|
rule);
|
||||||
}
|
}
|
||||||
smartlist_free(excludednodes);
|
smartlist_free(excludednodes);
|
||||||
if (!choice) {
|
if (!choice) {
|
||||||
|
Loading…
Reference in New Issue
Block a user