aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/or/entrynodes.c37
-rw-r--r--src/or/entrynodes.h5
-rw-r--r--src/or/nodelist.c8
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;