Don't build circuits till primary guards have descriptors

In addition to not wanting to build circuits until we can see most
of the paths in the network, and in addition to not wanting to build
circuits until we have a consensus ... we shouldn't build circuits
till all of our (in-use) primary guards have descriptors that we can
use for them.

This is another bug 21242 fix.
This commit is contained in:
Nick Mathewson 2017-01-31 12:31:43 -05:00
parent 02da24f8e5
commit 746d959100
3 changed files with 50 additions and 0 deletions

View File

@ -3335,6 +3335,43 @@ guards_retry_optimistic(const or_options_t *options)
return 1;
}
/**
* Return true iff we know enough directory information to construct
* circuits through all of the primary guards we'd currently use.
*/
int
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;
SMARTLIST_FOREACH_BEGIN(gs->primary_entry_guards, entry_guard_t *, guard) {
entry_guard_consider_retry(guard);
if (guard->is_reachable == GUARD_REACHABLE_NO)
continue;
n_considered++;
if (!guard_has_descriptor(guard))
n_missing_descriptors++;
if (n_considered >= num_primary)
break;
} SMARTLIST_FOREACH_END(guard);
return n_missing_descriptors == 0;
}
/** As guard_selection_have_enough_dir_info_to_build_circuits, but uses
* the default guard selection. */
int
entry_guards_have_enough_dir_info_to_build_circuits(void)
{
return guard_selection_have_enough_dir_info_to_build_circuits(
get_guard_selection_info());
}
/** Free one guard selection context */
STATIC void
guard_selection_free(guard_selection_t *gs)

View File

@ -482,6 +482,7 @@ STATIC entry_guard_t *get_sampled_guard_with_id(guard_selection_t *gs,
const uint8_t *rsa_id);
MOCK_DECL(STATIC time_t, randomize_time, (time_t now, time_t max_backdate));
STATIC entry_guard_t *entry_guard_add_to_sample(guard_selection_t *gs,
const node_t *node);
STATIC entry_guard_t *entry_guards_expand_sample(guard_selection_t *gs);
@ -566,6 +567,10 @@ int getinfo_helper_entry_guards(control_connection_t *conn,
int entries_known_but_down(const or_options_t *options);
void entries_retry_all(const or_options_t *options);
int guard_selection_have_enough_dir_info_to_build_circuits(
guard_selection_t *gs);
int entry_guards_have_enough_dir_info_to_build_circuits(void);
void entry_guards_free_all(void);
double pathbias_get_close_success_count(entry_guard_t *guard);

View File

@ -43,6 +43,7 @@
#include "config.h"
#include "control.h"
#include "dirserv.h"
#include "entrynodes.h"
#include "geoip.h"
#include "main.h"
#include "microdesc.h"
@ -1991,6 +1992,13 @@ update_router_have_minimum_dir_info(void)
using_md = consensus->flavor == FLAV_MICRODESC;
if (! entry_guards_have_enough_dir_info_to_build_circuits()) {
strlcpy(dir_info_status, "We're missing descriptors for some of our "
"primary entry guards", sizeof(dir_info_status));
res = 0;
goto done;
}
/* Check fraction of available paths */
{
char *status = NULL;