Commit 01184f16 authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

Merge remote-tracking branch 'public/bug8158'

parents 36e2eb67 c8f5f35d
Loading
Loading
Loading
Loading

changes/bug8158

0 → 100644
+3 −0
Original line number Diff line number Diff line
  o Minor bugfixes:
    - Use less space when formatting identical microdescriptor lines in
      directory votes. Fixes bug 8158; bugfix on 0.2.4.1-alpha.
+2 −32
Original line number Diff line number Diff line
@@ -66,19 +66,6 @@ static cached_dir_t *the_directory = NULL;
/** For authoritative directories: the current (v1) network status. */
static cached_dir_t the_runningrouters;

/** Array of start and end of consensus methods used for supported
    microdescriptor formats. */
static const struct consensus_method_range_t {
  int low;
  int high;
} microdesc_consensus_methods[] = {
  {MIN_METHOD_FOR_MICRODESC, MIN_METHOD_FOR_A_LINES - 1},
  {MIN_METHOD_FOR_A_LINES, MIN_METHOD_FOR_P6_LINES - 1},
  {MIN_METHOD_FOR_P6_LINES, MIN_METHOD_FOR_NTOR_KEY - 1},
  {MIN_METHOD_FOR_NTOR_KEY, MAX_SUPPORTED_CONSENSUS_METHOD},
  {-1, -1}
};

static void directory_remove_invalid(void);
static cached_dir_t *dirserv_regenerate_directory(void);
static char *format_versions_list(config_line_t *ln);
@@ -2811,11 +2798,9 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
  microdescriptors = smartlist_new();

  SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
    const struct consensus_method_range_t *cmr = NULL;
    if (ri->cache_info.published_on >= cutoff) {
      routerstatus_t *rs;
      vote_routerstatus_t *vrs;
      microdesc_t *md;
      node_t *node = node_get_mutable_by_id(ri->cache_info.identity_digest);
      if (!node)
        continue;
@@ -2833,23 +2818,8 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
        rs->is_flagged_running = 0;

      vrs->version = version_from_platform(ri->platform);
      for (cmr = microdesc_consensus_methods;
           cmr->low != -1 && cmr->high != -1;
           cmr++) {
        md = dirvote_create_microdescriptor(ri, cmr->low);
        if (md) {
          char buf[128];
          vote_microdesc_hash_t *h;
          dirvote_format_microdesc_vote_line(buf, sizeof(buf), md,
                                             cmr->low, cmr->high);
          h = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
          h->microdesc_hash_line = tor_strdup(buf);
          h->next = vrs->microdesc;
          vrs->microdesc = h;
          md->last_listed = now;
          smartlist_add(microdescriptors, md);
        }
      }
      vrs->microdesc = dirvote_format_all_microdesc_vote_lines(ri, now,
                                                        microdescriptors);

      smartlist_add(routerstatuses, vrs);
    }
+81 −0
Original line number Diff line number Diff line
@@ -3651,6 +3651,87 @@ dirvote_format_microdesc_vote_line(char *out_buf, size_t out_buf_len,
  return ret;
}

/** Array of start and end of consensus methods used for supported
    microdescriptor formats. */
static const struct consensus_method_range_t {
  int low;
  int high;
} microdesc_consensus_methods[] = {
  {MIN_METHOD_FOR_MICRODESC, MIN_METHOD_FOR_A_LINES - 1},
  {MIN_METHOD_FOR_A_LINES, MIN_METHOD_FOR_P6_LINES - 1},
  {MIN_METHOD_FOR_P6_LINES, MIN_METHOD_FOR_NTOR_KEY - 1},
  {MIN_METHOD_FOR_NTOR_KEY, MAX_SUPPORTED_CONSENSUS_METHOD},
  {-1, -1}
};

/** Helper type used when generating the microdescriptor lines in a directory
 * vote. */
typedef struct microdesc_vote_line_t {
  int low;
  int high;
  microdesc_t *md;
  struct microdesc_vote_line_t *next;
} microdesc_vote_line_t;

/** Generate and return a linked list of all the lines that should appear to
 * describe a router's microdescriptor versions in a directory vote.
 * Add the generated microdescriptors to <b>microdescriptors_out</b>. */
vote_microdesc_hash_t *
dirvote_format_all_microdesc_vote_lines(const routerinfo_t *ri, time_t now,
                                        smartlist_t *microdescriptors_out)
{
  const struct consensus_method_range_t *cmr;
  microdesc_vote_line_t *entries = NULL, *ep;
  vote_microdesc_hash_t *result = NULL;

  /* Generate the microdescriptors. */
  for (cmr = microdesc_consensus_methods;
       cmr->low != -1 && cmr->high != -1;
       cmr++) {
    microdesc_t *md = dirvote_create_microdescriptor(ri, cmr->low);
    if (md) {
      microdesc_vote_line_t *e =
        tor_malloc_zero(sizeof(microdesc_vote_line_t));
      e->md = md;
      e->low = cmr->low;
      e->high = cmr->high;
      e->next = entries;
      entries = e;
    }
  }

  /* Compress adjacent identical ones */
  for (ep = entries; ep; ep = ep->next) {
    while (ep->next &&
           fast_memeq(ep->md->digest, ep->next->md->digest, DIGEST256_LEN) &&
           ep->low == ep->next->high + 1) {
      microdesc_vote_line_t *next = ep->next;
      ep->low = next->low;
      microdesc_free(next->md);
      ep->next = next->next;
      tor_free(next);
    }
  }

  /* Format them into vote_microdesc_hash_t, and add to microdescriptors_out.*/
  while ((ep = entries)) {
    char buf[128];
    vote_microdesc_hash_t *h;
    dirvote_format_microdesc_vote_line(buf, sizeof(buf), ep->md,
                                       ep->low, ep->high);
    h = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
    h->microdesc_hash_line = tor_strdup(buf);
    h->next = result;
    result = h;
    ep->md->last_listed = now;
    smartlist_add(microdescriptors_out, ep->md);
    entries = ep->next;
    tor_free(ep);
  }

  return result;
}

/** If <b>vrs</b> has a hash made for the consensus method <b>method</b> with
 * the digest algorithm <b>alg</b>, decode it and copy it into
 * <b>digest256_out</b> and return 0.  Otherwise return -1. */
+5 −0
Original line number Diff line number Diff line
@@ -109,6 +109,11 @@ ssize_t dirvote_format_microdesc_vote_line(char *out, size_t out_len,
                                           const microdesc_t *md,
                                           int consensus_method_low,
                                           int consensus_method_high);
vote_microdesc_hash_t *dirvote_format_all_microdesc_vote_lines(
                                        const routerinfo_t *ri,
                                        time_t now,
                                        smartlist_t *microdescriptors_out);

int vote_routerstatus_find_microdesc_hash(char *digest256_out,
                                          const vote_routerstatus_t *vrs,
                                          int method,