summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2017-02-01 15:53:16 -0500
committerNick Mathewson <nickm@torproject.org>2017-02-01 15:53:16 -0500
commit2d2ab29ce89d85f64f4bf4802d6b1e22a74a9ad9 (patch)
treeb9d8149101b27ae5efde4891b82544b53f78a180
parent77788fa5374448fe6e12ab9bf7672d8187f73997 (diff)
parentdef7115fe4cab45b4e3edc8fa3d8e063f04675d3 (diff)
downloadtor-2d2ab29ce89d85f64f4bf4802d6b1e22a74a9ad9.tar.gz
tor-2d2ab29ce89d85f64f4bf4802d6b1e22a74a9ad9.zip
Merge remote-tracking branch 'asn/bug21052'
-rw-r--r--changes/bug210524
-rw-r--r--src/or/entrynodes.c74
2 files changed, 53 insertions, 25 deletions
diff --git a/changes/bug21052 b/changes/bug21052
new file mode 100644
index 0000000000..0597b3b306
--- /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 e341739379..b7c05f1930 100644
--- a/src/or/entrynodes.c
+++ b/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;
@@ -1892,30 +1940,6 @@ entry_guards_note_guard_failure(guard_selection_t *gs,
}
/**
- * 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>,
* return the new guard-state of the circuit.