diff options
author | Roger Dingledine <arma@torproject.org> | 2012-01-25 20:18:51 -0500 |
---|---|---|
committer | Andrea Shepard <andrea@torproject.org> | 2013-02-02 08:04:20 -0800 |
commit | a8297cdbd3324ac707165ae9922ecf478c4608a1 (patch) | |
tree | 921123e6fd3e8b2838c9256579c52f49ec084805 /src/or/entrynodes.c | |
parent | acb43c0735af8a7cd9e8eb57bb8835b11a90a1be (diff) | |
download | tor-a8297cdbd3324ac707165ae9922ecf478c4608a1.tar.gz tor-a8297cdbd3324ac707165ae9922ecf478c4608a1.zip |
use microdescriptors if *any* of our bridges can handle them
Now as we move into a future where most bridges can handle microdescs
we will generally find ourselves using them, rather than holding back
just because one of our bridges doesn't use them.
Diffstat (limited to 'src/or/entrynodes.c')
-rw-r--r-- | src/or/entrynodes.c | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index 4ca56cbacf..d029d85935 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -23,6 +23,7 @@ #include "directory.h" #include "entrynodes.h" #include "main.h" +#include "microdesc.h" #include "nodelist.h" #include "policies.h" #include "router.h" @@ -63,7 +64,8 @@ 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); + dirinfo_type_t dirtype, + int prefer_microdescs); /** Return the list of entry guards, creating it if necessary. */ const smartlist_t * @@ -829,15 +831,33 @@ entry_list_is_constrained(const or_options_t *options) return 0; } +/** Return true iff this node can answer directory questions about + * microdescriptors. */ +static int +node_understands_microdescriptors(const node_t *node) +{ + tor_assert(node); + if (node->rs && node->rs->version_supports_microdesc_cache) + return 1; + if (node->ri && tor_version_supports_microdescriptors(node->ri->platform)) + return 1; + return 0; +} + /** 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). */ + * 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. + */ const node_t * -choose_random_entry(cpath_build_state_t *state) +choose_random_entry(cpath_build_state_t *state, int prefer_microdescs) { - return choose_random_entry_impl(state, 0, 0); + return choose_random_entry_impl(state, 0, 0, prefer_microdescs); } /** Pick a live (up and listed) directory guard from entry_guards for @@ -845,13 +865,13 @@ choose_random_entry(cpath_build_state_t *state) const node_t * choose_random_dirguard(dirinfo_type_t type) { - return choose_random_entry_impl(NULL, 1, type); + return choose_random_entry_impl(NULL, 1, type, 0); } /** 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) + dirinfo_type_t dirinfo_type, int prefer_microdescs) { const or_options_t *options = get_options(); smartlist_t *live_entry_guards = smartlist_new(); @@ -903,6 +923,10 @@ 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)) + 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 && !routerset_contains_node(options->EntryNodes, node)) { @@ -1982,7 +2006,7 @@ int any_bridge_descriptors_known(void) { tor_assert(get_options()->UseBridges); - return choose_random_entry(NULL)!=NULL ? 1 : 0; + return choose_random_entry(NULL, 0)!=NULL ? 1 : 0; } /** Return 1 if there are any directory conns fetching bridge descriptors @@ -2064,29 +2088,24 @@ entries_retry_all(const or_options_t *options) entries_retry_helper(options, 1); } -/** Return true if we've ever had a bridge running a Tor version that can't - * provide microdescriptors to us. In that case fall back to asking for - * full descriptors. Eventually all bridges will support microdescriptors - * and we can take this check out; see bug 4013. */ +/** Return true if at least one of our bridges runs a Tor version that can + * provide microdescriptors to us. If not, we'll fall back to asking for + * full descriptors. */ int -any_bridges_dont_support_microdescriptors(void) +any_bridge_supports_microdescriptors(void) { const node_t *node; - static int ever_answered_yes = 0; if (!get_options()->UseBridges || !entry_guards) return 0; - if (ever_answered_yes) - return 1; /* if we ever answer 'yes', always answer 'yes' */ SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, e) { node = node_get_by_id(e->identity); - if (node && node->ri && + if (node && node->is_running && node_is_bridge(node) && node_is_a_configured_bridge(node) && - !tor_version_supports_microdescriptors(node->ri->platform)) { + node_understands_microdescriptors(node)) { /* This is one of our current bridges, and we know enough about - * it to know that it won't be able to answer our microdescriptor + * it to know that it will be able to answer our microdescriptor * questions. */ - ever_answered_yes = 1; - return 1; + return 1; } } SMARTLIST_FOREACH_END(e); return 0; |