]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Don't build circuits till primary guards have descriptors
authorNick Mathewson <nickm@torproject.org>
Tue, 31 Jan 2017 17:31:43 +0000 (12:31 -0500)
committerNick Mathewson <nickm@torproject.org>
Tue, 31 Jan 2017 17:31:43 +0000 (12:31 -0500)
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.

src/or/entrynodes.c
src/or/entrynodes.h
src/or/nodelist.c

index 1cf1ff2c8e0ef91563321d21e8bb5179828e0a6e..6249e847a9b687647567558b69790d648317ac50 100644 (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)
index 0c29292c17744b6a2adf7394feb5208346d982c2..f02901f5d704cd15794a4453f0221970df33eda7 100644 (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);
index 804af297baf83ab994f5249a53a60452210a973d..96e95baf5a6c7130f05c08cc6db1138d6c272274 100644 (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;