dirvote.c
上传用户:awang829
上传日期:2019-07-14
资源大小:2356k
文件大小:78k
源码类别:

网络

开发平台:

Unix_Linux

  1. /* Copyright (c) 2001-2004, Roger Dingledine.
  2.  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3.  * Copyright (c) 2007-2009, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #define DIRVOTE_PRIVATE
  6. #include "or.h"
  7. /**
  8.  * file dirvote.c
  9.  * brief Functions to compute directory consensus, and schedule voting.
  10.  **/
  11. static int dirvote_add_signatures_to_pending_consensus(
  12.                        const char *detached_signatures_body,
  13.                        const char **msg_out);
  14. static char *list_v3_auth_ids(void);
  15. static void dirvote_fetch_missing_votes(void);
  16. static void dirvote_fetch_missing_signatures(void);
  17. static int dirvote_perform_vote(void);
  18. static void dirvote_clear_votes(int all_votes);
  19. static int dirvote_compute_consensus(void);
  20. static int dirvote_publish_consensus(void);
  21. /* =====
  22.  * Voting
  23.  * =====*/
  24. /** Return a new string containing the string representation of the vote in
  25.  * <b>v3_ns</b>, signed with our v3 signing key <b>private_signing_key</b>.
  26.  * For v3 authorities. */
  27. char *
  28. format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
  29.                           networkstatus_t *v3_ns)
  30. {
  31.   size_t len;
  32.   char *status = NULL;
  33.   const char *client_versions = NULL, *server_versions = NULL;
  34.   char *outp, *endp;
  35.   char fingerprint[FINGERPRINT_LEN+1];
  36.   char ipaddr[INET_NTOA_BUF_LEN];
  37.   char digest[DIGEST_LEN];
  38.   struct in_addr in;
  39.   uint32_t addr;
  40.   routerlist_t *rl = router_get_routerlist();
  41.   char *version_lines = NULL;
  42.   networkstatus_voter_info_t *voter;
  43.   tor_assert(private_signing_key);
  44.   tor_assert(v3_ns->type == NS_TYPE_VOTE || v3_ns->type == NS_TYPE_OPINION);
  45.   voter = smartlist_get(v3_ns->voters, 0);
  46.   addr = voter->addr;
  47.   in.s_addr = htonl(addr);
  48.   tor_inet_ntoa(&in, ipaddr, sizeof(ipaddr));
  49.   base16_encode(fingerprint, sizeof(fingerprint),
  50.                 v3_ns->cert->cache_info.identity_digest, DIGEST_LEN);
  51.   client_versions = v3_ns->client_versions;
  52.   server_versions = v3_ns->server_versions;
  53.   if (client_versions || server_versions) {
  54.     size_t v_len = 64;
  55.     char *cp;
  56.     if (client_versions)
  57.       v_len += strlen(client_versions);
  58.     if (server_versions)
  59.       v_len += strlen(server_versions);
  60.     version_lines = tor_malloc(v_len);
  61.     cp = version_lines;
  62.     if (client_versions) {
  63.       tor_snprintf(cp, v_len-(cp-version_lines),
  64.                    "client-versions %sn", client_versions);
  65.       cp += strlen(cp);
  66.     }
  67.     if (server_versions)
  68.       tor_snprintf(cp, v_len-(cp-version_lines),
  69.                    "server-versions %sn", server_versions);
  70.   } else {
  71.     version_lines = tor_strdup("");
  72.   }
  73.   len = 8192;
  74.   len += strlen(version_lines);
  75.   len += (RS_ENTRY_LEN)*smartlist_len(rl->routers);
  76.   len += v3_ns->cert->cache_info.signed_descriptor_len;
  77.   status = tor_malloc(len);
  78.   {
  79.     char published[ISO_TIME_LEN+1];
  80.     char va[ISO_TIME_LEN+1];
  81.     char fu[ISO_TIME_LEN+1];
  82.     char vu[ISO_TIME_LEN+1];
  83.     char *flags = smartlist_join_strings(v3_ns->known_flags, " ", 0, NULL);
  84.     authority_cert_t *cert = v3_ns->cert;
  85.     format_iso_time(published, v3_ns->published);
  86.     format_iso_time(va, v3_ns->valid_after);
  87.     format_iso_time(fu, v3_ns->fresh_until);
  88.     format_iso_time(vu, v3_ns->valid_until);
  89.     tor_assert(cert);
  90.     tor_snprintf(status, len,
  91.                  "network-status-version 3n"
  92.                  "vote-status %sn"
  93.                  "consensus-methods 1 2 3 4 5n"
  94.                  "published %sn"
  95.                  "valid-after %sn"
  96.                  "fresh-until %sn"
  97.                  "valid-until %sn"
  98.                  "voting-delay %d %dn"
  99.                  "%s" /* versions */
  100.                  "known-flags %sn"
  101.                  "dir-source %s %s %s %s %d %dn"
  102.                  "contact %sn",
  103.                  v3_ns->type == NS_TYPE_VOTE ? "vote" : "opinion",
  104.                  published, va, fu, vu,
  105.                  v3_ns->vote_seconds, v3_ns->dist_seconds,
  106.                  version_lines,
  107.                  flags,
  108.                  voter->nickname, fingerprint, voter->address,
  109.                    ipaddr, voter->dir_port, voter->or_port, voter->contact);
  110.     tor_free(flags);
  111.     outp = status + strlen(status);
  112.     endp = status + len;
  113.     if (!tor_digest_is_zero(voter->legacy_id_digest)) {
  114.       char fpbuf[HEX_DIGEST_LEN+1];
  115.       base16_encode(fpbuf, sizeof(fpbuf), voter->legacy_id_digest, DIGEST_LEN);
  116.       tor_snprintf(outp, endp-outp, "legacy-dir-key %sn", fpbuf);
  117.       outp += strlen(outp);
  118.     }
  119.     tor_assert(outp + cert->cache_info.signed_descriptor_len < endp);
  120.     memcpy(outp, cert->cache_info.signed_descriptor_body,
  121.            cert->cache_info.signed_descriptor_len);
  122.     outp += cert->cache_info.signed_descriptor_len;
  123.   }
  124.   SMARTLIST_FOREACH(v3_ns->routerstatus_list, vote_routerstatus_t *, vrs,
  125.   {
  126.     if (routerstatus_format_entry(outp, endp-outp, &vrs->status,
  127.                                   vrs->version, 0, 0) < 0) {
  128.       log_warn(LD_BUG, "Unable to print router status.");
  129.       goto err;
  130.     }
  131.     outp += strlen(outp);
  132.   });
  133.   {
  134.     char signing_key_fingerprint[FINGERPRINT_LEN+1];
  135.     if (tor_snprintf(outp, endp-outp, "directory-signature ")<0) {
  136.       log_warn(LD_BUG, "Unable to start signature line.");
  137.       goto err;
  138.     }
  139.     outp += strlen(outp);
  140.     if (crypto_pk_get_fingerprint(private_signing_key,
  141.                                   signing_key_fingerprint, 0)<0) {
  142.       log_warn(LD_BUG, "Unable to get fingerprint for signing key");
  143.       goto err;
  144.     }
  145.     if (tor_snprintf(outp, endp-outp, "%s %sn", fingerprint,
  146.                      signing_key_fingerprint)<0) {
  147.       log_warn(LD_BUG, "Unable to end signature line.");
  148.       goto err;
  149.     }
  150.     outp += strlen(outp);
  151.   }
  152.   if (router_get_networkstatus_v3_hash(status, digest)<0)
  153.     goto err;
  154.   note_crypto_pk_op(SIGN_DIR);
  155.   if (router_append_dirobj_signature(outp,endp-outp,digest,
  156.                                      private_signing_key)<0) {
  157.     log_warn(LD_BUG, "Unable to sign networkstatus vote.");
  158.     goto err;
  159.   }
  160.   {
  161.     networkstatus_t *v;
  162.     if (!(v = networkstatus_parse_vote_from_string(status, NULL,
  163.                                                    v3_ns->type))) {
  164.       log_err(LD_BUG,"Generated a networkstatus %s we couldn't parse: "
  165.               "<<%s>>",
  166.               v3_ns->type == NS_TYPE_VOTE ? "vote" : "opinion", status);
  167.       goto err;
  168.     }
  169.     networkstatus_vote_free(v);
  170.   }
  171.   goto done;
  172.  err:
  173.   tor_free(status);
  174.  done:
  175.   tor_free(version_lines);
  176.   return status;
  177. }
  178. /* =====
  179.  * Consensus generation
  180.  * ===== */
  181. /** Given a vote <b>vote</b> (not a consensus!), return its associated
  182.  * networkstatus_voter_info_t. */
  183. static networkstatus_voter_info_t *
  184. get_voter(const networkstatus_t *vote)
  185. {
  186.   tor_assert(vote);
  187.   tor_assert(vote->type == NS_TYPE_VOTE);
  188.   tor_assert(vote->voters);
  189.   tor_assert(smartlist_len(vote->voters) == 1);
  190.   return smartlist_get(vote->voters, 0);
  191. }
  192. /** Temporary structure used in constructing a list of dir-source entries
  193.  * for a consensus.  One of these is generated for every vote, and one more
  194.  * for every legacy key in each vote. */
  195. typedef struct dir_src_ent_t {
  196.   networkstatus_t *v;
  197.   const char *digest;
  198.   int is_legacy;
  199. } dir_src_ent_t;
  200. /** Helper for sorting networkstatus_t votes (not consensuses) by the
  201.  * hash of their voters' identity digests. */
  202. static int
  203. _compare_votes_by_authority_id(const void **_a, const void **_b)
  204. {
  205.   const networkstatus_t *a = *_a, *b = *_b;
  206.   return memcmp(get_voter(a)->identity_digest,
  207.                 get_voter(b)->identity_digest, DIGEST_LEN);
  208. }
  209. /** Helper: Compare the dir_src_ent_ts in *<b>_a</b> and *<b>_b</b> by
  210.  * their identity digests, and return -1, 0, or 1 depending on their
  211.  * ordering */
  212. static int
  213. _compare_dir_src_ents_by_authority_id(const void **_a, const void **_b)
  214. {
  215.   const dir_src_ent_t *a = *_a, *b = *_b;
  216.   const networkstatus_voter_info_t *a_v = get_voter(a->v),
  217.     *b_v = get_voter(b->v);
  218.   const char *a_id, *b_id;
  219.   a_id = a->is_legacy ? a_v->legacy_id_digest : a_v->identity_digest;
  220.   b_id = b->is_legacy ? b_v->legacy_id_digest : b_v->identity_digest;
  221.   return memcmp(a_id, b_id, DIGEST_LEN);
  222. }
  223. /** Given a sorted list of strings <b>in</b>, add every member to <b>out</b>
  224.  * that occurs more than <b>min</b> times. */
  225. static void
  226. get_frequent_members(smartlist_t *out, smartlist_t *in, int min)
  227. {
  228.   char *cur = NULL;
  229.   int count = 0;
  230.   SMARTLIST_FOREACH(in, char *, cp,
  231.   {
  232.     if (cur && !strcmp(cp, cur)) {
  233.       ++count;
  234.     } else {
  235.       if (count > min)
  236.         smartlist_add(out, cur);
  237.       cur = cp;
  238.       count = 1;
  239.     }
  240.   });
  241.   if (count > min)
  242.     smartlist_add(out, cur);
  243. }
  244. /** Given a sorted list of strings <b>lst</b>, return the member that appears
  245.  * most.  Break ties in favor of later-occurring members. */
  246. static const char *
  247. get_most_frequent_member(smartlist_t *lst)
  248. {
  249.   const char *most_frequent = NULL;
  250.   int most_frequent_count = 0;
  251.   const char *cur = NULL;
  252.   int count = 0;
  253.   SMARTLIST_FOREACH(lst, const char *, s,
  254.   {
  255.     if (cur && !strcmp(s, cur)) {
  256.       ++count;
  257.     } else {
  258.       if (count >= most_frequent_count) {
  259.         most_frequent = cur;
  260.         most_frequent_count = count;
  261.       }
  262.       cur = s;
  263.       count = 1;
  264.     }
  265.   });
  266.   if (count >= most_frequent_count) {
  267.     most_frequent = cur;
  268.     most_frequent_count = count;
  269.   }
  270.   return most_frequent;
  271. }
  272. /** Return 0 if and only if <b>a</b> and <b>b</b> are routerstatuses
  273.  * that come from the same routerinfo, with the same derived elements.
  274.  */
  275. static int
  276. compare_vote_rs(const vote_routerstatus_t *a, const vote_routerstatus_t *b)
  277. {
  278.   int r;
  279.   if ((r = memcmp(a->status.identity_digest, b->status.identity_digest,
  280.                   DIGEST_LEN)))
  281.     return r;
  282.   if ((r = memcmp(a->status.descriptor_digest, b->status.descriptor_digest,
  283.                   DIGEST_LEN)))
  284.     return r;
  285.   if ((r = (int)(b->status.published_on - a->status.published_on)))
  286.     return r;
  287.   if ((r = strcmp(b->status.nickname, a->status.nickname)))
  288.     return r;
  289.   if ((r = (((int)b->status.addr) - ((int)a->status.addr))))
  290.     return r;
  291.   if ((r = (((int)b->status.or_port) - ((int)a->status.or_port))))
  292.     return r;
  293.   if ((r = (((int)b->status.dir_port) - ((int)a->status.dir_port))))
  294.     return r;
  295.   return 0;
  296. }
  297. /** Helper for sorting routerlists based on compare_vote_rs. */
  298. static int
  299. _compare_vote_rs(const void **_a, const void **_b)
  300. {
  301.   const vote_routerstatus_t *a = *_a, *b = *_b;
  302.   return compare_vote_rs(a,b);
  303. }
  304. /** Given a list of vote_routerstatus_t, all for the same router identity,
  305.  * return whichever is most frequent, breaking ties in favor of more
  306.  * recently published vote_routerstatus_t and in case of ties there,
  307.  * in favor of smaller descriptor digest.
  308.  */
  309. static vote_routerstatus_t *
  310. compute_routerstatus_consensus(smartlist_t *votes)
  311. {
  312.   vote_routerstatus_t *most = NULL, *cur = NULL;
  313.   int most_n = 0, cur_n = 0;
  314.   time_t most_published = 0;
  315.   /* _compare_vote_rs() sorts the items by identity digest (all the same),
  316.    * then by SD digest.  That way, if we have a tie that the published_on
  317.    * date cannot tie, we use the descriptor with the smaller digest.
  318.    */
  319.   smartlist_sort(votes, _compare_vote_rs);
  320.   SMARTLIST_FOREACH(votes, vote_routerstatus_t *, rs,
  321.   {
  322.     if (cur && !compare_vote_rs(cur, rs)) {
  323.       ++cur_n;
  324.     } else {
  325.       if (cur_n > most_n ||
  326.           (cur && cur_n == most_n &&
  327.            cur->status.published_on > most_published)) {
  328.         most = cur;
  329.         most_n = cur_n;
  330.         most_published = cur->status.published_on;
  331.       }
  332.       cur_n = 1;
  333.       cur = rs;
  334.     }
  335.   });
  336.   if (cur_n > most_n ||
  337.       (cur && cur_n == most_n && cur->status.published_on > most_published)) {
  338.     most = cur;
  339.     most_n = cur_n;
  340.     most_published = cur->status.published_on;
  341.   }
  342.   tor_assert(most);
  343.   return most;
  344. }
  345. /** Given a list of strings in <b>lst</b>, set the DIGEST_LEN-byte digest at
  346.  * <b>digest_out</b> to the hash of the concatenation of those strings. */
  347. static void
  348. hash_list_members(char *digest_out, smartlist_t *lst)
  349. {
  350.   crypto_digest_env_t *d = crypto_new_digest_env();
  351.   SMARTLIST_FOREACH(lst, const char *, cp,
  352.                     crypto_digest_add_bytes(d, cp, strlen(cp)));
  353.   crypto_digest_get_digest(d, digest_out, DIGEST_LEN);
  354.   crypto_free_digest_env(d);
  355. }
  356. /** Sorting helper: compare two strings based on their values as base-ten
  357.  * positive integers. (Non-integers are treated as prior to all integers, and
  358.  * compared lexically.) */
  359. static int
  360. _cmp_int_strings(const void **_a, const void **_b)
  361. {
  362.   const char *a = *_a, *b = *_b;
  363.   int ai = (int)tor_parse_long(a, 10, 1, INT_MAX, NULL, NULL);
  364.   int bi = (int)tor_parse_long(b, 10, 1, INT_MAX, NULL, NULL);
  365.   if (ai<bi) {
  366.     return -1;
  367.   } else if (ai==bi) {
  368.     if (ai == 0) /* Parsing failed. */
  369.       return strcmp(a, b);
  370.     return 0;
  371.   } else {
  372.     return 1;
  373.   }
  374. }
  375. /** Given a list of networkstatus_t votes, determine and return the number of
  376.  * the highest consensus method that is supported by 2/3 of the voters. */
  377. static int
  378. compute_consensus_method(smartlist_t *votes)
  379. {
  380.   smartlist_t *all_methods = smartlist_create();
  381.   smartlist_t *acceptable_methods = smartlist_create();
  382.   smartlist_t *tmp = smartlist_create();
  383.   int min = (smartlist_len(votes) * 2) / 3;
  384.   int n_ok;
  385.   int result;
  386.   SMARTLIST_FOREACH(votes, networkstatus_t *, vote,
  387.   {
  388.     tor_assert(vote->supported_methods);
  389.     smartlist_add_all(tmp, vote->supported_methods);
  390.     smartlist_sort(tmp, _cmp_int_strings);
  391.     smartlist_uniq(tmp, _cmp_int_strings, NULL);
  392.     smartlist_add_all(all_methods, tmp);
  393.     smartlist_clear(tmp);
  394.   });
  395.   smartlist_sort(all_methods, _cmp_int_strings);
  396.   get_frequent_members(acceptable_methods, all_methods, min);
  397.   n_ok = smartlist_len(acceptable_methods);
  398.   if (n_ok) {
  399.     const char *best = smartlist_get(acceptable_methods, n_ok-1);
  400.     result = (int)tor_parse_long(best, 10, 1, INT_MAX, NULL, NULL);
  401.   } else {
  402.     result = 1;
  403.   }
  404.   smartlist_free(tmp);
  405.   smartlist_free(all_methods);
  406.   smartlist_free(acceptable_methods);
  407.   return result;
  408. }
  409. /** Return true iff <b>method</b> is a consensus method that we support. */
  410. static int
  411. consensus_method_is_supported(int method)
  412. {
  413.   return (method >= 1) && (method <= 5);
  414. }
  415. /** Helper: given <b>lst</b>, a list of version strings such that every
  416.  * version appears once for every versioning voter who recommends it, return a
  417.  * newly allocated string holding the resulting client-versions or
  418.  * server-versions list. May change contents of <b>lst</b> */
  419. static char *
  420. compute_consensus_versions_list(smartlist_t *lst, int n_versioning)
  421. {
  422.   int min = n_versioning / 2;
  423.   smartlist_t *good = smartlist_create();
  424.   char *result;
  425.   sort_version_list(lst, 0);
  426.   get_frequent_members(good, lst, min);
  427.   result = smartlist_join_strings(good, ",", 0, NULL);
  428.   smartlist_free(good);
  429.   return result;
  430. }
  431. /** Given a list of vote networkstatus_t in <b>votes</b>, our public
  432.  * authority <b>identity_key</b>, our private authority <b>signing_key</b>,
  433.  * and the number of <b>total_authorities</b> that we believe exist in our
  434.  * voting quorum, generate the text of a new v3 consensus vote, and return the
  435.  * value in a newly allocated string.
  436.  *
  437.  * Note: this function DOES NOT check whether the votes are from
  438.  * recognized authorities.   (dirvote_add_vote does that.) */
  439. char *
  440. networkstatus_compute_consensus(smartlist_t *votes,
  441.                                 int total_authorities,
  442.                                 crypto_pk_env_t *identity_key,
  443.                                 crypto_pk_env_t *signing_key,
  444.                                 const char *legacy_id_key_digest,
  445.                                 crypto_pk_env_t *legacy_signing_key)
  446. {
  447.   smartlist_t *chunks;
  448.   char *result = NULL;
  449.   int consensus_method;
  450.   time_t valid_after, fresh_until, valid_until;
  451.   int vote_seconds, dist_seconds;
  452.   char *client_versions = NULL, *server_versions = NULL;
  453.   smartlist_t *flags;
  454.   tor_assert(total_authorities >= smartlist_len(votes));
  455.   if (!smartlist_len(votes)) {
  456.     log_warn(LD_DIR, "Can't compute a consensus from no votes.");
  457.     return NULL;
  458.   }
  459.   flags = smartlist_create();
  460.   consensus_method = compute_consensus_method(votes);
  461.   if (consensus_method_is_supported(consensus_method)) {
  462.     log_info(LD_DIR, "Generating consensus using method %d.",
  463.              consensus_method);
  464.   } else {
  465.     log_warn(LD_DIR, "The other authorities will use consensus method %d, "
  466.              "which I don't support.  Maybe I should upgrade!",
  467.              consensus_method);
  468.     consensus_method = 1;
  469.   }
  470.   /* Compute medians of time-related things, and figure out how many
  471.    * routers we might need to talk about. */
  472.   {
  473.     int n_votes = smartlist_len(votes);
  474.     time_t *va_times = tor_malloc(n_votes * sizeof(time_t));
  475.     time_t *fu_times = tor_malloc(n_votes * sizeof(time_t));
  476.     time_t *vu_times = tor_malloc(n_votes * sizeof(time_t));
  477.     int *votesec_list = tor_malloc(n_votes * sizeof(int));
  478.     int *distsec_list = tor_malloc(n_votes * sizeof(int));
  479.     int n_versioning_clients = 0, n_versioning_servers = 0;
  480.     smartlist_t *combined_client_versions = smartlist_create();
  481.     smartlist_t *combined_server_versions = smartlist_create();
  482.     SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) {
  483.       tor_assert(v->type == NS_TYPE_VOTE);
  484.       va_times[v_sl_idx] = v->valid_after;
  485.       fu_times[v_sl_idx] = v->fresh_until;
  486.       vu_times[v_sl_idx] = v->valid_until;
  487.       votesec_list[v_sl_idx] = v->vote_seconds;
  488.       distsec_list[v_sl_idx] = v->dist_seconds;
  489.       if (v->client_versions) {
  490.         smartlist_t *cv = smartlist_create();
  491.         ++n_versioning_clients;
  492.         smartlist_split_string(cv, v->client_versions, ",",
  493.                                SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  494.         sort_version_list(cv, 1);
  495.         smartlist_add_all(combined_client_versions, cv);
  496.         smartlist_free(cv); /* elements get freed later. */
  497.       }
  498.       if (v->server_versions) {
  499.         smartlist_t *sv = smartlist_create();
  500.         ++n_versioning_servers;
  501.         smartlist_split_string(sv, v->server_versions, ",",
  502.                                SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  503.         sort_version_list(sv, 1);
  504.         smartlist_add_all(combined_server_versions, sv);
  505.         smartlist_free(sv); /* elements get freed later. */
  506.       }
  507.       SMARTLIST_FOREACH(v->known_flags, const char *, cp,
  508.                         smartlist_add(flags, tor_strdup(cp)));
  509.     } SMARTLIST_FOREACH_END(v);
  510.     valid_after = median_time(va_times, n_votes);
  511.     fresh_until = median_time(fu_times, n_votes);
  512.     valid_until = median_time(vu_times, n_votes);
  513.     vote_seconds = median_int(votesec_list, n_votes);
  514.     dist_seconds = median_int(distsec_list, n_votes);
  515.     tor_assert(valid_after+MIN_VOTE_INTERVAL <= fresh_until);
  516.     tor_assert(fresh_until+MIN_VOTE_INTERVAL <= valid_until);
  517.     tor_assert(vote_seconds >= MIN_VOTE_SECONDS);
  518.     tor_assert(dist_seconds >= MIN_DIST_SECONDS);
  519.     server_versions = compute_consensus_versions_list(combined_server_versions,
  520.                                                       n_versioning_servers);
  521.     client_versions = compute_consensus_versions_list(combined_client_versions,
  522.                                                       n_versioning_clients);
  523.     SMARTLIST_FOREACH(combined_server_versions, char *, cp, tor_free(cp));
  524.     SMARTLIST_FOREACH(combined_client_versions, char *, cp, tor_free(cp));
  525.     smartlist_free(combined_server_versions);
  526.     smartlist_free(combined_client_versions);
  527.     smartlist_sort_strings(flags);
  528.     smartlist_uniq_strings(flags);
  529.     tor_free(va_times);
  530.     tor_free(fu_times);
  531.     tor_free(vu_times);
  532.     tor_free(votesec_list);
  533.     tor_free(distsec_list);
  534.   }
  535.   chunks = smartlist_create();
  536.   {
  537.     char buf[1024];
  538.     char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
  539.       vu_buf[ISO_TIME_LEN+1];
  540.     char *flaglist;
  541.     format_iso_time(va_buf, valid_after);
  542.     format_iso_time(fu_buf, fresh_until);
  543.     format_iso_time(vu_buf, valid_until);
  544.     flaglist = smartlist_join_strings(flags, " ", 0, NULL);
  545.     smartlist_add(chunks, tor_strdup("network-status-version 3n"
  546.                                      "vote-status consensusn"));
  547.     if (consensus_method >= 2) {
  548.       tor_snprintf(buf, sizeof(buf), "consensus-method %dn",
  549.                    consensus_method);
  550.       smartlist_add(chunks, tor_strdup(buf));
  551.     }
  552.     tor_snprintf(buf, sizeof(buf),
  553.                  "valid-after %sn"
  554.                  "fresh-until %sn"
  555.                  "valid-until %sn"
  556.                  "voting-delay %d %dn"
  557.                  "client-versions %sn"
  558.                  "server-versions %sn"
  559.                  "known-flags %sn",
  560.                  va_buf, fu_buf, vu_buf,
  561.                  vote_seconds, dist_seconds,
  562.                  client_versions, server_versions, flaglist);
  563.     smartlist_add(chunks, tor_strdup(buf));
  564.     tor_free(flaglist);
  565.   }
  566.   /* Sort the votes. */
  567.   smartlist_sort(votes, _compare_votes_by_authority_id);
  568.   /* Add the authority sections. */
  569.   {
  570.     smartlist_t *dir_sources = smartlist_create();
  571.     SMARTLIST_FOREACH(votes, networkstatus_t *, v,
  572.     {
  573.       dir_src_ent_t *e = tor_malloc_zero(sizeof(dir_src_ent_t));
  574.       e->v = v;
  575.       e->digest = get_voter(v)->identity_digest;
  576.       e->is_legacy = 0;
  577.       smartlist_add(dir_sources, e);
  578.       if (consensus_method >= 3 &&
  579.           !tor_digest_is_zero(get_voter(v)->legacy_id_digest)) {
  580.         dir_src_ent_t *e_legacy = tor_malloc_zero(sizeof(dir_src_ent_t));
  581.         e_legacy->v = v;
  582.         e_legacy->digest = get_voter(v)->legacy_id_digest;
  583.         e_legacy->is_legacy = 1;
  584.         smartlist_add(dir_sources, e_legacy);
  585.       }
  586.     });
  587.     smartlist_sort(dir_sources, _compare_dir_src_ents_by_authority_id);
  588.     SMARTLIST_FOREACH(dir_sources, const dir_src_ent_t *, e,
  589.     {
  590.       char buf[1024];
  591.       struct in_addr in;
  592.       char ip[INET_NTOA_BUF_LEN];
  593.       char fingerprint[HEX_DIGEST_LEN+1];
  594.       char votedigest[HEX_DIGEST_LEN+1];
  595.       networkstatus_t *v = e->v;
  596.       networkstatus_voter_info_t *voter = get_voter(v);
  597.       if (e->is_legacy)
  598.         tor_assert(consensus_method >= 2);
  599.       in.s_addr = htonl(voter->addr);
  600.       tor_inet_ntoa(&in, ip, sizeof(ip));
  601.       base16_encode(fingerprint, sizeof(fingerprint), e->digest, DIGEST_LEN);
  602.       base16_encode(votedigest, sizeof(votedigest), voter->vote_digest,
  603.                     DIGEST_LEN);
  604.       tor_snprintf(buf, sizeof(buf),
  605.                    "dir-source %s%s %s %s %s %d %dn",
  606.                    voter->nickname, e->is_legacy ? "-legacy" : "",
  607.                    fingerprint, voter->address, ip,
  608.                    voter->dir_port,
  609.                    voter->or_port);
  610.       smartlist_add(chunks, tor_strdup(buf));
  611.       if (! e->is_legacy) {
  612.         tor_snprintf(buf, sizeof(buf),
  613.                      "contact %sn"
  614.                      "vote-digest %sn",
  615.                      voter->contact,
  616.                      votedigest);
  617.         smartlist_add(chunks, tor_strdup(buf));
  618.       }
  619.     });
  620.     SMARTLIST_FOREACH(dir_sources, dir_src_ent_t *, e, tor_free(e));
  621.     smartlist_free(dir_sources);
  622.   }
  623.   /* Add the actual router entries. */
  624.   {
  625.     int *index; /* index[j] is the current index into votes[j]. */
  626.     int *size; /* size[j] is the number of routerstatuses in votes[j]. */
  627.     int *flag_counts; /* The number of voters that list flag[j] for the
  628.                        * currently considered router. */
  629.     int i;
  630.     smartlist_t *matching_descs = smartlist_create();
  631.     smartlist_t *chosen_flags = smartlist_create();
  632.     smartlist_t *versions = smartlist_create();
  633.     smartlist_t *exitsummaries = smartlist_create();
  634.     uint32_t *bandwidths = tor_malloc(sizeof(uint32_t) * smartlist_len(votes));
  635.     int num_bandwidths;
  636.     int *n_voter_flags; /* n_voter_flags[j] is the number of flags that
  637.                          * votes[j] knows about. */
  638.     int *n_flag_voters; /* n_flag_voters[f] is the number of votes that care
  639.                          * about flags[f]. */
  640.     int **flag_map; /* flag_map[j][b] is an index f such that flag_map[f]
  641.                      * is the same flag as votes[j]->known_flags[b]. */
  642.     int *named_flag; /* Index of the flag "Named" for votes[j] */
  643.     int *unnamed_flag; /* Index of the flag "Unnamed" for votes[j] */
  644.     int chosen_named_idx, chosen_unnamed_idx;
  645.     strmap_t *name_to_id_map = strmap_new();
  646.     char conflict[DIGEST_LEN];
  647.     char unknown[DIGEST_LEN];
  648.     memset(conflict, 0, sizeof(conflict));
  649.     memset(unknown, 0xff, sizeof(conflict));
  650.     index = tor_malloc_zero(sizeof(int)*smartlist_len(votes));
  651.     size = tor_malloc_zero(sizeof(int)*smartlist_len(votes));
  652.     n_voter_flags = tor_malloc_zero(sizeof(int) * smartlist_len(votes));
  653.     n_flag_voters = tor_malloc_zero(sizeof(int) * smartlist_len(flags));
  654.     flag_map = tor_malloc_zero(sizeof(int*) * smartlist_len(votes));
  655.     named_flag = tor_malloc_zero(sizeof(int) * smartlist_len(votes));
  656.     unnamed_flag = tor_malloc_zero(sizeof(int) * smartlist_len(votes));
  657.     for (i = 0; i < smartlist_len(votes); ++i)
  658.       unnamed_flag[i] = named_flag[i] = -1;
  659.     chosen_named_idx = smartlist_string_pos(flags, "Named");
  660.     chosen_unnamed_idx = smartlist_string_pos(flags, "Unnamed");
  661.     /* Build the flag index. */
  662.     SMARTLIST_FOREACH(votes, networkstatus_t *, v,
  663.     {
  664.       flag_map[v_sl_idx] = tor_malloc_zero(
  665.                            sizeof(int)*smartlist_len(v->known_flags));
  666.       SMARTLIST_FOREACH(v->known_flags, const char *, fl,
  667.       {
  668.         int p = smartlist_string_pos(flags, fl);
  669.         tor_assert(p >= 0);
  670.         flag_map[v_sl_idx][fl_sl_idx] = p;
  671.         ++n_flag_voters[p];
  672.         if (!strcmp(fl, "Named"))
  673.           named_flag[v_sl_idx] = fl_sl_idx;
  674.         if (!strcmp(fl, "Unnamed"))
  675.           unnamed_flag[v_sl_idx] = fl_sl_idx;
  676.       });
  677.       n_voter_flags[v_sl_idx] = smartlist_len(v->known_flags);
  678.       size[v_sl_idx] = smartlist_len(v->routerstatus_list);
  679.     });
  680.     /* Named and Unnamed get treated specially */
  681.     if (consensus_method >= 2) {
  682.       SMARTLIST_FOREACH(votes, networkstatus_t *, v,
  683.       {
  684.         uint64_t nf;
  685.         if (named_flag[v_sl_idx]<0)
  686.           continue;
  687.         nf = U64_LITERAL(1) << named_flag[v_sl_idx];
  688.         SMARTLIST_FOREACH(v->routerstatus_list, vote_routerstatus_t *, rs,
  689.         {
  690.           if ((rs->flags & nf) != 0) {
  691.             const char *d = strmap_get_lc(name_to_id_map, rs->status.nickname);
  692.             if (!d) {
  693.               /* We have no name officially mapped to this digest. */
  694.               strmap_set_lc(name_to_id_map, rs->status.nickname,
  695.                             rs->status.identity_digest);
  696.             } else if (d != conflict &&
  697.                 memcmp(d, rs->status.identity_digest, DIGEST_LEN)) {
  698.               /* Authorities disagree about this nickname. */
  699.               strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
  700.             } else {
  701.               /* It's already a conflict, or it's already this ID. */
  702.             }
  703.           }
  704.         });
  705.       });
  706.       SMARTLIST_FOREACH(votes, networkstatus_t *, v,
  707.       {
  708.         uint64_t uf;
  709.         if (unnamed_flag[v_sl_idx]<0)
  710.           continue;
  711.         uf = U64_LITERAL(1) << unnamed_flag[v_sl_idx];
  712.         SMARTLIST_FOREACH(v->routerstatus_list, vote_routerstatus_t *, rs,
  713.         {
  714.           if ((rs->flags & uf) != 0) {
  715.             const char *d = strmap_get_lc(name_to_id_map, rs->status.nickname);
  716.             if (d == conflict || d == unknown) {
  717.               /* Leave it alone; we know what it is. */
  718.             } else if (!d) {
  719.               /* We have no name officially mapped to this digest. */
  720.               strmap_set_lc(name_to_id_map, rs->status.nickname, unknown);
  721.             } else if (!memcmp(d, rs->status.identity_digest, DIGEST_LEN)) {
  722.               /* Authorities disagree about this nickname. */
  723.               strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
  724.             } else {
  725.               /* It's mapped to a different name. */
  726.             }
  727.           }
  728.         });
  729.       });
  730.     }
  731.     /* Now go through all the votes */
  732.     flag_counts = tor_malloc(sizeof(int) * smartlist_len(flags));
  733.     while (1) {
  734.       vote_routerstatus_t *rs;
  735.       routerstatus_t rs_out;
  736.       const char *lowest_id = NULL;
  737.       const char *chosen_version;
  738.       const char *chosen_name = NULL;
  739.       int exitsummary_disagreement = 0;
  740.       int is_named = 0, is_unnamed = 0, is_running = 0;
  741.       int naming_conflict = 0;
  742.       int n_listing = 0;
  743.       int i;
  744.       char buf[256];
  745.       /* Of the next-to-be-considered digest in each voter, which is first? */
  746.       SMARTLIST_FOREACH(votes, networkstatus_t *, v, {
  747.         if (index[v_sl_idx] < size[v_sl_idx]) {
  748.           rs = smartlist_get(v->routerstatus_list, index[v_sl_idx]);
  749.           if (!lowest_id ||
  750.               memcmp(rs->status.identity_digest, lowest_id, DIGEST_LEN) < 0)
  751.             lowest_id = rs->status.identity_digest;
  752.         }
  753.       });
  754.       if (!lowest_id) /* we're out of routers. */
  755.         break;
  756.       memset(flag_counts, 0, sizeof(int)*smartlist_len(flags));
  757.       smartlist_clear(matching_descs);
  758.       smartlist_clear(chosen_flags);
  759.       smartlist_clear(versions);
  760.       num_bandwidths = 0;
  761.       /* Okay, go through all the entries for this digest. */
  762.       SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) {
  763.         if (index[v_sl_idx] >= size[v_sl_idx])
  764.           continue; /* out of entries. */
  765.         rs = smartlist_get(v->routerstatus_list, index[v_sl_idx]);
  766.         if (memcmp(rs->status.identity_digest, lowest_id, DIGEST_LEN))
  767.           continue; /* doesn't include this router. */
  768.         /* At this point, we know that we're looking at a routerstatus with
  769.          * identity "lowest".
  770.          */
  771.         ++index[v_sl_idx];
  772.         ++n_listing;
  773.         smartlist_add(matching_descs, rs);
  774.         if (rs->version && rs->version[0])
  775.           smartlist_add(versions, rs->version);
  776.         /* Tally up all the flags. */
  777.         for (i = 0; i < n_voter_flags[v_sl_idx]; ++i) {
  778.           if (rs->flags & (U64_LITERAL(1) << i))
  779.             ++flag_counts[flag_map[v_sl_idx][i]];
  780.         }
  781.         if (rs->flags & (U64_LITERAL(1) << named_flag[v_sl_idx])) {
  782.           if (chosen_name && strcmp(chosen_name, rs->status.nickname)) {
  783.             log_notice(LD_DIR, "Conflict on naming for router: %s vs %s",
  784.                        chosen_name, rs->status.nickname);
  785.             naming_conflict = 1;
  786.           }
  787.           chosen_name = rs->status.nickname;
  788.         }
  789.         /* count bandwidths */
  790.         if (rs->status.has_bandwidth)
  791.           bandwidths[num_bandwidths++] = rs->status.bandwidth;
  792.       } SMARTLIST_FOREACH_END(v);
  793.       /* We don't include this router at all unless more than half of
  794.        * the authorities we believe in list it. */
  795.       if (n_listing <= total_authorities/2)
  796.         continue;
  797.       /* Figure out the most popular opinion of what the most recent
  798.        * routerinfo and its contents are. */
  799.       rs = compute_routerstatus_consensus(matching_descs);
  800.       /* Copy bits of that into rs_out. */
  801.       tor_assert(!memcmp(lowest_id, rs->status.identity_digest, DIGEST_LEN));
  802.       memcpy(rs_out.identity_digest, lowest_id, DIGEST_LEN);
  803.       memcpy(rs_out.descriptor_digest, rs->status.descriptor_digest,
  804.              DIGEST_LEN);
  805.       rs_out.addr = rs->status.addr;
  806.       rs_out.published_on = rs->status.published_on;
  807.       rs_out.dir_port = rs->status.dir_port;
  808.       rs_out.or_port = rs->status.or_port;
  809.       rs_out.has_bandwidth = 0;
  810.       rs_out.has_exitsummary = 0;
  811.       if (chosen_name && !naming_conflict) {
  812.         strlcpy(rs_out.nickname, chosen_name, sizeof(rs_out.nickname));
  813.       } else {
  814.         strlcpy(rs_out.nickname, rs->status.nickname, sizeof(rs_out.nickname));
  815.       }
  816.       if (consensus_method == 1) {
  817.         is_named = chosen_named_idx >= 0 &&
  818.           (!naming_conflict && flag_counts[chosen_named_idx]);
  819.       } else {
  820.         const char *d = strmap_get_lc(name_to_id_map, rs_out.nickname);
  821.         if (!d) {
  822.           is_named = is_unnamed = 0;
  823.         } else if (!memcmp(d, lowest_id, DIGEST_LEN)) {
  824.           is_named = 1; is_unnamed = 0;
  825.         } else {
  826.           is_named = 0; is_unnamed = 1;
  827.         }
  828.       }
  829.       /* Set the flags. */
  830.       smartlist_add(chosen_flags, (char*)"s"); /* for the start of the line. */
  831.       SMARTLIST_FOREACH(flags, const char *, fl,
  832.       {
  833.         if (!strcmp(fl, "Named")) {
  834.           if (is_named)
  835.             smartlist_add(chosen_flags, (char*)fl);
  836.         } else if (!strcmp(fl, "Unnamed") && consensus_method >= 2) {
  837.           if (is_unnamed)
  838.             smartlist_add(chosen_flags, (char*)fl);
  839.         } else {
  840.           if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2) {
  841.             smartlist_add(chosen_flags, (char*)fl);
  842.             if (!strcmp(fl, "Running"))
  843.               is_running = 1;
  844.           }
  845.         }
  846.       });
  847.       /* Starting with consensus method 4 we do not list servers
  848.        * that are not running in a consensus.  See Proposal 138 */
  849.       if (consensus_method >= 4 && !is_running)
  850.         continue;
  851.       /* Pick the version. */
  852.       if (smartlist_len(versions)) {
  853.         sort_version_list(versions, 0);
  854.         chosen_version = get_most_frequent_member(versions);
  855.       } else {
  856.         chosen_version = NULL;
  857.       }
  858.       /* Pick a bandwidth */
  859.       if (consensus_method >= 5 && num_bandwidths > 0) {
  860.         rs_out.has_bandwidth = 1;
  861.         rs_out.bandwidth = median_uint32(bandwidths, num_bandwidths);
  862.       }
  863.       /* Ok, we already picked a descriptor digest we want to list
  864.        * previously.  Now we want to use the exit policy summary from
  865.        * that descriptor.  If everybody plays nice all the voters who
  866.        * listed that descriptor will have the same summary.  If not then
  867.        * something is fishy and we'll use the most common one (breaking
  868.        * ties in favor of lexicographically larger one (only because it
  869.        * lets me reuse more existing code.
  870.        *
  871.        * The other case that can happen is that no authority that voted
  872.        * for that descriptor has an exit policy summary.  That's
  873.        * probably quite unlikely but can happen.  In that case we use
  874.        * the policy that was most often listed in votes, again breaking
  875.        * ties like in the previous case.
  876.        */
  877.       if (consensus_method >= 5) {
  878.         /* Okay, go through all the votes for this router.  We prepared
  879.          * that list previously */
  880.         const char *chosen_exitsummary = NULL;
  881.         smartlist_clear(exitsummaries);
  882.         SMARTLIST_FOREACH(matching_descs, vote_routerstatus_t *, vsr, {
  883.           /* Check if the vote where this status comes from had the
  884.            * proper descriptor */
  885.           tor_assert(!memcmp(rs_out.identity_digest,
  886.                              vsr->status.identity_digest,
  887.                              DIGEST_LEN));
  888.           if (vsr->status.has_exitsummary &&
  889.                !memcmp(rs_out.descriptor_digest,
  890.                        vsr->status.descriptor_digest,
  891.                        DIGEST_LEN)) {
  892.             tor_assert(vsr->status.exitsummary);
  893.             smartlist_add(exitsummaries, vsr->status.exitsummary);
  894.             if (!chosen_exitsummary) {
  895.               chosen_exitsummary = vsr->status.exitsummary;
  896.             } else if (strcmp(chosen_exitsummary, vsr->status.exitsummary)) {
  897.               /* Great.  There's disagreement among the voters.  That
  898.                * really shouldn't be */
  899.               exitsummary_disagreement = 1;
  900.             }
  901.           }
  902.         });
  903.         if (exitsummary_disagreement) {
  904.           char id[HEX_DIGEST_LEN+1];
  905.           char dd[HEX_DIGEST_LEN+1];
  906.           base16_encode(id, sizeof(dd), rs_out.identity_digest, DIGEST_LEN);
  907.           base16_encode(dd, sizeof(dd), rs_out.descriptor_digest, DIGEST_LEN);
  908.           log_warn(LD_DIR, "The voters disagreed on the exit policy summary "
  909.                    " for router %s with descriptor %s.  This really shouldn't"
  910.                    " have happened.", id, dd);
  911.           smartlist_sort_strings(exitsummaries);
  912.           chosen_exitsummary = get_most_frequent_member(exitsummaries);
  913.         } else if (!chosen_exitsummary) {
  914.           char id[HEX_DIGEST_LEN+1];
  915.           char dd[HEX_DIGEST_LEN+1];
  916.           base16_encode(id, sizeof(dd), rs_out.identity_digest, DIGEST_LEN);
  917.           base16_encode(dd, sizeof(dd), rs_out.descriptor_digest, DIGEST_LEN);
  918.           log_warn(LD_DIR, "Not one of the voters that made us select"
  919.                    "descriptor %s for router %s had an exit policy"
  920.                    "summary", dd, id);
  921.           /* Ok, none of those voting for the digest we chose had an
  922.            * exit policy for us.  Well, that kinda sucks.
  923.            */
  924.           smartlist_clear(exitsummaries);
  925.           SMARTLIST_FOREACH(matching_descs, vote_routerstatus_t *, vsr, {
  926.             if (vsr->status.has_exitsummary)
  927.               smartlist_add(exitsummaries, vsr->status.exitsummary);
  928.           });
  929.           smartlist_sort_strings(exitsummaries);
  930.           chosen_exitsummary = get_most_frequent_member(exitsummaries);
  931.           if (!chosen_exitsummary)
  932.             log_warn(LD_DIR, "Wow, not one of the voters had an exit "
  933.                      "policy summary for %s.  Wow.", id);
  934.         }
  935.         if (chosen_exitsummary) {
  936.           rs_out.has_exitsummary = 1;
  937.           /* yea, discards the const */
  938.           rs_out.exitsummary = (char *)chosen_exitsummary;
  939.         }
  940.       }
  941.       /* Okay!! Now we can write the descriptor... */
  942.       /*     First line goes into "buf". */
  943.       routerstatus_format_entry(buf, sizeof(buf), &rs_out, NULL, 1, 0);
  944.       smartlist_add(chunks, tor_strdup(buf));
  945.       /*     Second line is all flags.  The "n" is missing. */
  946.       smartlist_add(chunks,
  947.                     smartlist_join_strings(chosen_flags, " ", 0, NULL));
  948.       /*     Now the version line. */
  949.       if (chosen_version) {
  950.         smartlist_add(chunks, tor_strdup("nv "));
  951.         smartlist_add(chunks, tor_strdup(chosen_version));
  952.       }
  953.       smartlist_add(chunks, tor_strdup("n"));
  954.       /*     Now the weight line. */
  955.       if (rs_out.has_bandwidth) {
  956.         int r = tor_snprintf(buf, sizeof(buf),
  957.                              "w Bandwidth=%dn", rs_out.bandwidth);
  958.         if (r<0) {
  959.           log_warn(LD_BUG, "Not enough space in buffer for weight line.");
  960.           *buf = '';
  961.         }
  962.         smartlist_add(chunks, tor_strdup(buf));
  963.       };
  964.       /*     Now the exitpolicy summary line. */
  965.       if (rs_out.has_exitsummary) {
  966.         char buf[MAX_POLICY_LINE_LEN+1];
  967.         int r = tor_snprintf(buf, sizeof(buf), "p %sn", rs_out.exitsummary);
  968.         if (r<0) {
  969.           log_warn(LD_BUG, "Not enough space in buffer for exitpolicy line.");
  970.           *buf = '';
  971.         }
  972.         smartlist_add(chunks, tor_strdup(buf));
  973.       };
  974.       /* And the loop is over and we move on to the next router */
  975.     }
  976.     tor_free(index);
  977.     tor_free(size);
  978.     tor_free(n_voter_flags);
  979.     tor_free(n_flag_voters);
  980.     for (i = 0; i < smartlist_len(votes); ++i)
  981.       tor_free(flag_map[i]);
  982.     tor_free(flag_map);
  983.     tor_free(flag_counts);
  984.     tor_free(named_flag);
  985.     tor_free(unnamed_flag);
  986.     strmap_free(name_to_id_map, NULL);
  987.     smartlist_free(matching_descs);
  988.     smartlist_free(chosen_flags);
  989.     smartlist_free(versions);
  990.     smartlist_free(exitsummaries);
  991.     tor_free(bandwidths);
  992.   }
  993.   /* Add a signature. */
  994.   {
  995.     char digest[DIGEST_LEN];
  996.     char fingerprint[HEX_DIGEST_LEN+1];
  997.     char signing_key_fingerprint[HEX_DIGEST_LEN+1];
  998.     char buf[4096];
  999.     smartlist_add(chunks, tor_strdup("directory-signature "));
  1000.     /* Compute the hash of the chunks. */
  1001.     hash_list_members(digest, chunks);
  1002.     /* Get the fingerprints */
  1003.     crypto_pk_get_fingerprint(identity_key, fingerprint, 0);
  1004.     crypto_pk_get_fingerprint(signing_key, signing_key_fingerprint, 0);
  1005.     /* add the junk that will go at the end of the line. */
  1006.     tor_snprintf(buf, sizeof(buf), "%s %sn", fingerprint,
  1007.                  signing_key_fingerprint);
  1008.     /* And the signature. */
  1009.     if (router_append_dirobj_signature(buf, sizeof(buf), digest,
  1010.                                        signing_key)) {
  1011.       log_warn(LD_BUG, "Couldn't sign consensus networkstatus.");
  1012.       return NULL; /* This leaks, but it should never happen. */
  1013.     }
  1014.     smartlist_add(chunks, tor_strdup(buf));
  1015.     if (legacy_id_key_digest && legacy_signing_key && consensus_method >= 3) {
  1016.       smartlist_add(chunks, tor_strdup("directory-signature "));
  1017.       base16_encode(fingerprint, sizeof(fingerprint),
  1018.                     legacy_id_key_digest, DIGEST_LEN);
  1019.       crypto_pk_get_fingerprint(legacy_signing_key,
  1020.                                 signing_key_fingerprint, 0);
  1021.       tor_snprintf(buf, sizeof(buf), "%s %sn", fingerprint,
  1022.                    signing_key_fingerprint);
  1023.       if (router_append_dirobj_signature(buf, sizeof(buf), digest,
  1024.                                          legacy_signing_key)) {
  1025.         log_warn(LD_BUG, "Couldn't sign consensus networkstatus.");
  1026.         return NULL; /* This leaks, but it should never happen. */
  1027.       }
  1028.       smartlist_add(chunks, tor_strdup(buf));
  1029.     }
  1030.   }
  1031.   result = smartlist_join_strings(chunks, "", 0, NULL);
  1032.   tor_free(client_versions);
  1033.   tor_free(server_versions);
  1034.   SMARTLIST_FOREACH(flags, char *, cp, tor_free(cp));
  1035.   smartlist_free(flags);
  1036.   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
  1037.   smartlist_free(chunks);
  1038.   {
  1039.     networkstatus_t *c;
  1040.     if (!(c = networkstatus_parse_vote_from_string(result, NULL,
  1041.                                                    NS_TYPE_CONSENSUS))) {
  1042.       log_err(LD_BUG,"Generated a networkstatus consensus we couldn't "
  1043.               "parse.");
  1044.       tor_free(result);
  1045.       return NULL;
  1046.     }
  1047.     networkstatus_vote_free(c);
  1048.   }
  1049.   return result;
  1050. }
  1051. /** Given a consensus vote <b>target</b> and a set of detached signatures in
  1052.  * <b>sigs</b> that correspond to the same consensus, check whether there are
  1053.  * any new signatures in <b>src_voter_list</b> that should be added to
  1054.  * <b>target</b>. (A signature should be added if we have no signature for that
  1055.  * voter in <b>target</b> yet, or if we have no verifiable signature and the
  1056.  * new signature is verifiable.)  Return the number of signatures added or
  1057.  * changed, or -1 if the document signed by <b>sigs</b> isn't the same
  1058.  * document as <b>target</b>. */
  1059. int
  1060. networkstatus_add_detached_signatures(networkstatus_t *target,
  1061.                                       ns_detached_signatures_t *sigs,
  1062.                                       const char **msg_out)
  1063. {
  1064.   int r = 0;
  1065.   tor_assert(sigs);
  1066.   tor_assert(target);
  1067.   tor_assert(target->type == NS_TYPE_CONSENSUS);
  1068.   /* Do the times seem right? */
  1069.   if (target->valid_after != sigs->valid_after) {
  1070.     *msg_out = "Valid-After times do not match "
  1071.       "when adding detached signatures to consensus";
  1072.     return -1;
  1073.   }
  1074.   if (target->fresh_until != sigs->fresh_until) {
  1075.     *msg_out = "Fresh-until times do not match "
  1076.       "when adding detached signatures to consensus";
  1077.     return -1;
  1078.   }
  1079.   if (target->valid_until != sigs->valid_until) {
  1080.     *msg_out = "Valid-until times do not match "
  1081.       "when adding detached signatures to consensus";
  1082.     return -1;
  1083.   }
  1084.   /* Are they the same consensus? */
  1085.   if (memcmp(target->networkstatus_digest, sigs->networkstatus_digest,
  1086.              DIGEST_LEN)) {
  1087.     *msg_out = "Digest mismatch when adding detached signatures to consensus";
  1088.     return -1;
  1089.   }
  1090.   /* For each voter in src... */
  1091.   SMARTLIST_FOREACH_BEGIN(sigs->signatures, networkstatus_voter_info_t *,
  1092.                           src_voter) {
  1093.       char voter_identity[HEX_DIGEST_LEN+1];
  1094.       networkstatus_voter_info_t *target_voter =
  1095.         networkstatus_get_voter_by_id(target, src_voter->identity_digest);
  1096.       authority_cert_t *cert = NULL;
  1097.       base16_encode(voter_identity, sizeof(voter_identity),
  1098.                     src_voter->identity_digest, DIGEST_LEN);
  1099.       log_info(LD_DIR, "Looking at signature from %s", voter_identity);
  1100.       /* If the target doesn't know about this voter, then forget it. */
  1101.       if (!target_voter) {
  1102.         log_info(LD_DIR, "We do not know about %s", voter_identity);
  1103.         continue;
  1104.       }
  1105.       /* If the target already has a good signature from this voter, then skip
  1106.        * this one. */
  1107.       if (target_voter->good_signature) {
  1108.         log_info(LD_DIR, "We already have a good signature from %s",
  1109.                          voter_identity);
  1110.         continue;
  1111.       }
  1112.       /* Try checking the signature if we haven't already. */
  1113.       if (!src_voter->good_signature && !src_voter->bad_signature) {
  1114.         cert = authority_cert_get_by_digests(src_voter->identity_digest,
  1115.                                              src_voter->signing_key_digest);
  1116.         if (cert) {
  1117.           networkstatus_check_voter_signature(target, src_voter, cert);
  1118.         }
  1119.       }
  1120.       /* If this signature is good, or we don't have any signature yet,
  1121.        * then add it. */
  1122.       if (src_voter->good_signature || !target_voter->signature) {
  1123.         log_info(LD_DIR, "Adding signature from %s", voter_identity);
  1124.         ++r;
  1125.         tor_free(target_voter->signature);
  1126.         target_voter->signature =
  1127.           tor_memdup(src_voter->signature, src_voter->signature_len);
  1128.         memcpy(target_voter->signing_key_digest, src_voter->signing_key_digest,
  1129.                DIGEST_LEN);
  1130.         target_voter->signature_len = src_voter->signature_len;
  1131.         target_voter->good_signature = src_voter->good_signature;
  1132.         target_voter->bad_signature = src_voter->bad_signature;
  1133.       } else {
  1134.         log_info(LD_DIR, "Not adding signature from %s", voter_identity);
  1135.       }
  1136.   } SMARTLIST_FOREACH_END(src_voter);
  1137.   return r;
  1138. }
  1139. /** Return a newly allocated string holding the detached-signatures document
  1140.  * corresponding to the signatures on <b>consensus</b>. */
  1141. char *
  1142. networkstatus_get_detached_signatures(networkstatus_t *consensus)
  1143. {
  1144.   smartlist_t *elements;
  1145.   char buf[4096];
  1146.   char *result = NULL;
  1147.   int n_sigs = 0;
  1148.   tor_assert(consensus);
  1149.   tor_assert(consensus->type == NS_TYPE_CONSENSUS);
  1150.   elements = smartlist_create();
  1151.   {
  1152.     char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
  1153.       vu_buf[ISO_TIME_LEN+1];
  1154.     char d[HEX_DIGEST_LEN+1];
  1155.     base16_encode(d, sizeof(d), consensus->networkstatus_digest, DIGEST_LEN);
  1156.     format_iso_time(va_buf, consensus->valid_after);
  1157.     format_iso_time(fu_buf, consensus->fresh_until);
  1158.     format_iso_time(vu_buf, consensus->valid_until);
  1159.     tor_snprintf(buf, sizeof(buf),
  1160.                  "consensus-digest %sn"
  1161.                  "valid-after %sn"
  1162.                  "fresh-until %sn"
  1163.                  "valid-until %sn", d, va_buf, fu_buf, vu_buf);
  1164.     smartlist_add(elements, tor_strdup(buf));
  1165.   }
  1166.   SMARTLIST_FOREACH(consensus->voters, networkstatus_voter_info_t *, v,
  1167.     {
  1168.       char sk[HEX_DIGEST_LEN+1];
  1169.       char id[HEX_DIGEST_LEN+1];
  1170.       if (!v->signature || v->bad_signature)
  1171.         continue;
  1172.       ++n_sigs;
  1173.       base16_encode(sk, sizeof(sk), v->signing_key_digest, DIGEST_LEN);
  1174.       base16_encode(id, sizeof(id), v->identity_digest, DIGEST_LEN);
  1175.       tor_snprintf(buf, sizeof(buf),
  1176.                    "directory-signature %s %sn-----BEGIN SIGNATURE-----n",
  1177.                    id, sk);
  1178.       smartlist_add(elements, tor_strdup(buf));
  1179.       base64_encode(buf, sizeof(buf), v->signature, v->signature_len);
  1180.       strlcat(buf, "-----END SIGNATURE-----n", sizeof(buf));
  1181.       smartlist_add(elements, tor_strdup(buf));
  1182.     });
  1183.   result = smartlist_join_strings(elements, "", 0, NULL);
  1184.   SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
  1185.   smartlist_free(elements);
  1186.   if (!n_sigs)
  1187.     tor_free(result);
  1188.   return result;
  1189. }
  1190. /** Release all storage held in <b>s</b>. */
  1191. void
  1192. ns_detached_signatures_free(ns_detached_signatures_t *s)
  1193. {
  1194.   if (s->signatures) {
  1195.     SMARTLIST_FOREACH(s->signatures, networkstatus_voter_info_t *, v,
  1196.       {
  1197.         tor_free(v->signature);
  1198.         tor_free(v);
  1199.       });
  1200.     smartlist_free(s->signatures);
  1201.   }
  1202.   tor_free(s);
  1203. }
  1204. /* =====
  1205.  * Certificate functions
  1206.  * ===== */
  1207. /** Allocate and return a new authority_cert_t with the same contents as
  1208.  * <b>cert</b>. */
  1209. authority_cert_t *
  1210. authority_cert_dup(authority_cert_t *cert)
  1211. {
  1212.   authority_cert_t *out = tor_malloc(sizeof(authority_cert_t));
  1213.   tor_assert(cert);
  1214.   memcpy(out, cert, sizeof(authority_cert_t));
  1215.   /* Now copy pointed-to things. */
  1216.   out->cache_info.signed_descriptor_body =
  1217.     tor_strndup(cert->cache_info.signed_descriptor_body,
  1218.                 cert->cache_info.signed_descriptor_len);
  1219.   out->cache_info.saved_location = SAVED_NOWHERE;
  1220.   out->identity_key = crypto_pk_dup_key(cert->identity_key);
  1221.   out->signing_key = crypto_pk_dup_key(cert->signing_key);
  1222.   return out;
  1223. }
  1224. /* =====
  1225.  * Vote scheduling
  1226.  * ===== */
  1227. /** Set *<b>timing_out</b> to the intervals at which we would like to vote.
  1228.  * Note that these aren't the intervals we'll use to vote; they're the ones
  1229.  * that we'll vote to use. */
  1230. void
  1231. dirvote_get_preferred_voting_intervals(vote_timing_t *timing_out)
  1232. {
  1233.   or_options_t *options = get_options();
  1234.   tor_assert(timing_out);
  1235.   timing_out->vote_interval = options->V3AuthVotingInterval;
  1236.   timing_out->n_intervals_valid = options->V3AuthNIntervalsValid;
  1237.   timing_out->vote_delay = options->V3AuthVoteDelay;
  1238.   timing_out->dist_delay = options->V3AuthDistDelay;
  1239. }
  1240. /** Return the start of the next interval of size <b>interval</b> (in seconds)
  1241.  * after <b>now</b>.  Midnight always starts a fresh interval, and if the last
  1242.  * interval of a day would be truncated to less than half its size, it is
  1243.  * rolled into the previous interval. */
  1244. time_t
  1245. dirvote_get_start_of_next_interval(time_t now, int interval)
  1246. {
  1247.   struct tm tm;
  1248.   time_t midnight_today;
  1249.   time_t midnight_tomorrow;
  1250.   time_t next;
  1251.   tor_gmtime_r(&now, &tm);
  1252.   tm.tm_hour = 0;
  1253.   tm.tm_min = 0;
  1254.   tm.tm_sec = 0;
  1255.   midnight_today = tor_timegm(&tm);
  1256.   midnight_tomorrow = midnight_today + (24*60*60);
  1257.   next = midnight_today + ((now-midnight_today)/interval + 1)*interval;
  1258.   /* Intervals never cross midnight. */
  1259.   if (next > midnight_tomorrow)
  1260.     next = midnight_tomorrow;
  1261.   /* If the interval would only last half as long as it's supposed to, then
  1262.    * skip over to the next day. */
  1263.   if (next + interval/2 > midnight_tomorrow)
  1264.     next = midnight_tomorrow;
  1265.   return next;
  1266. }
  1267. /** Scheduling information for a voting interval. */
  1268. static struct {
  1269.   /** When do we generate and distribute our vote for this interval? */
  1270.   time_t voting_starts;
  1271.   /** When do we send an HTTP request for any votes that we haven't
  1272.    * been posted yet?*/
  1273.   time_t fetch_missing_votes;
  1274.   /** When do we give up on getting more votes and generate a consensus? */
  1275.   time_t voting_ends;
  1276.   /** When do we send an HTTP request for any signatures we're expecting to
  1277.    * see on the consensus? */
  1278.   time_t fetch_missing_signatures;
  1279.   /** When do we publish the consensus? */
  1280.   time_t interval_starts;
  1281.   /* True iff we have generated and distributed our vote. */
  1282.   int have_voted;
  1283.   /* True iff we've requested missing votes. */
  1284.   int have_fetched_missing_votes;
  1285.   /* True iff we have built a consensus and sent the signatures around. */
  1286.   int have_built_consensus;
  1287.   /* True iff we've fetched missing signatures. */
  1288.   int have_fetched_missing_signatures;
  1289.   /* True iff we have published our consensus. */
  1290.   int have_published_consensus;
  1291. } voting_schedule = {0,0,0,0,0,0,0,0,0,0};
  1292. /** Set voting_schedule to hold the timing for the next vote we should be
  1293.  * doing. */
  1294. void
  1295. dirvote_recalculate_timing(or_options_t *options, time_t now)
  1296. {
  1297.   int interval, vote_delay, dist_delay;
  1298.   time_t start;
  1299.   time_t end;
  1300.   networkstatus_t *consensus;
  1301.   if (!authdir_mode_v3(options))
  1302.     return;
  1303.   consensus = networkstatus_get_live_consensus(now);
  1304.   memset(&voting_schedule, 0, sizeof(voting_schedule));
  1305.   if (consensus) {
  1306.     interval = (int)( consensus->fresh_until - consensus->valid_after );
  1307.     vote_delay = consensus->vote_seconds;
  1308.     dist_delay = consensus->dist_seconds;
  1309.   } else {
  1310.     interval = options->TestingV3AuthInitialVotingInterval;
  1311.     vote_delay = options->TestingV3AuthInitialVoteDelay;
  1312.     dist_delay = options->TestingV3AuthInitialDistDelay;
  1313.   }
  1314.   tor_assert(interval > 0);
  1315.   if (vote_delay + dist_delay > interval/2)
  1316.     vote_delay = dist_delay = interval / 4;
  1317.   start = voting_schedule.interval_starts =
  1318.     dirvote_get_start_of_next_interval(now,interval);
  1319.   end = dirvote_get_start_of_next_interval(start+1, interval);
  1320.   tor_assert(end > start);
  1321.   voting_schedule.fetch_missing_signatures = start - (dist_delay/2);
  1322.   voting_schedule.voting_ends = start - dist_delay;
  1323.   voting_schedule.fetch_missing_votes = start - dist_delay - (vote_delay/2);
  1324.   voting_schedule.voting_starts = start - dist_delay - vote_delay;
  1325.   {
  1326.     char tbuf[ISO_TIME_LEN+1];
  1327.     format_iso_time(tbuf, voting_schedule.interval_starts);
  1328.     log_notice(LD_DIR,"Choosing expected valid-after time as %s: "
  1329.                "consensus_set=%d, interval=%d",
  1330.                tbuf, consensus?1:0, interval);
  1331.   }
  1332. }
  1333. /** Entry point: Take whatever voting actions are pending as of <b>now</b>. */
  1334. void
  1335. dirvote_act(or_options_t *options, time_t now)
  1336. {
  1337.   if (!authdir_mode_v3(options))
  1338.     return;
  1339.   if (!voting_schedule.voting_starts) {
  1340.     char *keys = list_v3_auth_ids();
  1341.     authority_cert_t *c = get_my_v3_authority_cert();
  1342.     log_notice(LD_DIR, "Scheduling voting.  Known authority IDs are %s. "
  1343.                "Mine is %s.",
  1344.                keys, hex_str(c->cache_info.identity_digest, DIGEST_LEN));
  1345.     tor_free(keys);
  1346.     dirvote_recalculate_timing(options, now);
  1347.   }
  1348.   if (voting_schedule.voting_starts < now && !voting_schedule.have_voted) {
  1349.     log_notice(LD_DIR, "Time to vote.");
  1350.     dirvote_perform_vote();
  1351.     voting_schedule.have_voted = 1;
  1352.   }
  1353.   if (voting_schedule.fetch_missing_votes < now &&
  1354.       !voting_schedule.have_fetched_missing_votes) {
  1355.     log_notice(LD_DIR, "Time to fetch any votes that we're missing.");
  1356.     dirvote_fetch_missing_votes();
  1357.     voting_schedule.have_fetched_missing_votes = 1;
  1358.   }
  1359.   if (voting_schedule.voting_ends < now &&
  1360.       !voting_schedule.have_built_consensus) {
  1361.     log_notice(LD_DIR, "Time to compute a consensus.");
  1362.     dirvote_compute_consensus();
  1363.     /* XXXX We will want to try again later if we haven't got enough
  1364.      * votes yet.  Implement this if it turns out to ever happen. */
  1365.     voting_schedule.have_built_consensus = 1;
  1366.   }
  1367.   if (voting_schedule.fetch_missing_signatures < now &&
  1368.       !voting_schedule.have_fetched_missing_signatures) {
  1369.     log_notice(LD_DIR, "Time to fetch any signatures that we're missing.");
  1370.     dirvote_fetch_missing_signatures();
  1371.     voting_schedule.have_fetched_missing_signatures = 1;
  1372.   }
  1373.   if (voting_schedule.interval_starts < now &&
  1374.       !voting_schedule.have_published_consensus) {
  1375.     log_notice(LD_DIR, "Time to publish the consensus and discard old votes");
  1376.     dirvote_publish_consensus();
  1377.     dirvote_clear_votes(0);
  1378.     voting_schedule.have_published_consensus = 1;
  1379.     /* XXXX We will want to try again later if we haven't got enough
  1380.      * signatures yet.  Implement this if it turns out to ever happen. */
  1381.     dirvote_recalculate_timing(options, now);
  1382.   }
  1383. }
  1384. /** A vote networkstatus_t and its unparsed body: held around so we can
  1385.  * use it to generate a consensus (at voting_ends) and so we can serve it to
  1386.  * other authorities that might want it. */
  1387. typedef struct pending_vote_t {
  1388.   cached_dir_t *vote_body;
  1389.   networkstatus_t *vote;
  1390. } pending_vote_t;
  1391. /** List of pending_vote_t for the current vote.  Before we've used them to
  1392.  * build a consensus, the votes go here. */
  1393. static smartlist_t *pending_vote_list = NULL;
  1394. /** List of pending_vote_t for the previous vote.  After we've used them to
  1395.  * build a consensus, the votes go here for the next period. */
  1396. static smartlist_t *previous_vote_list = NULL;
  1397. /** The body of the consensus that we're currently building.  Once we
  1398.  * have it built, it goes into dirserv.c */
  1399. static char *pending_consensus_body = NULL;
  1400. /** The detached signatures for the consensus that we're currently
  1401.  * building. */
  1402. static char *pending_consensus_signatures = NULL;
  1403. /** The parsed in-progress consensus document. */
  1404. static networkstatus_t *pending_consensus = NULL;
  1405. /** List of ns_detached_signatures_t: hold signatures that get posted to us
  1406.  * before we have generated the consensus on our own. */
  1407. static smartlist_t *pending_consensus_signature_list = NULL;
  1408. /** Generate a networkstatus vote and post it to all the v3 authorities.
  1409.  * (V3 Authority only) */
  1410. static int
  1411. dirvote_perform_vote(void)
  1412. {
  1413.   crypto_pk_env_t *key = get_my_v3_authority_signing_key();
  1414.   authority_cert_t *cert = get_my_v3_authority_cert();
  1415.   networkstatus_t *ns;
  1416.   char *contents;
  1417.   pending_vote_t *pending_vote;
  1418.   time_t now = time(NULL);
  1419.   int status;
  1420.   const char *msg = "";
  1421.   if (!cert || !key) {
  1422.     log_warn(LD_NET, "Didn't find key/certificate to generate v3 vote");
  1423.     return -1;
  1424.   } else if (cert->expires < now) {
  1425.     log_warn(LD_NET, "Can't generate v3 vote with expired certificate");
  1426.     return -1;
  1427.   }
  1428.   if (!(ns = dirserv_generate_networkstatus_vote_obj(key, cert)))
  1429.     return -1;
  1430.   contents = format_networkstatus_vote(key, ns);
  1431.   networkstatus_vote_free(ns);
  1432.   if (!contents)
  1433.     return -1;
  1434.   pending_vote = dirvote_add_vote(contents, &msg, &status);
  1435.   tor_free(contents);
  1436.   if (!pending_vote) {
  1437.     log_warn(LD_DIR, "Couldn't store my own vote! (I told myself, '%s'.)",
  1438.              msg);
  1439.     return -1;
  1440.   }
  1441.   directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_VOTE,
  1442.                                ROUTER_PURPOSE_GENERAL,
  1443.                                V3_AUTHORITY,
  1444.                                pending_vote->vote_body->dir,
  1445.                                pending_vote->vote_body->dir_len, 0);
  1446.   log_notice(LD_DIR, "Vote posted.");
  1447.   return 0;
  1448. }
  1449. /** Send an HTTP request to every other v3 authority, for the votes of every
  1450.  * authority for which we haven't received a vote yet in this period. (V3
  1451.  * authority only) */
  1452. static void
  1453. dirvote_fetch_missing_votes(void)
  1454. {
  1455.   smartlist_t *missing_fps = smartlist_create();
  1456.   char *resource;
  1457.   SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
  1458.                     trusted_dir_server_t *, ds,
  1459.     {
  1460.       if (!(ds->type & V3_AUTHORITY))
  1461.         continue;
  1462.       if (!dirvote_get_vote(ds->v3_identity_digest,
  1463.                             DGV_BY_ID|DGV_INCLUDE_PENDING)) {
  1464.         char *cp = tor_malloc(HEX_DIGEST_LEN+1);
  1465.         base16_encode(cp, HEX_DIGEST_LEN+1, ds->v3_identity_digest,
  1466.                       DIGEST_LEN);
  1467.         smartlist_add(missing_fps, cp);
  1468.       }
  1469.     });
  1470.   if (!smartlist_len(missing_fps)) {
  1471.     smartlist_free(missing_fps);
  1472.     return;
  1473.   }
  1474.   log_notice(LOG_NOTICE, "We're missing votes from %d authorities. Asking "
  1475.              "every other authority for a copy.", smartlist_len(missing_fps));
  1476.   resource = smartlist_join_strings(missing_fps, "+", 0, NULL);
  1477.   directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE,
  1478.                                      0, resource);
  1479.   tor_free(resource);
  1480.   SMARTLIST_FOREACH(missing_fps, char *, cp, tor_free(cp));
  1481.   smartlist_free(missing_fps);
  1482. }
  1483. /** Send a request to every other authority for its detached signatures,
  1484.  * unless we have signatures from all other v3 authorities already. */
  1485. static void
  1486. dirvote_fetch_missing_signatures(void)
  1487. {
  1488.   if (!pending_consensus)
  1489.     return;
  1490.   if (networkstatus_check_consensus_signature(pending_consensus, -1) == 1)
  1491.     return; /* we have a signature from everybody. */
  1492.   directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
  1493.                                      0, NULL);
  1494. }
  1495. /** Drop all currently pending votes, consensus, and detached signatures. */
  1496. static void
  1497. dirvote_clear_votes(int all_votes)
  1498. {
  1499.   if (!previous_vote_list)
  1500.     previous_vote_list = smartlist_create();
  1501.   if (!pending_vote_list)
  1502.     pending_vote_list = smartlist_create();
  1503.   /* All "previous" votes are now junk. */
  1504.   SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, v, {
  1505.       cached_dir_decref(v->vote_body);
  1506.       v->vote_body = NULL;
  1507.       networkstatus_vote_free(v->vote);
  1508.       tor_free(v);
  1509.     });
  1510.   smartlist_clear(previous_vote_list);
  1511.   if (all_votes) {
  1512.     /* If we're dumping all the votes, we delete the pending ones. */
  1513.     SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v, {
  1514.         cached_dir_decref(v->vote_body);
  1515.         v->vote_body = NULL;
  1516.         networkstatus_vote_free(v->vote);
  1517.         tor_free(v);
  1518.       });
  1519.   } else {
  1520.     /* Otherwise, we move them into "previous". */
  1521.     smartlist_add_all(previous_vote_list, pending_vote_list);
  1522.   }
  1523.   smartlist_clear(pending_vote_list);
  1524.   if (pending_consensus_signature_list) {
  1525.     SMARTLIST_FOREACH(pending_consensus_signature_list, char *, cp,
  1526.                       tor_free(cp));
  1527.     smartlist_clear(pending_consensus_signature_list);
  1528.   }
  1529.   tor_free(pending_consensus_body);
  1530.   tor_free(pending_consensus_signatures);
  1531.   if (pending_consensus) {
  1532.     networkstatus_vote_free(pending_consensus);
  1533.     pending_consensus = NULL;
  1534.   }
  1535. }
  1536. /** Return a newly allocated string containing the hex-encoded v3 authority
  1537.     identity digest of every recognized v3 authority. */
  1538. static char *
  1539. list_v3_auth_ids(void)
  1540. {
  1541.   smartlist_t *known_v3_keys = smartlist_create();
  1542.   char *keys;
  1543.   SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
  1544.                     trusted_dir_server_t *, ds,
  1545.     if ((ds->type & V3_AUTHORITY) &&
  1546.         !tor_digest_is_zero(ds->v3_identity_digest))
  1547.       smartlist_add(known_v3_keys,
  1548.                     tor_strdup(hex_str(ds->v3_identity_digest, DIGEST_LEN))));
  1549.   keys = smartlist_join_strings(known_v3_keys, ", ", 0, NULL);
  1550.   SMARTLIST_FOREACH(known_v3_keys, char *, cp, tor_free(cp));
  1551.   smartlist_free(known_v3_keys);
  1552.   return keys;
  1553. }
  1554. /** Called when we have received a networkstatus vote in <b>vote_body</b>.
  1555.  * Parse and validate it, and on success store it as a pending vote (which we
  1556.  * then return).  Return NULL on failure.  Sets *<b>msg_out</b> and
  1557.  * *<b>status_out</b> to an HTTP response and status code.  (V3 authority
  1558.  * only) */
  1559. pending_vote_t *
  1560. dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out)
  1561. {
  1562.   networkstatus_t *vote;
  1563.   networkstatus_voter_info_t *vi;
  1564.   trusted_dir_server_t *ds;
  1565.   pending_vote_t *pending_vote = NULL;
  1566.   const char *end_of_vote = NULL;
  1567.   int any_failed = 0;
  1568.   tor_assert(vote_body);
  1569.   tor_assert(msg_out);
  1570.   tor_assert(status_out);
  1571.   if (!pending_vote_list)
  1572.     pending_vote_list = smartlist_create();
  1573.   *status_out = 0;
  1574.   *msg_out = NULL;
  1575.  again:
  1576.   vote = networkstatus_parse_vote_from_string(vote_body, &end_of_vote,
  1577.                                               NS_TYPE_VOTE);
  1578.   if (!end_of_vote)
  1579.     end_of_vote = vote_body + strlen(vote_body);
  1580.   if (!vote) {
  1581.     log_warn(LD_DIR, "Couldn't parse vote: length was %d",
  1582.              (int)strlen(vote_body));
  1583.     *msg_out = "Unable to parse vote";
  1584.     goto err;
  1585.   }
  1586.   tor_assert(smartlist_len(vote->voters) == 1);
  1587.   vi = get_voter(vote);
  1588.   tor_assert(vi->good_signature == 1);
  1589.   ds = trusteddirserver_get_by_v3_auth_digest(vi->identity_digest);
  1590.   if (!ds) {
  1591.     char *keys = list_v3_auth_ids();
  1592.     log_warn(LD_DIR, "Got a vote from an authority (nickname %s, address %s) "
  1593.              "with authority key ID %s. "
  1594.              "This key ID is not recognized.  Known v3 key IDs are: %s",
  1595.              vi->nickname, vi->address,
  1596.              hex_str(vi->identity_digest, DIGEST_LEN), keys);
  1597.     tor_free(keys);
  1598.     *msg_out = "Vote not from a recognized v3 authority";
  1599.     goto err;
  1600.   }
  1601.   tor_assert(vote->cert);
  1602.   if (!authority_cert_get_by_digests(vote->cert->cache_info.identity_digest,
  1603.                                      vote->cert->signing_key_digest)) {
  1604.     /* Hey, it's a new cert! */
  1605.     trusted_dirs_load_certs_from_string(
  1606.                                vote->cert->cache_info.signed_descriptor_body,
  1607.                                0 /* from_store */, 1 /*flush*/);
  1608.     if (!authority_cert_get_by_digests(vote->cert->cache_info.identity_digest,
  1609.                                        vote->cert->signing_key_digest)) {
  1610.       log_warn(LD_BUG, "We added a cert, but still couldn't find it.");
  1611.     }
  1612.   }
  1613.   /* Is it for the right period? */
  1614.   if (vote->valid_after != voting_schedule.interval_starts) {
  1615.     char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1];
  1616.     format_iso_time(tbuf1, vote->valid_after);
  1617.     format_iso_time(tbuf2, voting_schedule.interval_starts);
  1618.     log_warn(LD_DIR, "Rejecting vote from %s with valid-after time of %s; "
  1619.              "we were expecting %s", vi->address, tbuf1, tbuf2);
  1620.     *msg_out = "Bad valid-after time";
  1621.     goto err;
  1622.   }
  1623.   /* Now see whether we already have a vote from this authority. */
  1624.   SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v, {
  1625.       if (! memcmp(v->vote->cert->cache_info.identity_digest,
  1626.                    vote->cert->cache_info.identity_digest,
  1627.                    DIGEST_LEN)) {
  1628.         networkstatus_voter_info_t *vi_old = get_voter(v->vote);
  1629.         if (!memcmp(vi_old->vote_digest, vi->vote_digest, DIGEST_LEN)) {
  1630.           /* Ah, it's the same vote. Not a problem. */
  1631.           log_info(LD_DIR, "Discarding a vote we already have.");
  1632.           if (*status_out < 200)
  1633.             *status_out = 200;
  1634.           goto discard;
  1635.         } else if (v->vote->published < vote->published) {
  1636.           log_notice(LD_DIR, "Replacing an older pending vote from this "
  1637.                      "directory.");
  1638.           cached_dir_decref(v->vote_body);
  1639.           networkstatus_vote_free(v->vote);
  1640.           v->vote_body = new_cached_dir(tor_strndup(vote_body,
  1641.                                                     end_of_vote-vote_body),
  1642.                                         vote->published);
  1643.           v->vote = vote;
  1644.           if (end_of_vote &&
  1645.               !strcmpstart(end_of_vote, "network-status-version"))
  1646.             goto again;
  1647.           if (*status_out < 200)
  1648.             *status_out = 200;
  1649.           if (!*msg_out)
  1650.             *msg_out = "OK";
  1651.           return v;
  1652.         } else {
  1653.           *msg_out = "Already have a newer pending vote";
  1654.           goto err;
  1655.         }
  1656.       }
  1657.     });
  1658.   pending_vote = tor_malloc_zero(sizeof(pending_vote_t));
  1659.   pending_vote->vote_body = new_cached_dir(tor_strndup(vote_body,
  1660.                                                        end_of_vote-vote_body),
  1661.                                            vote->published);
  1662.   pending_vote->vote = vote;
  1663.   smartlist_add(pending_vote_list, pending_vote);
  1664.   if (!strcmpstart(end_of_vote, "network-status-version ")) {
  1665.     vote_body = end_of_vote;
  1666.     goto again;
  1667.   }
  1668.   goto done;
  1669.  err:
  1670.   any_failed = 1;
  1671.   if (!*msg_out)
  1672.     *msg_out = "Error adding vote";
  1673.   if (*status_out < 400)
  1674.     *status_out = 400;
  1675.  discard:
  1676.   if (vote)
  1677.     networkstatus_vote_free(vote);
  1678.   if (end_of_vote && !strcmpstart(end_of_vote, "network-status-version ")) {
  1679.     vote_body = end_of_vote;
  1680.     goto again;
  1681.   }
  1682.  done:
  1683.   if (*status_out < 200)
  1684.     *status_out = 200;
  1685.   if (!*msg_out) {
  1686.     if (!any_failed && !pending_vote) {
  1687.       *msg_out = "Duplicate discarded";
  1688.     } else {
  1689.       *msg_out = "ok";
  1690.     }
  1691.   }
  1692.   return any_failed ? NULL : pending_vote;
  1693. }
  1694. /** Try to compute a v3 networkstatus consensus from the currently pending
  1695.  * votes.  Return 0 on success, -1 on failure.  Store the consensus in
  1696.  * pending_consensus: it won't be ready to be published until we have
  1697.  * everybody else's signatures collected too. (V3 Authority only) */
  1698. static int
  1699. dirvote_compute_consensus(void)
  1700. {
  1701.   /* Have we got enough votes to try? */
  1702.   int n_votes, n_voters;
  1703.   smartlist_t *votes = NULL, *votestrings = NULL;
  1704.   char *consensus_body = NULL, *signatures = NULL, *votefile;
  1705.   networkstatus_t *consensus = NULL;
  1706.   authority_cert_t *my_cert;
  1707.   if (!pending_vote_list)
  1708.     pending_vote_list = smartlist_create();
  1709.   n_voters = get_n_authorities(V3_AUTHORITY);
  1710.   n_votes = smartlist_len(pending_vote_list);
  1711.   if (n_votes <= n_voters/2) {
  1712.     log_warn(LD_DIR, "We don't have enough votes to generate a consensus: "
  1713.              "%d of %d", n_votes, n_voters/2);
  1714.     goto err;
  1715.   }
  1716.   if (!(my_cert = get_my_v3_authority_cert())) {
  1717.     log_warn(LD_DIR, "Can't generate consensus without a certificate.");
  1718.     goto err;
  1719.   }
  1720.   votes = smartlist_create();
  1721.   votestrings = smartlist_create();
  1722.   SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v,
  1723.     {
  1724.       sized_chunk_t *c = tor_malloc(sizeof(sized_chunk_t));
  1725.       c->bytes = v->vote_body->dir;
  1726.       c->len = v->vote_body->dir_len;
  1727.       smartlist_add(votestrings, c); /* collect strings to write to disk */
  1728.       smartlist_add(votes, v->vote); /* collect votes to compute consensus */
  1729.     });
  1730.   votefile = get_datadir_fname("v3-status-votes");
  1731.   write_chunks_to_file(votefile, votestrings, 0);
  1732.   tor_free(votefile);
  1733.   SMARTLIST_FOREACH(votestrings, sized_chunk_t *, c, tor_free(c));
  1734.   smartlist_free(votestrings);
  1735.   {
  1736.     char legacy_dbuf[DIGEST_LEN];
  1737.     crypto_pk_env_t *legacy_sign=NULL;
  1738.     char *legacy_id_digest = NULL;
  1739.     if (get_options()->V3AuthUseLegacyKey) {
  1740.       authority_cert_t *cert = get_my_v3_legacy_cert();
  1741.       legacy_sign = get_my_v3_legacy_signing_key();
  1742.       if (cert) {
  1743.         crypto_pk_get_digest(cert->identity_key, legacy_dbuf);
  1744.         legacy_id_digest = legacy_dbuf;
  1745.       }
  1746.     }
  1747.     consensus_body = networkstatus_compute_consensus(
  1748.         votes, n_voters,
  1749.         my_cert->identity_key,
  1750.         get_my_v3_authority_signing_key(), legacy_id_digest, legacy_sign);
  1751.   }
  1752.   if (!consensus_body) {
  1753.     log_warn(LD_DIR, "Couldn't generate a consensus at all!");
  1754.     goto err;
  1755.   }
  1756.   consensus = networkstatus_parse_vote_from_string(consensus_body, NULL,
  1757.                                                    NS_TYPE_CONSENSUS);
  1758.   if (!consensus) {
  1759.     log_warn(LD_DIR, "Couldn't parse consensus we generated!");
  1760.     goto err;
  1761.   }
  1762.   /* 'Check' our own signature, to mark it valid. */
  1763.   networkstatus_check_consensus_signature(consensus, -1);
  1764.   signatures = networkstatus_get_detached_signatures(consensus);
  1765.   if (!signatures) {
  1766.     log_warn(LD_DIR, "Couldn't extract signatures.");
  1767.     goto err;
  1768.   }
  1769.   tor_free(pending_consensus_body);
  1770.   pending_consensus_body = consensus_body;
  1771.   tor_free(pending_consensus_signatures);
  1772.   pending_consensus_signatures = signatures;
  1773.   if (pending_consensus)
  1774.     networkstatus_vote_free(pending_consensus);
  1775.   pending_consensus = consensus;
  1776.   if (pending_consensus_signature_list) {
  1777.     int n_sigs = 0;
  1778.     /* we may have gotten signatures for this consensus before we built
  1779.      * it ourself.  Add them now. */
  1780.     SMARTLIST_FOREACH(pending_consensus_signature_list, char *, sig,
  1781.       {
  1782.         const char *msg = NULL;
  1783.         int r = dirvote_add_signatures_to_pending_consensus(sig, &msg);
  1784.         if (r >= 0)
  1785.           n_sigs += r;
  1786.         else
  1787.           log_warn(LD_DIR,
  1788.                    "Could not add queued signature to new consensus: %s",
  1789.                    msg);
  1790.         tor_free(sig);
  1791.       });
  1792.     if (n_sigs)
  1793.       log_notice(LD_DIR, "Added %d pending signatures while building "
  1794.                  "consensus.", n_sigs);
  1795.     smartlist_clear(pending_consensus_signature_list);
  1796.   }
  1797.   log_notice(LD_DIR, "Consensus computed; uploading signature(s)");
  1798.   directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_SIGNATURES,
  1799.                                ROUTER_PURPOSE_GENERAL,
  1800.                                V3_AUTHORITY,
  1801.                                pending_consensus_signatures,
  1802.                                strlen(pending_consensus_signatures), 0);
  1803.   log_notice(LD_DIR, "Signature(s) posted.");
  1804.   return 0;
  1805.  err:
  1806.   if (votes)
  1807.     smartlist_free(votes);
  1808.   tor_free(consensus_body);
  1809.   tor_free(signatures);
  1810.   networkstatus_vote_free(consensus);
  1811.   return -1;
  1812. }
  1813. /** Helper: we just got the <b>detached_signatures_body</b> sent to us as
  1814.  * signatures on the currently pending consensus.  Add them to the consensus
  1815.  * as appropriate.  Return the number of signatures added. (?) */
  1816. static int
  1817. dirvote_add_signatures_to_pending_consensus(
  1818.                        const char *detached_signatures_body,
  1819.                        const char **msg_out)
  1820. {
  1821.   ns_detached_signatures_t *sigs = NULL;
  1822.   int r = -1;
  1823.   tor_assert(detached_signatures_body);
  1824.   tor_assert(msg_out);
  1825.   /* Only call if we have a pending consensus right now. */
  1826.   tor_assert(pending_consensus);
  1827.   tor_assert(pending_consensus_body);
  1828.   tor_assert(pending_consensus_signatures);
  1829.   *msg_out = NULL;
  1830.   if (!(sigs = networkstatus_parse_detached_signatures(
  1831.                                detached_signatures_body, NULL))) {
  1832.     *msg_out = "Couldn't parse detached signatures.";
  1833.     goto err;
  1834.   }
  1835.   log_info(LD_DIR, "Have %d signatures for adding to consensus.",
  1836.                    smartlist_len(sigs->signatures));
  1837.   r = networkstatus_add_detached_signatures(pending_consensus,
  1838.                                             sigs, msg_out);
  1839.   log_info(LD_DIR,"Added %d signatures to consensus.", r);
  1840.   if (r >= 1) {
  1841.     char *new_detached =
  1842.       networkstatus_get_detached_signatures(pending_consensus);
  1843.     const char *src;
  1844.     char *dst, *dst_end;
  1845.     size_t new_consensus_len;
  1846.     if (!new_detached) {
  1847.       *msg_out = "No signatures to add";
  1848.       goto err;
  1849.     }
  1850.     new_consensus_len =
  1851.       strlen(pending_consensus_body) + strlen(new_detached) + 1;
  1852.     pending_consensus_body = tor_realloc(pending_consensus_body,
  1853.                                          new_consensus_len);
  1854.     dst_end = pending_consensus_body + new_consensus_len;
  1855.     dst = strstr(pending_consensus_body, "directory-signature ");
  1856.     tor_assert(dst);
  1857.     src = strstr(new_detached, "directory-signature ");
  1858.     tor_assert(src);
  1859.     strlcpy(dst, src, dst_end-dst);
  1860.     /* We remove this block once it has failed to crash for a while.  But
  1861.      * unless it shows up in profiles, we're probably better leaving it in,
  1862.      * just in case we break detached signature processing at some point. */
  1863.     {
  1864.       ns_detached_signatures_t *sigs =
  1865.         networkstatus_parse_detached_signatures(new_detached, NULL);
  1866.       networkstatus_t *v = networkstatus_parse_vote_from_string(
  1867.                                              pending_consensus_body, NULL,
  1868.                                              NS_TYPE_CONSENSUS);
  1869.       tor_assert(sigs);
  1870.       ns_detached_signatures_free(sigs);
  1871.       tor_assert(v);
  1872.       networkstatus_vote_free(v);
  1873.     }
  1874.     tor_free(pending_consensus_signatures);
  1875.     pending_consensus_signatures = new_detached;
  1876.     *msg_out = "Signatures added";
  1877.   } else if (r == 0) {
  1878.     *msg_out = "Signatures ignored";
  1879.   } else {
  1880.     goto err;
  1881.   }
  1882.   goto done;
  1883.  err:
  1884.   if (!*msg_out)
  1885.     *msg_out = "Unrecognized error while adding detached signatures.";
  1886.  done:
  1887.   if (sigs)
  1888.     ns_detached_signatures_free(sigs);
  1889.   return r;
  1890. }
  1891. /** Helper: we just got the <b>detached_signatures_body</b> sent to us as
  1892.  * signatures on the currently pending consensus.  Add them to the pending
  1893.  * consensus (if we have one); otherwise queue them until we have a
  1894.  * consensus.  Return negative on failure, nonnegative on success. */
  1895. int
  1896. dirvote_add_signatures(const char *detached_signatures_body,
  1897.                        const char *source,
  1898.                        const char **msg)
  1899. {
  1900.   if (pending_consensus) {
  1901.     log_notice(LD_DIR, "Got a signature from %s. "
  1902.                        "Adding it to the pending consensus.", source);
  1903.     return dirvote_add_signatures_to_pending_consensus(
  1904.                                      detached_signatures_body, msg);
  1905.   } else {
  1906.     log_notice(LD_DIR, "Got a signature from %s. "
  1907.                        "Queuing it for the next consensus.", source);
  1908.     if (!pending_consensus_signature_list)
  1909.       pending_consensus_signature_list = smartlist_create();
  1910.     smartlist_add(pending_consensus_signature_list,
  1911.                   tor_strdup(detached_signatures_body));
  1912.     *msg = "Signature queued";
  1913.     return 0;
  1914.   }
  1915. }
  1916. /** Replace the consensus that we're currently serving with the one that we've
  1917.  * been building. (V3 Authority only) */
  1918. static int
  1919. dirvote_publish_consensus(void)
  1920. {
  1921.   /* Can we actually publish it yet? */
  1922.   if (!pending_consensus ||
  1923.       networkstatus_check_consensus_signature(pending_consensus, 1)<0) {
  1924.     log_warn(LD_DIR, "Not enough info to publish pending consensus");
  1925.     return -1;
  1926.   }
  1927.   if (networkstatus_set_current_consensus(pending_consensus_body, 0))
  1928.     log_warn(LD_DIR, "Error publishing consensus");
  1929.   else
  1930.     log_notice(LD_DIR, "Consensus published.");
  1931.   return 0;
  1932. }
  1933. /** Release all static storage held in dirvote.c */
  1934. void
  1935. dirvote_free_all(void)
  1936. {
  1937.   dirvote_clear_votes(1);
  1938.   /* now empty as a result of clear_pending_votes. */
  1939.   smartlist_free(pending_vote_list);
  1940.   pending_vote_list = NULL;
  1941.   smartlist_free(previous_vote_list);
  1942.   previous_vote_list = NULL;
  1943.   tor_free(pending_consensus_body);
  1944.   tor_free(pending_consensus_signatures);
  1945.   if (pending_consensus) {
  1946.     networkstatus_vote_free(pending_consensus);
  1947.     pending_consensus = NULL;
  1948.   }
  1949.   if (pending_consensus_signature_list) {
  1950.     /* now empty as a result of clear_pending_votes. */
  1951.     smartlist_free(pending_consensus_signature_list);
  1952.     pending_consensus_signature_list = NULL;
  1953.   }
  1954. }
  1955. /* ====
  1956.  * Access to pending items.
  1957.  * ==== */
  1958. /** Return the body of the consensus that we're currently trying to build. */
  1959. const char *
  1960. dirvote_get_pending_consensus(void)
  1961. {
  1962.   return pending_consensus_body;
  1963. }
  1964. /** Return the signatures that we know for the consensus that we're currently
  1965.  * trying to build */
  1966. const char *
  1967. dirvote_get_pending_detached_signatures(void)
  1968. {
  1969.   return pending_consensus_signatures;
  1970. }
  1971. /** Return a given vote specified by <b>fp</b>.  If <b>by_id</b>, return the
  1972.  * vote for the authority with the v3 authority identity key digest <b>fp</b>;
  1973.  * if <b>by_id</b> is false, return the vote whose digest is <b>fp</b>.  If
  1974.  * <b>fp</b> is NULL, return our own vote.  If <b>include_previous</b> is
  1975.  * false, do not consider any votes for a consensus that's already been built.
  1976.  * If <b>include_pending</b> is false, do not consider any votes for the
  1977.  * consensus that's in progress.  May return NULL if we have no vote for the
  1978.  * authority in question. */
  1979. const cached_dir_t *
  1980. dirvote_get_vote(const char *fp, int flags)
  1981. {
  1982.   int by_id = flags & DGV_BY_ID;
  1983.   const int include_pending = flags & DGV_INCLUDE_PENDING;
  1984.   const int include_previous = flags & DGV_INCLUDE_PREVIOUS;
  1985.   if (!pending_vote_list && !previous_vote_list)
  1986.     return NULL;
  1987.   if (fp == NULL) {
  1988.     authority_cert_t *c = get_my_v3_authority_cert();
  1989.     if (c) {
  1990.       fp = c->cache_info.identity_digest;
  1991.       by_id = 1;
  1992.     } else
  1993.       return NULL;
  1994.   }
  1995.   if (by_id) {
  1996.     if (pending_vote_list && include_pending) {
  1997.       SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv,
  1998.         if (!memcmp(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
  1999.           return pv->vote_body);
  2000.     }
  2001.     if (previous_vote_list && include_previous) {
  2002.       SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, pv,
  2003.         if (!memcmp(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
  2004.           return pv->vote_body);
  2005.     }
  2006.   } else {
  2007.     if (pending_vote_list && include_pending) {
  2008.       SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv,
  2009.         if (!memcmp(pv->vote->networkstatus_digest, fp, DIGEST_LEN))
  2010.           return pv->vote_body);
  2011.     }
  2012.     if (previous_vote_list && include_previous) {
  2013.       SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, pv,
  2014.         if (!memcmp(pv->vote->networkstatus_digest, fp, DIGEST_LEN))
  2015.           return pv->vote_body);
  2016.     }
  2017.   }
  2018.   return NULL;
  2019. }