[tor-commits] [tor/master] generalize choose_random_entry()'s dirinfo parameter

nickm at torproject.org nickm at torproject.org
Fri Feb 15 21:04:00 UTC 2013


commit bce5019eff37fc741747ef76c5d0a387569f9265
Author: Roger Dingledine <arma at torproject.org>
Date:   Wed Jan 25 20:49:32 2012 -0500

    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.
---
 src/or/circuitbuild.c |    2 +-
 src/or/directory.c    |    9 ++++-----
 src/or/entrynodes.c   |   38 ++++++++++++++++++++++----------------
 src/or/entrynodes.h   |    2 +-
 4 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 8c86aac..cea1cbd 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 c1bbe6b..a1ac2ad 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 d029d85..dab081d 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 8ed429c..235ef4b 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);





More information about the tor-commits mailing list