Преглед на файлове

Merge remote-tracking branch 'asn/bug21052'

Nick Mathewson преди 7 години
родител
ревизия
2d2ab29ce8
променени са 2 файла, в които са добавени 53 реда и са изтрити 25 реда
  1. 4 0
      changes/bug21052
  2. 49 25
      src/or/entrynodes.c

+ 4 - 0
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.

+ 49 - 25
src/or/entrynodes.c

@@ -531,6 +531,52 @@ get_extreme_restriction_threshold(void)
                                         1, INT32_MAX);
   return pct / 100.0;
 }
+
+/* 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
+ * try them again.
+ */
+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) {
+    mark_guard_maybe_reachable(guard);
+  } SMARTLIST_FOREACH_END(guard);
+}
+
+/* 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);
+}
+
 /**@}*/
 
 /**
@@ -1854,7 +1900,9 @@ select_entry_guard_for_circuit(guard_selection_t *gs,
                                                    SAMPLE_EXCLUDE_PENDING |
                                                    flags);
     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;
@@ -1891,30 +1939,6 @@ entry_guards_note_guard_failure(guard_selection_t *gs,
            entry_guard_describe(guard));
 }
 
-/**
- * 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
- * try them again.
- */
-STATIC void
-mark_primary_guards_maybe_reachable(guard_selection_t *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;
-
-    /* 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;
-
-  } SMARTLIST_FOREACH_END(guard);
-}
-
 /**
  * Note that we successfully connected to, and built a circuit through
  * <b>guard</b>. Given the old guard-state of the circuit in <b>old_state</b>,