Commit b3178134 authored by Nick Mathewson's avatar Nick Mathewson 🥔
Browse files

Make GETINFO entry-guards work again with prop271

This is not a great solution, but it's as close to
backward-compatible as possible.  A better GETINFO API should expose
more information.
parent ded98be4
Loading
Loading
Loading
Loading
+90 −41
Original line number Diff line number Diff line
@@ -4746,46 +4746,22 @@ entry_guards_update_state(or_state_t *state)
  entry_guards_dirty = 0;
}

/** If <b>question</b> is the string "entry-guards", then dump
 * to *<b>answer</b> a newly allocated string describing all of
 * the nodes in the global entry_guards list. See control-spec.txt
 * for details.
 * For backward compatibility, we also handle the string "helper-nodes".
 *
 * XXX this should be totally redesigned after prop 271 too, and that's
 * going to take some control spec work.
 * */
int
getinfo_helper_entry_guards(control_connection_t *conn,
                            const char *question, char **answer,
                            const char **errmsg)
/**
 * Format a single entry guard in the format expected by the controller.
 * Return a newly allocated string.
 */
STATIC char *
getinfo_helper_format_single_entry_guard(const entry_guard_t *e,
                                         int legacy_guard)
{
  guard_selection_t *gs = get_guard_selection_info();

  tor_assert(gs != NULL);
#ifdef ENABLE_LEGACY_GUARD_ALGORITHM
  tor_assert(gs->chosen_entry_guards != NULL);
#else
  // XXXX
  (void)question;
  (void)answer;
#endif

  (void) conn;
  (void) errmsg;

#ifdef ENABLE_LEGACY_GUARD_ALGORITHM
  if (!strcmp(question,"entry-guards") ||
      !strcmp(question,"helper-nodes")) {
    smartlist_t *sl = smartlist_new();
    char tbuf[ISO_TIME_LEN+1];
    char nbuf[MAX_VERBOSE_NICKNAME_LEN+1];

    SMARTLIST_FOREACH_BEGIN(gs->chosen_entry_guards, entry_guard_t *, e) {
  const char *status = NULL;
  time_t when = 0;
  const node_t *node;
  char tbuf[ISO_TIME_LEN+1];
  char nbuf[MAX_VERBOSE_NICKNAME_LEN+1];

  if (legacy_guard) {
#ifdef ENABLE_LEGACY_GUARD_ALGORITHM
    if (!e->made_contact) {
      status = "never-connected";
    } else if (e->bad_since) {
@@ -4797,8 +4773,32 @@ getinfo_helper_entry_guards(control_connection_t *conn,
    } else {
      status = "up";
    }
#else
    tor_assert_nonfatal_unreached();
    status = "BUG";
#endif
  } else {
    /* modern case.  This is going to be a bit tricky, since the status
     * codes above weren't really intended for prop271 guards.
     *
     * XXXX use a more appropriate format for exporting this information
     */
    if (e->confirmed_idx < 0) {
      status = "never-connected";
    } else if (! e->currently_listed) {
      when = e->unlisted_since_date;
      status = "unusable";
    } else if (! e->is_filtered_guard) {
      status = "unusable";
    } else if (e->is_reachable == GUARD_REACHABLE_NO) {
      when = e->failing_since;
      status = "down";
    } else {
      status = "up";
    }
  }

        node = node_get_by_id(e->identity);
  node = entry_guard_find_node(e);
  if (node) {
    node_get_verbose_nickname(node, nbuf);
  } else {
@@ -4808,18 +4808,67 @@ getinfo_helper_entry_guards(control_connection_t *conn,
     * this router any longer; don't include it. */
  }

  char *result = NULL;
  if (when) {
    format_iso_time(tbuf, when);
          smartlist_add_asprintf(sl, "%s %s %s\n", nbuf, status, tbuf);
    tor_asprintf(&result, "%s %s %s\n", nbuf, status, tbuf);
  } else {
    tor_asprintf(&result, "%s %s\n", nbuf, status);
  }
  return result;
}

/** If <b>question</b> is the string "entry-guards", then dump
 * to *<b>answer</b> a newly allocated string describing all of
 * the nodes in the global entry_guards list. See control-spec.txt
 * for details.
 * For backward compatibility, we also handle the string "helper-nodes".
 *
 * XXX this should be totally redesigned after prop 271 too, and that's
 * going to take some control spec work.
 * */
int
getinfo_helper_entry_guards(control_connection_t *conn,
                            const char *question, char **answer,
                            const char **errmsg)
{
  guard_selection_t *gs = get_guard_selection_info();

  tor_assert(gs != NULL);
#ifdef ENABLE_LEGACY_GUARD_ALGORITHM
  tor_assert(gs->chosen_entry_guards != NULL);
#endif

  (void) conn;
  (void) errmsg;

  if (!strcmp(question,"entry-guards") ||
      !strcmp(question,"helper-nodes")) {
    const smartlist_t *guards;
    int legacy_mode;
    if (gs->type == GS_TYPE_LEGACY) {
#ifdef ENABLE_LEGACY_GUARD_ALGORITHM
      guards = gs->chosen_entry_guards;
      legacy_mode = 1;
#else
      tor_assert_nonfatal_unreached();
      return 0;
#endif
    } else {
          smartlist_add_asprintf(sl, "%s %s\n", nbuf, status);
      guards = gs->sampled_entry_guards;
      legacy_mode = 0;
    }

    smartlist_t *sl = smartlist_new();

    SMARTLIST_FOREACH_BEGIN(guards, const entry_guard_t *, e) {
      char *cp = getinfo_helper_format_single_entry_guard(e, legacy_mode);
      smartlist_add(sl, cp);
    } SMARTLIST_FOREACH_END(e);
    *answer = smartlist_join_strings(sl, "", 0, NULL);
    SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
    smartlist_free(sl);
  }
#endif
  return 0;
}

+2 −1
Original line number Diff line number Diff line
@@ -610,7 +610,8 @@ STATIC unsigned entry_guards_note_guard_success(guard_selection_t *gs,
                                                entry_guard_t *guard,
                                                unsigned old_state);
STATIC int entry_guard_has_higher_priority(entry_guard_t *a, entry_guard_t *b);

STATIC char *getinfo_helper_format_single_entry_guard(const entry_guard_t *e,
                                                      int is_legacy);
#ifdef ENABLE_LEGACY_GUARD_ALGORITHM
// ---------- XXXX this stuff is pre-prop271.