Improve descriptor checks in the new guard algorithm.

- Make sure we check at least two guards for descriptor before making
  circuits. We typically use the first primary guard for circuits, but
  it can also happen that we use the second primary guard (e.g. if we
  pick our first primary guard as an exit), so we should make sure we
  have descriptors for both of them.

- Remove BUG() from the guard_has_descriptor() check since we now know
  that this can happen in rare but legitimate situations as well, and we
  should just move to the next guard in that case.
This commit is contained in:
George Kadianakis 2017-03-01 12:38:12 +02:00 committed by Nick Mathewson
parent 5ff31ff5b3
commit 18a98206ed
2 changed files with 13 additions and 3 deletions

4
changes/bug21415 Normal file
View File

@ -0,0 +1,4 @@
o Minor bugfix (entry guards):
- Silence a BUG() warning when attempting to use a guard whose descriptor
we don't know and make this scenario more unlikely to happen. Fixes bug
21415; bugfix on 0.3.0.1-alpha.

View File

@ -1843,7 +1843,7 @@ select_entry_guard_for_circuit(guard_selection_t *gs,
if (! entry_guard_obeys_restriction(guard, rst))
continue;
if (guard->is_reachable != GUARD_REACHABLE_NO) {
if (need_descriptor && BUG(!guard_has_descriptor(guard))) {
if (need_descriptor && !guard_has_descriptor(guard)) {
continue;
}
*state_out = GUARD_CIRC_STATE_USABLE_ON_COMPLETION;
@ -3357,9 +3357,15 @@ guard_selection_have_enough_dir_info_to_build_circuits(guard_selection_t *gs)
if (!gs->primary_guards_up_to_date)
entry_guards_update_primary(gs);
const int num_primary = get_n_primary_guards_to_use(GUARD_USAGE_TRAFFIC);
int n_missing_descriptors = 0;
int n_considered = 0;
int num_primary_to_check;
/* We want to check for the descriptor of at least the first two primary
* guards in our list, since these are the guards that we typically use for
* circuits. */
num_primary_to_check = get_n_primary_guards_to_use(GUARD_USAGE_TRAFFIC);
num_primary_to_check++;
SMARTLIST_FOREACH_BEGIN(gs->primary_entry_guards, entry_guard_t *, guard) {
entry_guard_consider_retry(guard);
@ -3368,7 +3374,7 @@ guard_selection_have_enough_dir_info_to_build_circuits(guard_selection_t *gs)
n_considered++;
if (!guard_has_descriptor(guard))
n_missing_descriptors++;
if (n_considered >= num_primary)
if (n_considered >= num_primary_to_check)
break;
} SMARTLIST_FOREACH_END(guard);