[tor-commits] [tor/master] Split select_entry_guard_for_circuit()

nickm at torproject.org nickm at torproject.org
Mon Jul 30 12:51:07 UTC 2018


commit 042d22c8d1c4e4224feadd4ff3995769eb8301b4
Author: rl1987 <rl1987 at sdf.lonestar.org>
Date:   Fri Jun 22 16:43:50 2018 +0300

    Split select_entry_guard_for_circuit()
---
 src/feature/client/entrynodes.c | 157 ++++++++++++++++++++++++++++------------
 1 file changed, 110 insertions(+), 47 deletions(-)

diff --git a/src/feature/client/entrynodes.c b/src/feature/client/entrynodes.c
index af68de611..494ad3352 100644
--- a/src/feature/client/entrynodes.c
+++ b/src/feature/client/entrynodes.c
@@ -2027,31 +2027,23 @@ entry_guards_note_internet_connectivity(guard_selection_t *gs)
 }
 
 /**
- * Get a guard for use with a circuit.  Prefer to pick a running primary
- * guard; then a non-pending running filtered confirmed guard; then a
- * non-pending runnable filtered guard.  Update the
+ * Pick a primary guard for use with a circuit, if available. Update the
  * <b>last_tried_to_connect</b> time and the <b>is_pending</b> fields of the
  * guard as appropriate.  Set <b>state_out</b> to the new guard-state
  * of the circuit.
  */
-STATIC entry_guard_t *
-select_entry_guard_for_circuit(guard_selection_t *gs,
-                               guard_usage_t usage,
-                               const entry_guard_restriction_t *rst,
-                               unsigned *state_out)
+static entry_guard_t *
+select_primary_guard_for_circuit(guard_selection_t *gs,
+                                 guard_usage_t usage,
+                                 const entry_guard_restriction_t *rst,
+                                 unsigned *state_out)
 {
   const int need_descriptor = (usage == GUARD_USAGE_TRAFFIC);
-  tor_assert(gs);
-  tor_assert(state_out);
-
-  if (!gs->primary_guards_up_to_date)
-    entry_guards_update_primary(gs);
+  entry_guard_t *chosen_guard = NULL;
 
   int num_entry_guards = get_n_primary_guards_to_use(usage);
   smartlist_t *usable_primary_guards = smartlist_new();
 
-  /* "If any entry in PRIMARY_GUARDS has {is_reachable} status of
-      <maybe> or <yes>, return the first such guard." */
   SMARTLIST_FOREACH_BEGIN(gs->primary_entry_guards, entry_guard_t *, guard) {
     entry_guard_consider_retry(guard);
     if (! entry_guard_obeys_restriction(guard, rst))
@@ -2069,18 +2061,30 @@ select_entry_guard_for_circuit(guard_selection_t *gs,
   } SMARTLIST_FOREACH_END(guard);
 
   if (smartlist_len(usable_primary_guards)) {
-    entry_guard_t *guard = smartlist_choose(usable_primary_guards);
+    chosen_guard = smartlist_choose(usable_primary_guards);
     smartlist_free(usable_primary_guards);
     log_info(LD_GUARD, "Selected primary guard %s for circuit.",
-             entry_guard_describe(guard));
-    return guard;
+             entry_guard_describe(chosen_guard));
   }
+
   smartlist_free(usable_primary_guards);
+  return chosen_guard;
+}
+
+/**
+ * For use with a circuit, pick a non-pending running filtered confirmed guard,
+ * if one is available. Update the <b>last_tried_to_connect</b> time and the
+ * <b>is_pending</b> fields of the guard as appropriate. Set <b>state_out</b>
+ * to the new guard-state of the circuit.
+ */
+static entry_guard_t *
+select_confirmed_guard_for_circuit(guard_selection_t *gs,
+                                  guard_usage_t usage,
+                                  const entry_guard_restriction_t *rst,
+                                  unsigned *state_out)
+{
+  const int need_descriptor = (usage == GUARD_USAGE_TRAFFIC);
 
-  /* "Otherwise, if the ordered intersection of {CONFIRMED_GUARDS}
-      and {USABLE_FILTERED_GUARDS} is nonempty, return the first
-      entry in that intersection that has {is_pending} set to
-      false." */
   SMARTLIST_FOREACH_BEGIN(gs->confirmed_entry_guards, entry_guard_t *, guard) {
     if (guard->is_primary)
       continue; /* we already considered this one. */
@@ -2101,34 +2105,93 @@ select_entry_guard_for_circuit(guard_selection_t *gs,
     }
   } SMARTLIST_FOREACH_END(guard);
 
+  return NULL;
+}
+
+/**
+ * For use with a circuit, pick a confirmed usable filtered guard
+ * at random. Update the <b>last_tried_to_connect</b> time and the
+ * <b>is_pending</b> fields of the guard as appropriate. Set <b>state_out</b>
+ * to the new guard-state of the circuit.
+ */
+static entry_guard_t *
+select_filtered_guard_for_circuit(guard_selection_t *gs,
+                                  guard_usage_t usage,
+                                  const entry_guard_restriction_t *rst,
+                                  unsigned *state_out)
+{
+  const int need_descriptor = (usage == GUARD_USAGE_TRAFFIC);
+  entry_guard_t *chosen_guard = NULL;
+  unsigned flags = 0;
+  if (need_descriptor)
+    flags |= SAMPLE_EXCLUDE_NO_DESCRIPTOR;
+  chosen_guard = sample_reachable_filtered_entry_guards(gs,
+                                                 rst,
+                                                 SAMPLE_EXCLUDE_CONFIRMED |
+                                                 SAMPLE_EXCLUDE_PRIMARY |
+                                                 SAMPLE_EXCLUDE_PENDING |
+                                                 flags);
+  if (!chosen_guard) {
+    return NULL;
+  }
+
+  chosen_guard->is_pending = 1;
+  chosen_guard->last_tried_to_connect = approx_time();
+  *state_out = GUARD_CIRC_STATE_USABLE_IF_NO_BETTER_GUARD;
+  log_info(LD_GUARD, "No primary or confirmed guards available. Selected "
+           "random guard %s for circuit. Will try other guards before "
+           "using this circuit.",
+           entry_guard_describe(chosen_guard));
+  return chosen_guard;
+}
+
+/**
+ * Get a guard for use with a circuit.  Prefer to pick a running primary
+ * guard; then a non-pending running filtered confirmed guard; then a
+ * non-pending runnable filtered guard.  Update the
+ * <b>last_tried_to_connect</b> time and the <b>is_pending</b> fields of the
+ * guard as appropriate.  Set <b>state_out</b> to the new guard-state
+ * of the circuit.
+ */
+STATIC entry_guard_t *
+select_entry_guard_for_circuit(guard_selection_t *gs,
+                               guard_usage_t usage,
+                               const entry_guard_restriction_t *rst,
+                               unsigned *state_out)
+{
+  entry_guard_t *chosen_guard = NULL;
+  tor_assert(gs);
+  tor_assert(state_out);
+
+  if (!gs->primary_guards_up_to_date)
+    entry_guards_update_primary(gs);
+
+  /* "If any entry in PRIMARY_GUARDS has {is_reachable} status of
+      <maybe> or <yes>, return the first such guard." */
+  chosen_guard = select_primary_guard_for_circuit(gs, usage, rst, state_out);
+  if (chosen_guard)
+    return chosen_guard;
+
+  /* "Otherwise, if the ordered intersection of {CONFIRMED_GUARDS}
+      and {USABLE_FILTERED_GUARDS} is nonempty, return the first
+      entry in that intersection that has {is_pending} set to
+      false." */
+  chosen_guard = select_confirmed_guard_for_circuit(gs, usage, rst, state_out);
+  if (chosen_guard)
+    return chosen_guard;
+
   /* "Otherwise, if there is no such entry, select a member at
       random from {USABLE_FILTERED_GUARDS}." */
-  {
-    entry_guard_t *guard;
-    unsigned flags = 0;
-    if (need_descriptor)
-      flags |= SAMPLE_EXCLUDE_NO_DESCRIPTOR;
-    guard = sample_reachable_filtered_entry_guards(gs,
-                                                   rst,
-                                                   SAMPLE_EXCLUDE_CONFIRMED |
-                                                   SAMPLE_EXCLUDE_PRIMARY |
-                                                   SAMPLE_EXCLUDE_PENDING |
-                                                   flags);
-    if (guard == NULL) {
-      log_info(LD_GUARD, "Absolutely no sampled guards were available. "
-               "Marking all guards for retry and starting from top again.");
-      mark_all_guards_maybe_reachable(gs);
-      return NULL;
-    }
-    guard->is_pending = 1;
-    guard->last_tried_to_connect = approx_time();
-    *state_out = GUARD_CIRC_STATE_USABLE_IF_NO_BETTER_GUARD;
-    log_info(LD_GUARD, "No primary or confirmed guards available. Selected "
-             "random guard %s for circuit. Will try other guards before "
-             "using this circuit.",
-             entry_guard_describe(guard));
-    return guard;
+  chosen_guard = select_filtered_guard_for_circuit(gs, usage, rst, state_out);
+
+  if (chosen_guard == NULL) {
+    log_info(LD_GUARD, "Absolutely no sampled guards were available. "
+             "Marking all guards for retry and starting from top again.");
+    mark_all_guards_maybe_reachable(gs);
+    return NULL;
   }
+
+  return chosen_guard;
 }
 
 /**





More information about the tor-commits mailing list