aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2012-01-25 20:49:32 -0500
committerAndrea Shepard <andrea@torproject.org>2013-02-02 08:19:27 -0800
commitbce5019eff37fc741747ef76c5d0a387569f9265 (patch)
tree8a5199b366aeb30bc4d2effc622c2de30384fec0 /src
parenta8297cdbd3324ac707165ae9922ecf478c4608a1 (diff)
downloadtor-bce5019eff37fc741747ef76c5d0a387569f9265.tar
tor-bce5019eff37fc741747ef76c5d0a387569f9265.tar.gz
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.
Diffstat (limited to 'src')
-rw-r--r--src/or/circuitbuild.c2
-rw-r--r--src/or/directory.c9
-rw-r--r--src/or/entrynodes.c38
-rw-r--r--src/or/entrynodes.h2
4 files changed, 28 insertions, 23 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 8c86aac90..cea1cbd52 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -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();
diff --git a/src/or/directory.c b/src/or/directory.c
index c1bbe6bd8..a1ac2ad2e 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -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;
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index d029d8593..dab081d1f 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -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
diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h
index 8ed429c8f..235ef4bfd 100644
--- a/src/or/entrynodes.h
+++ b/src/or/entrynodes.h
@@ -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);