diff options
-rw-r--r-- | src/or/entrynodes.c | 37 | ||||
-rw-r--r-- | src/or/entrynodes.h | 5 | ||||
-rw-r--r-- | src/or/nodelist.c | 8 |
3 files changed, 50 insertions, 0 deletions
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index 1cf1ff2c8e..6249e847a9 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -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) diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h index 0c29292c17..f02901f5d7 100644 --- a/src/or/entrynodes.h +++ b/src/or/entrynodes.h @@ -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); diff --git a/src/or/nodelist.c b/src/or/nodelist.c index 804af297ba..96e95baf5a 100644 --- a/src/or/nodelist.c +++ b/src/or/nodelist.c @@ -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; |