Commit 746d9591 authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

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.
parent 02da24f8
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -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)
+5 −0
Original line number Diff line number Diff line
@@ -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);
+8 −0
Original line number Diff line number Diff line
@@ -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;