mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
generalize choose_random_entry()'s dirinfo parameter
Now we can specify to skip bridges that wouldn't be able to answer the type of dir fetch we're launching. It's still the responsibility of the rest of the code to prevent us from launching a given dir fetch if we have no bridges that could handle it.
This commit is contained in:
parent
a8297cdbd3
commit
bce5019eff
@ -3373,7 +3373,7 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state)
|
||||
(purpose != CIRCUIT_PURPOSE_TESTING || options->BridgeRelay)) {
|
||||
/* This request is for an entry server to use for a regular circuit,
|
||||
* and we use entry guard nodes. Just return one of the guard nodes. */
|
||||
return choose_random_entry(state, 0);
|
||||
return choose_random_entry(state, NO_DIRINFO);
|
||||
}
|
||||
|
||||
excluded = smartlist_new();
|
||||
|
@ -472,14 +472,13 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
|
||||
if (options->UseBridges && type != BRIDGE_DIRINFO) {
|
||||
/* We want to ask a running bridge for which we have a descriptor.
|
||||
*
|
||||
* When we ask choose_random_entry() for a bridge, we specify that
|
||||
* we're going to be using it for a dir fetch: if any of our bridges
|
||||
* can handle microdescriptor questions, we'll get one of the ones
|
||||
* that can.
|
||||
* When we ask choose_random_entry() for a bridge, we specify what
|
||||
* sort of dir fetch we'll be doing, so it won't return a bridge
|
||||
* that can't answer our question.
|
||||
*/
|
||||
/* XXX024 Not all bridges handle conditional consensus downloading,
|
||||
* so, for now, never assume the server supports that. -PP */
|
||||
const node_t *node = choose_random_entry(NULL, 1);
|
||||
const node_t *node = choose_random_entry(NULL, type);
|
||||
if (node && node->ri) {
|
||||
/* every bridge has a routerinfo. */
|
||||
tor_addr_t addr;
|
||||
|
@ -64,8 +64,7 @@ static int entry_guards_dirty = 0;
|
||||
static void bridge_free(bridge_info_t *bridge);
|
||||
static const node_t *choose_random_entry_impl(cpath_build_state_t *state,
|
||||
int for_directory,
|
||||
dirinfo_type_t dirtype,
|
||||
int prefer_microdescs);
|
||||
dirinfo_type_t dirtype);
|
||||
|
||||
/** Return the list of entry guards, creating it if necessary. */
|
||||
const smartlist_t *
|
||||
@ -844,20 +843,28 @@ node_understands_microdescriptors(const node_t *node)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Return true iff <b>node</b> is able to answer directory questions
|
||||
* of type <b>dirinfo</b>. */
|
||||
static int
|
||||
node_can_handle_dirinfo(const node_t *node, dirinfo_type_t dirinfo)
|
||||
{
|
||||
if ((dirinfo & MICRODESC_DIRINFO) &&
|
||||
!node_understands_microdescriptors(node))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Pick a live (up and listed) entry guard from entry_guards. If
|
||||
* <b>state</b> is non-NULL, this is for a specific circuit --
|
||||
* make sure not to pick this circuit's exit or any node in the
|
||||
* exit's family. If <b>state</b> is NULL, we're looking for a random
|
||||
* guard (likely a bridge).
|
||||
*
|
||||
* If the prefer_microdescs flag is set, we are looking for a bridge to
|
||||
* use for directory fetching and pick a bridge that supports microdescriptors
|
||||
* if we know any that do so.
|
||||
*/
|
||||
* guard (likely a bridge). If <b>dirinfo</b> is not NO_DIRINFO, then
|
||||
* only select from nodes that know how to answer directory questions
|
||||
* of that type. */
|
||||
const node_t *
|
||||
choose_random_entry(cpath_build_state_t *state, int prefer_microdescs)
|
||||
choose_random_entry(cpath_build_state_t *state, dirinfo_type_t dirinfo)
|
||||
{
|
||||
return choose_random_entry_impl(state, 0, 0, prefer_microdescs);
|
||||
return choose_random_entry_impl(state, 0, dirinfo);
|
||||
}
|
||||
|
||||
/** Pick a live (up and listed) directory guard from entry_guards for
|
||||
@ -865,13 +872,13 @@ choose_random_entry(cpath_build_state_t *state, int prefer_microdescs)
|
||||
const node_t *
|
||||
choose_random_dirguard(dirinfo_type_t type)
|
||||
{
|
||||
return choose_random_entry_impl(NULL, 1, type, 0);
|
||||
return choose_random_entry_impl(NULL, 1, type);
|
||||
}
|
||||
|
||||
/** Helper for choose_random{entry,dirguard}. */
|
||||
static const node_t *
|
||||
choose_random_entry_impl(cpath_build_state_t *state, int for_directory,
|
||||
dirinfo_type_t dirinfo_type, int prefer_microdescs)
|
||||
dirinfo_type_t dirinfo_type)
|
||||
{
|
||||
const or_options_t *options = get_options();
|
||||
smartlist_t *live_entry_guards = smartlist_new();
|
||||
@ -923,9 +930,8 @@ choose_random_entry_impl(cpath_build_state_t *state, int for_directory,
|
||||
continue; /* don't pick the same node for entry and exit */
|
||||
if (consider_exit_family && smartlist_contains(exit_family, node))
|
||||
continue; /* avoid relays that are family members of our exit */
|
||||
if (prefer_microdescs &&
|
||||
we_use_microdescriptors_for_circuits(options) &&
|
||||
!node_understands_microdescriptors(node))
|
||||
if (dirinfo_type != NO_DIRINFO &&
|
||||
!node_can_handle_dirinfo(node, dirinfo_type))
|
||||
continue; /* this node won't be able to answer our dir questions */
|
||||
#if 0 /* since EntryNodes is always strict now, this clause is moot */
|
||||
if (options->EntryNodes &&
|
||||
@ -2006,7 +2012,7 @@ int
|
||||
any_bridge_descriptors_known(void)
|
||||
{
|
||||
tor_assert(get_options()->UseBridges);
|
||||
return choose_random_entry(NULL, 0)!=NULL ? 1 : 0;
|
||||
return choose_random_entry(NULL, NO_DIRINFO)!=NULL ? 1 : 0;
|
||||
}
|
||||
|
||||
/** Return 1 if there are any directory conns fetching bridge descriptors
|
||||
|
@ -79,7 +79,7 @@ int entry_guard_register_connect_status(const char *digest, int succeeded,
|
||||
void entry_nodes_should_be_added(void);
|
||||
int entry_list_is_constrained(const or_options_t *options);
|
||||
const node_t *choose_random_entry(cpath_build_state_t *state,
|
||||
int prefer_microdescs);
|
||||
dirinfo_type_t dirinfo);
|
||||
const node_t *choose_random_dirguard(dirinfo_type_t t);
|
||||
int entry_guards_parse_state(or_state_t *state, int set, char **msg);
|
||||
void entry_guards_update_state(or_state_t *state);
|
||||
|
Loading…
Reference in New Issue
Block a user