diff options
author | teor <teor@riseup.net> | 2020-05-11 17:58:28 +1000 |
---|---|---|
committer | teor <teor@riseup.net> | 2020-05-18 21:53:52 +1000 |
commit | 3f7f976d4812a92bdbf5f14e25db0d276f123cef (patch) | |
tree | 60bd7fec8ce75d5db5ec0ae57af5707018f4c34a /src/feature/nodelist | |
parent | 2ea1692c20b4afa929e9f1c6da16ee2fb134abe0 (diff) | |
download | tor-3f7f976d4812a92bdbf5f14e25db0d276f123cef.tar.gz tor-3f7f976d4812a92bdbf5f14e25db0d276f123cef.zip |
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.
Diffstat (limited to 'src/feature/nodelist')
-rw-r--r-- | src/feature/nodelist/node_select.c | 69 |
1 files changed, 47 insertions, 22 deletions
diff --git a/src/feature/nodelist/node_select.c b/src/feature/nodelist/node_select.c index 11abc84d4b..85ef5ad568 100644 --- a/src/feature/nodelist/node_select.c +++ b/src/feature/nodelist/node_select.c @@ -930,6 +930,42 @@ nodelist_subtract(smartlist_t *sl, const smartlist_t *excluded) bitarray_free(excluded_idx); } +/* Node selection helper for router_choose_random_node(). + * + * Populates a node list based on <b>flags</b>, ignoring nodes in + * <b>excludednodes</b> and <b>excludedset</b>. Chooses the node based on + * <b>rule</b>. */ +static const node_t * +router_choose_random_node_helper(smartlist_t *excludednodes, + routerset_t *excludedset, + router_crn_flags_t flags, + bandwidth_weight_rule_t rule) +{ + smartlist_t *sl=smartlist_new(); + const node_t *choice = NULL; + + router_add_running_nodes_to_smartlist(sl, flags); + log_debug(LD_CIRC, + "We found %d running nodes.", + smartlist_len(sl)); + + nodelist_subtract(sl, excludednodes); + + if (excludedset) { + routerset_subtract_nodes(sl,excludedset); + log_debug(LD_CIRC, + "We removed excludedset, leaving %d nodes.", + smartlist_len(sl)); + } + + // Always weight by bandwidth + choice = node_sl_choose_by_bandwidth(sl, rule); + + 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. @@ -942,15 +978,14 @@ router_choose_random_node(smartlist_t *excludedsmartlist, routerset_t *excludedset, router_crn_flags_t flags) { - /* A limited set of flags, used for weighting and fallback node selection. + /* 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 *sl=smartlist_new(), - *excludednodes=smartlist_new(); + smartlist_t *excludednodes=smartlist_new(); const node_t *choice = NULL; const routerinfo_t *r; bandwidth_weight_rule_t rule; @@ -963,29 +998,17 @@ router_choose_random_node(smartlist_t *excludedsmartlist, if ((r = router_get_my_routerinfo())) routerlist_add_node_and_family(excludednodes, r); - router_add_running_nodes_to_smartlist(sl, flags); - log_debug(LD_CIRC, - "We found %d running nodes.", - smartlist_len(sl)); - if (excludedsmartlist) { smartlist_add_all(excludednodes, excludedsmartlist); } - nodelist_subtract(sl, excludednodes); - if (excludedset) { - routerset_subtract_nodes(sl,excludedset); - log_debug(LD_CIRC, - "We removed excludedset, leaving %d nodes.", - smartlist_len(sl)); - } + choice = router_choose_random_node_helper(excludednodes, + excludedset, + flags, + rule); - // Always weight by bandwidth - choice = node_sl_choose_by_bandwidth(sl, rule); - - smartlist_free(sl); 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, "We couldn't find any live%s%s%s%s routers; falling back " "to list of all routers.", @@ -995,8 +1018,10 @@ router_choose_random_node(smartlist_t *excludedsmartlist, pref_addr?", preferred address":""); flags &= ~ (CRN_NEED_UPTIME|CRN_NEED_CAPACITY|CRN_NEED_GUARD| CRN_PREF_ADDR); - choice = router_choose_random_node( - excludedsmartlist, excludedset, flags); + choice = router_choose_random_node_helper(excludednodes, + excludedset, + flags, + rule); } smartlist_free(excludednodes); if (!choice) { |