From 2938fd3b859a71b9f484623b8dae61e8e7a7f7ec Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Tue, 17 Jan 2017 12:59:41 +0200 Subject: [PATCH 1/2] 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(-) create mode 100644 changes/bug21052 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 ca3e57b064..2b7023080b 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 guard 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); } From def7115fe4cab45b4e3edc8fa3d8e063f04675d3 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Tue, 17 Jan 2017 13:04:45 +0200 Subject: [PATCH 2/2] prop271: Move new funcs to top, to avoid compiler warnings. --- src/or/entrynodes.c | 91 +++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index 2b7023080b..e26f32d56e 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -570,6 +570,52 @@ get_extreme_restriction_threshold(void) 1, INT32_MAX); return pct / 100.0; } + +/* Mark guard 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); +} + /**@}*/ /** @@ -1939,51 +1985,6 @@ entry_guards_note_guard_failure(guard_selection_t *gs, entry_guard_describe(guard)); } -/* Mark guard 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); -} - /** * Note that we successfully connected to, and built a circuit through * guard. Given the old guard-state of the circuit in old_state,