[tor-commits] [tor/master] prop271: When we exhaust all guards, mark all of them for retry.

nickm at torproject.org nickm at torproject.org
Wed Feb 1 20:56:10 UTC 2017


commit 2938fd3b859a71b9f484623b8dae61e8e7a7f7ec
Author: George Kadianakis <desnacked at riseup.net>
Date:   Tue Jan 17 12:59:41 2017 +0200

    prop271: When we exhaust all guards, mark all of them for retry.
    
    In the past, when we exhausted all guards in our sampled set, we just
    waited there till we mark a guard for retry again (usually takes 10 mins
    for a primary guard, 1 hour for a non-primary guard). This patch marks
    all guards as maybe-reachable when we exhaust all guards (this can
    happen when network is down for some time).
---
 changes/bug21052    |  4 ++++
 src/or/entrynodes.c | 39 +++++++++++++++++++++++++++++++--------
 2 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/changes/bug21052 b/changes/bug21052
new file mode 100644
index 0000000..0597b3b
--- /dev/null
+++ b/changes/bug21052
@@ -0,0 +1,4 @@
+  o Minor bugfixes (client, guards):
+    - Fix a bug of the new guard algorithm where tor could stall for up to 10
+      minutes before retrying a guard after a long period of no network.
+      Fixes bug 21052; bugfix on 0.3.0.1-alpha.
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index ca3e57b..2b70230 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -1900,7 +1900,9 @@ select_entry_guard_for_circuit(guard_selection_t *gs,
                                                    SAMPLE_EXCLUDE_PRIMARY |
                                                    SAMPLE_EXCLUDE_PENDING);
     if (guard == NULL) {
-      log_info(LD_GUARD, "Absolutely no sampled guards were available.");
+      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;
@@ -1937,6 +1939,21 @@ entry_guards_note_guard_failure(guard_selection_t *gs,
            entry_guard_describe(guard));
 }
 
+/* Mark <b>guard</b> as maybe reachable again. */
+static void
+mark_guard_maybe_reachable(entry_guard_t *guard)
+{
+  if (guard->is_reachable != GUARD_REACHABLE_NO) {
+    return;
+  }
+
+  /* Note that we do not clear failing_since: this guard is now only
+   * _maybe-reachable_. */
+  guard->is_reachable = GUARD_REACHABLE_MAYBE;
+  if (guard->is_filtered_guard)
+    guard->is_usable_filtered_guard = 1;
+}
+
 /**
  * Called when the network comes up after having seemed to be down for
  * a while: Mark the primary guards as maybe-reachable so that we'll
@@ -1945,19 +1962,25 @@ entry_guards_note_guard_failure(guard_selection_t *gs,
 STATIC void
 mark_primary_guards_maybe_reachable(guard_selection_t *gs)
 {
+  tor_assert(gs);
+
   if (!gs->primary_guards_up_to_date)
     entry_guards_update_primary(gs);
 
   SMARTLIST_FOREACH_BEGIN(gs->primary_entry_guards, entry_guard_t *, guard) {
-    if (guard->is_reachable != GUARD_REACHABLE_NO)
-      continue;
+    mark_guard_maybe_reachable(guard);
+  } SMARTLIST_FOREACH_END(guard);
+}
 
-    /* Note that we do not clear failing_since: this guard is now only
-     * _maybe-reachable_. */
-    guard->is_reachable = GUARD_REACHABLE_MAYBE;
-    if (guard->is_filtered_guard)
-      guard->is_usable_filtered_guard = 1;
+/* Called when we exhaust all guards in our sampled set: Marks all guards as
+ * maybe-reachable so that we 'll try them again. */
+static void
+mark_all_guards_maybe_reachable(guard_selection_t *gs)
+{
+  tor_assert(gs);
 
+  SMARTLIST_FOREACH_BEGIN(gs->sampled_entry_guards, entry_guard_t *, guard) {
+    mark_guard_maybe_reachable(guard);
   } SMARTLIST_FOREACH_END(guard);
 }
 





More information about the tor-commits mailing list