Tor  0.4.7.0-alpha-dev
dirvote.c
Go to the documentation of this file.
1 /* Copyright (c) 2001-2004, Roger Dingledine.
2  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3  * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
6 #define DIRVOTE_PRIVATE
7 
8 #include "core/or/or.h"
9 #include "app/config/config.h"
11 #include "core/or/policies.h"
12 #include "core/or/protover.h"
13 #include "core/or/tor_version_st.h"
14 #include "core/or/versions.h"
15 #include "feature/dirauth/bwauth.h"
36 #include "feature/relay/router.h"
38 #include "feature/stats/rephist.h"
39 #include "feature/client/entrynodes.h" /* needed for guardfraction methods */
42 
47 
63 
64 #include "lib/container/order.h"
65 #include "lib/encoding/confline.h"
67 
68 /* Algorithm to use for the bandwidth file digest. */
69 #define DIGEST_ALG_BW_FILE DIGEST_SHA256
70 
71 /**
72  * \file dirvote.c
73  * \brief Functions to compute directory consensus, and schedule voting.
74  *
75  * This module is the center of the consensus-voting based directory
76  * authority system. With this system, a set of authorities first
77  * publish vote based on their opinions of the network, and then compute
78  * a consensus from those votes. Each authority signs the consensus,
79  * and clients trust the consensus if enough known authorities have
80  * signed it.
81  *
82  * The code in this module is only invoked on directory authorities. It's
83  * responsible for:
84  *
85  * <ul>
86  * <li>Generating this authority's vote networkstatus, based on the
87  * authority's view of the network as represented in dirserv.c
88  * <li>Formatting the vote networkstatus objects.
89  * <li>Generating the microdescriptors that correspond to our own
90  * vote.
91  * <li>Sending votes to all the other authorities.
92  * <li>Trying to fetch missing votes from other authorities.
93  * <li>Computing the consensus from a set of votes, as well as
94  * a "detached signature" object for other authorities to fetch.
95  * <li>Collecting other authorities' signatures on the same consensus,
96  * until there are enough.
97  * <li>Publishing the consensus to the reset of the directory system.
98  * <li>Scheduling all of the above operations.
99  * </ul>
100  *
101  * The main entry points are in dirvote_act(), which handles scheduled
102  * actions; and dirvote_add_vote() and dirvote_add_signatures(), which
103  * handle uploaded and downloaded votes and signatures.
104  *
105  * (See dir-spec.txt from torspec.git for a complete specification of
106  * the directory protocol and voting algorithms.)
107  **/
108 
109 /** A consensus that we have built and are appending signatures to. Once it's
110  * time to publish it, it will become an active consensus if it accumulates
111  * enough signatures. */
112 typedef struct pending_consensus_t {
113  /** The body of the consensus that we're currently building. Once we
114  * have it built, it goes into dirserv.c */
115  char *body;
116  /** The parsed in-progress consensus document. */
119 
120 /* DOCDOC dirvote_add_signatures_to_all_pending_consensuses */
122  const char *detached_signatures_body,
123  const char *source,
124  const char **msg_out);
128  const char *source,
129  int severity,
130  const char **msg_out);
131 static char *list_v3_auth_ids(void);
132 static void dirvote_fetch_missing_votes(void);
133 static void dirvote_fetch_missing_signatures(void);
134 static int dirvote_perform_vote(void);
135 static void dirvote_clear_votes(int all_votes);
136 static int dirvote_compute_consensuses(void);
137 static int dirvote_publish_consensus(void);
138 
139 /* =====
140  * Certificate functions
141  * ===== */
142 
143 /** Allocate and return a new authority_cert_t with the same contents as
144  * <b>cert</b>. */
147 {
148  authority_cert_t *out = tor_malloc(sizeof(authority_cert_t));
149  tor_assert(cert);
150 
151  memcpy(out, cert, sizeof(authority_cert_t));
152  /* Now copy pointed-to things. */
154  tor_strndup(cert->cache_info.signed_descriptor_body,
159 
160  return out;
161 }
162 
163 /* =====
164  * Voting
165  * =====*/
166 
167 /* If <b>opt_value</b> is non-NULL, return "keyword opt_value\n" in a new
168  * string. Otherwise return a new empty string. */
169 static char *
170 format_line_if_present(const char *keyword, const char *opt_value)
171 {
172  if (opt_value) {
173  char *result = NULL;
174  tor_asprintf(&result, "%s %s\n", keyword, opt_value);
175  return result;
176  } else {
177  return tor_strdup("");
178  }
179 }
180 
181 /** Format the recommended/required-relay-client protocols lines for a vote in
182  * a newly allocated string, and return that string. */
183 static char *
185 {
186  char *recommended_relay_protocols_line = NULL;
187  char *recommended_client_protocols_line = NULL;
188  char *required_relay_protocols_line = NULL;
189  char *required_client_protocols_line = NULL;
190 
191  recommended_relay_protocols_line =
192  format_line_if_present("recommended-relay-protocols",
194  recommended_client_protocols_line =
195  format_line_if_present("recommended-client-protocols",
196  v3_ns->recommended_client_protocols);
197  required_relay_protocols_line =
198  format_line_if_present("required-relay-protocols",
199  v3_ns->required_relay_protocols);
200  required_client_protocols_line =
201  format_line_if_present("required-client-protocols",
202  v3_ns->required_client_protocols);
203 
204  char *result = NULL;
205  tor_asprintf(&result, "%s%s%s%s",
206  recommended_relay_protocols_line,
207  recommended_client_protocols_line,
208  required_relay_protocols_line,
209  required_client_protocols_line);
210 
211  tor_free(recommended_relay_protocols_line);
212  tor_free(recommended_client_protocols_line);
213  tor_free(required_relay_protocols_line);
214  tor_free(required_client_protocols_line);
215 
216  return result;
217 }
218 
219 /** Return a new string containing the string representation of the vote in
220  * <b>v3_ns</b>, signed with our v3 signing key <b>private_signing_key</b>.
221  * For v3 authorities. */
222 STATIC char *
224  networkstatus_t *v3_ns)
225 {
226  smartlist_t *chunks = smartlist_new();
227  char fingerprint[FINGERPRINT_LEN+1];
228  char digest[DIGEST_LEN];
229  char *protocols_lines = NULL;
230  char *client_versions_line = NULL, *server_versions_line = NULL;
231  char *shared_random_vote_str = NULL;
233  char *status = NULL;
234 
235  tor_assert(private_signing_key);
236  tor_assert(v3_ns->type == NS_TYPE_VOTE || v3_ns->type == NS_TYPE_OPINION);
237 
238  voter = smartlist_get(v3_ns->voters, 0);
239 
240  base16_encode(fingerprint, sizeof(fingerprint),
242 
243  client_versions_line = format_line_if_present("client-versions",
244  v3_ns->client_versions);
245  server_versions_line = format_line_if_present("server-versions",
246  v3_ns->server_versions);
247  protocols_lines = format_protocols_lines_for_vote(v3_ns);
248 
249  /* Get shared random commitments/reveals line(s). */
250  shared_random_vote_str = sr_get_string_for_vote();
251 
252  {
253  char published[ISO_TIME_LEN+1];
254  char va[ISO_TIME_LEN+1];
255  char fu[ISO_TIME_LEN+1];
256  char vu[ISO_TIME_LEN+1];
257  char *flags = smartlist_join_strings(v3_ns->known_flags, " ", 0, NULL);
258  /* XXXX Abstraction violation: should be pulling a field out of v3_ns.*/
259  char *flag_thresholds = dirserv_get_flag_thresholds_line();
260  char *params;
261  char *bw_headers_line = NULL;
262  char *bw_file_digest = NULL;
263  authority_cert_t *cert = v3_ns->cert;
264  char *methods =
267  format_iso_time(published, v3_ns->published);
268  format_iso_time(va, v3_ns->valid_after);
269  format_iso_time(fu, v3_ns->fresh_until);
270  format_iso_time(vu, v3_ns->valid_until);
271 
272  if (v3_ns->net_params)
273  params = smartlist_join_strings(v3_ns->net_params, " ", 0, NULL);
274  else
275  params = tor_strdup("");
276  tor_assert(cert);
277 
278  /* v3_ns->bw_file_headers is only set when V3BandwidthsFile is
279  * configured */
280  if (v3_ns->bw_file_headers) {
281  char *bw_file_headers = NULL;
282  /* If there are too many headers, leave the header string NULL */
283  if (! BUG(smartlist_len(v3_ns->bw_file_headers)
285  bw_file_headers = smartlist_join_strings(v3_ns->bw_file_headers, " ",
286  0, NULL);
287  if (BUG(strlen(bw_file_headers) > MAX_BW_FILE_HEADERS_LINE_LEN)) {
288  /* Free and set to NULL, because the line was too long */
289  tor_free(bw_file_headers);
290  }
291  }
292  if (!bw_file_headers) {
293  /* If parsing failed, add a bandwidth header line with no entries */
294  bw_file_headers = tor_strdup("");
295  }
296  /* At this point, the line will always be present */
297  bw_headers_line = format_line_if_present("bandwidth-file-headers",
298  bw_file_headers);
299  tor_free(bw_file_headers);
300  }
301 
302  /* Create bandwidth-file-digest if applicable.
303  * v3_ns->b64_digest_bw_file will contain the digest when V3BandwidthsFile
304  * is configured and the bandwidth file could be read, even if it was not
305  * parseable.
306  */
307  if (!tor_digest256_is_zero((const char *)v3_ns->bw_file_digest256)) {
308  /* Encode the digest. */
309  char b64_digest_bw_file[BASE64_DIGEST256_LEN+1] = {0};
310  digest256_to_base64(b64_digest_bw_file,
311  (const char *)v3_ns->bw_file_digest256);
312  /* "bandwidth-file-digest" 1*(SP algorithm "=" digest) NL */
313  char *digest_algo_b64_digest_bw_file = NULL;
314  tor_asprintf(&digest_algo_b64_digest_bw_file, "%s=%s",
315  crypto_digest_algorithm_get_name(DIGEST_ALG_BW_FILE),
316  b64_digest_bw_file);
317  /* No need for tor_strdup(""), format_line_if_present does it. */
318  bw_file_digest = format_line_if_present(
319  "bandwidth-file-digest", digest_algo_b64_digest_bw_file);
320  tor_free(digest_algo_b64_digest_bw_file);
321  }
322 
323  const char *ip_str = fmt_addr(&voter->ipv4_addr);
324 
325  if (ip_str[0]) {
326  smartlist_add_asprintf(chunks,
327  "network-status-version 3\n"
328  "vote-status %s\n"
329  "consensus-methods %s\n"
330  "published %s\n"
331  "valid-after %s\n"
332  "fresh-until %s\n"
333  "valid-until %s\n"
334  "voting-delay %d %d\n"
335  "%s%s" /* versions */
336  "%s" /* protocols */
337  "known-flags %s\n"
338  "flag-thresholds %s\n"
339  "params %s\n"
340  "%s" /* bandwidth file headers */
341  "%s" /* bandwidth file digest */
342  "dir-source %s %s %s %s %d %d\n"
343  "contact %s\n"
344  "%s" /* shared randomness information */
345  ,
346  v3_ns->type == NS_TYPE_VOTE ? "vote" : "opinion",
347  methods,
348  published, va, fu, vu,
349  v3_ns->vote_seconds, v3_ns->dist_seconds,
350  client_versions_line,
351  server_versions_line,
352  protocols_lines,
353  flags,
354  flag_thresholds,
355  params,
356  bw_headers_line ? bw_headers_line : "",
357  bw_file_digest ? bw_file_digest: "",
358  voter->nickname, fingerprint, voter->address,
359  ip_str, voter->ipv4_dirport, voter->ipv4_orport,
360  voter->contact,
361  shared_random_vote_str ?
362  shared_random_vote_str : "");
363  }
364 
365  tor_free(params);
366  tor_free(flags);
367  tor_free(flag_thresholds);
368  tor_free(methods);
369  tor_free(shared_random_vote_str);
370  tor_free(bw_headers_line);
371  tor_free(bw_file_digest);
372 
373  if (ip_str[0] == '\0')
374  goto err;
375 
376  if (!tor_digest_is_zero(voter->legacy_id_digest)) {
377  char fpbuf[HEX_DIGEST_LEN+1];
378  base16_encode(fpbuf, sizeof(fpbuf), voter->legacy_id_digest, DIGEST_LEN);
379  smartlist_add_asprintf(chunks, "legacy-dir-key %s\n", fpbuf);
380  }
381 
382  smartlist_add(chunks, tor_strndup(cert->cache_info.signed_descriptor_body,
384  }
385 
387  vrs) {
388  char *rsf;
390  rsf = routerstatus_format_entry(&vrs->status,
391  vrs->version, vrs->protocols,
392  NS_V3_VOTE,
393  vrs);
394  if (rsf)
395  smartlist_add(chunks, rsf);
396 
397  for (h = vrs->microdesc; h; h = h->next) {
399  }
400  } SMARTLIST_FOREACH_END(vrs);
401 
402  smartlist_add_strdup(chunks, "directory-footer\n");
403 
404  /* The digest includes everything up through the space after
405  * directory-signature. (Yuck.) */
406  crypto_digest_smartlist(digest, DIGEST_LEN, chunks,
407  "directory-signature ", DIGEST_SHA1);
408 
409  {
410  char signing_key_fingerprint[FINGERPRINT_LEN+1];
411  if (crypto_pk_get_fingerprint(private_signing_key,
412  signing_key_fingerprint, 0)<0) {
413  log_warn(LD_BUG, "Unable to get fingerprint for signing key");
414  goto err;
415  }
416 
417  smartlist_add_asprintf(chunks, "directory-signature %s %s\n", fingerprint,
418  signing_key_fingerprint);
419  }
420 
421  {
422  char *sig = router_get_dirobj_signature(digest, DIGEST_LEN,
423  private_signing_key);
424  if (!sig) {
425  log_warn(LD_BUG, "Unable to sign networkstatus vote.");
426  goto err;
427  }
428  smartlist_add(chunks, sig);
429  }
430 
431  status = smartlist_join_strings(chunks, "", 0, NULL);
432 
433  {
434  networkstatus_t *v;
435  if (!(v = networkstatus_parse_vote_from_string(status, strlen(status),
436  NULL,
437  v3_ns->type))) {
438  log_err(LD_BUG,"Generated a networkstatus %s we couldn't parse: "
439  "<<%s>>",
440  v3_ns->type == NS_TYPE_VOTE ? "vote" : "opinion", status);
441  goto err;
442  }
443  networkstatus_vote_free(v);
444  }
445 
446  goto done;
447 
448  err:
449  tor_free(status);
450  done:
451  tor_free(client_versions_line);
452  tor_free(server_versions_line);
453  tor_free(protocols_lines);
454 
455  SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
456  smartlist_free(chunks);
457  return status;
458 }
459 
460 /** Set *<b>timing_out</b> to the intervals at which we would like to vote.
461  * Note that these aren't the intervals we'll use to vote; they're the ones
462  * that we'll vote to use. */
463 static void
465 {
466  const or_options_t *options = get_options();
467 
468  tor_assert(timing_out);
469 
470  timing_out->vote_interval = options->V3AuthVotingInterval;
471  timing_out->n_intervals_valid = options->V3AuthNIntervalsValid;
472  timing_out->vote_delay = options->V3AuthVoteDelay;
473  timing_out->dist_delay = options->V3AuthDistDelay;
474 }
475 
476 /* =====
477  * Consensus generation
478  * ===== */
479 
480 /** If <b>vrs</b> has a hash made for the consensus method <b>method</b> with
481  * the digest algorithm <b>alg</b>, decode it and copy it into
482  * <b>digest256_out</b> and return 0. Otherwise return -1. */
483 static int
485  const vote_routerstatus_t *vrs,
486  int method,
487  digest_algorithm_t alg)
488 {
489  /* XXXX only returns the sha256 method. */
490  const vote_microdesc_hash_t *h;
491  char mstr[64];
492  size_t mlen;
493  char dstr[64];
494 
495  tor_snprintf(mstr, sizeof(mstr), "%d", method);
496  mlen = strlen(mstr);
497  tor_snprintf(dstr, sizeof(dstr), " %s=",
499 
500  for (h = vrs->microdesc; h; h = h->next) {
501  const char *cp = h->microdesc_hash_line;
502  size_t num_len;
503  /* cp looks like \d+(,\d+)* (digesttype=val )+ . Let's hunt for mstr in
504  * the first part. */
505  while (1) {
506  num_len = strspn(cp, "1234567890");
507  if (num_len == mlen && fast_memeq(mstr, cp, mlen)) {
508  /* This is the line. */
509  char buf[BASE64_DIGEST256_LEN+1];
510  /* XXXX ignores extraneous stuff if the digest is too long. This
511  * seems harmless enough, right? */
512  cp = strstr(cp, dstr);
513  if (!cp)
514  return -1;
515  cp += strlen(dstr);
516  strlcpy(buf, cp, sizeof(buf));
517  return digest256_from_base64(digest256_out, buf);
518  }
519  if (num_len == 0 || cp[num_len] != ',')
520  break;
521  cp += num_len + 1;
522  }
523  }
524  return -1;
525 }
526 
527 /** Given a vote <b>vote</b> (not a consensus!), return its associated
528  * networkstatus_voter_info_t. */
531 {
532  tor_assert(vote);
533  tor_assert(vote->type == NS_TYPE_VOTE);
534  tor_assert(vote->voters);
535  tor_assert(smartlist_len(vote->voters) == 1);
536  return smartlist_get(vote->voters, 0);
537 }
538 
539 /** Temporary structure used in constructing a list of dir-source entries
540  * for a consensus. One of these is generated for every vote, and one more
541  * for every legacy key in each vote. */
542 typedef struct dir_src_ent_t {
543  networkstatus_t *v;
544  const char *digest;
545  int is_legacy;
546 } dir_src_ent_t;
547 
548 /** Helper for sorting networkstatus_t votes (not consensuses) by the
549  * hash of their voters' identity digests. */
550 static int
551 compare_votes_by_authority_id_(const void **_a, const void **_b)
552 {
553  const networkstatus_t *a = *_a, *b = *_b;
554  return fast_memcmp(get_voter(a)->identity_digest,
555  get_voter(b)->identity_digest, DIGEST_LEN);
556 }
557 
558 /** Helper: Compare the dir_src_ent_ts in *<b>_a</b> and *<b>_b</b> by
559  * their identity digests, and return -1, 0, or 1 depending on their
560  * ordering */
561 static int
562 compare_dir_src_ents_by_authority_id_(const void **_a, const void **_b)
563 {
564  const dir_src_ent_t *a = *_a, *b = *_b;
565  const networkstatus_voter_info_t *a_v = get_voter(a->v),
566  *b_v = get_voter(b->v);
567  const char *a_id, *b_id;
568  a_id = a->is_legacy ? a_v->legacy_id_digest : a_v->identity_digest;
569  b_id = b->is_legacy ? b_v->legacy_id_digest : b_v->identity_digest;
570 
571  return fast_memcmp(a_id, b_id, DIGEST_LEN);
572 }
573 
574 /** Given a sorted list of strings <b>in</b>, add every member to <b>out</b>
575  * that occurs more than <b>min</b> times. */
576 static void
578 {
579  char *cur = NULL;
580  int count = 0;
581  SMARTLIST_FOREACH_BEGIN(in, char *, cp) {
582  if (cur && !strcmp(cp, cur)) {
583  ++count;
584  } else {
585  if (count > min)
586  smartlist_add(out, cur);
587  cur = cp;
588  count = 1;
589  }
590  } SMARTLIST_FOREACH_END(cp);
591  if (count > min)
592  smartlist_add(out, cur);
593 }
594 
595 /** Given a sorted list of strings <b>lst</b>, return the member that appears
596  * most. Break ties in favor of later-occurring members. */
597 #define get_most_frequent_member(lst) \
598  smartlist_get_most_frequent_string(lst)
599 
600 /** Return 0 if and only if <b>a</b> and <b>b</b> are routerstatuses
601  * that come from the same routerinfo, with the same derived elements.
602  */
603 static int
605 {
606  int r;
607  tor_assert(a);
608  tor_assert(b);
609 
611  DIGEST_LEN)))
612  return r;
615  DIGEST_LEN)))
616  return r;
617  /* If we actually reached this point, then the identities and
618  * the descriptor digests matched, so somebody is making SHA1 collisions.
619  */
620 #define CMP_FIELD(utype, itype, field) do { \
621  utype aval = (utype) (itype) a->status.field; \
622  utype bval = (utype) (itype) b->status.field; \
623  utype u = bval - aval; \
624  itype r2 = (itype) u; \
625  if (r2 < 0) { \
626  return -1; \
627  } else if (r2 > 0) { \
628  return 1; \
629  } \
630  } while (0)
631 
632  CMP_FIELD(uint64_t, int64_t, published_on);
633 
634  if ((r = strcmp(b->status.nickname, a->status.nickname)))
635  return r;
636 
637  if ((r = tor_addr_compare(&a->status.ipv4_addr, &b->status.ipv4_addr,
638  CMP_EXACT))) {
639  return r;
640  }
641  CMP_FIELD(unsigned, int, ipv4_orport);
642  CMP_FIELD(unsigned, int, ipv4_dirport);
643 
644  return 0;
645 }
646 
647 /** Helper for sorting routerlists based on compare_vote_rs. */
648 static int
649 compare_vote_rs_(const void **_a, const void **_b)
650 {
651  const vote_routerstatus_t *a = *_a, *b = *_b;
652  return compare_vote_rs(a,b);
653 }
654 
655 /** Helper for sorting OR ports. */
656 static int
657 compare_orports_(const void **_a, const void **_b)
658 {
659  const tor_addr_port_t *a = *_a, *b = *_b;
660  int r;
661 
662  if ((r = tor_addr_compare(&a->addr, &b->addr, CMP_EXACT)))
663  return r;
664  if ((r = (((int) b->port) - ((int) a->port))))
665  return r;
666 
667  return 0;
668 }
669 
670 /** Given a list of vote_routerstatus_t, all for the same router identity,
671  * return whichever is most frequent, breaking ties in favor of more
672  * recently published vote_routerstatus_t and in case of ties there,
673  * in favor of smaller descriptor digest.
674  */
675 static vote_routerstatus_t *
676 compute_routerstatus_consensus(smartlist_t *votes, int consensus_method,
677  char *microdesc_digest256_out,
678  tor_addr_port_t *best_alt_orport_out)
679 {
680  vote_routerstatus_t *most = NULL, *cur = NULL;
681  int most_n = 0, cur_n = 0;
682  time_t most_published = 0;
683 
684  /* compare_vote_rs_() sorts the items by identity digest (all the same),
685  * then by SD digest. That way, if we have a tie that the published_on
686  * date cannot break, we use the descriptor with the smaller digest.
687  */
690  if (cur && !compare_vote_rs(cur, rs)) {
691  ++cur_n;
692  } else {
693  if (cur && (cur_n > most_n ||
694  (cur_n == most_n &&
695  cur->status.published_on > most_published))) {
696  most = cur;
697  most_n = cur_n;
698  most_published = cur->status.published_on;
699  }
700  cur_n = 1;
701  cur = rs;
702  }
703  } SMARTLIST_FOREACH_END(rs);
704 
705  if (cur_n > most_n ||
706  (cur && cur_n == most_n && cur->status.published_on > most_published)) {
707  most = cur;
708  // most_n = cur_n; // unused after this point.
709  // most_published = cur->status.published_on; // unused after this point.
710  }
711 
712  tor_assert(most);
713 
714  /* Vote on potential alternative (sets of) OR port(s) in the winning
715  * routerstatuses.
716  *
717  * XXX prop186 There's at most one alternative OR port (_the_ IPv6
718  * port) for now. */
719  if (best_alt_orport_out) {
720  smartlist_t *alt_orports = smartlist_new();
721  const tor_addr_port_t *most_alt_orport = NULL;
722 
724  tor_assert(rs);
725  if (compare_vote_rs(most, rs) == 0 &&
726  !tor_addr_is_null(&rs->status.ipv6_addr)
727  && rs->status.ipv6_orport) {
728  smartlist_add(alt_orports, tor_addr_port_new(&rs->status.ipv6_addr,
729  rs->status.ipv6_orport));
730  }
731  } SMARTLIST_FOREACH_END(rs);
732 
733  smartlist_sort(alt_orports, compare_orports_);
734  most_alt_orport = smartlist_get_most_frequent(alt_orports,
736  if (most_alt_orport) {
737  memcpy(best_alt_orport_out, most_alt_orport, sizeof(tor_addr_port_t));
738  log_debug(LD_DIR, "\"a\" line winner for %s is %s",
739  most->status.nickname,
740  fmt_addrport(&most_alt_orport->addr, most_alt_orport->port));
741  }
742 
743  SMARTLIST_FOREACH(alt_orports, tor_addr_port_t *, ap, tor_free(ap));
744  smartlist_free(alt_orports);
745  }
746 
747  if (microdesc_digest256_out) {
748  smartlist_t *digests = smartlist_new();
749  const uint8_t *best_microdesc_digest;
751  char d[DIGEST256_LEN];
752  if (compare_vote_rs(rs, most))
753  continue;
754  if (!vote_routerstatus_find_microdesc_hash(d, rs, consensus_method,
755  DIGEST_SHA256))
756  smartlist_add(digests, tor_memdup(d, sizeof(d)));
757  } SMARTLIST_FOREACH_END(rs);
758  smartlist_sort_digests256(digests);
759  best_microdesc_digest = smartlist_get_most_frequent_digest256(digests);
760  if (best_microdesc_digest)
761  memcpy(microdesc_digest256_out, best_microdesc_digest, DIGEST256_LEN);
762  SMARTLIST_FOREACH(digests, char *, cp, tor_free(cp));
763  smartlist_free(digests);
764  }
765 
766  return most;
767 }
768 
769 /** Sorting helper: compare two strings based on their values as base-ten
770  * positive integers. (Non-integers are treated as prior to all integers, and
771  * compared lexically.) */
772 static int
773 cmp_int_strings_(const void **_a, const void **_b)
774 {
775  const char *a = *_a, *b = *_b;
776  int ai = (int)tor_parse_long(a, 10, 1, INT_MAX, NULL, NULL);
777  int bi = (int)tor_parse_long(b, 10, 1, INT_MAX, NULL, NULL);
778  if (ai<bi) {
779  return -1;
780  } else if (ai==bi) {
781  if (ai == 0) /* Parsing failed. */
782  return strcmp(a, b);
783  return 0;
784  } else {
785  return 1;
786  }
787 }
788 
789 /** Given a list of networkstatus_t votes, determine and return the number of
790  * the highest consensus method that is supported by 2/3 of the voters. */
791 static int
793 {
794  smartlist_t *all_methods = smartlist_new();
795  smartlist_t *acceptable_methods = smartlist_new();
796  smartlist_t *tmp = smartlist_new();
797  int min = (smartlist_len(votes) * 2) / 3;
798  int n_ok;
799  int result;
800  SMARTLIST_FOREACH(votes, networkstatus_t *, vote,
801  {
802  tor_assert(vote->supported_methods);
803  smartlist_add_all(tmp, vote->supported_methods);
805  smartlist_uniq(tmp, cmp_int_strings_, NULL);
806  smartlist_add_all(all_methods, tmp);
807  smartlist_clear(tmp);
808  });
809 
810  smartlist_sort(all_methods, cmp_int_strings_);
811  get_frequent_members(acceptable_methods, all_methods, min);
812  n_ok = smartlist_len(acceptable_methods);
813  if (n_ok) {
814  const char *best = smartlist_get(acceptable_methods, n_ok-1);
815  result = (int)tor_parse_long(best, 10, 1, INT_MAX, NULL, NULL);
816  } else {
817  result = 1;
818  }
819  smartlist_free(tmp);
820  smartlist_free(all_methods);
821  smartlist_free(acceptable_methods);
822  return result;
823 }
824 
825 /** Return true iff <b>method</b> is a consensus method that we support. */
826 static int
828 {
829  return (method >= MIN_SUPPORTED_CONSENSUS_METHOD) &&
830  (method <= MAX_SUPPORTED_CONSENSUS_METHOD);
831 }
832 
833 /** Return a newly allocated string holding the numbers between low and high
834  * (inclusive) that are supported consensus methods. */
835 STATIC char *
836 make_consensus_method_list(int low, int high, const char *separator)
837 {
838  char *list;
839 
840  int i;
841  smartlist_t *lst;
842  lst = smartlist_new();
843  for (i = low; i <= high; ++i) {
845  continue;
846  smartlist_add_asprintf(lst, "%d", i);
847  }
848  list = smartlist_join_strings(lst, separator, 0, NULL);
849  tor_assert(list);
850  SMARTLIST_FOREACH(lst, char *, cp, tor_free(cp));
851  smartlist_free(lst);
852  return list;
853 }
854 
855 /** Helper: given <b>lst</b>, a list of version strings such that every
856  * version appears once for every versioning voter who recommends it, return a
857  * newly allocated string holding the resulting client-versions or
858  * server-versions list. May change contents of <b>lst</b> */
859 static char *
861 {
862  int min = n_versioning / 2;
863  smartlist_t *good = smartlist_new();
864  char *result;
865  SMARTLIST_FOREACH_BEGIN(lst, const char *, v) {
866  if (strchr(v, ' ')) {
867  log_warn(LD_DIR, "At least one authority has voted for a version %s "
868  "that contains a space. This probably wasn't intentional, and "
869  "is likely to cause trouble. Please tell them to stop it.",
870  escaped(v));
871  }
872  } SMARTLIST_FOREACH_END(v);
873  sort_version_list(lst, 0);
874  get_frequent_members(good, lst, min);
875  result = smartlist_join_strings(good, ",", 0, NULL);
876  smartlist_free(good);
877  return result;
878 }
879 
880 /** Given a list of K=V values, return the int32_t value corresponding to
881  * KEYWORD=, or default_val if no such value exists, or if the value is
882  * corrupt.
883  */
884 STATIC int32_t
886  const char *keyword,
887  int32_t default_val)
888 {
889  unsigned int n_found = 0;
890  int32_t value = default_val;
891 
892  SMARTLIST_FOREACH_BEGIN(param_list, const char *, k_v_pair) {
893  if (!strcmpstart(k_v_pair, keyword) && k_v_pair[strlen(keyword)] == '=') {
894  const char *integer_str = &k_v_pair[strlen(keyword)+1];
895  int ok;
896  value = (int32_t)
897  tor_parse_long(integer_str, 10, INT32_MIN, INT32_MAX, &ok, NULL);
898  if (BUG(!ok))
899  return default_val;
900  ++n_found;
901  }
902  } SMARTLIST_FOREACH_END(k_v_pair);
903 
904  if (n_found == 1) {
905  return value;
906  } else {
907  tor_assert_nonfatal(n_found == 0);
908  return default_val;
909  }
910 }
911 
912 /** Minimum number of directory authorities voting for a parameter to
913  * include it in the consensus, if consensus method 12 or later is to be
914  * used. See proposal 178 for details. */
915 #define MIN_VOTES_FOR_PARAM 3
916 
917 /** Helper: given a list of valid networkstatus_t, return a new smartlist
918  * containing the contents of the consensus network parameter set.
919  */
921 dirvote_compute_params(smartlist_t *votes, int method, int total_authorities)
922 {
923  int i;
924  int32_t *vals;
925 
926  int cur_param_len;
927  const char *cur_param;
928  const char *eq;
929 
930  const int n_votes = smartlist_len(votes);
931  smartlist_t *output;
932  smartlist_t *param_list = smartlist_new();
933  (void) method;
934 
935  /* We require that the parameter lists in the votes are well-formed: that
936  is, that their keywords are unique and sorted, and that their values are
937  between INT32_MIN and INT32_MAX inclusive. This should be guaranteed by
938  the parsing code. */
939 
940  vals = tor_calloc(n_votes, sizeof(int));
941 
943  if (!v->net_params)
944  continue;
945  smartlist_add_all(param_list, v->net_params);
946  } SMARTLIST_FOREACH_END(v);
947 
948  if (smartlist_len(param_list) == 0) {
949  tor_free(vals);
950  return param_list;
951  }
952 
953  smartlist_sort_strings(param_list);
954  i = 0;
955  cur_param = smartlist_get(param_list, 0);
956  eq = strchr(cur_param, '=');
957  tor_assert(eq);
958  cur_param_len = (int)(eq+1 - cur_param);
959 
960  output = smartlist_new();
961 
962  SMARTLIST_FOREACH_BEGIN(param_list, const char *, param) {
963  /* resolve spurious clang shallow analysis null pointer errors */
964  tor_assert(param);
965 
966  const char *next_param;
967  int ok=0;
968  eq = strchr(param, '=');
969  tor_assert(i<n_votes); /* Make sure we prevented vote-stuffing. */
970  vals[i++] = (int32_t)
971  tor_parse_long(eq+1, 10, INT32_MIN, INT32_MAX, &ok, NULL);
972  tor_assert(ok); /* Already checked these when parsing. */
973 
974  if (param_sl_idx+1 == smartlist_len(param_list))
975  next_param = NULL;
976  else
977  next_param = smartlist_get(param_list, param_sl_idx+1);
978 
979  if (!next_param || strncmp(next_param, param, cur_param_len)) {
980  /* We've reached the end of a series. */
981  /* Make sure enough authorities voted on this param, unless the
982  * the consensus method we use is too old for that. */
983  if (i > total_authorities/2 ||
984  i >= MIN_VOTES_FOR_PARAM) {
985  int32_t median = median_int32(vals, i);
986  char *out_string = tor_malloc(64+cur_param_len);
987  memcpy(out_string, param, cur_param_len);
988  tor_snprintf(out_string+cur_param_len,64, "%ld", (long)median);
989  smartlist_add(output, out_string);
990  }
991 
992  i = 0;
993  if (next_param) {
994  eq = strchr(next_param, '=');
995  cur_param_len = (int)(eq+1 - next_param);
996  }
997  }
998  } SMARTLIST_FOREACH_END(param);
999 
1000  smartlist_free(param_list);
1001  tor_free(vals);
1002  return output;
1003 }
1004 
1005 #define RANGE_CHECK(a,b,c,d,e,f,g,mx) \
1006  ((a) >= 0 && (a) <= (mx) && (b) >= 0 && (b) <= (mx) && \
1007  (c) >= 0 && (c) <= (mx) && (d) >= 0 && (d) <= (mx) && \
1008  (e) >= 0 && (e) <= (mx) && (f) >= 0 && (f) <= (mx) && \
1009  (g) >= 0 && (g) <= (mx))
1010 
1011 #define CHECK_EQ(a, b, margin) \
1012  ((a)-(b) >= 0 ? (a)-(b) <= (margin) : (b)-(a) <= (margin))
1013 
1014 typedef enum {
1015  BW_WEIGHTS_NO_ERROR = 0,
1016  BW_WEIGHTS_RANGE_ERROR = 1,
1017  BW_WEIGHTS_SUMG_ERROR = 2,
1018  BW_WEIGHTS_SUME_ERROR = 3,
1019  BW_WEIGHTS_SUMD_ERROR = 4,
1020  BW_WEIGHTS_BALANCE_MID_ERROR = 5,
1021  BW_WEIGHTS_BALANCE_EG_ERROR = 6
1022 } bw_weights_error_t;
1023 
1024 /**
1025  * Verify that any weightings satisfy the balanced formulas.
1026  */
1027 static bw_weights_error_t
1028 networkstatus_check_weights(int64_t Wgg, int64_t Wgd, int64_t Wmg,
1029  int64_t Wme, int64_t Wmd, int64_t Wee,
1030  int64_t Wed, int64_t scale, int64_t G,
1031  int64_t M, int64_t E, int64_t D, int64_t T,
1032  int64_t margin, int do_balance) {
1033  bw_weights_error_t berr = BW_WEIGHTS_NO_ERROR;
1034 
1035  // Wed + Wmd + Wgd == 1
1036  if (!CHECK_EQ(Wed + Wmd + Wgd, scale, margin)) {
1037  berr = BW_WEIGHTS_SUMD_ERROR;
1038  goto out;
1039  }
1040 
1041  // Wmg + Wgg == 1
1042  if (!CHECK_EQ(Wmg + Wgg, scale, margin)) {
1043  berr = BW_WEIGHTS_SUMG_ERROR;
1044  goto out;
1045  }
1046 
1047  // Wme + Wee == 1
1048  if (!CHECK_EQ(Wme + Wee, scale, margin)) {
1049  berr = BW_WEIGHTS_SUME_ERROR;
1050  goto out;
1051  }
1052 
1053  // Verify weights within range 0->1
1054  if (!RANGE_CHECK(Wgg, Wgd, Wmg, Wme, Wmd, Wed, Wee, scale)) {
1055  berr = BW_WEIGHTS_RANGE_ERROR;
1056  goto out;
1057  }
1058 
1059  if (do_balance) {
1060  // Wgg*G + Wgd*D == Wee*E + Wed*D, already scaled
1061  if (!CHECK_EQ(Wgg*G + Wgd*D, Wee*E + Wed*D, (margin*T)/3)) {
1062  berr = BW_WEIGHTS_BALANCE_EG_ERROR;
1063  goto out;
1064  }
1065 
1066  // Wgg*G + Wgd*D == M*scale + Wmd*D + Wme*E + Wmg*G, already scaled
1067  if (!CHECK_EQ(Wgg*G + Wgd*D, M*scale + Wmd*D + Wme*E + Wmg*G,
1068  (margin*T)/3)) {
1069  berr = BW_WEIGHTS_BALANCE_MID_ERROR;
1070  goto out;
1071  }
1072  }
1073 
1074  out:
1075  if (berr) {
1076  log_info(LD_DIR,
1077  "Bw weight mismatch %d. G=%"PRId64" M=%"PRId64
1078  " E=%"PRId64" D=%"PRId64" T=%"PRId64
1079  " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1080  " Wgd=%d Wgg=%d Wme=%d Wmg=%d",
1081  berr,
1082  (G), (M), (E),
1083  (D), (T),
1084  (int)Wmd, (int)Wme, (int)Wmg, (int)Wed, (int)Wee,
1085  (int)Wgd, (int)Wgg, (int)Wme, (int)Wmg);
1086  }
1087 
1088  return berr;
1089 }
1090 
1091 /**
1092  * This function computes the bandwidth weights for consensus method 10.
1093  *
1094  * It returns true if weights could be computed, false otherwise.
1095  */
1096 int
1098  int64_t M, int64_t E, int64_t D,
1099  int64_t T, int64_t weight_scale)
1100 {
1101  bw_weights_error_t berr = 0;
1102  int64_t Wgg = -1, Wgd = -1;
1103  int64_t Wmg = -1, Wme = -1, Wmd = -1;
1104  int64_t Wed = -1, Wee = -1;
1105  const char *casename;
1106 
1107  if (G <= 0 || M <= 0 || E <= 0 || D <= 0) {
1108  log_warn(LD_DIR, "Consensus with empty bandwidth: "
1109  "G=%"PRId64" M=%"PRId64" E=%"PRId64
1110  " D=%"PRId64" T=%"PRId64,
1111  (G), (M), (E),
1112  (D), (T));
1113  return 0;
1114  }
1115 
1116  /*
1117  * Computed from cases in 3.8.3 of dir-spec.txt
1118  *
1119  * 1. Neither are scarce
1120  * 2. Both Guard and Exit are scarce
1121  * a. R+D <= S
1122  * b. R+D > S
1123  * 3. One of Guard or Exit is scarce
1124  * a. S+D < T/3
1125  * b. S+D >= T/3
1126  */
1127  if (3*E >= T && 3*G >= T) { // E >= T/3 && G >= T/3
1128  /* Case 1: Neither are scarce. */
1129  casename = "Case 1 (Wgd=Wmd=Wed)";
1130  Wgd = weight_scale/3;
1131  Wed = weight_scale/3;
1132  Wmd = weight_scale/3;
1133  Wee = (weight_scale*(E+G+M))/(3*E);
1134  Wme = weight_scale - Wee;
1135  Wmg = (weight_scale*(2*G-E-M))/(3*G);
1136  Wgg = weight_scale - Wmg;
1137 
1138  berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed,
1139  weight_scale, G, M, E, D, T, 10, 1);
1140 
1141  if (berr) {
1142  log_warn(LD_DIR,
1143  "Bw Weights error %d for %s v10. G=%"PRId64" M=%"PRId64
1144  " E=%"PRId64" D=%"PRId64" T=%"PRId64
1145  " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1146  " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
1147  berr, casename,
1148  (G), (M), (E),
1149  (D), (T),
1150  (int)Wmd, (int)Wme, (int)Wmg, (int)Wed, (int)Wee,
1151  (int)Wgd, (int)Wgg, (int)Wme, (int)Wmg, (int)weight_scale);
1152  return 0;
1153  }
1154  } else if (3*E < T && 3*G < T) { // E < T/3 && G < T/3
1155  int64_t R = MIN(E, G);
1156  int64_t S = MAX(E, G);
1157  /*
1158  * Case 2: Both Guards and Exits are scarce
1159  * Balance D between E and G, depending upon
1160  * D capacity and scarcity.
1161  */
1162  if (R+D < S) { // Subcase a
1163  Wgg = weight_scale;
1164  Wee = weight_scale;
1165  Wmg = 0;
1166  Wme = 0;
1167  Wmd = 0;
1168  if (E < G) {
1169  casename = "Case 2a (E scarce)";
1170  Wed = weight_scale;
1171  Wgd = 0;
1172  } else { /* E >= G */
1173  casename = "Case 2a (G scarce)";
1174  Wed = 0;
1175  Wgd = weight_scale;
1176  }
1177  } else { // Subcase b: R+D >= S
1178  casename = "Case 2b1 (Wgg=weight_scale, Wmd=Wgd)";
1179  Wee = (weight_scale*(E - G + M))/E;
1180  Wed = (weight_scale*(D - 2*E + 4*G - 2*M))/(3*D);
1181  Wme = (weight_scale*(G-M))/E;
1182  Wmg = 0;
1183  Wgg = weight_scale;
1184  Wmd = (weight_scale - Wed)/2;
1185  Wgd = (weight_scale - Wed)/2;
1186 
1187  berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed,
1188  weight_scale, G, M, E, D, T, 10, 1);
1189 
1190  if (berr) {
1191  casename = "Case 2b2 (Wgg=weight_scale, Wee=weight_scale)";
1192  Wgg = weight_scale;
1193  Wee = weight_scale;
1194  Wed = (weight_scale*(D - 2*E + G + M))/(3*D);
1195  Wmd = (weight_scale*(D - 2*M + G + E))/(3*D);
1196  Wme = 0;
1197  Wmg = 0;
1198 
1199  if (Wmd < 0) { // Can happen if M > T/3
1200  casename = "Case 2b3 (Wmd=0)";
1201  Wmd = 0;
1202  log_warn(LD_DIR,
1203  "Too much Middle bandwidth on the network to calculate "
1204  "balanced bandwidth-weights. Consider increasing the "
1205  "number of Guard nodes by lowering the requirements.");
1206  }
1207  Wgd = weight_scale - Wed - Wmd;
1208  berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
1209  Wed, weight_scale, G, M, E, D, T, 10, 1);
1210  }
1211  if (berr != BW_WEIGHTS_NO_ERROR &&
1212  berr != BW_WEIGHTS_BALANCE_MID_ERROR) {
1213  log_warn(LD_DIR,
1214  "Bw Weights error %d for %s v10. G=%"PRId64" M=%"PRId64
1215  " E=%"PRId64" D=%"PRId64" T=%"PRId64
1216  " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1217  " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
1218  berr, casename,
1219  (G), (M), (E),
1220  (D), (T),
1221  (int)Wmd, (int)Wme, (int)Wmg, (int)Wed, (int)Wee,
1222  (int)Wgd, (int)Wgg, (int)Wme, (int)Wmg, (int)weight_scale);
1223  return 0;
1224  }
1225  }
1226  } else { // if (E < T/3 || G < T/3) {
1227  int64_t S = MIN(E, G);
1228  // Case 3: Exactly one of Guard or Exit is scarce
1229  if (!(3*E < T || 3*G < T) || !(3*G >= T || 3*E >= T)) {
1230  log_warn(LD_BUG,
1231  "Bw-Weights Case 3 v10 but with G=%"PRId64" M="
1232  "%"PRId64" E=%"PRId64" D=%"PRId64" T=%"PRId64,
1233  (G), (M), (E),
1234  (D), (T));
1235  }
1236 
1237  if (3*(S+D) < T) { // Subcase a: S+D < T/3
1238  if (G < E) {
1239  casename = "Case 3a (G scarce)";
1240  Wgg = Wgd = weight_scale;
1241  Wmd = Wed = Wmg = 0;
1242  // Minor subcase, if E is more scarce than M,
1243  // keep its bandwidth in place.
1244  if (E < M) Wme = 0;
1245  else Wme = (weight_scale*(E-M))/(2*E);
1246  Wee = weight_scale-Wme;
1247  } else { // G >= E
1248  casename = "Case 3a (E scarce)";
1249  Wee = Wed = weight_scale;
1250  Wmd = Wgd = Wme = 0;
1251  // Minor subcase, if G is more scarce than M,
1252  // keep its bandwidth in place.
1253  if (G < M) Wmg = 0;
1254  else Wmg = (weight_scale*(G-M))/(2*G);
1255  Wgg = weight_scale-Wmg;
1256  }
1257  } else { // Subcase b: S+D >= T/3
1258  // D != 0 because S+D >= T/3
1259  if (G < E) {
1260  casename = "Case 3bg (G scarce, Wgg=weight_scale, Wmd == Wed)";
1261  Wgg = weight_scale;
1262  Wgd = (weight_scale*(D - 2*G + E + M))/(3*D);
1263  Wmg = 0;
1264  Wee = (weight_scale*(E+M))/(2*E);
1265  Wme = weight_scale - Wee;
1266  Wmd = (weight_scale - Wgd)/2;
1267  Wed = (weight_scale - Wgd)/2;
1268 
1269  berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
1270  Wed, weight_scale, G, M, E, D, T, 10, 1);
1271  } else { // G >= E
1272  casename = "Case 3be (E scarce, Wee=weight_scale, Wmd == Wgd)";
1273  Wee = weight_scale;
1274  Wed = (weight_scale*(D - 2*E + G + M))/(3*D);
1275  Wme = 0;
1276  Wgg = (weight_scale*(G+M))/(2*G);
1277  Wmg = weight_scale - Wgg;
1278  Wmd = (weight_scale - Wed)/2;
1279  Wgd = (weight_scale - Wed)/2;
1280 
1281  berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
1282  Wed, weight_scale, G, M, E, D, T, 10, 1);
1283  }
1284  if (berr) {
1285  log_warn(LD_DIR,
1286  "Bw Weights error %d for %s v10. G=%"PRId64" M=%"PRId64
1287  " E=%"PRId64" D=%"PRId64" T=%"PRId64
1288  " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1289  " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
1290  berr, casename,
1291  (G), (M), (E),
1292  (D), (T),
1293  (int)Wmd, (int)Wme, (int)Wmg, (int)Wed, (int)Wee,
1294  (int)Wgd, (int)Wgg, (int)Wme, (int)Wmg, (int)weight_scale);
1295  return 0;
1296  }
1297  }
1298  }
1299 
1300  /* We cast down the weights to 32 bit ints on the assumption that
1301  * weight_scale is ~= 10000. We need to ensure a rogue authority
1302  * doesn't break this assumption to rig our weights */
1303  tor_assert(0 < weight_scale && weight_scale <= INT32_MAX);
1304 
1305  /*
1306  * Provide Wgm=Wgg, Wmm=weight_scale, Wem=Wee, Weg=Wed. May later determine
1307  * that middle nodes need different bandwidth weights for dirport traffic,
1308  * or that weird exit policies need special weight, or that bridges
1309  * need special weight.
1310  *
1311  * NOTE: This list is sorted.
1312  */
1313  smartlist_add_asprintf(chunks,
1314  "bandwidth-weights Wbd=%d Wbe=%d Wbg=%d Wbm=%d "
1315  "Wdb=%d "
1316  "Web=%d Wed=%d Wee=%d Weg=%d Wem=%d "
1317  "Wgb=%d Wgd=%d Wgg=%d Wgm=%d "
1318  "Wmb=%d Wmd=%d Wme=%d Wmg=%d Wmm=%d\n",
1319  (int)Wmd, (int)Wme, (int)Wmg, (int)weight_scale,
1320  (int)weight_scale,
1321  (int)weight_scale, (int)Wed, (int)Wee, (int)Wed, (int)Wee,
1322  (int)weight_scale, (int)Wgd, (int)Wgg, (int)Wgg,
1323  (int)weight_scale, (int)Wmd, (int)Wme, (int)Wmg, (int)weight_scale);
1324 
1325  log_notice(LD_CIRC, "Computed bandwidth weights for %s with v10: "
1326  "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64
1327  " T=%"PRId64,
1328  casename,
1329  (G), (M), (E),
1330  (D), (T));
1331  return 1;
1332 }
1333 
1334 /** Update total bandwidth weights (G/M/E/D/T) with the bandwidth of
1335  * the router in <b>rs</b>. */
1336 static void
1338  int is_exit, int is_guard,
1339  int64_t *G, int64_t *M, int64_t *E, int64_t *D,
1340  int64_t *T)
1341 {
1342  int default_bandwidth = rs->bandwidth_kb;
1343  int guardfraction_bandwidth = 0;
1344 
1345  if (!rs->has_bandwidth) {
1346  log_info(LD_BUG, "Missing consensus bandwidth for router %s",
1347  rs->nickname);
1348  return;
1349  }
1350 
1351  /* If this routerstatus represents a guard that we have
1352  * guardfraction information on, use it to calculate its actual
1353  * bandwidth. From proposal236:
1354  *
1355  * Similarly, when calculating the bandwidth-weights line as in
1356  * section 3.8.3 of dir-spec.txt, directory authorities should treat N
1357  * as if fraction F of its bandwidth has the guard flag and (1-F) does
1358  * not. So when computing the totals G,M,E,D, each relay N with guard
1359  * visibility fraction F and bandwidth B should be added as follows:
1360  *
1361  * G' = G + F*B, if N does not have the exit flag
1362  * M' = M + (1-F)*B, if N does not have the exit flag
1363  *
1364  * or
1365  *
1366  * D' = D + F*B, if N has the exit flag
1367  * E' = E + (1-F)*B, if N has the exit flag
1368  *
1369  * In this block of code, we prepare the bandwidth values by setting
1370  * the default_bandwidth to F*B and guardfraction_bandwidth to (1-F)*B.
1371  */
1372  if (rs->has_guardfraction) {
1373  guardfraction_bandwidth_t guardfraction_bw;
1374 
1375  tor_assert(is_guard);
1376 
1377  guard_get_guardfraction_bandwidth(&guardfraction_bw,
1378  rs->bandwidth_kb,
1380 
1381  default_bandwidth = guardfraction_bw.guard_bw;
1382  guardfraction_bandwidth = guardfraction_bw.non_guard_bw;
1383  }
1384 
1385  /* Now calculate the total bandwidth weights with or without
1386  * guardfraction. Depending on the flags of the relay, add its
1387  * bandwidth to the appropriate weight pool. If it's a guard and
1388  * guardfraction is enabled, add its bandwidth to both pools as
1389  * indicated by the previous comment.
1390  */
1391  *T += default_bandwidth;
1392  if (is_exit && is_guard) {
1393 
1394  *D += default_bandwidth;
1395  if (rs->has_guardfraction) {
1396  *E += guardfraction_bandwidth;
1397  }
1398 
1399  } else if (is_exit) {
1400 
1401  *E += default_bandwidth;
1402 
1403  } else if (is_guard) {
1404 
1405  *G += default_bandwidth;
1406  if (rs->has_guardfraction) {
1407  *M += guardfraction_bandwidth;
1408  }
1409 
1410  } else {
1411 
1412  *M += default_bandwidth;
1413  }
1414 }
1415 
1416 /** Considering the different recommended/required protocols sets as a
1417  * 4-element array, return the element from <b>vote</b> for that protocol
1418  * set.
1419  */
1420 static const char *
1422 {
1423  switch (n) {
1424  case 0: return vote->recommended_client_protocols;
1425  case 1: return vote->recommended_relay_protocols;
1426  case 2: return vote->required_client_protocols;
1427  case 3: return vote->required_relay_protocols;
1428  default:
1429  tor_assert_unreached();
1430  return NULL;
1431  }
1432 }
1433 
1434 /** Considering the different recommended/required protocols sets as a
1435  * 4-element array, return a newly allocated string for the consensus value
1436  * for the n'th set.
1437  */
1438 static char *
1439 compute_nth_protocol_set(int n, int n_voters, const smartlist_t *votes)
1440 {
1441  const char *keyword;
1442  smartlist_t *proto_votes = smartlist_new();
1443  int threshold;
1444  switch (n) {
1445  case 0:
1446  keyword = "recommended-client-protocols";
1447  threshold = CEIL_DIV(n_voters, 2);
1448  break;
1449  case 1:
1450  keyword = "recommended-relay-protocols";
1451  threshold = CEIL_DIV(n_voters, 2);
1452  break;
1453  case 2:
1454  keyword = "required-client-protocols";
1455  threshold = CEIL_DIV(n_voters * 2, 3);
1456  break;
1457  case 3:
1458  keyword = "required-relay-protocols";
1459  threshold = CEIL_DIV(n_voters * 2, 3);
1460  break;
1461  default:
1462  tor_assert_unreached();
1463  return NULL;
1464  }
1465 
1466  SMARTLIST_FOREACH_BEGIN(votes, const networkstatus_t *, ns) {
1467  const char *v = get_nth_protocol_set_vote(n, ns);
1468  if (v)
1469  smartlist_add(proto_votes, (void*)v);
1470  } SMARTLIST_FOREACH_END(ns);
1471 
1472  char *protocols = protover_compute_vote(proto_votes, threshold);
1473  smartlist_free(proto_votes);
1474 
1475  char *result = NULL;
1476  tor_asprintf(&result, "%s %s\n", keyword, protocols);
1477  tor_free(protocols);
1478 
1479  return result;
1480 }
1481 
1482 /** Given a list of vote networkstatus_t in <b>votes</b>, our public
1483  * authority <b>identity_key</b>, our private authority <b>signing_key</b>,
1484  * and the number of <b>total_authorities</b> that we believe exist in our
1485  * voting quorum, generate the text of a new v3 consensus or microdescriptor
1486  * consensus (depending on <b>flavor</b>), and return the value in a newly
1487  * allocated string.
1488  *
1489  * Note: this function DOES NOT check whether the votes are from
1490  * recognized authorities. (dirvote_add_vote does that.)
1491  *
1492  * <strong>WATCH OUT</strong>: You need to think before you change the
1493  * behavior of this function, or of the functions it calls! If some
1494  * authorities compute the consensus with a different algorithm than
1495  * others, they will not reach the same result, and they will not all
1496  * sign the same thing! If you really need to change the algorithm
1497  * here, you should allocate a new "consensus_method" for the new
1498  * behavior, and make the new behavior conditional on a new-enough
1499  * consensus_method.
1500  **/
1501 STATIC char *
1503  int total_authorities,
1504  crypto_pk_t *identity_key,
1505  crypto_pk_t *signing_key,
1506  const char *legacy_id_key_digest,
1508  consensus_flavor_t flavor)
1509 {
1510  smartlist_t *chunks;
1511  char *result = NULL;
1512  int consensus_method;
1513  time_t valid_after, fresh_until, valid_until;
1514  int vote_seconds, dist_seconds;
1515  char *client_versions = NULL, *server_versions = NULL;
1516  smartlist_t *flags;
1517  const char *flavor_name;
1518  uint32_t max_unmeasured_bw_kb = DEFAULT_MAX_UNMEASURED_BW_KB;
1519  int64_t G, M, E, D, T; /* For bandwidth weights */
1520  const routerstatus_format_type_t rs_format =
1521  flavor == FLAV_NS ? NS_V3_CONSENSUS : NS_V3_CONSENSUS_MICRODESC;
1522  char *params = NULL;
1523  char *packages = NULL;
1524  int added_weights = 0;
1525  dircollator_t *collator = NULL;
1526  smartlist_t *param_list = NULL;
1527 
1528  tor_assert(flavor == FLAV_NS || flavor == FLAV_MICRODESC);
1529  tor_assert(total_authorities >= smartlist_len(votes));
1530  tor_assert(total_authorities > 0);
1531 
1532  flavor_name = networkstatus_get_flavor_name(flavor);
1533 
1534  if (!smartlist_len(votes)) {
1535  log_warn(LD_DIR, "Can't compute a consensus from no votes.");
1536  return NULL;
1537  }
1538  flags = smartlist_new();
1539 
1540  consensus_method = compute_consensus_method(votes);
1541  if (consensus_method_is_supported(consensus_method)) {
1542  log_info(LD_DIR, "Generating consensus using method %d.",
1543  consensus_method);
1544  } else {
1545  log_warn(LD_DIR, "The other authorities will use consensus method %d, "
1546  "which I don't support. Maybe I should upgrade!",
1547  consensus_method);
1548  consensus_method = MAX_SUPPORTED_CONSENSUS_METHOD;
1549  }
1550 
1551  {
1552  /* It's smarter to initialize these weights to 1, so that later on,
1553  * we can't accidentally divide by zero. */
1554  G = M = E = D = 1;
1555  T = 4;
1556  }
1557 
1558  /* Compute medians of time-related things, and figure out how many
1559  * routers we might need to talk about. */
1560  {
1561  int n_votes = smartlist_len(votes);
1562  time_t *va_times = tor_calloc(n_votes, sizeof(time_t));
1563  time_t *fu_times = tor_calloc(n_votes, sizeof(time_t));
1564  time_t *vu_times = tor_calloc(n_votes, sizeof(time_t));
1565  int *votesec_list = tor_calloc(n_votes, sizeof(int));
1566  int *distsec_list = tor_calloc(n_votes, sizeof(int));
1567  int n_versioning_clients = 0, n_versioning_servers = 0;
1568  smartlist_t *combined_client_versions = smartlist_new();
1569  smartlist_t *combined_server_versions = smartlist_new();
1570 
1572  tor_assert(v->type == NS_TYPE_VOTE);
1573  va_times[v_sl_idx] = v->valid_after;
1574  fu_times[v_sl_idx] = v->fresh_until;
1575  vu_times[v_sl_idx] = v->valid_until;
1576  votesec_list[v_sl_idx] = v->vote_seconds;
1577  distsec_list[v_sl_idx] = v->dist_seconds;
1578  if (v->client_versions) {
1579  smartlist_t *cv = smartlist_new();
1580  ++n_versioning_clients;
1581  smartlist_split_string(cv, v->client_versions, ",",
1582  SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1583  sort_version_list(cv, 1);
1584  smartlist_add_all(combined_client_versions, cv);
1585  smartlist_free(cv); /* elements get freed later. */
1586  }
1587  if (v->server_versions) {
1588  smartlist_t *sv = smartlist_new();
1589  ++n_versioning_servers;
1590  smartlist_split_string(sv, v->server_versions, ",",
1591  SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1592  sort_version_list(sv, 1);
1593  smartlist_add_all(combined_server_versions, sv);
1594  smartlist_free(sv); /* elements get freed later. */
1595  }
1596  SMARTLIST_FOREACH(v->known_flags, const char *, cp,
1597  smartlist_add_strdup(flags, cp));
1598  } SMARTLIST_FOREACH_END(v);
1599  valid_after = median_time(va_times, n_votes);
1600  fresh_until = median_time(fu_times, n_votes);
1601  valid_until = median_time(vu_times, n_votes);
1602  vote_seconds = median_int(votesec_list, n_votes);
1603  dist_seconds = median_int(distsec_list, n_votes);
1604 
1605  tor_assert(valid_after +
1606  (get_options()->TestingTorNetwork ?
1607  MIN_VOTE_INTERVAL_TESTING : MIN_VOTE_INTERVAL) <= fresh_until);
1608  tor_assert(fresh_until +
1609  (get_options()->TestingTorNetwork ?
1610  MIN_VOTE_INTERVAL_TESTING : MIN_VOTE_INTERVAL) <= valid_until);
1611  tor_assert(vote_seconds >= MIN_VOTE_SECONDS);
1612  tor_assert(dist_seconds >= MIN_DIST_SECONDS);
1613 
1614  server_versions = compute_consensus_versions_list(combined_server_versions,
1615  n_versioning_servers);
1616  client_versions = compute_consensus_versions_list(combined_client_versions,
1617  n_versioning_clients);
1618  packages = compute_consensus_package_lines(votes);
1619 
1620  SMARTLIST_FOREACH(combined_server_versions, char *, cp, tor_free(cp));
1621  SMARTLIST_FOREACH(combined_client_versions, char *, cp, tor_free(cp));
1622  smartlist_free(combined_server_versions);
1623  smartlist_free(combined_client_versions);
1624 
1625  smartlist_add_strdup(flags, "NoEdConsensus");
1626 
1627  smartlist_sort_strings(flags);
1628  smartlist_uniq_strings(flags);
1629 
1630  tor_free(va_times);
1631  tor_free(fu_times);
1632  tor_free(vu_times);
1633  tor_free(votesec_list);
1634  tor_free(distsec_list);
1635  }
1636 
1637  chunks = smartlist_new();
1638 
1639  {
1640  char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
1641  vu_buf[ISO_TIME_LEN+1];
1642  char *flaglist;
1643  format_iso_time(va_buf, valid_after);
1644  format_iso_time(fu_buf, fresh_until);
1645  format_iso_time(vu_buf, valid_until);
1646  flaglist = smartlist_join_strings(flags, " ", 0, NULL);
1647 
1648  smartlist_add_asprintf(chunks, "network-status-version 3%s%s\n"
1649  "vote-status consensus\n",
1650  flavor == FLAV_NS ? "" : " ",
1651  flavor == FLAV_NS ? "" : flavor_name);
1652 
1653  smartlist_add_asprintf(chunks, "consensus-method %d\n",
1654  consensus_method);
1655 
1656  smartlist_add_asprintf(chunks,
1657  "valid-after %s\n"
1658  "fresh-until %s\n"
1659  "valid-until %s\n"
1660  "voting-delay %d %d\n"
1661  "client-versions %s\n"
1662  "server-versions %s\n"
1663  "%s" /* packages */
1664  "known-flags %s\n",
1665  va_buf, fu_buf, vu_buf,
1666  vote_seconds, dist_seconds,
1667  client_versions, server_versions,
1668  packages,
1669  flaglist);
1670 
1671  tor_free(flaglist);
1672  }
1673 
1674  {
1675  int num_dirauth = get_n_authorities(V3_DIRINFO);
1676  int idx;
1677  for (idx = 0; idx < 4; ++idx) {
1678  char *proto_line = compute_nth_protocol_set(idx, num_dirauth, votes);
1679  if (BUG(!proto_line))
1680  continue;
1681  smartlist_add(chunks, proto_line);
1682  }
1683  }
1684 
1685  param_list = dirvote_compute_params(votes, consensus_method,
1686  total_authorities);
1687  if (smartlist_len(param_list)) {
1688  params = smartlist_join_strings(param_list, " ", 0, NULL);
1689  smartlist_add_strdup(chunks, "params ");
1690  smartlist_add(chunks, params);
1691  smartlist_add_strdup(chunks, "\n");
1692  }
1693 
1694  {
1695  int num_dirauth = get_n_authorities(V3_DIRINFO);
1696  /* Default value of this is 2/3 of the total number of authorities. For
1697  * instance, if we have 9 dirauth, the default value is 6. The following
1698  * calculation will round it down. */
1699  int32_t num_srv_agreements =
1701  "AuthDirNumSRVAgreements",
1702  (num_dirauth * 2) / 3);
1703  /* Add the shared random value. */
1704  char *srv_lines = sr_get_string_for_consensus(votes, num_srv_agreements);
1705  if (srv_lines != NULL) {
1706  smartlist_add(chunks, srv_lines);
1707  }
1708  }
1709 
1710  /* Sort the votes. */
1712  /* Add the authority sections. */
1713  {
1714  smartlist_t *dir_sources = smartlist_new();
1716  dir_src_ent_t *e = tor_malloc_zero(sizeof(dir_src_ent_t));
1717  e->v = v;
1718  e->digest = get_voter(v)->identity_digest;
1719  e->is_legacy = 0;
1720  smartlist_add(dir_sources, e);
1721  if (!tor_digest_is_zero(get_voter(v)->legacy_id_digest)) {
1722  dir_src_ent_t *e_legacy = tor_malloc_zero(sizeof(dir_src_ent_t));
1723  e_legacy->v = v;
1724  e_legacy->digest = get_voter(v)->legacy_id_digest;
1725  e_legacy->is_legacy = 1;
1726  smartlist_add(dir_sources, e_legacy);
1727  }
1728  } SMARTLIST_FOREACH_END(v);
1730 
1731  SMARTLIST_FOREACH_BEGIN(dir_sources, const dir_src_ent_t *, e) {
1732  char fingerprint[HEX_DIGEST_LEN+1];
1733  char votedigest[HEX_DIGEST_LEN+1];
1734  networkstatus_t *v = e->v;
1736 
1737  base16_encode(fingerprint, sizeof(fingerprint), e->digest, DIGEST_LEN);
1738  base16_encode(votedigest, sizeof(votedigest), voter->vote_digest,
1739  DIGEST_LEN);
1740 
1741  smartlist_add_asprintf(chunks,
1742  "dir-source %s%s %s %s %s %d %d\n",
1743  voter->nickname, e->is_legacy ? "-legacy" : "",
1744  fingerprint, voter->address, fmt_addr(&voter->ipv4_addr),
1745  voter->ipv4_dirport,
1746  voter->ipv4_orport);
1747  if (! e->is_legacy) {
1748  smartlist_add_asprintf(chunks,
1749  "contact %s\n"
1750  "vote-digest %s\n",
1751  voter->contact,
1752  votedigest);
1753  }
1754  } SMARTLIST_FOREACH_END(e);
1755  SMARTLIST_FOREACH(dir_sources, dir_src_ent_t *, e, tor_free(e));
1756  smartlist_free(dir_sources);
1757  }
1758 
1759  {
1760  if (consensus_method < MIN_METHOD_FOR_CORRECT_BWWEIGHTSCALE) {
1761  max_unmeasured_bw_kb = (int32_t) extract_param_buggy(
1762  params, "maxunmeasuredbw", DEFAULT_MAX_UNMEASURED_BW_KB);
1763  } else {
1764  max_unmeasured_bw_kb = dirvote_get_intermediate_param_value(
1765  param_list, "maxunmeasurdbw", DEFAULT_MAX_UNMEASURED_BW_KB);
1766  if (max_unmeasured_bw_kb < 1)
1767  max_unmeasured_bw_kb = 1;
1768  }
1769  }
1770 
1771  /* Add the actual router entries. */
1772  {
1773  int *size; /* size[j] is the number of routerstatuses in votes[j]. */
1774  int *flag_counts; /* The number of voters that list flag[j] for the
1775  * currently considered router. */
1776  int i;
1777  smartlist_t *matching_descs = smartlist_new();
1778  smartlist_t *chosen_flags = smartlist_new();
1779  smartlist_t *versions = smartlist_new();
1780  smartlist_t *protocols = smartlist_new();
1781  smartlist_t *exitsummaries = smartlist_new();
1782  uint32_t *bandwidths_kb = tor_calloc(smartlist_len(votes),
1783  sizeof(uint32_t));
1784  uint32_t *measured_bws_kb = tor_calloc(smartlist_len(votes),
1785  sizeof(uint32_t));
1786  uint32_t *measured_guardfraction = tor_calloc(smartlist_len(votes),
1787  sizeof(uint32_t));
1788  int num_bandwidths;
1789  int num_mbws;
1790  int num_guardfraction_inputs;
1791 
1792  int *n_voter_flags; /* n_voter_flags[j] is the number of flags that
1793  * votes[j] knows about. */
1794  int *n_flag_voters; /* n_flag_voters[f] is the number of votes that care
1795  * about flags[f]. */
1796  int **flag_map; /* flag_map[j][b] is an index f such that flag_map[f]
1797  * is the same flag as votes[j]->known_flags[b]. */
1798  int *named_flag; /* Index of the flag "Named" for votes[j] */
1799  int *unnamed_flag; /* Index of the flag "Unnamed" for votes[j] */
1800  int n_authorities_measuring_bandwidth;
1801 
1802  strmap_t *name_to_id_map = strmap_new();
1803  char conflict[DIGEST_LEN];
1804  char unknown[DIGEST_LEN];
1805  memset(conflict, 0, sizeof(conflict));
1806  memset(unknown, 0xff, sizeof(conflict));
1807 
1808  size = tor_calloc(smartlist_len(votes), sizeof(int));
1809  n_voter_flags = tor_calloc(smartlist_len(votes), sizeof(int));
1810  n_flag_voters = tor_calloc(smartlist_len(flags), sizeof(int));
1811  flag_map = tor_calloc(smartlist_len(votes), sizeof(int *));
1812  named_flag = tor_calloc(smartlist_len(votes), sizeof(int));
1813  unnamed_flag = tor_calloc(smartlist_len(votes), sizeof(int));
1814  for (i = 0; i < smartlist_len(votes); ++i)
1815  unnamed_flag[i] = named_flag[i] = -1;
1816 
1817  /* Build the flag indexes. Note that no vote can have more than 64 members
1818  * for known_flags, so no value will be greater than 63, so it's safe to
1819  * do UINT64_C(1) << index on these values. But note also that
1820  * named_flag and unnamed_flag are initialized to -1, so we need to check
1821  * that they're actually set before doing UINT64_C(1) << index with
1822  * them.*/
1824  flag_map[v_sl_idx] = tor_calloc(smartlist_len(v->known_flags),
1825  sizeof(int));
1826  if (smartlist_len(v->known_flags) > MAX_KNOWN_FLAGS_IN_VOTE) {
1827  log_warn(LD_BUG, "Somehow, a vote has %d entries in known_flags",
1828  smartlist_len(v->known_flags));
1829  }
1830  SMARTLIST_FOREACH_BEGIN(v->known_flags, const char *, fl) {
1831  int p = smartlist_string_pos(flags, fl);
1832  tor_assert(p >= 0);
1833  flag_map[v_sl_idx][fl_sl_idx] = p;
1834  ++n_flag_voters[p];
1835  if (!strcmp(fl, "Named"))
1836  named_flag[v_sl_idx] = fl_sl_idx;
1837  if (!strcmp(fl, "Unnamed"))
1838  unnamed_flag[v_sl_idx] = fl_sl_idx;
1839  } SMARTLIST_FOREACH_END(fl);
1840  n_voter_flags[v_sl_idx] = smartlist_len(v->known_flags);
1841  size[v_sl_idx] = smartlist_len(v->routerstatus_list);
1842  } SMARTLIST_FOREACH_END(v);
1843 
1844  /* Named and Unnamed get treated specially */
1845  {
1847  uint64_t nf;
1848  if (named_flag[v_sl_idx]<0)
1849  continue;
1850  nf = UINT64_C(1) << named_flag[v_sl_idx];
1851  SMARTLIST_FOREACH_BEGIN(v->routerstatus_list,
1852  vote_routerstatus_t *, rs) {
1853 
1854  if ((rs->flags & nf) != 0) {
1855  const char *d = strmap_get_lc(name_to_id_map, rs->status.nickname);
1856  if (!d) {
1857  /* We have no name officially mapped to this digest. */
1858  strmap_set_lc(name_to_id_map, rs->status.nickname,
1859  rs->status.identity_digest);
1860  } else if (d != conflict &&
1861  fast_memcmp(d, rs->status.identity_digest, DIGEST_LEN)) {
1862  /* Authorities disagree about this nickname. */
1863  strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
1864  } else {
1865  /* It's already a conflict, or it's already this ID. */
1866  }
1867  }
1868  } SMARTLIST_FOREACH_END(rs);
1869  } SMARTLIST_FOREACH_END(v);
1870 
1872  uint64_t uf;
1873  if (unnamed_flag[v_sl_idx]<0)
1874  continue;
1875  uf = UINT64_C(1) << unnamed_flag[v_sl_idx];
1876  SMARTLIST_FOREACH_BEGIN(v->routerstatus_list,
1877  vote_routerstatus_t *, rs) {
1878  if ((rs->flags & uf) != 0) {
1879  const char *d = strmap_get_lc(name_to_id_map, rs->status.nickname);
1880  if (d == conflict || d == unknown) {
1881  /* Leave it alone; we know what it is. */
1882  } else if (!d) {
1883  /* We have no name officially mapped to this digest. */
1884  strmap_set_lc(name_to_id_map, rs->status.nickname, unknown);
1885  } else if (fast_memeq(d, rs->status.identity_digest, DIGEST_LEN)) {
1886  /* Authorities disagree about this nickname. */
1887  strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
1888  } else {
1889  /* It's mapped to a different name. */
1890  }
1891  }
1892  } SMARTLIST_FOREACH_END(rs);
1893  } SMARTLIST_FOREACH_END(v);
1894  }
1895 
1896  /* We need to know how many votes measure bandwidth. */
1897  n_authorities_measuring_bandwidth = 0;
1898  SMARTLIST_FOREACH(votes, const networkstatus_t *, v,
1899  if (v->has_measured_bws) {
1900  ++n_authorities_measuring_bandwidth;
1901  }
1902  );
1903 
1904  /* Populate the collator */
1905  collator = dircollator_new(smartlist_len(votes), total_authorities);
1907  dircollator_add_vote(collator, v);
1908  } SMARTLIST_FOREACH_END(v);
1909 
1910  dircollator_collate(collator, consensus_method);
1911 
1912  /* Now go through all the votes */
1913  flag_counts = tor_calloc(smartlist_len(flags), sizeof(int));
1914  const int num_routers = dircollator_n_routers(collator);
1915  for (i = 0; i < num_routers; ++i) {
1916  vote_routerstatus_t **vrs_lst =
1917  dircollator_get_votes_for_router(collator, i);
1918 
1919  vote_routerstatus_t *rs;
1920  routerstatus_t rs_out;
1921  const char *current_rsa_id = NULL;
1922  const char *chosen_version;
1923  const char *chosen_protocol_list;
1924  const char *chosen_name = NULL;
1925  int exitsummary_disagreement = 0;
1926  int is_named = 0, is_unnamed = 0, is_running = 0, is_valid = 0;
1927  int is_guard = 0, is_exit = 0, is_bad_exit = 0;
1928  int naming_conflict = 0;
1929  int n_listing = 0;
1930  char microdesc_digest[DIGEST256_LEN];
1931  tor_addr_port_t alt_orport = {TOR_ADDR_NULL, 0};
1932 
1933  memset(flag_counts, 0, sizeof(int)*smartlist_len(flags));
1934  smartlist_clear(matching_descs);
1935  smartlist_clear(chosen_flags);
1936  smartlist_clear(versions);
1937  smartlist_clear(protocols);
1938  num_bandwidths = 0;
1939  num_mbws = 0;
1940  num_guardfraction_inputs = 0;
1941  int ed_consensus = 0;
1942  const uint8_t *ed_consensus_val = NULL;
1943 
1944  /* Okay, go through all the entries for this digest. */
1945  for (int voter_idx = 0; voter_idx < smartlist_len(votes); ++voter_idx) {
1946  if (vrs_lst[voter_idx] == NULL)
1947  continue; /* This voter had nothing to say about this entry. */
1948  rs = vrs_lst[voter_idx];
1949  ++n_listing;
1950 
1951  current_rsa_id = rs->status.identity_digest;
1952 
1953  smartlist_add(matching_descs, rs);
1954  if (rs->version && rs->version[0])
1955  smartlist_add(versions, rs->version);
1956 
1957  if (rs->protocols) {
1958  /* We include this one even if it's empty: voting for an
1959  * empty protocol list actually is meaningful. */
1960  smartlist_add(protocols, rs->protocols);
1961  }
1962 
1963  /* Tally up all the flags. */
1964  for (int flag = 0; flag < n_voter_flags[voter_idx]; ++flag) {
1965  if (rs->flags & (UINT64_C(1) << flag))
1966  ++flag_counts[flag_map[voter_idx][flag]];
1967  }
1968  if (named_flag[voter_idx] >= 0 &&
1969  (rs->flags & (UINT64_C(1) << named_flag[voter_idx]))) {
1970  if (chosen_name && strcmp(chosen_name, rs->status.nickname)) {
1971  log_notice(LD_DIR, "Conflict on naming for router: %s vs %s",
1972  chosen_name, rs->status.nickname);
1973  naming_conflict = 1;
1974  }
1975  chosen_name = rs->status.nickname;
1976  }
1977 
1978  /* Count guardfraction votes and note down the values. */
1979  if (rs->status.has_guardfraction) {
1980  measured_guardfraction[num_guardfraction_inputs++] =
1982  }
1983 
1984  /* count bandwidths */
1985  if (rs->has_measured_bw)
1986  measured_bws_kb[num_mbws++] = rs->measured_bw_kb;
1987 
1988  if (rs->status.has_bandwidth)
1989  bandwidths_kb[num_bandwidths++] = rs->status.bandwidth_kb;
1990 
1991  /* Count number for which ed25519 is canonical. */
1992  if (rs->ed25519_reflects_consensus) {
1993  ++ed_consensus;
1994  if (ed_consensus_val) {
1995  tor_assert(fast_memeq(ed_consensus_val, rs->ed25519_id,
1997  } else {
1998  ed_consensus_val = rs->ed25519_id;
1999  }
2000  }
2001  }
2002 
2003  /* We don't include this router at all unless more than half of
2004  * the authorities we believe in list it. */
2005  if (n_listing <= total_authorities/2)
2006  continue;
2007 
2008  if (ed_consensus > 0) {
2009  if (ed_consensus <= total_authorities / 2) {
2010  log_warn(LD_BUG, "Not enough entries had ed_consensus set; how "
2011  "can we have a consensus of %d?", ed_consensus);
2012  }
2013  }
2014 
2015  /* The clangalyzer can't figure out that this will never be NULL
2016  * if n_listing is at least 1 */
2017  tor_assert(current_rsa_id);
2018 
2019  /* Figure out the most popular opinion of what the most recent
2020  * routerinfo and its contents are. */
2021  memset(microdesc_digest, 0, sizeof(microdesc_digest));
2022  rs = compute_routerstatus_consensus(matching_descs, consensus_method,
2023  microdesc_digest, &alt_orport);
2024  /* Copy bits of that into rs_out. */
2025  memset(&rs_out, 0, sizeof(rs_out));
2026  tor_assert(fast_memeq(current_rsa_id,
2028  memcpy(rs_out.identity_digest, current_rsa_id, DIGEST_LEN);
2029  memcpy(rs_out.descriptor_digest, rs->status.descriptor_digest,
2030  DIGEST_LEN);
2031  tor_addr_copy(&rs_out.ipv4_addr, &rs->status.ipv4_addr);
2032  rs_out.published_on = rs->status.published_on;
2033  rs_out.ipv4_dirport = rs->status.ipv4_dirport;
2034  rs_out.ipv4_orport = rs->status.ipv4_orport;
2035  tor_addr_copy(&rs_out.ipv6_addr, &alt_orport.addr);
2036  rs_out.ipv6_orport = alt_orport.port;
2037  rs_out.has_bandwidth = 0;
2038  rs_out.has_exitsummary = 0;
2039 
2040  if (chosen_name && !naming_conflict) {
2041  strlcpy(rs_out.nickname, chosen_name, sizeof(rs_out.nickname));
2042  } else {
2043  strlcpy(rs_out.nickname, rs->status.nickname, sizeof(rs_out.nickname));
2044  }
2045 
2046  {
2047  const char *d = strmap_get_lc(name_to_id_map, rs_out.nickname);
2048  if (!d) {
2049  is_named = is_unnamed = 0;
2050  } else if (fast_memeq(d, current_rsa_id, DIGEST_LEN)) {
2051  is_named = 1; is_unnamed = 0;
2052  } else {
2053  is_named = 0; is_unnamed = 1;
2054  }
2055  }
2056 
2057  /* Set the flags. */
2058  smartlist_add(chosen_flags, (char*)"s"); /* for the start of the line. */
2059  SMARTLIST_FOREACH_BEGIN(flags, const char *, fl) {
2060  if (!strcmp(fl, "Named")) {
2061  if (is_named)
2062  smartlist_add(chosen_flags, (char*)fl);
2063  } else if (!strcmp(fl, "Unnamed")) {
2064  if (is_unnamed)
2065  smartlist_add(chosen_flags, (char*)fl);
2066  } else if (!strcmp(fl, "NoEdConsensus")) {
2067  if (ed_consensus <= total_authorities/2)
2068  smartlist_add(chosen_flags, (char*)fl);
2069  } else {
2070  if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2) {
2071  smartlist_add(chosen_flags, (char*)fl);
2072  if (!strcmp(fl, "Exit"))
2073  is_exit = 1;
2074  else if (!strcmp(fl, "Guard"))
2075  is_guard = 1;
2076  else if (!strcmp(fl, "Running"))
2077  is_running = 1;
2078  else if (!strcmp(fl, "BadExit"))
2079  is_bad_exit = 1;
2080  else if (!strcmp(fl, "Valid"))
2081  is_valid = 1;
2082  }
2083  }
2084  } SMARTLIST_FOREACH_END(fl);
2085 
2086  /* Starting with consensus method 4 we do not list servers
2087  * that are not running in a consensus. See Proposal 138 */
2088  if (!is_running)
2089  continue;
2090 
2091  /* Starting with consensus method 24, we don't list servers
2092  * that are not valid in a consensus. See Proposal 272 */
2093  if (!is_valid)
2094  continue;
2095 
2096  /* Pick the version. */
2097  if (smartlist_len(versions)) {
2098  sort_version_list(versions, 0);
2099  chosen_version = get_most_frequent_member(versions);
2100  } else {
2101  chosen_version = NULL;
2102  }
2103 
2104  /* Pick the protocol list */
2105  if (smartlist_len(protocols)) {
2106  smartlist_sort_strings(protocols);
2107  chosen_protocol_list = get_most_frequent_member(protocols);
2108  } else {
2109  chosen_protocol_list = NULL;
2110  }
2111 
2112  /* If it's a guard and we have enough guardfraction votes,
2113  calculate its consensus guardfraction value. */
2114  if (is_guard && num_guardfraction_inputs > 2) {
2115  rs_out.has_guardfraction = 1;
2116  rs_out.guardfraction_percentage = median_uint32(measured_guardfraction,
2117  num_guardfraction_inputs);
2118  /* final value should be an integer percentage! */
2119  tor_assert(rs_out.guardfraction_percentage <= 100);
2120  }
2121 
2122  /* Pick a bandwidth */
2123  if (num_mbws > 2) {
2124  rs_out.has_bandwidth = 1;
2125  rs_out.bw_is_unmeasured = 0;
2126  rs_out.bandwidth_kb = median_uint32(measured_bws_kb, num_mbws);
2127  } else if (num_bandwidths > 0) {
2128  rs_out.has_bandwidth = 1;
2129  rs_out.bw_is_unmeasured = 1;
2130  rs_out.bandwidth_kb = median_uint32(bandwidths_kb, num_bandwidths);
2131  if (n_authorities_measuring_bandwidth > 2) {
2132  /* Cap non-measured bandwidths. */
2133  if (rs_out.bandwidth_kb > max_unmeasured_bw_kb) {
2134  rs_out.bandwidth_kb = max_unmeasured_bw_kb;
2135  }
2136  }
2137  }
2138 
2139  /* Fix bug 2203: Do not count BadExit nodes as Exits for bw weights */
2140  is_exit = is_exit && !is_bad_exit;
2141 
2142  /* Update total bandwidth weights with the bandwidths of this router. */
2143  {
2145  is_exit, is_guard,
2146  &G, &M, &E, &D, &T);
2147  }
2148 
2149  /* Ok, we already picked a descriptor digest we want to list
2150  * previously. Now we want to use the exit policy summary from
2151  * that descriptor. If everybody plays nice all the voters who
2152  * listed that descriptor will have the same summary. If not then
2153  * something is fishy and we'll use the most common one (breaking
2154  * ties in favor of lexicographically larger one (only because it
2155  * lets me reuse more existing code)).
2156  *
2157  * The other case that can happen is that no authority that voted
2158  * for that descriptor has an exit policy summary. That's
2159  * probably quite unlikely but can happen. In that case we use
2160  * the policy that was most often listed in votes, again breaking
2161  * ties like in the previous case.
2162  */
2163  {
2164  /* Okay, go through all the votes for this router. We prepared
2165  * that list previously */
2166  const char *chosen_exitsummary = NULL;
2167  smartlist_clear(exitsummaries);
2168  SMARTLIST_FOREACH_BEGIN(matching_descs, vote_routerstatus_t *, vsr) {
2169  /* Check if the vote where this status comes from had the
2170  * proper descriptor */
2172  vsr->status.identity_digest,
2173  DIGEST_LEN));
2174  if (vsr->status.has_exitsummary &&
2176  vsr->status.descriptor_digest,
2177  DIGEST_LEN)) {
2178  tor_assert(vsr->status.exitsummary);
2179  smartlist_add(exitsummaries, vsr->status.exitsummary);
2180  if (!chosen_exitsummary) {
2181  chosen_exitsummary = vsr->status.exitsummary;
2182  } else if (strcmp(chosen_exitsummary, vsr->status.exitsummary)) {
2183  /* Great. There's disagreement among the voters. That
2184  * really shouldn't be */
2185  exitsummary_disagreement = 1;
2186  }
2187  }
2188  } SMARTLIST_FOREACH_END(vsr);
2189 
2190  if (exitsummary_disagreement) {
2191  char id[HEX_DIGEST_LEN+1];
2192  char dd[HEX_DIGEST_LEN+1];
2193  base16_encode(id, sizeof(dd), rs_out.identity_digest, DIGEST_LEN);
2194  base16_encode(dd, sizeof(dd), rs_out.descriptor_digest, DIGEST_LEN);
2195  log_warn(LD_DIR, "The voters disagreed on the exit policy summary "
2196  " for router %s with descriptor %s. This really shouldn't"
2197  " have happened.", id, dd);
2198 
2199  smartlist_sort_strings(exitsummaries);
2200  chosen_exitsummary = get_most_frequent_member(exitsummaries);
2201  } else if (!chosen_exitsummary) {
2202  char id[HEX_DIGEST_LEN+1];
2203  char dd[HEX_DIGEST_LEN+1];
2204  base16_encode(id, sizeof(dd), rs_out.identity_digest, DIGEST_LEN);
2205  base16_encode(dd, sizeof(dd), rs_out.descriptor_digest, DIGEST_LEN);
2206  log_warn(LD_DIR, "Not one of the voters that made us select"
2207  "descriptor %s for router %s had an exit policy"
2208  "summary", dd, id);
2209 
2210  /* Ok, none of those voting for the digest we chose had an
2211  * exit policy for us. Well, that kinda sucks.
2212  */
2213  smartlist_clear(exitsummaries);
2214  SMARTLIST_FOREACH(matching_descs, vote_routerstatus_t *, vsr, {
2215  if (vsr->status.has_exitsummary)
2216  smartlist_add(exitsummaries, vsr->status.exitsummary);
2217  });
2218  smartlist_sort_strings(exitsummaries);
2219  chosen_exitsummary = get_most_frequent_member(exitsummaries);
2220 
2221  if (!chosen_exitsummary)
2222  log_warn(LD_DIR, "Wow, not one of the voters had an exit "
2223  "policy summary for %s. Wow.", id);
2224  }
2225 
2226  if (chosen_exitsummary) {
2227  rs_out.has_exitsummary = 1;
2228  /* yea, discards the const */
2229  rs_out.exitsummary = (char *)chosen_exitsummary;
2230  }
2231  }
2232 
2233  if (flavor == FLAV_MICRODESC &&
2234  tor_digest256_is_zero(microdesc_digest)) {
2235  /* With no microdescriptor digest, we omit the entry entirely. */
2236  continue;
2237  }
2238 
2239  {
2240  char *buf;
2241  /* Okay!! Now we can write the descriptor... */
2242  /* First line goes into "buf". */
2243  buf = routerstatus_format_entry(&rs_out, NULL, NULL,
2244  rs_format, NULL);
2245  if (buf)
2246  smartlist_add(chunks, buf);
2247  }
2248  /* Now an m line, if applicable. */
2249  if (flavor == FLAV_MICRODESC &&
2250  !tor_digest256_is_zero(microdesc_digest)) {
2251  char m[BASE64_DIGEST256_LEN+1];
2252  digest256_to_base64(m, microdesc_digest);
2253  smartlist_add_asprintf(chunks, "m %s\n", m);
2254  }
2255  /* Next line is all flags. The "\n" is missing. */
2256  smartlist_add(chunks,
2257  smartlist_join_strings(chosen_flags, " ", 0, NULL));
2258  /* Now the version line. */
2259  if (chosen_version) {
2260  smartlist_add_strdup(chunks, "\nv ");
2261  smartlist_add_strdup(chunks, chosen_version);
2262  }
2263  smartlist_add_strdup(chunks, "\n");
2264  if (chosen_protocol_list) {
2265  smartlist_add_asprintf(chunks, "pr %s\n", chosen_protocol_list);
2266  }
2267  /* Now the weight line. */
2268  if (rs_out.has_bandwidth) {
2269  char *guardfraction_str = NULL;
2270  int unmeasured = rs_out.bw_is_unmeasured;
2271 
2272  /* If we have guardfraction info, include it in the 'w' line. */
2273  if (rs_out.has_guardfraction) {
2274  tor_asprintf(&guardfraction_str,
2275  " GuardFraction=%u", rs_out.guardfraction_percentage);
2276  }
2277  smartlist_add_asprintf(chunks, "w Bandwidth=%d%s%s\n",
2278  rs_out.bandwidth_kb,
2279  unmeasured?" Unmeasured=1":"",
2280  guardfraction_str ? guardfraction_str : "");
2281 
2282  tor_free(guardfraction_str);
2283  }
2284 
2285  /* Now the exitpolicy summary line. */
2286  if (rs_out.has_exitsummary && flavor == FLAV_NS) {
2287  smartlist_add_asprintf(chunks, "p %s\n", rs_out.exitsummary);
2288  }
2289 
2290  /* And the loop is over and we move on to the next router */
2291  }
2292 
2293  tor_free(size);
2294  tor_free(n_voter_flags);
2295  tor_free(n_flag_voters);
2296  for (i = 0; i < smartlist_len(votes); ++i)
2297  tor_free(flag_map[i]);
2298  tor_free(flag_map);
2299  tor_free(flag_counts);
2300  tor_free(named_flag);
2301  tor_free(unnamed_flag);
2302  strmap_free(name_to_id_map, NULL);
2303  smartlist_free(matching_descs);
2304  smartlist_free(chosen_flags);
2305  smartlist_free(versions);
2306  smartlist_free(protocols);
2307  smartlist_free(exitsummaries);
2308  tor_free(bandwidths_kb);
2309  tor_free(measured_bws_kb);
2310  tor_free(measured_guardfraction);
2311  }
2312 
2313  /* Mark the directory footer region */
2314  smartlist_add_strdup(chunks, "directory-footer\n");
2315 
2316  {
2317  int64_t weight_scale;
2318  if (consensus_method < MIN_METHOD_FOR_CORRECT_BWWEIGHTSCALE) {
2319  weight_scale = extract_param_buggy(params, "bwweightscale",
2320  BW_WEIGHT_SCALE);
2321  } else {
2322  weight_scale = dirvote_get_intermediate_param_value(
2323  param_list, "bwweightscale", BW_WEIGHT_SCALE);
2324  if (weight_scale < 1)
2325  weight_scale = 1;
2326  }
2327  added_weights = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D,
2328  T, weight_scale);
2329  }
2330 
2331  /* Add a signature. */
2332  {
2333  char digest[DIGEST256_LEN];
2334  char fingerprint[HEX_DIGEST_LEN+1];
2335  char signing_key_fingerprint[HEX_DIGEST_LEN+1];
2336  digest_algorithm_t digest_alg =
2337  flavor == FLAV_NS ? DIGEST_SHA1 : DIGEST_SHA256;
2338  size_t digest_len =
2339  flavor == FLAV_NS ? DIGEST_LEN : DIGEST256_LEN;
2340  const char *algname = crypto_digest_algorithm_get_name(digest_alg);
2341  char *signature;
2342 
2343  smartlist_add_strdup(chunks, "directory-signature ");
2344 
2345  /* Compute the hash of the chunks. */
2346  crypto_digest_smartlist(digest, digest_len, chunks, "", digest_alg);
2347 
2348  /* Get the fingerprints */
2349  crypto_pk_get_fingerprint(identity_key, fingerprint, 0);
2350  crypto_pk_get_fingerprint(signing_key, signing_key_fingerprint, 0);
2351 
2352  /* add the junk that will go at the end of the line. */
2353  if (flavor == FLAV_NS) {
2354  smartlist_add_asprintf(chunks, "%s %s\n", fingerprint,
2355  signing_key_fingerprint);
2356  } else {
2357  smartlist_add_asprintf(chunks, "%s %s %s\n",
2358  algname, fingerprint,
2359  signing_key_fingerprint);
2360  }
2361  /* And the signature. */
2362  if (!(signature = router_get_dirobj_signature(digest, digest_len,
2363  signing_key))) {
2364  log_warn(LD_BUG, "Couldn't sign consensus networkstatus.");
2365  goto done;
2366  }
2367  smartlist_add(chunks, signature);
2368 
2369  if (legacy_id_key_digest && legacy_signing_key) {
2370  smartlist_add_strdup(chunks, "directory-signature ");
2371  base16_encode(fingerprint, sizeof(fingerprint),
2372  legacy_id_key_digest, DIGEST_LEN);
2374  signing_key_fingerprint, 0);
2375  if (flavor == FLAV_NS) {
2376  smartlist_add_asprintf(chunks, "%s %s\n", fingerprint,
2377  signing_key_fingerprint);
2378  } else {
2379  smartlist_add_asprintf(chunks, "%s %s %s\n",
2380  algname, fingerprint,
2381  signing_key_fingerprint);
2382  }
2383 
2384  if (!(signature = router_get_dirobj_signature(digest, digest_len,
2385  legacy_signing_key))) {
2386  log_warn(LD_BUG, "Couldn't sign consensus networkstatus.");
2387  goto done;
2388  }
2389  smartlist_add(chunks, signature);
2390  }
2391  }
2392 
2393  result = smartlist_join_strings(chunks, "", 0, NULL);
2394 
2395  {
2396  networkstatus_t *c;
2397  if (!(c = networkstatus_parse_vote_from_string(result, strlen(result),
2398  NULL,
2399  NS_TYPE_CONSENSUS))) {
2400  log_err(LD_BUG, "Generated a networkstatus consensus we couldn't "
2401  "parse.");
2402  tor_free(result);
2403  goto done;
2404  }
2405  // Verify balancing parameters
2406  if (added_weights) {
2407  networkstatus_verify_bw_weights(c, consensus_method);
2408  }
2409  networkstatus_vote_free(c);
2410  }
2411 
2412  done:
2413 
2414  dircollator_free(collator);
2415  tor_free(client_versions);
2416  tor_free(server_versions);
2417  tor_free(packages);
2418  SMARTLIST_FOREACH(flags, char *, cp, tor_free(cp));
2419  smartlist_free(flags);
2420  SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2421  smartlist_free(chunks);
2422  SMARTLIST_FOREACH(param_list, char *, cp, tor_free(cp));
2423  smartlist_free(param_list);
2424 
2425  return result;
2426 }
2427 
2428 /** Extract the value of a parameter from a string encoding a list of
2429  * parameters, badly.
2430  *
2431  * This is a deliberately buggy implementation, for backward compatibility
2432  * with versions of Tor affected by #19011. Once all authorities have
2433  * upgraded to consensus method 31 or later, then we can throw away this
2434  * function. */
2435 STATIC int64_t
2436 extract_param_buggy(const char *params,
2437  const char *param_name,
2438  int64_t default_value)
2439 {
2440  int64_t value = default_value;
2441  const char *param_str = NULL;
2442 
2443  if (params) {
2444  char *prefix1 = NULL, *prefix2=NULL;
2445  tor_asprintf(&prefix1, "%s=", param_name);
2446  tor_asprintf(&prefix2, " %s=", param_name);
2447  if (strcmpstart(params, prefix1) == 0)
2448  param_str = params;
2449  else
2450  param_str = strstr(params, prefix2);
2451  tor_free(prefix1);
2452  tor_free(prefix2);
2453  }
2454 
2455  if (param_str) {
2456  int ok=0;
2457  char *eq = strchr(param_str, '=');
2458  if (eq) {
2459  value = tor_parse_long(eq+1, 10, 1, INT32_MAX, &ok, NULL);
2460  if (!ok) {
2461  log_warn(LD_DIR, "Bad element '%s' in %s",
2462  escaped(param_str), param_name);
2463  value = default_value;
2464  }
2465  } else {
2466  log_warn(LD_DIR, "Bad element '%s' in %s",
2467  escaped(param_str), param_name);
2468  value = default_value;
2469  }
2470  }
2471 
2472  return value;
2473 }
2474 
2475 /** Given a list of networkstatus_t for each vote, return a newly allocated
2476  * string containing the "package" lines for the vote. */
2477 STATIC char *
2479 {
2480  const int n_votes = smartlist_len(votes);
2481 
2482  /* This will be a map from "packagename version" strings to arrays
2483  * of const char *, with the i'th member of the array corresponding to the
2484  * package line from the i'th vote.
2485  */
2486  strmap_t *package_status = strmap_new();
2487 
2489  if (! v->package_lines)
2490  continue;
2491  SMARTLIST_FOREACH_BEGIN(v->package_lines, const char *, line) {
2493  continue;
2494 
2495  /* Skip 'cp' to the second space in the line. */
2496  const char *cp = strchr(line, ' ');
2497  if (!cp) continue;
2498  ++cp;
2499  cp = strchr(cp, ' ');
2500  if (!cp) continue;
2501 
2502  char *key = tor_strndup(line, cp - line);
2503 
2504  const char **status = strmap_get(package_status, key);
2505  if (!status) {
2506  status = tor_calloc(n_votes, sizeof(const char *));
2507  strmap_set(package_status, key, status);
2508  }
2509  status[v_sl_idx] = line; /* overwrite old value */
2510  tor_free(key);
2511  } SMARTLIST_FOREACH_END(line);
2512  } SMARTLIST_FOREACH_END(v);
2513 
2514  smartlist_t *entries = smartlist_new(); /* temporary */
2515  smartlist_t *result_list = smartlist_new(); /* output */
2516  STRMAP_FOREACH(package_status, key, const char **, values) {
2517  int i, count=-1;
2518  for (i = 0; i < n_votes; ++i) {
2519  if (values[i])
2520  smartlist_add(entries, (void*) values[i]);
2521  }
2522  smartlist_sort_strings(entries);
2523  int n_voting_for_entry = smartlist_len(entries);
2524  const char *most_frequent =
2525  smartlist_get_most_frequent_string_(entries, &count);
2526 
2527  if (n_voting_for_entry >= 3 && count > n_voting_for_entry / 2) {
2528  smartlist_add_asprintf(result_list, "package %s\n", most_frequent);
2529  }
2530 
2531  smartlist_clear(entries);
2532 
2533  } STRMAP_FOREACH_END;
2534 
2535  smartlist_sort_strings(result_list);
2536 
2537  char *result = smartlist_join_strings(result_list, "", 0, NULL);
2538 
2539  SMARTLIST_FOREACH(result_list, char *, cp, tor_free(cp));
2540  smartlist_free(result_list);
2541  smartlist_free(entries);
2542  strmap_free(package_status, tor_free_);
2543 
2544  return result;
2545 }
2546 
2547 /** Given a consensus vote <b>target</b> and a set of detached signatures in
2548  * <b>sigs</b> that correspond to the same consensus, check whether there are
2549  * any new signatures in <b>src_voter_list</b> that should be added to
2550  * <b>target</b>. (A signature should be added if we have no signature for that
2551  * voter in <b>target</b> yet, or if we have no verifiable signature and the
2552  * new signature is verifiable.)
2553  *
2554  * Return the number of signatures added or changed, or -1 if the document
2555  * signatures are invalid. Sets *<b>msg_out</b> to a string constant
2556  * describing the signature status.
2557  */
2558 STATIC int
2561  const char *source,
2562  int severity,
2563  const char **msg_out)
2564 {
2565  int r = 0;
2566  const char *flavor;
2567  smartlist_t *siglist;
2568  tor_assert(sigs);
2569  tor_assert(target);
2570  tor_assert(target->type == NS_TYPE_CONSENSUS);
2571 
2572  flavor = networkstatus_get_flavor_name(target->flavor);
2573 
2574  /* Do the times seem right? */
2575  if (target->valid_after != sigs->valid_after) {
2576  *msg_out = "Valid-After times do not match "
2577  "when adding detached signatures to consensus";
2578  return -1;
2579  }
2580  if (target->fresh_until != sigs->fresh_until) {
2581  *msg_out = "Fresh-until times do not match "
2582  "when adding detached signatures to consensus";
2583  return -1;
2584  }
2585  if (target->valid_until != sigs->valid_until) {
2586  *msg_out = "Valid-until times do not match "
2587  "when adding detached signatures to consensus";
2588  return -1;
2589  }
2590  siglist = strmap_get(sigs->signatures, flavor);
2591  if (!siglist) {
2592  *msg_out = "No signatures for given consensus flavor";
2593  return -1;
2594  }
2595 
2596  /** Make sure all the digests we know match, and at least one matches. */
2597  {
2598  common_digests_t *digests = strmap_get(sigs->digests, flavor);
2599  int n_matches = 0;
2600  int alg;
2601  if (!digests) {
2602  *msg_out = "No digests for given consensus flavor";
2603  return -1;
2604  }
2605  for (alg = DIGEST_SHA1; alg < N_COMMON_DIGEST_ALGORITHMS; ++alg) {
2606  if (!fast_mem_is_zero(digests->d[alg], DIGEST256_LEN)) {
2607  if (fast_memeq(target->digests.d[alg], digests->d[alg],
2608  DIGEST256_LEN)) {
2609  ++n_matches;
2610  } else {
2611  *msg_out = "Mismatched digest.";
2612  return -1;
2613  }
2614  }
2615  }
2616  if (!n_matches) {
2617  *msg_out = "No recognized digests for given consensus flavor";
2618  }
2619  }
2620 
2621  /* For each voter in src... */
2623  char voter_identity[HEX_DIGEST_LEN+1];
2624  networkstatus_voter_info_t *target_voter =
2625  networkstatus_get_voter_by_id(target, sig->identity_digest);
2626  authority_cert_t *cert = NULL;
2627  const char *algorithm;
2628  document_signature_t *old_sig = NULL;
2629 
2630  algorithm = crypto_digest_algorithm_get_name(sig->alg);
2631 
2632  base16_encode(voter_identity, sizeof(voter_identity),
2633  sig->identity_digest, DIGEST_LEN);
2634  log_info(LD_DIR, "Looking at signature from %s using %s", voter_identity,
2635  algorithm);
2636  /* If the target doesn't know about this voter, then forget it. */
2637  if (!target_voter) {
2638  log_info(LD_DIR, "We do not know any voter with ID %s", voter_identity);
2639  continue;
2640  }
2641 
2642  old_sig = networkstatus_get_voter_sig_by_alg(target_voter, sig->alg);
2643 
2644  /* If the target already has a good signature from this voter, then skip
2645  * this one. */
2646  if (old_sig && old_sig->good_signature) {
2647  log_info(LD_DIR, "We already have a good signature from %s using %s",
2648  voter_identity, algorithm);
2649  continue;
2650  }
2651 
2652  /* Try checking the signature if we haven't already. */
2653  if (!sig->good_signature && !sig->bad_signature) {
2654  cert = authority_cert_get_by_digests(sig->identity_digest,
2655  sig->signing_key_digest);
2656  if (cert) {
2657  /* Not checking the return value here, since we are going to look
2658  * at the status of sig->good_signature in a moment. */
2659  (void) networkstatus_check_document_signature(target, sig, cert);
2660  }
2661  }
2662 
2663  /* If this signature is good, or we don't have any signature yet,
2664  * then maybe add it. */
2665  if (sig->good_signature || !old_sig || old_sig->bad_signature) {
2666  log_info(LD_DIR, "Adding signature from %s with %s", voter_identity,
2667  algorithm);
2668  tor_log(severity, LD_DIR, "Added a signature for %s from %s.",
2669  target_voter->nickname, source);
2670  ++r;
2671  if (old_sig) {
2672  smartlist_remove(target_voter->sigs, old_sig);
2673  document_signature_free(old_sig);
2674  }
2675  smartlist_add(target_voter->sigs, document_signature_dup(sig));
2676  } else {
2677  log_info(LD_DIR, "Not adding signature from %s", voter_identity);
2678  }
2679  } SMARTLIST_FOREACH_END(sig);
2680 
2681  return r;
2682 }
2683 
2684 /** Return a newly allocated string containing all the signatures on
2685  * <b>consensus</b> by all voters. If <b>for_detached_signatures</b> is true,
2686  * then the signatures will be put in a detached signatures document, so
2687  * prefix any non-NS-flavored signatures with "additional-signature" rather
2688  * than "directory-signature". */
2689 static char *
2691  int for_detached_signatures)
2692 {
2693  smartlist_t *elements;
2694  char buf[4096];
2695  char *result = NULL;
2696  int n_sigs = 0;
2697  const consensus_flavor_t flavor = consensus->flavor;
2698  const char *flavor_name = networkstatus_get_flavor_name(flavor);
2699  const char *keyword;
2700 
2701  if (for_detached_signatures && flavor != FLAV_NS)
2702  keyword = "additional-signature";
2703  else
2704  keyword = "directory-signature";
2705 
2706  elements = smartlist_new();
2707 
2710  char sk[HEX_DIGEST_LEN+1];
2711  char id[HEX_DIGEST_LEN+1];
2712  if (!sig->signature || sig->bad_signature)
2713  continue;
2714  ++n_sigs;
2715  base16_encode(sk, sizeof(sk), sig->signing_key_digest, DIGEST_LEN);
2716  base16_encode(id, sizeof(id), sig->identity_digest, DIGEST_LEN);
2717  if (flavor == FLAV_NS) {
2718  smartlist_add_asprintf(elements,
2719  "%s %s %s\n-----BEGIN SIGNATURE-----\n",
2720  keyword, id, sk);
2721  } else {
2722  const char *digest_name =
2724  smartlist_add_asprintf(elements,
2725  "%s%s%s %s %s %s\n-----BEGIN SIGNATURE-----\n",
2726  keyword,
2727  for_detached_signatures ? " " : "",
2728  for_detached_signatures ? flavor_name : "",
2729  digest_name, id, sk);
2730  }
2731  base64_encode(buf, sizeof(buf), sig->signature, sig->signature_len,
2732  BASE64_ENCODE_MULTILINE);
2733  strlcat(buf, "-----END SIGNATURE-----\n", sizeof(buf));
2734  smartlist_add_strdup(elements, buf);
2735  } SMARTLIST_FOREACH_END(sig);
2736  } SMARTLIST_FOREACH_END(v);
2737 
2738  result = smartlist_join_strings(elements, "", 0, NULL);
2739  SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2740  smartlist_free(elements);
2741  if (!n_sigs)
2742  tor_free(result);
2743  return result;
2744 }
2745 
2746 /** Return a newly allocated string holding the detached-signatures document
2747  * corresponding to the signatures on <b>consensuses</b>, which must contain
2748  * exactly one FLAV_NS consensus, and no more than one consensus for each
2749  * other flavor. */
2750 STATIC char *
2752 {
2753  smartlist_t *elements;
2754  char *result = NULL, *sigs = NULL;
2755  networkstatus_t *consensus_ns = NULL;
2756  tor_assert(consensuses);
2757 
2758  SMARTLIST_FOREACH(consensuses, networkstatus_t *, ns, {
2759  tor_assert(ns);
2760  tor_assert(ns->type == NS_TYPE_CONSENSUS);
2761  if (ns && ns->flavor == FLAV_NS)
2762  consensus_ns = ns;
2763  });
2764  if (!consensus_ns) {
2765  log_warn(LD_BUG, "No NS consensus given.");
2766  return NULL;
2767  }
2768 
2769  elements = smartlist_new();
2770 
2771  {
2772  char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
2773  vu_buf[ISO_TIME_LEN+1];
2774  char d[HEX_DIGEST_LEN+1];
2775 
2776  base16_encode(d, sizeof(d),
2777  consensus_ns->digests.d[DIGEST_SHA1], DIGEST_LEN);
2778  format_iso_time(va_buf, consensus_ns->valid_after);
2779  format_iso_time(fu_buf, consensus_ns->fresh_until);
2780  format_iso_time(vu_buf, consensus_ns->valid_until);
2781 
2782  smartlist_add_asprintf(elements,
2783  "consensus-digest %s\n"
2784  "valid-after %s\n"
2785  "fresh-until %s\n"
2786  "valid-until %s\n", d, va_buf, fu_buf, vu_buf);
2787  }
2788 
2789  /* Get all the digests for the non-FLAV_NS consensuses */
2790  SMARTLIST_FOREACH_BEGIN(consensuses, networkstatus_t *, ns) {
2791  const char *flavor_name = networkstatus_get_flavor_name(ns->flavor);
2792  int alg;
2793  if (ns->flavor == FLAV_NS)
2794  continue;
2795 
2796  /* start with SHA256; we don't include SHA1 for anything but the basic
2797  * consensus. */
2798  for (alg = DIGEST_SHA256; alg < N_COMMON_DIGEST_ALGORITHMS; ++alg) {
2799  char d[HEX_DIGEST256_LEN+1];
2800  const char *alg_name =
2802  if (fast_mem_is_zero(ns->digests.d[alg], DIGEST256_LEN))
2803  continue;
2804  base16_encode(d, sizeof(d), ns->digests.d[alg], DIGEST256_LEN);
2805  smartlist_add_asprintf(elements, "additional-digest %s %s %s\n",
2806  flavor_name, alg_name, d);
2807  }
2808  } SMARTLIST_FOREACH_END(ns);
2809 
2810  /* Now get all the sigs for non-FLAV_NS consensuses */
2811  SMARTLIST_FOREACH_BEGIN(consensuses, networkstatus_t *, ns) {
2812  char *sigs_on_this_consensus;
2813  if (ns->flavor == FLAV_NS)
2814  continue;
2815  sigs_on_this_consensus = networkstatus_format_signatures(ns, 1);
2816  if (!sigs_on_this_consensus) {
2817  log_warn(LD_DIR, "Couldn't format signatures");
2818  goto err;
2819  }
2820  smartlist_add(elements, sigs_on_this_consensus);
2821  } SMARTLIST_FOREACH_END(ns);
2822 
2823  /* Now add the FLAV_NS consensus signatrures. */
2824  sigs = networkstatus_format_signatures(consensus_ns, 1);
2825  if (!sigs)
2826  goto err;
2827  smartlist_add(elements, sigs);
2828 
2829  result = smartlist_join_strings(elements, "", 0, NULL);
2830  err:
2831  SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2832  smartlist_free(elements);
2833  return result;
2834 }
2835 
2836 /** Return a newly allocated string holding a detached-signatures document for
2837  * all of the in-progress consensuses in the <b>n_flavors</b>-element array at
2838  * <b>pending</b>. */
2839 static char *
2841  int n_flavors)
2842 {
2843  int flav;
2844  char *signatures;
2845  smartlist_t *c = smartlist_new();
2846  for (flav = 0; flav < n_flavors; ++flav) {
2847  if (pending[flav].consensus)
2848  smartlist_add(c, pending[flav].consensus);
2849  }
2850  signatures = networkstatus_get_detached_signatures(c);
2851  smartlist_free(c);
2852  return signatures;
2853 }
2854 
2855 /**
2856  * Entry point: Take whatever voting actions are pending as of <b>now</b>.
2857  *
2858  * Return the time at which the next action should be taken.
2859  */
2860 time_t
2861 dirvote_act(const or_options_t *options, time_t now)
2862 {
2863  if (!authdir_mode_v3(options))
2864  return TIME_MAX;
2865  tor_assert_nonfatal(voting_schedule.voting_starts);
2866  /* If we haven't initialized this object through this codeflow, we need to
2867  * recalculate the timings to match our vote. The reason to do that is if we
2868  * have a voting schedule initialized 1 minute ago, the voting timings might
2869  * not be aligned to what we should expect with "now". This is especially
2870  * true for TestingTorNetwork using smaller timings. */
2871  if (voting_schedule.created_on_demand) {
2872  char *keys = list_v3_auth_ids();
2874  log_notice(LD_DIR, "Scheduling voting. Known authority IDs are %s. "
2875  "Mine is %s.",
2877  tor_free(keys);
2878  dirauth_sched_recalculate_timing(options, now);
2879  }
2880 
2881 #define IF_TIME_FOR_NEXT_ACTION(when_field, done_field) \
2882  if (! voting_schedule.done_field) { \
2883  if (voting_schedule.when_field > now) { \
2884  return voting_schedule.when_field; \
2885  } else {
2886 #define ENDIF \
2887  } \
2888  }
2889 
2890  IF_TIME_FOR_NEXT_ACTION(voting_starts, have_voted) {
2891  log_notice(LD_DIR, "Time to vote.");
2893  voting_schedule.have_voted = 1;
2894  } ENDIF
2895  IF_TIME_FOR_NEXT_ACTION(fetch_missing_votes, have_fetched_missing_votes) {
2896  log_notice(LD_DIR, "Time to fetch any votes that we're missing.");
2898  voting_schedule.have_fetched_missing_votes = 1;
2899  } ENDIF
2900  IF_TIME_FOR_NEXT_ACTION(voting_ends, have_built_consensus) {
2901  log_notice(LD_DIR, "Time to compute a consensus.");
2903  /* XXXX We will want to try again later if we haven't got enough
2904  * votes yet. Implement this if it turns out to ever happen. */
2905  voting_schedule.have_built_consensus = 1;
2906  } ENDIF
2907  IF_TIME_FOR_NEXT_ACTION(fetch_missing_signatures,
2908  have_fetched_missing_signatures) {
2909  log_notice(LD_DIR, "Time to fetch any signatures that we're missing.");
2911  voting_schedule.have_fetched_missing_signatures = 1;
2912  } ENDIF
2913  IF_TIME_FOR_NEXT_ACTION(interval_starts,
2914  have_published_consensus) {
2915  log_notice(LD_DIR, "Time to publish the consensus and discard old votes");
2918  voting_schedule.have_published_consensus = 1;
2919  /* Update our shared random state with the consensus just published. */
2922  /* XXXX We will want to try again later if we haven't got enough
2923  * signatures yet. Implement this if it turns out to ever happen. */
2924  dirauth_sched_recalculate_timing(options, now);
2925  return voting_schedule.voting_starts;
2926  } ENDIF
2927 
2929  return now + 1;
2930 
2931 #undef ENDIF
2932 #undef IF_TIME_FOR_NEXT_ACTION
2933 }
2934 
2935 /** A vote networkstatus_t and its unparsed body: held around so we can
2936  * use it to generate a consensus (at voting_ends) and so we can serve it to
2937  * other authorities that might want it. */
2938 typedef struct pending_vote_t {
2939  cached_dir_t *vote_body;
2940  networkstatus_t *vote;
2941 } pending_vote_t;
2942 
2943 /** List of pending_vote_t for the current vote. Before we've used them to
2944  * build a consensus, the votes go here. */
2946 /** List of pending_vote_t for the previous vote. After we've used them to
2947  * build a consensus, the votes go here for the next period. */
2949 
2950 /* DOCDOC pending_consensuses */
2951 static pending_consensus_t pending_consensuses[N_CONSENSUS_FLAVORS];
2952 
2953 /** The detached signatures for the consensus that we're currently
2954  * building. */
2955 static char *pending_consensus_signatures = NULL;
2956 
2957 /** List of ns_detached_signatures_t: hold signatures that get posted to us
2958  * before we have generated the consensus on our own. */
2960 
2961 /** Generate a networkstatus vote and post it to all the v3 authorities.
2962  * (V3 Authority only) */
2963 static int
2965 {
2968  networkstatus_t *ns;
2969  char *contents;
2970  pending_vote_t *pending_vote;
2971  time_t now = time(NULL);
2972 
2973  int status;
2974  const char *msg = "";
2975 
2976  if (!cert || !key) {
2977  log_warn(LD_NET, "Didn't find key/certificate to generate v3 vote");
2978  return -1;
2979  } else if (cert->expires < now) {
2980  log_warn(LD_NET, "Can't generate v3 vote with expired certificate");
2981  return -1;
2982  }
2983  if (!(ns = dirserv_generate_networkstatus_vote_obj(key, cert)))
2984  return -1;
2985 
2986  contents = format_networkstatus_vote(key, ns);
2987  networkstatus_vote_free(ns);
2988  if (!contents)
2989  return -1;
2990 
2991  pending_vote = dirvote_add_vote(contents, 0, "self", &msg, &status);
2992  tor_free(contents);
2993  if (!pending_vote) {
2994  log_warn(LD_DIR, "Couldn't store my own vote! (I told myself, '%s'.)",
2995  msg);
2996  return -1;
2997  }
2998 
3001  V3_DIRINFO,
3002  pending_vote->vote_body->dir,
3003  pending_vote->vote_body->dir_len, 0);
3004  log_notice(LD_DIR, "Vote posted.");
3005  return 0;
3006 }
3007 
3008 /** Send an HTTP request to every other v3 authority, for the votes of every
3009  * authority for which we haven't received a vote yet in this period. (V3
3010  * authority only) */
3011 static void
3013 {
3014  smartlist_t *missing_fps = smartlist_new();
3015  char *resource;
3016 
3017  SMARTLIST_FOREACH_BEGIN(router_get_trusted_dir_servers(),
3018  dir_server_t *, ds) {
3019  if (!(ds->type & V3_DIRINFO))
3020  continue;
3021  if (!dirvote_get_vote(ds->v3_identity_digest,
3022  DGV_BY_ID|DGV_INCLUDE_PENDING)) {
3023  char *cp = tor_malloc(HEX_DIGEST_LEN+1);
3024  base16_encode(cp, HEX_DIGEST_LEN+1, ds->v3_identity_digest,
3025  DIGEST_LEN);
3026  smartlist_add(missing_fps, cp);
3027  }
3028  } SMARTLIST_FOREACH_END(ds);
3029 
3030  if (!smartlist_len(missing_fps)) {
3031  smartlist_free(missing_fps);
3032  return;
3033  }
3034  {
3035  char *tmp = smartlist_join_strings(missing_fps, " ", 0, NULL);
3036  log_notice(LOG_NOTICE, "We're missing votes from %d authorities (%s). "
3037  "Asking every other authority for a copy.",
3038  smartlist_len(missing_fps), tmp);
3039  tor_free(tmp);
3040  }
3041  resource = smartlist_join_strings(missing_fps, "+", 0, NULL);
3043  0, resource);
3044  tor_free(resource);
3045  SMARTLIST_FOREACH(missing_fps, char *, cp, tor_free(cp));
3046  smartlist_free(missing_fps);
3047 }
3048 
3049 /** Send a request to every other authority for its detached signatures,
3050  * unless we have signatures from all other v3 authorities already. */
3051 static void
3053 {
3054  int need_any = 0;
3055  int i;
3056  for (i=0; i < N_CONSENSUS_FLAVORS; ++i) {
3057  networkstatus_t *consensus = pending_consensuses[i].consensus;
3058  if (!consensus ||
3059  networkstatus_check_consensus_signature(consensus, -1) == 1) {
3060  /* We have no consensus, or we have one that's signed by everybody. */
3061  continue;
3062  }
3063  need_any = 1;
3064  }
3065  if (!need_any)
3066  return;
3067 
3069  0, NULL);
3070 }
3071 
3072 /** Release all storage held by pending consensuses (those waiting for
3073  * signatures). */
3074 static void
3076 {
3077  int i;
3078  for (i = 0; i < N_CONSENSUS_FLAVORS; ++i) {
3079  pending_consensus_t *pc = &pending_consensuses[i];
3080  tor_free(pc->body);
3081 
3082  networkstatus_vote_free(pc->consensus);
3083  pc->consensus = NULL;
3084  }
3085 }
3086 
3087 /** Drop all currently pending votes, consensus, and detached signatures. */
3088 static void
3089 dirvote_clear_votes(int all_votes)
3090 {
3091  if (!previous_vote_list)
3093  if (!pending_vote_list)
3095 
3096  /* All "previous" votes are now junk. */
3098  cached_dir_decref(v->vote_body);
3099  v->vote_body = NULL;
3100  networkstatus_vote_free(v->vote);
3101  tor_free(v);
3102  });
3104 
3105  if (all_votes) {
3106  /* If we're dumping all the votes, we delete the pending ones. */
3108  cached_dir_decref(v->vote_body);
3109  v->vote_body = NULL;
3110  networkstatus_vote_free(v->vote);
3111  tor_free(v);
3112  });
3113  } else {
3114  /* Otherwise, we move them into "previous". */
3116  }
3118 
3121  tor_free(cp));
3123  }
3126 }
3127 
3128 /** Return a newly allocated string containing the hex-encoded v3 authority
3129  identity digest of every recognized v3 authority. */
3130 static char *
3132 {
3133  smartlist_t *known_v3_keys = smartlist_new();
3134  char *keys;
3135  SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
3136  dir_server_t *, ds,
3137  if ((ds->type & V3_DIRINFO) &&
3138  !tor_digest_is_zero(ds->v3_identity_digest))
3139  smartlist_add(known_v3_keys,
3140  tor_strdup(hex_str(ds->v3_identity_digest, DIGEST_LEN))));
3141  keys = smartlist_join_strings(known_v3_keys, ", ", 0, NULL);
3142  SMARTLIST_FOREACH(known_v3_keys, char *, cp, tor_free(cp));
3143  smartlist_free(known_v3_keys);
3144  return keys;
3145 }
3146 
3147 /* Check the voter information <b>vi</b>, and assert that at least one
3148  * signature is good. Asserts on failure. */
3149 static void
3150 assert_any_sig_good(const networkstatus_voter_info_t *vi)
3151 {
3152  int any_sig_good = 0;
3154  if (sig->good_signature)
3155  any_sig_good = 1);
3156  tor_assert(any_sig_good);
3157 }
3158 
3159 /* Add <b>cert</b> to our list of known authority certificates. */
3160 static void
3161 add_new_cert_if_needed(const struct authority_cert_t *cert)
3162 {
3163  tor_assert(cert);
3165  cert->signing_key_digest)) {
3166  /* Hey, it's a new cert! */
3169  TRUSTED_DIRS_CERTS_SRC_FROM_VOTE, 1 /*flush*/,
3170  NULL);
3172  cert->signing_key_digest)) {
3173  log_warn(LD_BUG, "We added a cert, but still couldn't find it.");
3174  }
3175  }
3176 }
3177 
3178 /** Called when we have received a networkstatus vote in <b>vote_body</b>.
3179  * Parse and validate it, and on success store it as a pending vote (which we
3180  * then return). Return NULL on failure. Sets *<b>msg_out</b> and
3181  * *<b>status_out</b> to an HTTP response and status code. (V3 authority
3182  * only) */
3184 dirvote_add_vote(const char *vote_body, time_t time_posted,
3185  const char *where_from,
3186  const char **msg_out, int *status_out)
3187 {
3188  networkstatus_t *vote;
3190  dir_server_t *ds;
3191  pending_vote_t *pending_vote = NULL;
3192  const char *end_of_vote = NULL;
3193  int any_failed = 0;
3194  tor_assert(vote_body);
3195  tor_assert(msg_out);
3196  tor_assert(status_out);
3197 
3198  if (!pending_vote_list)
3200  *status_out = 0;
3201  *msg_out = NULL;
3202 
3203  again:
3204  vote = networkstatus_parse_vote_from_string(vote_body, strlen(vote_body),
3205  &end_of_vote,
3206  NS_TYPE_VOTE);
3207  if (!end_of_vote)
3208  end_of_vote = vote_body + strlen(vote_body);
3209  if (!vote) {
3210  log_warn(LD_DIR, "Couldn't parse vote: length was %d",
3211  (int)strlen(vote_body));
3212  *msg_out = "Unable to parse vote";
3213  goto err;
3214  }
3215  tor_assert(smartlist_len(vote->voters) == 1);
3216  vi = get_voter(vote);
3217  assert_any_sig_good(vi);
3219  if (!ds) {
3220  char *keys = list_v3_auth_ids();
3221  log_warn(LD_DIR, "Got a vote from an authority (nickname %s, address %s) "
3222  "with authority key ID %s. "
3223  "This key ID is not recognized. Known v3 key IDs are: %s",
3224  vi->nickname, vi->address,
3225  hex_str(vi->identity_digest, DIGEST_LEN), keys);
3226  tor_free(keys);
3227  *msg_out = "Vote not from a recognized v3 authority";
3228  goto err;
3229  }
3230  add_new_cert_if_needed(vote->cert);
3231 
3232  /* Is it for the right period? */
3233  if (vote->valid_after != voting_schedule.interval_starts) {
3234  char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1];
3235  format_iso_time(tbuf1, vote->valid_after);
3236  format_iso_time(tbuf2, voting_schedule.interval_starts);
3237  log_warn(LD_DIR, "Rejecting vote from %s with valid-after time of %s; "
3238  "we were expecting %s", vi->address, tbuf1, tbuf2);
3239  *msg_out = "Bad valid-after time";
3240  goto err;
3241  }
3242 
3243  if (time_posted) { /* they sent it to me via a POST */
3244  log_notice(LD_DIR, "%s posted a vote to me from %s.",
3245  vi->nickname, where_from);
3246  } else { /* I imported this one myself */
3247  log_notice(LD_DIR, "Retrieved %s's vote from %s.",
3248  vi->nickname, where_from);
3249  }
3250 
3251  /* Check if we received it, as a post, after the cutoff when we
3252  * start asking other dir auths for it. If we do, the best plan
3253  * is to discard it, because using it greatly increases the chances
3254  * of a split vote for this round (some dir auths got it in time,
3255  * some didn't). */
3256  if (time_posted && time_posted > voting_schedule.fetch_missing_votes) {
3257  char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1];
3258  format_iso_time(tbuf1, time_posted);
3259  format_iso_time(tbuf2, voting_schedule.fetch_missing_votes);
3260  log_warn(LD_DIR, "Rejecting %s's posted vote from %s received at %s; "
3261  "our cutoff for received votes is %s. Check your clock, "
3262  "CPU load, and network load. Also check the authority that "
3263  "posted the vote.", vi->nickname, vi->address, tbuf1, tbuf2);
3264  *msg_out = "Posted vote received too late, would be dangerous to count it";
3265  goto err;
3266  }
3267 
3268  /* Fetch any new router descriptors we just learned about */
3269  update_consensus_router_descriptor_downloads(time(NULL), 1, vote);
3270 
3271  /* Now see whether we already have a vote from this authority. */
3273  if (fast_memeq(v->vote->cert->cache_info.identity_digest,
3275  DIGEST_LEN)) {
3276  networkstatus_voter_info_t *vi_old = get_voter(v->vote);
3277  if (fast_memeq(vi_old->vote_digest, vi->vote_digest, DIGEST_LEN)) {
3278  /* Ah, it's the same vote. Not a problem. */
3279  log_notice(LD_DIR, "Discarding a vote we already have (from %s).",
3280  vi->address);
3281  if (*status_out < 200)
3282  *status_out = 200;
3283  goto discard;
3284  } else if (v->vote->published < vote->published) {
3285  log_notice(LD_DIR, "Replacing an older pending vote from this "
3286  "directory (%s)", vi->address);
3287  cached_dir_decref(v->vote_body);
3288  networkstatus_vote_free(v->vote);
3289  v->vote_body = new_cached_dir(tor_strndup(vote_body,
3290  end_of_vote-vote_body),
3291  vote->published);
3292  v->vote = vote;
3293  if (end_of_vote &&
3294  !strcmpstart(end_of_vote, "network-status-version"))
3295  goto again;
3296 
3297  if (*status_out < 200)
3298  *status_out = 200;
3299  if (!*msg_out)
3300  *msg_out = "OK";
3301  return v;
3302  } else {
3303  log_notice(LD_DIR, "Discarding vote from %s because we have "
3304  "a newer one already.", vi->address);
3305  *msg_out = "Already have a newer pending vote";
3306  goto err;
3307  }
3308  }
3309  } SMARTLIST_FOREACH_END(v);
3310 
3311  /* This a valid vote, update our shared random state. */
3312  sr_handle_received_commits(vote->sr_info.commits,
3313  vote->cert->identity_key);
3314 
3315  pending_vote = tor_malloc_zero(sizeof(pending_vote_t));
3316  pending_vote->vote_body = new_cached_dir(tor_strndup(vote_body,
3317  end_of_vote-vote_body),
3318  vote->published);
3319  pending_vote->vote = vote;
3320  smartlist_add(pending_vote_list, pending_vote);
3321 
3322  if (!strcmpstart(end_of_vote, "network-status-version ")) {
3323  vote_body = end_of_vote;
3324  goto again;
3325  }
3326 
3327  goto done;
3328 
3329  err:
3330  any_failed = 1;
3331  if (!*msg_out)
3332  *msg_out = "Error adding vote";
3333  if (*status_out < 400)
3334  *status_out = 400;
3335 
3336  discard:
3337  networkstatus_vote_free(vote);
3338 
3339  if (end_of_vote && !strcmpstart(end_of_vote, "network-status-version ")) {
3340  vote_body = end_of_vote;
3341  goto again;
3342  }
3343 
3344  done:
3345 
3346  if (*status_out < 200)
3347  *status_out = 200;
3348  if (!*msg_out) {
3349  if (!any_failed && !pending_vote) {
3350  *msg_out = "Duplicate discarded";
3351  } else {
3352  *msg_out = "ok";
3353  }
3354  }
3355 
3356  return any_failed ? NULL : pending_vote;
3357 }
3358 
3359 /* Write the votes in <b>pending_vote_list</b> to disk. */
3360 static void
3361 write_v3_votes_to_disk(const smartlist_t *pending_votes)
3362 {
3363  smartlist_t *votestrings = smartlist_new();
3364  char *votefile = NULL;
3365 
3366  SMARTLIST_FOREACH(pending_votes, pending_vote_t *, v,
3367  {
3368  sized_chunk_t *c = tor_malloc(sizeof(sized_chunk_t));
3369  c->bytes = v->vote_body->dir;
3370  c->len = v->vote_body->dir_len;
3371  smartlist_add(votestrings, c); /* collect strings to write to disk */
3372  });
3373 
3374  votefile = get_datadir_fname("v3-status-votes");
3375  write_chunks_to_file(votefile, votestrings, 0, 0);
3376  log_debug(LD_DIR, "Wrote votes to disk (%s)!", votefile);
3377 
3378  tor_free(votefile);
3379  SMARTLIST_FOREACH(votestrings, sized_chunk_t *, c, tor_free(c));
3380  smartlist_free(votestrings);
3381 }
3382 
3383 /** Try to compute a v3 networkstatus consensus from the currently pending
3384  * votes. Return 0 on success, -1 on failure. Store the consensus in
3385  * pending_consensus: it won't be ready to be published until we have
3386  * everybody else's signatures collected too. (V3 Authority only) */
3387 static int
3389 {
3390  /* Have we got enough votes to try? */
3391  int n_votes, n_voters, n_vote_running = 0;
3392  smartlist_t *votes = NULL;
3393  char *consensus_body = NULL, *signatures = NULL;
3394  networkstatus_t *consensus = NULL;
3395  authority_cert_t *my_cert;
3397  int flav;
3398 
3399  memset(pending, 0, sizeof(pending));
3400 
3401  if (!pending_vote_list)
3403 
3404  /* Write votes to disk */
3405  write_v3_votes_to_disk(pending_vote_list);
3406 
3407  /* Setup votes smartlist */
3408  votes = smartlist_new();
3410  {
3411  smartlist_add(votes, v->vote); /* collect votes to compute consensus */
3412  });
3413 
3414  /* See if consensus managed to achieve majority */
3415  n_voters = get_n_authorities(V3_DIRINFO);
3416  n_votes = smartlist_len(pending_vote_list);
3417  if (n_votes <= n_voters/2) {
3418  log_warn(LD_DIR, "We don't have enough votes to generate a consensus: "
3419  "%d of %d", n_votes, n_voters/2+1);
3420  goto err;
3421  }
3424  if (smartlist_contains_string(v->vote->known_flags, "Running"))
3425  n_vote_running++;
3426  });
3427  if (!n_vote_running) {
3428  /* See task 1066. */
3429  log_warn(LD_DIR, "Nobody has voted on the Running flag. Generating "
3430  "and publishing a consensus without Running nodes "
3431  "would make many clients stop working. Not "
3432  "generating a consensus!");
3433  goto err;
3434  }
3435 
3436  if (!(my_cert = get_my_v3_authority_cert())) {
3437  log_warn(LD_DIR, "Can't generate consensus without a certificate.");
3438  goto err;
3439  }
3440 
3441  {
3442  char legacy_dbuf[DIGEST_LEN];
3443  crypto_pk_t *legacy_sign=NULL;
3444  char *legacy_id_digest = NULL;
3445  int n_generated = 0;
3446  if (get_options()->V3AuthUseLegacyKey) {
3448  legacy_sign = get_my_v3_legacy_signing_key();
3449  if (cert) {
3450  if (crypto_pk_get_digest(cert->identity_key, legacy_dbuf)) {
3451  log_warn(LD_BUG,
3452  "Unable to compute digest of legacy v3 identity key");
3453  } else {
3454  legacy_id_digest = legacy_dbuf;
3455  }
3456  }
3457  }
3458 
3459  for (flav = 0; flav < N_CONSENSUS_FLAVORS; ++flav) {
3460  const char *flavor_name = networkstatus_get_flavor_name(flav);
3461  consensus_body = networkstatus_compute_consensus(
3462  votes, n_voters,
3463  my_cert->identity_key,
3464  get_my_v3_authority_signing_key(), legacy_id_digest, legacy_sign,
3465  flav);
3466 
3467  if (!consensus_body) {
3468  log_warn(LD_DIR, "Couldn't generate a %s consensus at all!",
3469  flavor_name);
3470  continue;
3471  }
3472  consensus = networkstatus_parse_vote_from_string(consensus_body,
3473  strlen(consensus_body),
3474  NULL,
3475  NS_TYPE_CONSENSUS);
3476  if (!consensus) {
3477  log_warn(LD_DIR, "Couldn't parse %s consensus we generated!",
3478  flavor_name);
3479  tor_free(consensus_body);
3480  continue;
3481  }
3482 
3483  /* 'Check' our own signature, to mark it valid. */
3485 
3486  pending[flav].body = consensus_body;
3487  pending[flav].consensus = consensus;
3488  n_generated++;
3489 
3490  /* Write it out to disk too, for dir auth debugging purposes */
3491  {
3492  char *filename;
3493  tor_asprintf(&filename, "my-consensus-%s", flavor_name);
3494  write_str_to_file(get_datadir_fname(filename), consensus_body, 0);
3495  tor_free(filename);
3496  }
3497 
3498  consensus_body = NULL;
3499  consensus = NULL;
3500  }
3501  if (!n_generated) {
3502  log_warn(LD_DIR, "Couldn't generate any consensus flavors at all.");
3503  goto err;
3504  }
3505  }
3506 
3508  pending, N_CONSENSUS_FLAVORS);
3509 
3510  if (!signatures) {
3511  log_warn(LD_DIR, "Couldn't extract signatures.");
3512  goto err;
3513  }
3514 
3516  memcpy(pending_consensuses, pending, sizeof(pending));
3517 
3519  pending_consensus_signatures = signatures;
3520 
3522  int n_sigs = 0;
3523  /* we may have gotten signatures for this consensus before we built
3524  * it ourself. Add them now. */
3526  const char *msg = NULL;
3528  "pending", &msg);
3529  if (r >= 0)
3530  n_sigs += r;
3531  else
3532  log_warn(LD_DIR,
3533  "Could not add queued signature to new consensus: %s",
3534  msg);
3535  tor_free(sig);
3536  } SMARTLIST_FOREACH_END(sig);
3537  if (n_sigs)
3538  log_notice(LD_DIR, "Added %d pending signatures while building "
3539  "consensus.", n_sigs);
3541  }
3542 
3543  log_notice(LD_DIR, "Consensus computed; uploading signature(s)");
3544 
3547  V3_DIRINFO,
3549  strlen(pending_consensus_signatures), 0);
3550  log_notice(LD_DIR, "Signature(s) posted.");
3551 
3552  smartlist_free(votes);
3553  return 0;
3554  err:
3555  smartlist_free(votes);
3556  tor_free(consensus_body);
3557  tor_free(signatures);
3558  networkstatus_vote_free(consensus);
3559 
3560  return -1;
3561 }
3562 
3563 /** Helper: we just got the <b>detached_signatures_body</b> sent to us as
3564  * signatures on the currently pending consensus. Add them to <b>pc</b>
3565  * as appropriate. Return the number of signatures added. (?) */
3566 static int
3568  pending_consensus_t *pc,
3570  const char *source,
3571  int severity,
3572  const char **msg_out)
3573 {
3574  const char *flavor_name;
3575  int r = -1;
3576 
3577  /* Only call if we have a pending consensus right now. */
3578  tor_assert(pc->consensus);
3579  tor_assert(pc->body);
3581 
3582  flavor_name = networkstatus_get_flavor_name(pc->consensus->flavor);
3583  *msg_out = NULL;
3584 
3585  {
3586  smartlist_t *sig_list = strmap_get(sigs->signatures, flavor_name);
3587  log_info(LD_DIR, "Have %d signatures for adding to %s consensus.",
3588  sig_list ? smartlist_len(sig_list) : 0, flavor_name);
3589  }
3591  source, severity, msg_out);
3592  if (r >= 0) {
3593  log_info(LD_DIR,"Added %d signatures to consensus.", r);
3594  } else {
3595  log_fn(LOG_PROTOCOL_WARN, LD_DIR,
3596  "Unable to add signatures to consensus: %s",
3597  *msg_out ? *msg_out : "(unknown)");
3598  }
3599 
3600  if (r >= 1) {
3601  char *new_signatures =
3603  char *dst, *dst_end;
3604  size_t new_consensus_len;
3605  if (!new_signatures) {
3606  *msg_out = "No signatures to add";
3607  goto err;
3608  }
3609  new_consensus_len =
3610  strlen(pc->body) + strlen(new_signatures) + 1;
3611  pc->body = tor_realloc(pc->body, new_consensus_len);
3612  dst_end = pc->body + new_consensus_len;
3613  dst = (char *) find_str_at_start_of_line(pc->body, "directory-signature ");
3614  tor_assert(dst);
3615  strlcpy(dst, new_signatures, dst_end-dst);
3616 
3617  /* We remove this block once it has failed to crash for a while. But
3618  * unless it shows up in profiles, we're probably better leaving it in,
3619  * just in case we break detached signature processing at some point. */
3620  {
3622  pc->body, strlen(pc->body), NULL,
3623  NS_TYPE_CONSENSUS);
3624  tor_assert(v);
3625  networkstatus_vote_free(v);
3626  }
3627  *msg_out = "Signatures added";
3628  tor_free(new_signatures);
3629  } else if (r == 0) {
3630  *msg_out = "Signatures ignored";
3631  } else {
3632  goto err;
3633  }
3634 
3635  goto done;
3636  err:
3637  if (!*msg_out)
3638  *msg_out = "Unrecognized error while adding detached signatures.";
3639  done:
3640  return r;
3641 }
3642 
3643 /** Helper: we just got the <b>detached_signatures_body</b> sent to us as
3644  * signatures on the currently pending consensus. Add them to the pending
3645  * consensus (if we have one).
3646  *
3647  * Set *<b>msg</b> to a string constant describing the status, regardless of
3648  * success or failure.
3649  *
3650  * Return negative on failure, nonnegative on success. */
3651 static int
3653  const char *detached_signatures_body,
3654  const char *source,
3655  const char **msg_out)
3656 {
3657  int r=0, i, n_added = 0, errors = 0;
3659  tor_assert(detached_signatures_body);
3660  tor_assert(msg_out);
3662 
3664  detached_signatures_body, NULL))) {
3665  *msg_out = "Couldn't parse detached signatures.";
3666  goto err;
3667  }
3668 
3669  for (i = 0; i < N_CONSENSUS_FLAVORS; ++i) {
3670  int res;
3671  int severity = i == FLAV_NS ? LOG_NOTICE : LOG_INFO;
3672  pending_consensus_t *pc = &pending_consensuses[i];
3673  if (!pc->consensus)
3674  continue;
3675  res = dirvote_add_signatures_to_pending_consensus(pc, sigs, source,
3676  severity, msg_out);
3677  if (res < 0)
3678  errors++;
3679  else
3680  n_added += res;
3681  }
3682 
3683  if (errors && !n_added) {
3684  r = -1;
3685  goto err;
3686  }
3687 
3688  if (n_added && pending_consensuses[FLAV_NS].consensus) {
3689  char *new_detached =
3691  pending_consensuses, N_CONSENSUS_FLAVORS);
3692  if (new_detached) {
3694  pending_consensus_signatures = new_detached;
3695  }
3696  }
3697 
3698  r = n_added;
3699  goto done;
3700  err:
3701  if (!*msg_out)
3702  *msg_out = "Unrecognized error while adding detached signatures.";
3703  done:
3704  ns_detached_signatures_free(sigs);
3705  /* XXXX NM Check how return is used. We can now have an error *and*
3706  signatures added. */
3707  return r;
3708 }
3709 
3710 /** Helper: we just got the <b>detached_signatures_body</b> sent to us as
3711  * signatures on the currently pending consensus. Add them to the pending
3712  * consensus (if we have one); otherwise queue them until we have a
3713  * consensus.
3714  *
3715  * Set *<b>msg</b> to a string constant describing the status, regardless of
3716  * success or failure.
3717  *
3718  * Return negative on failure, nonnegative on success. */
3719 int
3720 dirvote_add_signatures(const char *detached_signatures_body,
3721  const char *source,
3722  const char **msg)
3723 {
3724  if (pending_consensuses[FLAV_NS].consensus) {
3725  log_notice(LD_DIR, "Got a signature from %s. "
3726  "Adding it to the pending consensus.", source);
3728  detached_signatures_body, source, msg);
3729  } else {
3730  log_notice(LD_DIR, "Got a signature from %s. "
3731  "Queuing it for the next consensus.", source);
3735  detached_signatures_body);
3736  *msg = "Signature queued";
3737  return 0;
3738  }
3739 }
3740 
3741 /** Replace the consensus that we're currently serving with the one that we've
3742  * been building. (V3 Authority only) */
3743 static int
3745 {
3746  int i;
3747 
3748  /* Now remember all the other consensuses as if we were a directory cache. */
3749  for (i = 0; i < N_CONSENSUS_FLAVORS; ++i) {
3750  pending_consensus_t *pending = &pending_consensuses[i];
3751  const char *name;
3753  tor_assert(name);
3754  if (!pending->consensus ||
3756  log_warn(LD_DIR, "Not enough info to publish pending %s consensus",name);
3757  continue;
3758  }
3759 
3761  strlen(pending->body),
3762  name, 0, NULL))
3763  log_warn(LD_DIR, "Error publishing %s consensus", name);
3764  else
3765  log_notice(LD_DIR, "Published %s consensus", name);
3766  }
3767 
3768  return 0;
3769 }
3770 
3771 /** Release all static storage held in dirvote.c */
3772 void
3774 {
3776  /* now empty as a result of dirvote_clear_votes(). */
3777  smartlist_free(pending_vote_list);
3778  pending_vote_list = NULL;
3779  smartlist_free(previous_vote_list);
3780  previous_vote_list = NULL;
3781 
3785  /* now empty as a result of dirvote_clear_votes(). */
3786  smartlist_free(pending_consensus_signature_list);
3788  }
3789 }
3790 
3791 /* ====
3792  * Access to pending items.
3793  * ==== */
3794 
3795 /** Return the body of the consensus that we're currently trying to build. */
3796 MOCK_IMPL(const char *,
3798 {
3799  tor_assert(((int)flav) >= 0 && (int)flav < N_CONSENSUS_FLAVORS);
3800  return pending_consensuses[flav].body;
3801 }
3802 
3803 /** Return the signatures that we know for the consensus that we're currently
3804  * trying to build. */
3805 MOCK_IMPL(const char *,
3807 {
3809 }
3810 
3811 /** Return a given vote specified by <b>fp</b>. If <b>by_id</b>, return the
3812  * vote for the authority with the v3 authority identity key digest <b>fp</b>;
3813  * if <b>by_id</b> is false, return the vote whose digest is <b>fp</b>. If
3814  * <b>fp</b> is NULL, return our own vote. If <b>include_previous</b> is
3815  * false, do not consider any votes for a consensus that's already been built.
3816  * If <b>include_pending</b> is false, do not consider any votes for the
3817  * consensus that's in progress. May return NULL if we have no vote for the
3818  * authority in question. */
3819 const cached_dir_t *
3820 dirvote_get_vote(const char *fp, int flags)
3821 {
3822  int by_id = flags & DGV_BY_ID;
3823  const int include_pending = flags & DGV_INCLUDE_PENDING;
3824  const int include_previous = flags & DGV_INCLUDE_PREVIOUS;
3825 
3827  return NULL;
3828  if (fp == NULL) {
3830  if (c) {
3831  fp = c->cache_info.identity_digest;
3832  by_id = 1;
3833  } else
3834  return NULL;
3835  }
3836  if (by_id) {
3837  if (pending_vote_list && include_pending) {
3839  if (fast_memeq(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
3840  return pv->vote_body);
3841  }
3842  if (previous_vote_list && include_previous) {
3844  if (fast_memeq(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
3845  return pv->vote_body);
3846  }
3847  } else {
3848  if (pending_vote_list && include_pending) {
3850  if (fast_memeq(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN))
3851  return pv->vote_body);
3852  }
3853  if (previous_vote_list && include_previous) {
3855  if (fast_memeq(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN))
3856  return pv->vote_body);
3857  }
3858  }
3859  return NULL;
3860 }
3861 
3862 /** Construct and return a new microdescriptor from a routerinfo <b>ri</b>
3863  * according to <b>consensus_method</b>.
3864  **/
3866 dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method)
3867 {
3868  microdesc_t *result = NULL;
3869  char *key = NULL, *summary = NULL, *family = NULL;
3870  size_t keylen;
3871  smartlist_t *chunks = smartlist_new();
3872  char *output = NULL;
3873  crypto_pk_t *rsa_pubkey = router_get_rsa_onion_pkey(ri->onion_pkey,
3874  ri->onion_pkey_len);
3875 
3876  if (crypto_pk_write_public_key_to_string(rsa_pubkey, &key, &keylen)<0)
3877  goto done;
3878  summary = policy_summarize(ri->exit_policy, AF_INET);
3879  if (ri->declared_family)
3880  family = smartlist_join_strings(ri->declared_family, " ", 0, NULL);
3881 
3882  smartlist_add_asprintf(chunks, "onion-key\n%s", key);
3883 
3884  if (ri->onion_curve25519_pkey) {
3885  char kbuf[CURVE25519_BASE64_PADDED_LEN + 1];
3886  bool add_padding = (consensus_method < MIN_METHOD_FOR_UNPADDED_NTOR_KEY);
3887  curve25519_public_to_base64(kbuf, ri->onion_curve25519_pkey, add_padding);
3888  smartlist_add_asprintf(chunks, "ntor-onion-key %s\n", kbuf);
3889  }
3890 
3891  if (family) {
3892  if (consensus_method < MIN_METHOD_FOR_CANONICAL_FAMILIES_IN_MICRODESCS) {
3893  smartlist_add_asprintf(chunks, "family %s\n", family);
3894  } else {
3895  const uint8_t *id = (const uint8_t *)ri->cache_info.identity_digest;
3896  char *canonical_family = nodefamily_canonicalize(family, id, 0);
3897  smartlist_add_asprintf(chunks, "family %s\n", canonical_family);
3898  tor_free(canonical_family);
3899  }
3900  }
3901 
3902  if (summary && strcmp(summary, "reject 1-65535"))
3903  smartlist_add_asprintf(chunks, "p %s\n", summary);
3904 
3905  if (ri->ipv6_exit_policy) {
3906  /* XXXX+++ This doesn't match proposal 208, which says these should
3907  * be taken unchanged from the routerinfo. That's bogosity, IMO:
3908  * the proposal should have said to do this instead.*/
3909  char *p6 = write_short_policy(ri->ipv6_exit_policy);
3910  if (p6 && strcmp(p6, "reject 1-65535"))
3911  smartlist_add_asprintf(chunks, "p6 %s\n", p6);
3912  tor_free(p6);
3913  }
3914 
3915  {
3916  char idbuf[ED25519_BASE64_LEN+1];
3917  const char *keytype;
3918  if (ri->cache_info.signing_key_cert &&
3919  ri->cache_info.signing_key_cert->signing_key_included) {
3920  keytype = "ed25519";
3922  &ri->cache_info.signing_key_cert->signing_key);
3923  } else {
3924  keytype = "rsa1024";
3925  digest_to_base64(idbuf, ri->cache_info.identity_digest);
3926  }
3927  smartlist_add_asprintf(chunks, "id %s %s\n", keytype, idbuf);
3928  }
3929 
3930  output = smartlist_join_strings(chunks, "", 0, NULL);
3931 
3932  {
3934  output+strlen(output), 0,
3935  SAVED_NOWHERE, NULL);
3936  if (smartlist_len(lst) != 1) {
3937  log_warn(LD_DIR, "We generated a microdescriptor we couldn't parse.");
3938  SMARTLIST_FOREACH(lst, microdesc_t *, md, microdesc_free(md));
3939  smartlist_free(lst);
3940  goto done;
3941  }
3942  result = smartlist_get(lst, 0);
3943  smartlist_free(lst);
3944  }
3945 
3946  done:
3947  crypto_pk_free(rsa_pubkey);
3948  tor_free(output);
3949  tor_free(key);
3950  tor_free(summary);
3951  tor_free(family);
3952  if (chunks) {
3953  SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3954  smartlist_free(chunks);
3955  }
3956  return result;
3957 }
3958 
3959 /** Format the appropriate vote line to describe the microdescriptor <b>md</b>
3960  * in a consensus vote document. Write it into the <b>out_len</b>-byte buffer
3961  * in <b>out</b>. Return -1 on failure and the number of characters written
3962  * on success. */
3963 static ssize_t
3964 dirvote_format_microdesc_vote_line(char *out_buf, size_t out_buf_len,
3965  const microdesc_t *md,
3966  int consensus_method_low,
3967  int consensus_method_high)
3968 {
3969  ssize_t ret = -1;
3970  char d64[BASE64_DIGEST256_LEN+1];
3971  char *microdesc_consensus_methods =
3972  make_consensus_method_list(consensus_method_low,
3973  consensus_method_high,
3974  ",");
3975  tor_assert(microdesc_consensus_methods);
3976 
3977  digest256_to_base64(d64, md->digest);
3978 
3979  if (tor_snprintf(out_buf, out_buf_len, "m %s sha256=%s\n",
3980  microdesc_consensus_methods, d64)<0)
3981  goto out;
3982 
3983  ret = strlen(out_buf);
3984 
3985  out:
3986  tor_free(microdesc_consensus_methods);
3987  return ret;
3988 }
3989 
3990 /** Array of start and end of consensus methods used for supported
3991  microdescriptor formats. */
3992 static const struct consensus_method_range_t {
3993  int low;
3994  int high;
3995 } microdesc_consensus_methods[] = {
4002  {-1, -1}
4003 };
4004 
4005 /** Helper type used when generating the microdescriptor lines in a directory
4006  * vote. */
4007 typedef struct microdesc_vote_line_t {
4008  int low;
4009  int high;
4010  microdesc_t *md;
4011  struct microdesc_vote_line_t *next;
4013 
4014 /** Generate and return a linked list of all the lines that should appear to
4015  * describe a router's microdescriptor versions in a directory vote.
4016  * Add the generated microdescriptors to <b>microdescriptors_out</b>. */
4019  smartlist_t *microdescriptors_out)
4020 {
4021  const struct consensus_method_range_t *cmr;
4022  microdesc_vote_line_t *entries = NULL, *ep;
4023  vote_microdesc_hash_t *result = NULL;
4024 
4025  /* Generate the microdescriptors. */
4026  for (cmr = microdesc_consensus_methods;
4027  cmr->low != -1 && cmr->high != -1;
4028  cmr++) {
4029  microdesc_t *md = dirvote_create_microdescriptor(ri, cmr->low);
4030  if (md) {
4032  tor_malloc_zero(sizeof(microdesc_vote_line_t));
4033  e->md = md;
4034  e->low = cmr->low;
4035  e->high = cmr->high;
4036  e->next = entries;
4037  entries = e;
4038  }
4039  }
4040 
4041  /* Compress adjacent identical ones */
4042  for (ep = entries; ep; ep = ep->next) {
4043  while (ep->next &&
4044  fast_memeq(ep->md->digest, ep->next->md->digest, DIGEST256_LEN) &&
4045  ep->low == ep->next->high + 1) {
4046  microdesc_vote_line_t *next = ep->next;
4047  ep->low = next->low;
4048  microdesc_free(next->md);
4049  ep->next = next->next;
4050  tor_free(next);
4051  }
4052  }
4053 
4054  /* Format them into vote_microdesc_hash_t, and add to microdescriptors_out.*/
4055  while ((ep = entries)) {
4056  char buf[128];
4058  if (dirvote_format_microdesc_vote_line(buf, sizeof(buf), ep->md,
4059  ep->low, ep->high) >= 0) {
4060  h = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
4061  h->microdesc_hash_line = tor_strdup(buf);
4062  h->next = result;
4063  result = h;
4064  ep->md->last_listed = now;
4065  smartlist_add(microdescriptors_out, ep->md);
4066  }
4067  entries = ep->next;
4068  tor_free(ep);
4069  }
4070 
4071  return result;
4072 }
4073 
4074 /** Parse and extract all SR commits from <b>tokens</b> and place them in
4075  * <b>ns</b>. */
4076 static void
4078 {
4079  smartlist_t *chunks = NULL;
4080 
4081  tor_assert(ns);
4082  tor_assert(tokens);
4083  /* Commits are only present in a vote. */
4084  tor_assert(ns->type == NS_TYPE_VOTE);
4085 
4086  ns->sr_info.commits = smartlist_new();
4087 
4088  smartlist_t *commits = find_all_by_keyword(tokens, K_COMMIT);
4089  /* It's normal that a vote might contain no commits even if it participates
4090  * in the SR protocol. Don't treat it as an error. */
4091  if (commits == NULL) {
4092  goto end;
4093  }
4094 
4095  /* Parse the commit. We do NO validation of number of arguments or ordering
4096  * for forward compatibility, it's the parse commit job to inform us if it's
4097  * supported or not. */
4098  chunks = smartlist_new();
4099  SMARTLIST_FOREACH_BEGIN(commits, directory_token_t *, tok) {
4100  /* Extract all arguments and put them in the chunks list. */
4101  for (int i = 0; i < tok->n_args; i++) {
4102  smartlist_add(chunks, tok->args[i]);
4103  }
4104  sr_commit_t *commit = sr_parse_commit(chunks);
4105  smartlist_clear(chunks);
4106  if (commit == NULL) {
4107  /* Get voter identity so we can warn that this dirauth vote contains
4108  * commit we can't parse. */
4109  networkstatus_voter_info_t *voter = smartlist_get(ns->voters, 0);
4110  tor_assert(voter);
4111  log_warn(LD_DIR, "SR: Unable to parse commit %s from vote of voter %s.",
4112  escaped(tok->object_body),
4113  hex_str(voter->identity_digest,
4114  sizeof(voter->identity_digest)));
4115  /* Commitment couldn't be parsed. Continue onto the next commit because
4116  * this one could be unsupported for instance. */
4117  continue;
4118  }
4119  /* Add newly created commit object to the vote. */
4120  smartlist_add(ns->sr_info.commits, commit);
4121  } SMARTLIST_FOREACH_END(tok);
4122 
4123  end:
4124  smartlist_free(chunks);
4125  smartlist_free(commits);
4126 }
4127 
4128 /* Using the given directory tokens in tokens, parse the shared random commits
4129  * and put them in the given vote document ns.
4130  *
4131  * This also sets the SR participation flag if present in the vote. */
4132 void
4133 dirvote_parse_sr_commits(networkstatus_t *ns, const smartlist_t *tokens)
4134 {
4135  /* Does this authority participates in the SR protocol? */
4136  directory_token_t *tok = find_opt_by_keyword(tokens, K_SR_FLAG);
4137  if (tok) {
4138  ns->sr_info.participate = 1;
4139  /* Get the SR commitments and reveals from the vote. */
4140  extract_shared_random_commits(ns, tokens);
4141  }
4142 }
4143 
4144 /* For the given vote, free the shared random commits if any. */
4145 void
4146 dirvote_clear_commits(networkstatus_t *ns)
4147 {
4148  tor_assert(ns->type == NS_TYPE_VOTE);
4149 
4150  if (ns->sr_info.commits) {
4151  SMARTLIST_FOREACH(ns->sr_info.commits, sr_commit_t *, c,
4152  sr_commit_free(c));
4153  smartlist_free(ns->sr_info.commits);
4154  }
4155 }
4156 
4157 /* The given url is the /tor/status-vote GET directory request. Populates the
4158  * items list with strings that we can compress on the fly and dir_items with
4159  * cached_dir_t objects that have a precompressed deflated version. */
4160 void
4161 dirvote_dirreq_get_status_vote(const char *url, smartlist_t *items,
4162  smartlist_t *dir_items)
4163 {
4164  int current;
4165 
4166  url += strlen("/tor/status-vote/");
4167  current = !strcmpstart(url, "current/");
4168  url = strchr(url, '/');
4169  tor_assert(url);
4170  ++url;
4171  if (!strcmp(url, "consensus")) {
4172  const char *item;
4173  tor_assert(!current); /* we handle current consensus specially above,
4174  * since it wants to be spooled. */
4175  if ((item = dirvote_get_pending_consensus(FLAV_NS)))
4176  smartlist_add(items, (char*)item);
4177  } else if (!current && !strcmp(url, "consensus-signatures")) {
4178  /* XXXX the spec says that we should implement
4179  * current/consensus-signatures too. It doesn't seem to be needed,
4180  * though. */
4181  const char *item;
4183  smartlist_add(items, (char*)item);
4184  } else if (!strcmp(url, "authority")) {
4185  const cached_dir_t *d;
4186  int flags = DGV_BY_ID |
4187  (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
4188  if ((d=dirvote_get_vote(NULL, flags)))
4189  smartlist_add(dir_items, (cached_dir_t*)d);
4190  } else {
4191  const cached_dir_t *d;
4192  smartlist_t *fps = smartlist_new();
4193  int flags;
4194  if (!strcmpstart(url, "d/")) {
4195  url += 2;
4196  flags = DGV_INCLUDE_PENDING | DGV_INCLUDE_PREVIOUS;
4197  } else {
4198  flags = DGV_BY_ID |
4199  (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
4200  }
4201  dir_split_resource_into_fingerprints(url, fps, NULL,
4202  DSR_HEX|DSR_SORT_UNIQ);
4203  SMARTLIST_FOREACH(fps, char *, fp, {
4204  if ((d = dirvote_get_vote(fp, flags)))
4205  smartlist_add(dir_items, (cached_dir_t*)d);
4206  tor_free(fp);
4207  });
4208  smartlist_free(fps);
4209  }
4210 }
4211 
4212 /** Get the best estimate of a router's bandwidth for dirauth purposes,
4213  * preferring measured to advertised values if available. */
4215  (const routerinfo_t *ri))
4216 {
4217  uint32_t bw_kb = 0;
4218  /*
4219  * Yeah, measured bandwidths in measured_bw_line_t are (implicitly
4220  * signed) longs and the ones router_get_advertised_bandwidth() returns
4221  * are uint32_t.
4222  */
4223  long mbw_kb = 0;
4224 
4225  if (ri) {
4226  /*
4227  * * First try to see if we have a measured bandwidth; don't bother with
4228  * as_of_out here, on the theory that a stale measured bandwidth is still
4229  * better to trust than an advertised one.
4230  */
4232  &mbw_kb, NULL)) {
4233  /* Got one! */
4234  bw_kb = (uint32_t)mbw_kb;
4235  } else {
4236  /* If not, fall back to advertised */
4237  bw_kb = router_get_advertised_bandwidth(ri) / 1000;
4238  }
4239  }
4240 
4241  return bw_kb;
4242 }
4243 
4244 /**
4245  * Helper: compare the address of family `family` in `a` with the address in
4246  * `b`. The family must be one of `AF_INET` and `AF_INET6`.
4247  **/
4248 static int
4250  const routerinfo_t *b,
4251  int family)
4252 {
4253  const tor_addr_t *addr1 = (family==AF_INET) ? &a->ipv4_addr : &a->ipv6_addr;
4254  const tor_addr_t *addr2 = (family==AF_INET) ? &b->ipv4_addr : &b->ipv6_addr;
4255  return tor_addr_compare(addr1, addr2, CMP_EXACT);
4256 }
4257 
4258 /** Helper for sorting: compares two ipv4 routerinfos first by ipv4 address,
4259  * and then by descending order of "usefulness"
4260  * (see compare_routerinfo_usefulness)
4261  **/
4262 STATIC int
4263 compare_routerinfo_by_ipv4(const void **a, const void **b)
4264 {
4265  const routerinfo_t *first = *(const routerinfo_t **)a;
4266  const routerinfo_t *second = *(const routerinfo_t **)b;
4267  int comparison = compare_routerinfo_addrs_by_family(first, second, AF_INET);
4268  if (comparison == 0) {
4269  // If addresses are equal, use other comparison criteria
4270  return compare_routerinfo_usefulness(first, second);
4271  } else {
4272  return comparison;
4273  }
4274 }
4275 
4276 /** Helper for sorting: compares two ipv6 routerinfos first by ipv6 address,
4277  * and then by descending order of "usefulness"
4278  * (see compare_routerinfo_usefulness)
4279  **/
4280 STATIC int
4281 compare_routerinfo_by_ipv6(const void **a, const void **b)
4282 {
4283  const routerinfo_t *first = *(const routerinfo_t **)a;
4284  const routerinfo_t *second = *(const routerinfo_t **)b;
4285  int comparison = compare_routerinfo_addrs_by_family(first, second, AF_INET6);
4286  // If addresses are equal, use other comparison criteria
4287  if (comparison == 0)
4288  return compare_routerinfo_usefulness(first, second);
4289  else
4290  return comparison;
4291 }
4292 
4293 /**
4294 * Compare routerinfos by descending order of "usefulness" :
4295 * An authority is more useful than a non-authority; a running router is
4296 * more useful than a non-running router; and a router with more bandwidth
4297 * is more useful than one with less.
4298 **/
4299 STATIC int
4301  const routerinfo_t *second)
4302 {
4303  int first_is_auth, second_is_auth;
4304  const node_t *node_first, *node_second;
4305  int first_is_running, second_is_running;
4306  uint32_t bw_kb_first, bw_kb_second;
4307  /* Potentially, this next bit could cause k n lg n memeq calls. But in
4308  * reality, we will almost never get here, since addresses will usually be
4309  * different. */
4310  first_is_auth =
4311  router_digest_is_trusted_dir(first->cache_info.identity_digest);
4312  second_is_auth =
4313  router_digest_is_trusted_dir(second->cache_info.identity_digest);
4314 
4315  if (first_is_auth && !second_is_auth)
4316  return -1;
4317  else if (!first_is_auth && second_is_auth)
4318  return 1;
4319 
4320  node_first = node_get_by_id(first->cache_info.identity_digest);
4321  node_second = node_get_by_id(second->cache_info.identity_digest);
4322  first_is_running = node_first && node_first->is_running;
4323  second_is_running = node_second && node_second->is_running;
4324  if (first_is_running && !second_is_running)
4325  return -1;
4326  else if (!first_is_running && second_is_running)
4327  return 1;
4328 
4329  bw_kb_first = dirserv_get_bandwidth_for_router_kb(first);
4330  bw_kb_second = dirserv_get_bandwidth_for_router_kb(second);
4331 
4332  if (bw_kb_first > bw_kb_second)
4333  return -1;
4334  else if (bw_kb_first < bw_kb_second)
4335  return 1;
4336 
4337  /* They're equal! Compare by identity digest, so there's a
4338  * deterministic order and we avoid flapping. */
4339  return fast_memcmp(first->cache_info.identity_digest,
4340  second->cache_info.identity_digest,
4341  DIGEST_LEN);
4342 }
4343 
4344 /** Given a list of routerinfo_t in <b>routers</b> that all use the same
4345  * IP version, specified in <b>family</b>, return a new digestmap_t whose keys
4346  * are the identity digests of those routers that we're going to exclude for
4347  * Sybil-like appearance.
4348  */
4349 STATIC digestmap_t *
4351 {
4352  const dirauth_options_t *options = dirauth_get_options();
4353  digestmap_t *omit_as_sybil = digestmap_new();
4354  smartlist_t *routers_by_ip = smartlist_new();
4355  int addr_count = 0;
4356  routerinfo_t *last_ri = NULL;
4357  /* Allow at most this number of Tor servers on a single IP address, ... */
4358  int max_with_same_addr = options->AuthDirMaxServersPerAddr;
4359  if (max_with_same_addr <= 0)
4360  max_with_same_addr = INT_MAX;
4361 
4362  smartlist_add_all(routers_by_ip, routers);
4363  if (family == AF_INET6)
4365  else
4367 
4368  SMARTLIST_FOREACH_BEGIN(routers_by_ip, routerinfo_t *, ri) {
4369  bool addrs_equal;
4370  if (last_ri)
4371  addrs_equal = !compare_routerinfo_addrs_by_family(last_ri, ri, family);
4372  else
4373  addrs_equal = false;
4374 
4375  if (! addrs_equal) {
4376  last_ri = ri;
4377  addr_count = 1;
4378  } else if (++addr_count > max_with_same_addr) {
4379  digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4380  }
4381  } SMARTLIST_FOREACH_END(ri);
4382  smartlist_free(routers_by_ip);
4383  return omit_as_sybil;
4384 }
4385 
4386 /** Given a list of routerinfo_t in <b>routers</b>, return a new digestmap_t
4387  * whose keys are the identity digests of those routers that we're going to
4388  * exclude for Sybil-like appearance. */
4389 STATIC digestmap_t *
4391 {
4392  smartlist_t *routers_ipv6, *routers_ipv4;
4393  routers_ipv6 = smartlist_new();
4394  routers_ipv4 = smartlist_new();
4395  digestmap_t *omit_as_sybil_ipv4;
4396  digestmap_t *omit_as_sybil_ipv6;
4397  digestmap_t *omit_as_sybil = digestmap_new();
4398  // Sort the routers in two lists depending on their IP version
4399  SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
4400  // If the router has an IPv6 address
4401  if (tor_addr_family(&(ri->ipv6_addr)) == AF_INET6) {
4402  smartlist_add(routers_ipv6, ri);
4403  }
4404  // If the router has an IPv4 address
4405  if (tor_addr_family(&(ri->ipv4_addr)) == AF_INET) {
4406  smartlist_add(routers_ipv4, ri);
4407  }
4408  } SMARTLIST_FOREACH_END(ri);
4409  omit_as_sybil_ipv4 = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
4410  omit_as_sybil_ipv6 = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
4411 
4412  // Add all possible sybils to the common digestmap
4413  DIGESTMAP_FOREACH (omit_as_sybil_ipv4, sybil_id, routerinfo_t *, ri) {
4414  digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4416  DIGESTMAP_FOREACH (omit_as_sybil_ipv6, sybil_id, routerinfo_t *, ri) {
4417  digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4419  // Clean the temp variables
4420  smartlist_free(routers_ipv4);
4421  smartlist_free(routers_ipv6);
4422  digestmap_free(omit_as_sybil_ipv4, NULL);
4423  digestmap_free(omit_as_sybil_ipv6, NULL);
4424  // Return the digestmap: it now contains all the possible sybils
4425  return omit_as_sybil;
4426 }
4427 
4428 /** Given a platform string as in a routerinfo_t (possibly null), return a
4429  * newly allocated version string for a networkstatus document, or NULL if the
4430  * platform doesn't give a Tor version. */
4431 static char *
4432 version_from_platform(const char *platform)
4433 {
4434  if (platform && !strcmpstart(platform, "Tor ")) {
4435  const char *eos = find_whitespace(platform+4);
4436  if (eos && !strcmpstart(eos, " (r")) {
4437  /* XXXX Unify this logic with the other version extraction
4438  * logic in routerparse.c. */
4439  eos = find_whitespace(eos+1);
4440  }
4441  if (eos) {
4442  return tor_strndup(platform, eos-platform);
4443  }
4444  }
4445  return NULL;
4446 }
4447 
4448 /** Given a (possibly empty) list of config_line_t, each line of which contains
4449  * a list of comma-separated version numbers surrounded by optional space,
4450  * allocate and return a new string containing the version numbers, in order,
4451  * separated by commas. Used to generate Recommended(Client|Server)?Versions
4452  */
4453 char *
4455 {
4456  smartlist_t *versions;
4457  char *result;
4458  versions = smartlist_new();
4459  for ( ; ln; ln = ln->next) {
4460  smartlist_split_string(versions, ln->value, ",",
4461  SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4462  }
4463 
4464  /* Handle the case where a dirauth operator has accidentally made some
4465  * versions space-separated instead of comma-separated. */
4466  smartlist_t *more_versions = smartlist_new();
4467  SMARTLIST_FOREACH_BEGIN(versions, char *, v) {
4468  if (strchr(v, ' ')) {
4469  if (warn)
4470  log_warn(LD_DIRSERV, "Unexpected space in versions list member %s. "
4471  "(These are supposed to be comma-separated; I'll pretend you "
4472  "used commas instead.)", escaped(v));
4473  SMARTLIST_DEL_CURRENT(versions, v);
4474  smartlist_split_string(more_versions, v, NULL,
4475  SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4476  tor_free(v);
4477  }
4478  } SMARTLIST_FOREACH_END(v);
4479  smartlist_add_all(versions, more_versions);
4480  smartlist_free(more_versions);
4481 
4482  /* Check to make sure everything looks like a version. */
4483  if (warn) {
4484  SMARTLIST_FOREACH_BEGIN(versions, const char *, v) {
4485  tor_version_t ver;
4486  if (tor_version_parse(v, &ver) < 0) {
4487  log_warn(LD_DIRSERV, "Recommended version %s does not look valid. "
4488  " (I'll include it anyway, since you told me to.)",
4489  escaped(v));
4490  }
4491  } SMARTLIST_FOREACH_END(v);
4492  }
4493 
4494  sort_version_list(versions, 1);
4495  result = smartlist_join_strings(versions,",",0,NULL);
4496  SMARTLIST_FOREACH(versions,char *,s,tor_free(s));
4497  smartlist_free(versions);
4498  return result;
4499 }
4500 
4501 /** If there are entries in <b>routers</b> with exactly the same ed25519 keys,
4502  * remove the older one. If they are exactly the same age, remove the one
4503  * with the greater descriptor digest. May alter the order of the list. */
4504 static void
4506 {
4507  routerinfo_t *ri2;
4508  digest256map_t *by_ed_key = digest256map_new();
4509 
4510  SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
4511  ri->omit_from_vote = 0;
4512  if (ri->cache_info.signing_key_cert == NULL)
4513  continue; /* No ed key */
4514  const uint8_t *pk = ri->cache_info.signing_key_cert->signing_key.pubkey;
4515  if ((ri2 = digest256map_get(by_ed_key, pk))) {
4516  /* Duplicate; must omit one. Set the omit_from_vote flag in whichever
4517  * one has the earlier published_on. */
4518  const time_t ri_pub = ri->cache_info.published_on;
4519  const time_t ri2_pub = ri2->cache_info.published_on;
4520  if (ri2_pub < ri_pub ||
4521  (ri2_pub == ri_pub &&
4522  fast_memcmp(ri->cache_info.signed_descriptor_digest,
4523  ri2->cache_info.signed_descriptor_digest,DIGEST_LEN)<0)) {
4524  digest256map_set(by_ed_key, pk, ri);
4525  ri2->omit_from_vote = 1;
4526  } else {
4527  ri->omit_from_vote = 1;
4528  }
4529  } else {
4530  /* Add to map */
4531  digest256map_set(by_ed_key, pk, ri);
4532  }
4533  } SMARTLIST_FOREACH_END(ri);
4534 
4535  digest256map_free(by_ed_key, NULL);
4536 
4537  /* Now remove every router where the omit_from_vote flag got set. */
4538  SMARTLIST_FOREACH_BEGIN(routers, const routerinfo_t *, ri) {
4539  if (ri->omit_from_vote) {
4540  SMARTLIST_DEL_CURRENT(routers, ri);
4541  }
4542  } SMARTLIST_FOREACH_END(ri);
4543 }
4544 
4545 /** Routerstatus <b>rs</b> is part of a group of routers that are on too
4546  * narrow an IP-space. Clear out its flags since we don't want it be used
4547  * because of its Sybil-like appearance.
4548  *
4549  * Leave its BadExit flag alone though, since if we think it's a bad exit,
4550  * we want to vote that way in case all the other authorities are voting
4551  * Running and Exit.
4552  *
4553  * Also set the Sybil flag in order to let a relay operator know that's
4554  * why their relay hasn't been voted on.
4555  */
4556 static void
4558 {
4559  rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
4560  rs->is_flagged_running = rs->is_named = rs->is_valid =
4561  rs->is_hs_dir = rs->is_v2_dir = rs->is_possible_guard = 0;
4562  rs->is_sybil = 1;
4563  /* FFFF we might want some mechanism to check later on if we
4564  * missed zeroing any flags: it's easy to add a new flag but
4565  * forget to add it to this clause. */
4566 }
4567 
4568 /** Space-separated list of all the flags that we will always vote on. */
4570  "Authority "
4571  "Exit "
4572  "Fast "
4573  "Guard "
4574  "HSDir "
4575  "Stable "
4576  "StaleDesc "
4577  "Sybil "
4578  "V2Dir "
4579  "Valid";
4580 /** Space-separated list of all flags that we may or may not vote on,
4581  * depending on our configuration. */
4583  "BadExit "
4584  "Running";
4585 
4586 /** Return a new networkstatus_t* containing our current opinion. (For v3
4587  * authorities) */
4590  authority_cert_t *cert)
4591 {
4592  const or_options_t *options = get_options();
4593  const dirauth_options_t *d_options = dirauth_get_options();
4594  networkstatus_t *v3_out = NULL;
4595  tor_addr_t addr;
4596  char *hostname = NULL, *client_versions = NULL, *server_versions = NULL;
4597  const char *contact;
4598  smartlist_t *routers, *routerstatuses;
4599  char identity_digest[DIGEST_LEN];
4600  char signing_key_digest[DIGEST_LEN];
4601  const int listbadexits = d_options->AuthDirListBadExits;
4603  time_t now = time(NULL);
4604  time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
4605  networkstatus_voter_info_t *voter = NULL;
4606  vote_timing_t timing;
4607  const int vote_on_reachability = running_long_enough_to_decide_unreachable();
4608  smartlist_t *microdescriptors = NULL;
4609  smartlist_t *bw_file_headers = NULL;
4610  uint8_t bw_file_digest256[DIGEST256_LEN] = {0};
4611 
4612  tor_assert(private_key);
4613  tor_assert(cert);
4614 
4615  if (crypto_pk_get_digest(private_key, signing_key_digest)<0) {
4616  log_err(LD_BUG, "Error computing signing key digest");
4617  return NULL;
4618  }
4619  if (crypto_pk_get_digest(cert->identity_key, identity_digest)<0) {
4620  log_err(LD_BUG, "Error computing identity key digest");
4621  return NULL;
4622  }
4623  if (!find_my_address(options, AF_INET, LOG_WARN, &addr, NULL, &hostname)) {
4624  log_warn(LD_NET, "Couldn't resolve my hostname");
4625  return NULL;
4626  }
4627  if (!hostname || !strchr(hostname, '.')) {
4628  tor_free(hostname);
4629  hostname = tor_addr_to_str_dup(&addr);
4630  }
4631 
4632  if (!hostname) {
4633  log_err(LD_BUG, "Failed to determine hostname AND duplicate address");
4634  return NULL;
4635  }
4636 
4637  if (d_options->VersioningAuthoritativeDirectory) {
4638  client_versions =
4640  server_versions =
4642  }
4643 
4644  contact = get_options()->ContactInfo;
4645  if (!contact)
4646  contact = "(none)";
4647 
4648  /*
4649  * Do this so dirserv_compute_performance_thresholds() and
4650  * set_routerstatus_from_routerinfo() see up-to-date bandwidth info.
4651  */
4652  if (options->V3BandwidthsFile) {
4654  NULL);
4655  } else {
4656  /*
4657  * No bandwidths file; clear the measured bandwidth cache in case we had
4658  * one last time around.
4659  */
4662  }
4663  }
4664 
4665  /* precompute this part, since we need it to decide what "stable"
4666  * means. */
4667  SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
4668  dirserv_set_router_is_running(ri, now);
4669  });
4670 
4671  routers = smartlist_new();
4672  smartlist_add_all(routers, rl->routers);
4673  routers_make_ed_keys_unique(routers);
4674  /* After this point, don't use rl->routers; use 'routers' instead. */
4675  routers_sort_by_identity(routers);
4676  /* Get a digestmap of possible sybil routers, IPv4 or IPv6 */
4677  digestmap_t *omit_as_sybil = get_all_possible_sybil(routers);
4678  DIGESTMAP_FOREACH (omit_as_sybil, sybil_id, void *, ignore) {
4679  (void)ignore;
4680  rep_hist_make_router_pessimal(sybil_id, now);
4682  /* Count how many have measured bandwidths so we know how to assign flags;
4683  * this must come before dirserv_compute_performance_thresholds() */
4684  dirserv_count_measured_bws(routers);
4686  routerstatuses = smartlist_new();
4687  microdescriptors = smartlist_new();
4688 
4689  SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
4690  /* If it has a protover list and contains a protocol name greater than
4691  * MAX_PROTOCOL_NAME_LENGTH, skip it. */
4692  if (ri->protocol_list &&
4693  protover_list_is_invalid(ri->protocol_list)) {
4694  continue;
4695  }
4696  if (ri->cache_info.published_on >= cutoff) {
4697  routerstatus_t *rs;
4698  vote_routerstatus_t *vrs;
4699  node_t *node = node_get_mutable_by_id(ri->cache_info.identity_digest);
4700  if (!node)
4701  continue;
4702 
4703  vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
4704  rs = &vrs->status;
4705  dirauth_set_routerstatus_from_routerinfo(rs, node, ri, now,
4706  listbadexits);
4707 
4708  if (ri->cache_info.signing_key_cert) {
4709  memcpy(vrs->ed25519_id,
4710  ri->cache_info.signing_key_cert->signing_key.pubkey,
4712  }
4713  if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
4715 
4716  if (!vote_on_reachability)
4717  rs->is_flagged_running = 0;
4718 
4719  vrs->version = version_from_platform(ri->platform);
4720  if (ri->protocol_list) {
4721  vrs->protocols = tor_strdup(ri->protocol_list);
4722  } else {
4723  vrs->protocols = tor_strdup(
4725  }
4727  microdescriptors);
4728 
4729  smartlist_add(routerstatuses, vrs);
4730  }
4731  } SMARTLIST_FOREACH_END(ri);
4732 
4733  {
4734  smartlist_t *added =
4736  microdescriptors, SAVED_NOWHERE, 0);
4737  smartlist_free(added);
4738  smartlist_free(microdescriptors);
4739  }
4740 
4741  smartlist_free(routers);
4742  digestmap_free(omit_as_sybil, NULL);
4743 
4744  /* Apply guardfraction information to routerstatuses. */
4745  if (options->GuardfractionFile) {
4747  routerstatuses);
4748  }
4749 
4750  /* This pass through applies the measured bw lines to the routerstatuses */
4751  if (options->V3BandwidthsFile) {
4752  /* Only set bw_file_headers when V3BandwidthsFile is configured */
4753  bw_file_headers = smartlist_new();
4755  routerstatuses, bw_file_headers,
4756  bw_file_digest256);
4757  } else {
4758  /*
4759  * No bandwidths file; clear the measured bandwidth cache in case we had
4760  * one last time around.
4761  */
4764  }
4765  }
4766 
4767  v3_out = tor_malloc_zero(sizeof(networkstatus_t));
4768 
4769  v3_out->type = NS_TYPE_VOTE;
4771  v3_out->published = now;
4772  {
4773  char tbuf[ISO_TIME_LEN+1];
4774  networkstatus_t *current_consensus =
4776  long last_consensus_interval; /* only used to pick a valid_after */
4777  if (current_consensus)
4778  last_consensus_interval = current_consensus->fresh_until -
4779  current_consensus->valid_after;
4780  else
4781  last_consensus_interval = options->TestingV3AuthInitialVotingInterval;
4782  v3_out->valid_after =
4784  (int)last_consensus_interval,
4786  format_iso_time(tbuf, v3_out->valid_after);
4787  log_notice(LD_DIR,"Choosing valid-after time in vote as %s: "
4788  "consensus_set=%d, last_interval=%d",
4789  tbuf, current_consensus?1:0, (int)last_consensus_interval);
4790  }
4791  v3_out->fresh_until = v3_out->valid_after + timing.vote_interval;
4792  v3_out->valid_until = v3_out->valid_after +
4793  (timing.vote_interval * timing.n_intervals_valid);
4794  v3_out->vote_seconds = timing.vote_delay;
4795  v3_out->dist_seconds = timing.dist_delay;
4796  tor_assert(v3_out->vote_seconds > 0);
4797  tor_assert(v3_out->dist_seconds > 0);
4798  tor_assert(timing.n_intervals_valid > 0);
4799 
4800  v3_out->client_versions = client_versions;
4801  v3_out->server_versions = server_versions;
4802 
4803  /* These are hardwired, to avoid disaster. */
4804  v3_out->recommended_relay_protocols =
4805  tor_strdup(DIRVOTE_RECOMMEND_RELAY_PROTO);
4806  v3_out->recommended_client_protocols =
4807  tor_strdup(DIRVOTE_RECOMMEND_CLIENT_PROTO);
4808 
4809  v3_out->required_relay_protocols =
4810  tor_strdup(DIRVOTE_REQUIRE_RELAY_PROTO);
4811  v3_out->required_client_protocols =
4812  tor_strdup(DIRVOTE_REQUIRE_CLIENT_PROTO);
4813 
4814  /* We are not allowed to vote to require anything we don't have. */
4815  tor_assert(protover_all_supported(v3_out->required_relay_protocols, NULL));
4816  tor_assert(protover_all_supported(v3_out->required_client_protocols, NULL));
4817 
4818  /* We should not recommend anything we don't have. */
4819  tor_assert_nonfatal(protover_all_supported(
4820  v3_out->recommended_relay_protocols, NULL));
4821  tor_assert_nonfatal(protover_all_supported(
4822  v3_out->recommended_client_protocols, NULL));
4823 
4824  v3_out->known_flags = smartlist_new();
4827  0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4828  if (vote_on_reachability)
4829  smartlist_add_strdup(v3_out->known_flags, "Running");
4830  if (listbadexits)
4831  smartlist_add_strdup(v3_out->known_flags, "BadExit");
4833 
4834  if (d_options->ConsensusParams) {
4835  config_line_t *paramline = d_options->ConsensusParams;
4836  v3_out->net_params = smartlist_new();
4837  for ( ; paramline; paramline = paramline->next) {
4839  paramline->value, NULL, 0, 0);
4840  }
4842  }
4843  v3_out->bw_file_headers = bw_file_headers;
4844  memcpy(v3_out->bw_file_digest256, bw_file_digest256, DIGEST256_LEN);
4845 
4846  voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
4847  voter->nickname = tor_strdup(options->Nickname);
4848  memcpy(voter->identity_digest, identity_digest, DIGEST_LEN);
4849  voter->sigs = smartlist_new();
4850  voter->address = hostname;
4851  tor_addr_copy(&voter->ipv4_addr, &addr);
4852  voter->ipv4_dirport = routerconf_find_dir_port(options, 0);
4853  voter->ipv4_orport = routerconf_find_or_port(options, AF_INET);
4854  voter->contact = tor_strdup(contact);
4855  if (options->V3AuthUseLegacyKey) {
4857  if (c) {
4859  log_warn(LD_BUG, "Unable to compute digest of legacy v3 identity key");
4860  memset(voter->legacy_id_digest, 0, DIGEST_LEN);
4861  }
4862  }
4863  }
4864 
4865  v3_out->voters = smartlist_new();
4866  smartlist_add(v3_out->voters, voter);
4867  v3_out->cert = authority_cert_dup(cert);
4868  v3_out->routerstatus_list = routerstatuses;
4869  /* Note: networkstatus_digest is unset; it won't get set until we actually
4870  * format the vote. */
4871 
4872  return v3_out;
4873 }
log_fn
#define log_fn(severity, domain, args,...)
Definition: log.h:283
routerstatus_t::ipv4_dirport
uint16_t ipv4_dirport
Definition: routerstatus_st.h:34
guardfraction_bandwidth_t::non_guard_bw
int non_guard_bw
Definition: entrynodes.h:644
microdesc_t
Definition: microdesc_st.h:27
networkstatus_get_flavor_name
const char * networkstatus_get_flavor_name(consensus_flavor_t flav)
Definition: networkstatus.c:2577
authority_cert_t::identity_key
crypto_pk_t * identity_key
Definition: authority_cert_st.h:23
tor_addr_compare
int tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2, tor_addr_comparison_t how)
Definition: address.c:984
tor_free
#define tor_free(p)
Definition: malloc.h:52
MIN_DIST_SECONDS
#define MIN_DIST_SECONDS
Definition: dirvote.h:32
compare_routerinfo_usefulness
STATIC int compare_routerinfo_usefulness(const routerinfo_t *first, const routerinfo_t *second)
Definition: dirvote.c:4300
routerinfo_t
Definition: routerinfo_st.h:20
dirvote_fetch_missing_signatures
static void dirvote_fetch_missing_signatures(void)
Definition: dirvote.c:3052
dirauth_options_t::VersioningAuthoritativeDirectory
BOOL VersioningAuthoritativeDirectory
Definition: dirauth_options.inc:103
dir_server_st.h
Trusted/fallback directory server structure.
routerstatus_t::is_authority
unsigned int is_authority
Definition: routerstatus_st.h:37
or_options_t::TestingV3AuthVotingStartOffset
int TestingV3AuthVotingStartOffset
Definition: or_options_st.h:741
versions.h
Header file for versions.c.
networkstatus_t::valid_until
time_t valid_until
Definition: networkstatus_st.h:36
vote_routerstatus_t::microdesc
vote_microdesc_hash_t * microdesc
Definition: vote_routerstatus_st.h:40
find_str_at_start_of_line
const char * find_str_at_start_of_line(const char *haystack, const char *needle)
Definition: util_string.c:400
tor_free_
void tor_free_(void *mem)
Definition: malloc.c:227
vote_timing_st.h
Directory voting schedule structure.
tor_addr_family
static sa_family_t tor_addr_family(const tor_addr_t *a)
Definition: address.h:187
smartlist_split_string
int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep, int flags, int max)
Definition: smartlist_split.c:37
T
#define T(s, t, a, o)
Definition: parsecommon.h:246
dirvote_add_vote
pending_vote_t * dirvote_add_vote(const char *vote_body, time_t time_posted, const char *where_from, const char **msg_out, int *status_out)
Definition: dirvote.c:3184
hex_str
const char * hex_str(const char *from, size_t fromlen)
Definition: binascii.c:34
dirvote_fetch_missing_votes
static void dirvote_fetch_missing_votes(void)
Definition: dirvote.c:3012
MAX_BW_FILE_HEADER_COUNT_IN_VOTE
#define MAX_BW_FILE_HEADER_COUNT_IN_VOTE
Definition: bwauth.h:16
dirvote_get_pending_consensus
const char * dirvote_get_pending_consensus(consensus_flavor_t flav)
Definition: dirvote.c:3797
pending_vote_list
static smartlist_t * pending_vote_list
Definition: dirvote.c:2945
name
const char * name
Definition: config.c:2434
networkstatus_t::digests
common_digests_t digests
Definition: networkstatus_st.h:88
or_options_t::V3AuthDistDelay
int V3AuthDistDelay
Definition: or_options_st.h:713
sr_parse_commit
sr_commit_t * sr_parse_commit(const smartlist_t *args)
Definition: shared_random.c:1023
networkstatus_t::published
time_t published
Definition: networkstatus_st.h:32
microdesc_parse.h
Header file for microdesc_parse.c.
dirserv_query_measured_bw_cache_kb
int dirserv_query_measured_bw_cache_kb(const char *node_id, long *bw_kb_out, time_t *as_of_out)
Definition: bwauth.c:138
BW_WEIGHT_SCALE
#define BW_WEIGHT_SCALE
Definition: or.h:904
networkstatus_check_document_signature
int networkstatus_check_document_signature(const networkstatus_t *consensus, document_signature_t *sig, const authority_cert_t *cert)
Definition: networkstatus.c:458
tor_addr_t
Definition: address.h:69
or_options_t::V3AuthVotingInterval
int V3AuthVotingInterval
Definition: or_options_st.h:709
vote_timing_t::dist_delay
int dist_delay
Definition: vote_timing_st.h:25
ED25519_BASE64_LEN
#define ED25519_BASE64_LEN
Definition: x25519_sizes.h:43
protover.h
Headers and type declarations for protover.c.
smartlist_add_strdup
void smartlist_add_strdup(struct smartlist_t *sl, const char *string)
Definition: smartlist_core.c:137
LOG_NOTICE
#define LOG_NOTICE
Definition: log.h:50
get_sybil_list_by_ip_version
STATIC digestmap_t * get_sybil_list_by_ip_version(const smartlist_t *routers, sa_family_t family)
Definition: dirvote.c:4350
networkstatus_get_voter_sig_by_alg
document_signature_t * networkstatus_get_voter_sig_by_alg(const networkstatus_voter_info_t *voter, digest_algorithm_t alg)
Definition: networkstatus.c:442
vote_microdesc_hash_t
Definition: vote_microdesc_hash_st.h:18
dircollate.h
Header file for dircollate.c.
MIN_VOTE_INTERVAL
#define MIN_VOTE_INTERVAL
Definition: dirvote.h:37
MOCK_IMPL
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
networkstatus_t::bw_file_digest256
uint8_t bw_file_digest256[DIGEST256_LEN]
Definition: networkstatus_st.h:109
networkstatus_t::type
networkstatus_type_t type
Definition: networkstatus_st.h:27
pending_consensus_t
Definition: dirvote.c:112
get_voter
static networkstatus_voter_info_t * get_voter(const networkstatus_t *vote)
Definition: dirvote.c:530
BASE64_DIGEST256_LEN
#define BASE64_DIGEST256_LEN
Definition: crypto_digest.h:29
previous_vote_list
static smartlist_t * previous_vote_list
Definition: dirvote.c:2948
dirauth_options_t::ConsensusParams
LINELIST ConsensusParams
Definition: dirauth_options.inc:56
routers_sort_by_identity
void routers_sort_by_identity(smartlist_t *routers)
Definition: routerlist.c:3275
MIN_VOTE_INTERVAL_TESTING
#define MIN_VOTE_INTERVAL_TESTING
Definition: dirvote.h:46
compute_consensus_versions_list
static char * compute_consensus_versions_list(smartlist_t *lst, int n_versioning)
Definition: dirvote.c:860
microdesc_t::digest
char digest[DIGEST256_LEN]
Definition: microdesc_st.h:62
networkstatus_voter_info_t::identity_digest
char identity_digest[DIGEST_LEN]
Definition: networkstatus_voter_info_st.h:18
routerstatus_t::is_flagged_running
unsigned int is_flagged_running
Definition: routerstatus_st.h:45
list_v3_auth_ids
static char * list_v3_auth_ids(void)
Definition: dirvote.c:3131
compare_routerinfo_addrs_by_family
static int compare_routerinfo_addrs_by_family(const routerinfo_t *a, const routerinfo_t *b, int family)
Definition: dirvote.c:4249
tor_assert
#define tor_assert(expr)
Definition: util_bug.h:102
routerkeys.h
Header for routerkeys.c.
microdesc.h
Header file for microdesc.c.
LD_BUG
#define LD_BUG
Definition: log.h:86
router.h
Header file for router.c.
authcert.h
Header file for authcert.c.
dirserv_get_flag_thresholds_line
char * dirserv_get_flag_thresholds_line(void)
Definition: voteflags.c:433
routerinfo_t::ipv6_exit_policy
struct short_policy_t * ipv6_exit_policy
Definition: routerinfo_st.h:63
or_options_t::TestingV3AuthInitialVotingInterval
int TestingV3AuthInitialVotingInterval
Definition: or_options_st.h:729
format_iso_time
void format_iso_time(char *buf, time_t t)
Definition: time_fmt.c:295
fast_mem_is_zero
int fast_mem_is_zero(const char *mem, size_t len)
Definition: util_string.c:74
dsigs_parse.h
Code to parse and validate detached-signature objects.
routerstatus_t::is_valid
unsigned int is_valid
Definition: routerstatus_st.h:49
CURVE25519_BASE64_PADDED_LEN
#define CURVE25519_BASE64_PADDED_LEN
Definition: x25519_sizes.h:37
pending_consensus_t::body
char * body
Definition: dirvote.c:115
format_protocols_lines_for_vote
static char * format_protocols_lines_for_vote(const networkstatus_t *v3_ns)
Definition: dirvote.c:184
dirauth_options_t::RecommendedServerVersions
LINELIST RecommendedServerVersions
Definition: dirauth_options.inc:73
routerstatus_t::exitsummary
char * exitsummary
Definition: routerstatus_st.h:79
base16_encode
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
Definition: binascii.c:478
DIGESTMAP_FOREACH_END
#define DIGESTMAP_FOREACH_END
Definition: map.h:168
networkstatus_t::voters
smartlist_t * voters
Definition: networkstatus_st.h:83
sized_chunk_t
Definition: files.h:84
crypto_pk_dup_key
crypto_pk_t * crypto_pk_dup_key(crypto_pk_t *orig)
Definition: crypto_rsa_nss.c:351
directory_token_t
Definition: parsecommon.h:201
get_my_v3_authority_cert
authority_cert_t * get_my_v3_authority_cert(void)
Definition: router.c:449
smartlist_add_all
void smartlist_add_all(smartlist_t *s1, const smartlist_t *s2)
Definition: smartlist_core.c:125
smartlist_sort_digests256
void smartlist_sort_digests256(smartlist_t *sl)
Definition: smartlist.c:846
compare_orports_
static int compare_orports_(const void **_a, const void **_b)
Definition: dirvote.c:657
dirvote_get_pending_detached_signatures
const char * dirvote_get_pending_detached_signatures(void)
Definition: dirvote.c:3806
sr_act_post_consensus
void sr_act_post_consensus(const networkstatus_t *consensus)
Definition: shared_random.c:1232
node_get_by_id
const node_t * node_get_by_id(const char *identity_digest)
Definition: nodelist.c:226
networkstatus_get_live_consensus
networkstatus_t * networkstatus_get_live_consensus(time_t now)
Definition: networkstatus.c:1416
smartlist_add
void smartlist_add(smartlist_t *sl, void *element)
Definition: smartlist_core.c:117
networkstatus_t::bw_file_headers
smartlist_t * bw_file_headers
Definition: networkstatus_st.h:106
authority_cert_get_by_digests
authority_cert_t * authority_cert_get_by_digests(const char *id_digest, const char *sk_digest)
Definition: authcert.c:648
routerstatus_t::has_guardfraction
unsigned int has_guardfraction
Definition: routerstatus_st.h:75
vote_timing_t::vote_delay
int vote_delay
Definition: vote_timing_st.h:23
sr_handle_received_commits
void sr_handle_received_commits(smartlist_t *commits, crypto_pk_t *voter_key)
Definition: shared_random.c:1093
routerstatus_t
Definition: routerstatus_st.h:19
dirvote_clear_votes
static void dirvote_clear_votes(int all_votes)
Definition: dirvote.c:3089
voting_sched_get_start_of_interval_after
time_t voting_sched_get_start_of_interval_after(time_t now, int interval, int offset)
Definition: networkstatus.c:2792
routerlist_t::routers
smartlist_t * routers
Definition: routerlist_st.h:32
get_nth_protocol_set_vote
static const char * get_nth_protocol_set_vote(int n, const networkstatus_t *vote)
Definition: dirvote.c:1421
authority_cert_t::expires
time_t expires
Definition: authority_cert_st.h:29
sr_get_string_for_consensus
char * sr_get_string_for_consensus(const smartlist_t *votes, int32_t num_srv_agreements)
Definition: shared_random.c:1196
networkstatus_voter_info_t::contact
char * contact
Definition: networkstatus_voter_info_st.h:27
routerstatus_t::nickname
char nickname[MAX_NICKNAME_LEN+1]
Definition: routerstatus_st.h:25
find_my_address
bool find_my_address(const or_options_t *options, int family, int warn_severity, tor_addr_t *addr_out, resolved_addr_method_t *method_out, char **hostname_out)
Attempt to find our IP address that can be used as our external reachable address.
Definition: resolve_addr.c:715
dirauth_sched_recalculate_timing
void dirauth_sched_recalculate_timing(const or_options_t *options, time_t now)
Definition: voting_schedule.c:177
pending_vote_t
Definition: dirvote.c:2938
tor_version_t
Definition: tor_version_st.h:21
ED25519_PUBKEY_LEN
#define ED25519_PUBKEY_LEN
Definition: x25519_sizes.h:27
document_signature_t::good_signature
unsigned int good_signature
Definition: document_signature_st.h:29
pending_consensus_t::consensus
networkstatus_t * consensus
Definition: dirvote.c:117
pending_consensus_signatures
static char * pending_consensus_signatures
Definition: dirvote.c:2955
smartlist_new
smartlist_t * smartlist_new(void)
Definition: smartlist_core.c:26
dirvote_act
time_t dirvote_act(const or_options_t *options, time_t now)
Definition: dirvote.c:2861
base64_encode
int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen, int flags)
Definition: binascii.c:215
routerinfo_t::onion_pkey_len
size_t onion_pkey_len
Definition: routerinfo_st.h:39
tor_snprintf
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition: printf.c:27
routerinfo_t::ipv6_addr
tor_addr_t ipv6_addr
Definition: routerinfo_st.h:30
common_digests_t
Definition: crypto_digest.h:87
tor_parse_long
long tor_parse_long(const char *s, int base, long min, long max, int *ok, char **next)
Definition: parse_int.c:59
ed25519_public_to_base64
void ed25519_public_to_base64(char *output, const ed25519_public_key_t *pkey)
Definition: crypto_format.c:227
tor_version_parse
int tor_version_parse(const char *s, tor_version_t *out)
Definition: versions.c:206
SMARTLIST_FOREACH
#define SMARTLIST_FOREACH(sl, type, var, cmd)
Definition: smartlist_foreach.h:112
dir_split_resource_into_fingerprints
int dir_split_resource_into_fingerprints(const char *resource, smartlist_t *fp_out, int *compressed_out, int flags)
Definition: directory.c:640
routerstatus_t::is_fast
unsigned int is_fast
Definition: routerstatus_st.h:40
routerstatus_t::has_bandwidth
unsigned int has_bandwidth
Definition: routerstatus_st.h:63
networkstatus.h
Header file for networkstatus.c.
fmt_routerstatus.h
Format routerstatus entries for controller, vote, or consensus.
dirvote_publish_consensus
static int dirvote_publish_consensus(void)
Definition: dirvote.c:3744
dirserv_get_bandwidth_for_router_kb
uint32_t dirserv_get_bandwidth_for_router_kb(const routerinfo_t *ri)
Definition: dirvote.c:4215
digest256_to_base64
void digest256_to_base64(char *d64, const char *digest)
Definition: crypto_format.c:304
signed_descriptor_t::identity_digest
char identity_digest[DIGEST_LEN]
Definition: signed_descriptor_st.h:31
version_from_platform
static char * version_from_platform(const char *platform)
Definition: dirvote.c:4432
dirlist.h
Header file for dirlist.c.
consensus_flavor_t
consensus_flavor_t
Definition: or.h:761
DIR_PURPOSE_UPLOAD_VOTE
#define DIR_PURPOSE_UPLOAD_VOTE
Definition: directory.h:43
LD_CIRC
#define LD_CIRC
Definition: log.h:82
dirauth_options_t::AuthDirListBadExits
BOOL AuthDirListBadExits
Definition: dirauth_options.inc:28
dirserv_generate_networkstatus_vote_obj
networkstatus_t * dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, authority_cert_t *cert)
Definition: dirvote.c:4589
get_n_authorities
int get_n_authorities(dirinfo_type_t type)
Definition: dirlist.c:90
find_all_by_keyword
smartlist_t * find_all_by_keyword(const smartlist_t *s, directory_keyword k)
Definition: parsecommon.c:468
get_all_possible_sybil
STATIC digestmap_t * get_all_possible_sybil(const smartlist_t *routers)
Definition: dirvote.c:4390
vote_microdesc_hash_t::microdesc_hash_line
char * microdesc_hash_line
Definition: vote_microdesc_hash_st.h:23
ns_detached_signatures_t::digests
strmap_t * digests
Definition: ns_detached_signatures_st.h:21
MAX
#define MAX(a, b)
Definition: cmp.h:22
smartlist_string_pos
int smartlist_string_pos(const smartlist_t *sl, const char *element)
Definition: smartlist.c:106
write_str_to_file
int write_str_to_file(const char *fname, const char *str, int bin)
Definition: files.c:274
routerstatus_format_entry
char * routerstatus_format_entry(const routerstatus_t *rs, const char *version, const char *protocols, routerstatus_format_type_t format, const vote_routerstatus_t *vrs)
Definition: fmt_routerstatus.c:43
networkstatus_check_consensus_signature
int networkstatus_check_consensus_signature(networkstatus_t *consensus, int warn)
Definition: networkstatus.c:511
routerconf_find_dir_port
uint16_t routerconf_find_dir_port(const or_options_t *options, uint16_t dirport)
Definition: router.c:1607
DIGEST_LEN
#define DIGEST_LEN
Definition: digest_sizes.h:20
dirvote_format_microdesc_vote_line
static ssize_t dirvote_format_microdesc_vote_line(char *out_buf, size_t out_buf_len, const microdesc_t *md, int consensus_method_low, int consensus_method_high)
Definition: dirvote.c:3964
smartlist_get_most_frequent_string_
const char * smartlist_get_most_frequent_string_(smartlist_t *sl, int *count_out)
Definition: smartlist.c:566
make_consensus_method_list
STATIC char * make_consensus_method_list(int low, int high, const char *separator)
Definition: dirvote.c:836
vote_routerstatus_t::version
char * version
Definition: vote_routerstatus_st.h:26
node_get_mutable_by_id
node_t * node_get_mutable_by_id(const char *identity_digest)
Definition: nodelist.c:197
document_signature_t
Definition: document_signature_st.h:16
or_options_t::V3AuthNIntervalsValid
int V3AuthNIntervalsValid
Definition: or_options_st.h:715
routerstatus_t::is_possible_guard
unsigned int is_possible_guard
Definition: routerstatus_st.h:50
strmap_set_lc
void * strmap_set_lc(strmap_t *map, const char *key, void *val)
Definition: map.c:346
guardfraction_bandwidth_t
Definition: entrynodes.h:640
microdescs_parse_from_string
smartlist_t * microdescs_parse_from_string(const char *s, const char *eos, int allow_annotations, saved_location_t where, smartlist_t *invalid_digests_out)
Definition: microdesc_parse.c:293
crypto_format.h
Header for crypto_format.c.
shared_random_state.h
Header for shared_random_state.c.
compare_routerinfo_by_ipv4
STATIC int compare_routerinfo_by_ipv4(const void **a, const void **b)
Definition: dirvote.c:4263
voteflags.h
Header file for voteflags.c.
signed_descriptor_t::saved_location
saved_location_t saved_location
Definition: signed_descriptor_st.h:44
DIR_PURPOSE_UPLOAD_SIGNATURES
#define DIR_PURPOSE_UPLOAD_SIGNATURES
Definition: directory.h:45
routerlist_t
Definition: routerlist_st.h:18
networkstatus_get_latest_consensus_by_flavor
networkstatus_t * networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
Definition: networkstatus.c:1401
routerstatus_t::is_sybil
unsigned int is_sybil
Definition: routerstatus_st.h:61
routerinfo_t::ipv4_addr
tor_addr_t ipv4_addr
Definition: routerinfo_st.h:25
vote_routerstatus_t::flags
uint64_t flags
Definition: vote_routerstatus_st.h:24
tor_addr_port_t
Definition: address.h:81
routerstatus_t::ipv4_orport
uint16_t ipv4_orport
Definition: routerstatus_st.h:33
entrynodes.h
Header file for circuitbuild.c.
dirvote.h
Header file for dirvote.c.
dircollator_n_routers
int dircollator_n_routers(dircollator_t *dc)
Definition: dircollate.c:305
dirserv_count_measured_bws
void dirserv_count_measured_bws(const smartlist_t *routers)
Definition: bwauth.c:39
get_my_v3_legacy_cert
authority_cert_t * get_my_v3_legacy_cert(void)
Definition: router.c:466
smartlist_get_most_frequent_digest256
const uint8_t * smartlist_get_most_frequent_digest256(smartlist_t *sl)
Definition: smartlist.c:854
tor_assert_nonfatal_unreached
#define tor_assert_nonfatal_unreached()
Definition: util_bug.h:176
authority_cert_dup
STATIC authority_cert_t * authority_cert_dup(authority_cert_t *cert)
Definition: dirvote.c:146
node_t
Definition: node_st.h:34
vote_routerstatus_st.h
Routerstatus (vote entry) structure.
compare_routerinfo_by_ipv6
STATIC int compare_routerinfo_by_ipv6(const void **a, const void **b)
Definition: dirvote.c:4281
extract_shared_random_commits
static void extract_shared_random_commits(networkstatus_t *ns, const smartlist_t *tokens)
Definition: dirvote.c:4077
dirauth_options_st.h
Structure dirauth_options_t to hold directory authority options.
get_my_v3_authority_signing_key
crypto_pk_t * get_my_v3_authority_signing_key(void)
Definition: router.c:457
trusted_dirs_load_certs_from_string
int trusted_dirs_load_certs_from_string(const char *contents, int source, int flush, const char *source_dir)
Definition: authcert.c:373
MIN_METHOD_FOR_CANONICAL_FAMILIES_IN_MICRODESCS
#define MIN_METHOD_FOR_CANONICAL_FAMILIES_IN_MICRODESCS
Definition: dirvote.h:62
networkstatus_t::client_versions
char * client_versions
Definition: networkstatus_st.h:56
networkstatus_t::flavor
consensus_flavor_t flavor
Definition: networkstatus_st.h:28
torcert.h
Header for torcert.c.
vote_routerstatus_t::ed25519_id
uint8_t ed25519_id[ED25519_PUBKEY_LEN]
Definition: vote_routerstatus_st.h:42
crypto_digest_algorithm_get_name
const char * crypto_digest_algorithm_get_name(digest_algorithm_t alg)
Definition: crypto_digest.c:44
vote_routerstatus_t
Definition: vote_routerstatus_st.h:18
networkstatus_check_weights
static bw_weights_error_t networkstatus_check_weights(int64_t Wgg, int64_t Wgd, int64_t Wmg, int64_t Wme, int64_t Wmd, int64_t Wee, int64_t Wed, int64_t scale, int64_t G, int64_t M, int64_t E, int64_t D, int64_t T, int64_t margin, int do_balance)
Definition: dirvote.c:1028
directory.h
Header file for directory.c.
dircollator_add_vote
void dircollator_add_vote(dircollator_t *dc, networkstatus_t *v)
Definition: dircollate.c:194
crypto_pk_get_digest
int crypto_pk_get_digest(const crypto_pk_t *pk, char *digest_out)
Definition: crypto_rsa.c:356
routerstatus_t::published_on
time_t published_on
Definition: routerstatus_st.h:24
tor_digest_is_zero
int tor_digest_is_zero(const char *digest)
Definition: util_string.c:96
cached_dir_st.h
Cached large directory object structure.
consensus_method_range_t
Definition: dirvote.c:3992
nodefamily_canonicalize
char * nodefamily_canonicalize(const char *s, const uint8_t *rsa_id_self, unsigned flags)
Definition: nodefamily.c:111
protover_compute_vote
char * protover_compute_vote(const smartlist_t *list_of_proto_strings, int threshold)
Definition: protover.c:520
authority_cert_st.h
Authority certificate structure.
legacy_signing_key
static crypto_pk_t * legacy_signing_key
Definition: router.c:131
signed_descriptor_t::signed_descriptor_digest
char signed_descriptor_digest[DIGEST_LEN]
Definition: signed_descriptor_st.h:29
routerstatus_t::bw_is_unmeasured
unsigned int bw_is_unmeasured
Definition: routerstatus_st.h:65
vote_timing_t
Definition: vote_timing_st.h:16
escaped
const char * escaped(const char *s)
Definition: escape.c:126
dirvote_clear_pending_consensuses
static void dirvote_clear_pending_consensuses(void)
Definition: dirvote.c:3075
networkstatus_voter_info_t::ipv4_dirport
uint16_t ipv4_dirport
Definition: networkstatus_voter_info_st.h:25
strcmpstart
int strcmpstart(const char *s1, const char *s2)
Definition: util_string.c:215
networkstatus_t::sr_info
networkstatus_sr_info_t sr_info
Definition: networkstatus_st.h:103
networkstatus_voter_info_st.h
Single consensus voter structure.
DIR_PURPOSE_FETCH_STATUS_VOTE
#define DIR_PURPOSE_FETCH_STATUS_VOTE
Definition: directory.h:48
microdesc_st.h
Microdescriptor structure.
routerinfo_t::exit_policy
smartlist_t * exit_policy
Definition: routerinfo_st.h:59
routerlist_st.h
Router descriptor list structure.
authmode.h
Header file for directory authority mode.
sr_commit_t
Definition: shared_random.h:70
MIN_METHOD_FOR_UNPADDED_NTOR_KEY
#define MIN_METHOD_FOR_UNPADDED_NTOR_KEY
Definition: dirvote.h:66
vote_routerstatus_find_microdesc_hash
static int vote_routerstatus_find_microdesc_hash(char *digest256_out, const vote_routerstatus_t *vrs, int method, digest_algorithm_t alg)
Definition: dirvote.c:484
nodelist.h
Header file for nodelist.c.
compute_routerstatus_consensus
static vote_routerstatus_t * compute_routerstatus_consensus(smartlist_t *votes, int consensus_method, char *microdesc_digest256_out, tor_addr_port_t *best_alt_orport_out)
Definition: dirvote.c:676
dirauth_options_t::RecommendedClientVersions
LINELIST RecommendedClientVersions
Definition: dirauth_options.inc:70
routerlist.h
Header file for routerlist.c.
vote_routerstatus_t::has_measured_bw
unsigned int has_measured_bw
Definition: vote_routerstatus_st.h:30
dircollator_new
dircollator_t * dircollator_new(int n_votes, int n_authorities)
Definition: dircollate.c:149
networkstatus_voter_info_t::ipv4_orport
uint16_t ipv4_orport
Definition: networkstatus_voter_info_st.h:26
get_most_frequent_member
#define get_most_frequent_member(lst)
Definition: dirvote.c:597
networkstatus_voter_info_t
Definition: networkstatus_voter_info_st.h:16
routerstatus_t::has_exitsummary
unsigned int has_exitsummary
Definition: routerstatus_st.h:64
dirauth_options_t
Definition: dirauth_options.inc:13
microdesc_vote_line_t
Definition: dirvote.c:4007
N_COMMON_DIGEST_ALGORITHMS
#define N_COMMON_DIGEST_ALGORITHMS
Definition: crypto_digest.h:58
common_digests_t::d
char d[N_COMMON_DIGEST_ALGORITHMS][DIGEST256_LEN]
Definition: crypto_digest.h:89
networkstatus_voter_info_t::sigs
smartlist_t * sigs
Definition: networkstatus_voter_info_st.h:32
new_cached_dir
cached_dir_t * new_cached_dir(char *s, time_t published)
Definition: dirserv.c:135
routerinfo_t::declared_family
smartlist_t * declared_family
Definition: routerinfo_st.h:65
dirvote_add_signatures_to_all_pending_consensuses
static int dirvote_add_signatures_to_all_pending_consensuses(const char *detached_signatures_body, const char *source, const char **msg_out)
Definition: dirvote.c:3652
policy_summarize
char * policy_summarize(smartlist_t *policy, sa_family_t family)
Definition: policies.c:2573
smartlist_contains_string
int smartlist_contains_string(const smartlist_t *sl, const char *element)
Definition: smartlist.c:93
routerinfo_st.h
Router descriptor structure.
ROUTER_MAX_AGE_TO_PUBLISH
#define ROUTER_MAX_AGE_TO_PUBLISH
Definition: or.h:161
DIGEST256_LEN
#define DIGEST256_LEN
Definition: digest_sizes.h:23
dir_server_t
Definition: dir_server_st.h:21
MIN_SUPPORTED_CONSENSUS_METHOD
#define MIN_SUPPORTED_CONSENSUS_METHOD
Definition: dirvote.h:53
tor_addr_to_str_dup
char * tor_addr_to_str_dup(const tor_addr_t *addr)
Definition: address.c:1164
cached_dir_t
Definition: cached_dir_st.h:17
networkstatus_t::routerstatus_list
smartlist_t * routerstatus_list
Definition: networkstatus_st.h:96
document_signature_st.h
Authority signature structure.
networkstatus_t::cert
struct authority_cert_t * cert
Definition: networkstatus_st.h:85
authority_cert_t
Definition: authority_cert_st.h:19
ns_detached_signatures_st.h
Detached consensus signatures structure.
nodefamily.h
Header file for nodefamily.c.
guardfraction_bandwidth_t::guard_bw
int guard_bw
Definition: entrynodes.h:642
digest256_from_base64
int digest256_from_base64(char *digest, const char *d64)
Definition: crypto_format.c:320
vote_timing_t::vote_interval
int vote_interval
Definition: vote_timing_st.h:19
bwauth.h
Header file for bwauth.c.
routerstatus_t::is_stable
unsigned int is_stable
Definition: routerstatus_st.h:39
compare_vote_rs
static int compare_vote_rs(const vote_routerstatus_t *a, const vote_routerstatus_t *b)
Definition: dirvote.c:604
or_options_t::GuardfractionFile
char * GuardfractionFile
Definition: or_options_st.h:725
dirserv_compute_performance_thresholds
void dirserv_compute_performance_thresholds(digestmap_t *omit_as_sybil)
Definition: voteflags.c:239
smartlist_uniq_strings
void smartlist_uniq_strings(smartlist_t *sl)
Definition: smartlist.c:574
LOG_INFO
#define LOG_INFO
Definition: log.h:45
compare_vote_rs_
static int compare_vote_rs_(const void **_a, const void **_b)
Definition: dirvote.c:649
HEX_DIGEST256_LEN
#define HEX_DIGEST256_LEN
Definition: crypto_digest.h:37
or_options_t::V3AuthUseLegacyKey
int V3AuthUseLegacyKey
Definition: or_options_st.h:719
fmt_addr
#define fmt_addr(a)
Definition: address.h:239
cached_dir_decref
void cached_dir_decref(cached_dir_t *d)
Definition: dirserv.c:124
get_options
const or_options_t * get_options(void)
Definition: config.c:919
routerstatus_t::is_exit
unsigned int is_exit
Definition: routerstatus_st.h:38
ns_parse.h
Header file for ns_parse.c.
guardfraction.h
Header file for guardfraction.c.
protover_all_supported
int protover_all_supported(const char *s, char **missing_out)
Definition: protover.c:609
routerstatus_t::descriptor_digest
char descriptor_digest[DIGEST256_LEN]
Definition: routerstatus_st.h:31
tor_version_st.h
Parsed Tor version structure.
validate_recommended_package_line
int validate_recommended_package_line(const char *line)
Definition: recommend_pkg.c:38
router_get_advertised_bandwidth
uint32_t router_get_advertised_bandwidth(const routerinfo_t *router)
Definition: routerlist.c:643
rep_hist_make_router_pessimal
void rep_hist_make_router_pessimal(const char *id, time_t when)
Definition: rephist.c:493
recommend_pkg.h
Header file for recommend_pkg.c.
networkstatus_t::dist_seconds
int dist_seconds
Definition: networkstatus_st.h:52
fmt_addrport
const char * fmt_addrport(const tor_addr_t *addr, uint16_t port)
Definition: address.c:1199
N_CONSENSUS_FLAVORS
#define N_CONSENSUS_FLAVORS
Definition: or.h:767
dirauth_set_routerstatus_from_routerinfo
void dirauth_set_routerstatus_from_routerinfo(routerstatus_t *rs, node_t *node, const routerinfo_t *ri, time_t now, int listbadexits)
Definition: voteflags.c:564
MIN_VOTE_SECONDS
#define MIN_VOTE_SECONDS
Definition: dirvote.h:27
compare_votes_by_authority_id_
static int compare_votes_by_authority_id_(const void **_a, const void **_b)
Definition: dirvote.c:551
routerinfo_t::onion_pkey
char * onion_pkey
Definition: routerinfo_st.h:37
write_short_policy
char * write_short_policy(const short_policy_t *policy)
Definition: policies.c:2786
smartlist_clear
void smartlist_clear(smartlist_t *sl)
Definition: smartlist_core.c:50
cmp_int_strings_
static int cmp_int_strings_(const void **_a, const void **_b)
Definition: dirvote.c:773
networkstatus_parse_vote_from_string
networkstatus_t * networkstatus_parse_vote_from_string(const char *s, size_t len, const char **eos_out, enum networkstatus_type_t ns_type)
Definition: ns_parse.c:1089
resolve_addr.h
Header file for resolve_addr.c.
smartlist_sort_strings
void smartlist_sort_strings(smartlist_t *sl)
Definition: smartlist.c:549
routerstatus_t::guardfraction_percentage
uint32_t guardfraction_percentage
Definition: routerstatus_st.h:77
signing.h
Header file for signing.c.
authority_cert_t::cache_info
signed_descriptor_t cache_info
Definition: authority_cert_st.h:21
tor_digest256_is_zero
int tor_digest256_is_zero(const char *digest)
Definition: util_string.c:103
MAX_SUPPORTED_CONSENSUS_METHOD
#define MAX_SUPPORTED_CONSENSUS_METHOD
Definition: dirvote.h:56
clear_status_flags_on_sybil
static void clear_status_flags_on_sybil(routerstatus_t *rs)
Definition: dirvote.c:4557
signed_descriptor_t::signing_key_cert
struct tor_cert_st * signing_key_cert
Definition: signed_descriptor_st.h:39
networkstatus_compute_bw_weights_v10
int networkstatus_compute_bw_weights_v10(smartlist_t *chunks, int64_t G, int64_t M, int64_t E, int64_t D, int64_t T, int64_t weight_scale)
Definition: dirvote.c:1097
sort_version_list
void sort_version_list(smartlist_t *versions, int remove_duplicates)
Definition: versions.c:391
networkstatus_voter_info_t::nickname
char * nickname
Definition: networkstatus_voter_info_st.h:19
trusteddirserver_get_by_v3_auth_digest
dir_server_t * trusteddirserver_get_by_v3_auth_digest(const char *digest)
Definition: dirlist.c:202
cached_dir_t::dir_len
size_t dir_len
Definition: cached_dir_st.h:20
networkstatus_t::recommended_relay_protocols
char * recommended_relay_protocols
Definition: networkstatus_st.h:63
voting_schedule.h
Header file for voting_schedule.c.
tor_addr_port_new
tor_addr_port_t * tor_addr_port_new(const tor_addr_t *addr, uint16_t port)
Definition: address.c:2100
dirserv_clear_measured_bw_cache
void dirserv_clear_measured_bw_cache(void)
Definition: bwauth.c:103
networkstatus_voter_info_t::address
char * address
Definition: networkstatus_voter_info_st.h:23
get_microdesc_cache
microdesc_cache_t * get_microdesc_cache(void)
Definition: microdesc.c:251
dirserv_get_measured_bw_cache_size
int dirserv_get_measured_bw_cache_size(void)
Definition: bwauth.c:166
NS_V3_CONSENSUS
@ NS_V3_CONSENSUS
Definition: fmt_routerstatus.h:21
compute_nth_protocol_set
static char * compute_nth_protocol_set(int n, int n_voters, const smartlist_t *votes)
Definition: dirvote.c:1439
microdescs_add_list_to_cache
smartlist_t * microdescs_add_list_to_cache(microdesc_cache_t *cache, smartlist_t *descriptors, saved_location_t where, int no_save)
Definition: microdesc.c:383
confline.h
Header for confline.c.
get_detached_signatures_from_pending_consensuses
static char * get_detached_signatures_from_pending_consensuses(pending_consensus_t *pending, int n_flavors)
Definition: dirvote.c:2840
MAX_BW_FILE_HEADERS_LINE_LEN
#define MAX_BW_FILE_HEADERS_LINE_LEN
Definition: dirvote.h:84
V3_DIRINFO
@ V3_DIRINFO
Definition: or.h:788
networkstatus_t::valid_after
time_t valid_after
Definition: networkstatus_st.h:33
dirserv.h
Header file for dirserv.c.
parsecommon.h
Header file for parsecommon.c.
tor_addr_is_null
int tor_addr_is_null(const tor_addr_t *addr)
Definition: address.c:780
crypto_pk_get_fingerprint
int crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out, int add_space)
Definition: crypto_rsa.c:229
DEFAULT_MAX_UNMEASURED_BW_KB
#define DEFAULT_MAX_UNMEASURED_BW_KB
Definition: dirvote.h:76
document_signature_t::bad_signature
unsigned int bad_signature
Definition: document_signature_st.h:27
authority_cert_t::signing_key_digest
char signing_key_digest[DIGEST_LEN]
Definition: authority_cert_st.h:27
dirclient.h
Header file for dirclient.c.
strmap_get_lc
void * strmap_get_lc(const strmap_t *map, const char *key)
Definition: map.c:360
tor_asprintf
int tor_asprintf(char **strp, const char *fmt,...)
Definition: printf.c:75
dirvote_create_microdescriptor
STATIC microdesc_t * dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method)
Definition: dirvote.c:3866
dirvote_free_all
void dirvote_free_all(void)
Definition: dirvote.c:3773
vote_routerstatus_t::protocols
char * protocols
Definition: vote_routerstatus_st.h:28
SMARTLIST_FOREACH_BEGIN
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
Definition: smartlist_foreach.h:78
or_options_t::V3BandwidthsFile
char * V3BandwidthsFile
Definition: or_options_st.h:722
networkstatus_add_detached_signatures
STATIC int networkstatus_add_detached_signatures(networkstatus_t *target, ns_detached_signatures_t *sigs, const char *source, int severity, const char **msg_out)
Definition: dirvote.c:2559
crypto_pk_t
Definition: crypto_rsa_nss.c:37
protover_compute_for_old_tor
const char * protover_compute_for_old_tor(const char *version)
C_RUST_COUPLED: src/rust/protover/protover.rs compute_for_old_tor
Definition: protover.c:708
routerstatus_t::bandwidth_kb
uint32_t bandwidth_kb
Definition: routerstatus_st.h:71
SMARTLIST_DEL_CURRENT
#define SMARTLIST_DEL_CURRENT(sl, var)
Definition: smartlist_foreach.h:120
get_frequent_members
static void get_frequent_members(smartlist_t *out, smartlist_t *in, int min)
Definition: dirvote.c:577
dirserv_read_measured_bandwidths
int dirserv_read_measured_bandwidths(const char *from_file, smartlist_t *routerstatuses, smartlist_t *bw_file_headers, uint8_t *digest_out)
Definition: bwauth.c:232
compare_dir_src_ents_by_authority_id_
static int compare_dir_src_ents_by_authority_id_(const void **_a, const void **_b)
Definition: dirvote.c:562
or_options_t::ContactInfo
char * ContactInfo
Definition: or_options_st.h:433
router_get_routerlist
routerlist_t * router_get_routerlist(void)
Definition: routerlist.c:895
fast_memcmp
#define fast_memcmp(a, b, c)
Definition: di_ops.h:28
dirvote_compute_params
STATIC smartlist_t * dirvote_compute_params(smartlist_t *votes, int method, int total_authorities)
Definition: dirvote.c:921
HEX_DIGEST_LEN
#define HEX_DIGEST_LEN
Definition: crypto_digest.h:35
protover_list_is_invalid
bool protover_list_is_invalid(const char *s)
Definition: protover.c:302
networkstatus_set_current_consensus
int networkstatus_set_current_consensus(const char *consensus, size_t consensus_len, const char *flavor, unsigned flags, const char *source_dir)
Definition: networkstatus.c:1917
LOG_WARN
#define LOG_WARN
Definition: log.h:53
node_st.h
Node information structure.
routerstatus_t::ipv6_addr
tor_addr_t ipv6_addr
Definition: routerstatus_st.h:35
routers_make_ed_keys_unique
static void routers_make_ed_keys_unique(smartlist_t *routers)
Definition: dirvote.c:4505
networkstatus_voter_info_t::vote_digest
char vote_digest[DIGEST_LEN]
Definition: networkstatus_voter_info_st.h:28
or_options_t::Nickname
char * Nickname
Definition: or_options_st.h:97
DIRVOTE_UNIVERSAL_FLAGS
const char DIRVOTE_UNIVERSAL_FLAGS[]
Definition: dirvote.c:4569
crypto_pk_write_public_key_to_string
int crypto_pk_write_public_key_to_string(crypto_pk_t *env, char **dest, size_t *len)
Definition: crypto_rsa.c:466
vote_routerstatus_t::status
routerstatus_t status
Definition: vote_routerstatus_st.h:19
find_opt_by_keyword
directory_token_t * find_opt_by_keyword(const smartlist_t *s, directory_keyword keyword)
Definition: parsecommon.c:457
policies.h
Header file for policies.c.
order.h
Header for order.c.
update_consensus_router_descriptor_downloads
void update_consensus_router_descriptor_downloads(time_t now, int is_vote, networkstatus_t *consensus)
Definition: routerlist.c:2618
ns_detached_signatures_t::signatures
strmap_t * signatures
Definition: ns_detached_signatures_st.h:22
dirauth_options_t::AuthDirMaxServersPerAddr
POSINT AuthDirMaxServersPerAddr
Definition: dirauth_options.inc:31
consensus_method_is_supported
static int consensus_method_is_supported(int method)
Definition: dirvote.c:827
format_recommended_version_list
char * format_recommended_version_list(const config_line_t *ln, int warn)
Definition: dirvote.c:4454
NS_V3_CONSENSUS_MICRODESC
@ NS_V3_CONSENSUS_MICRODESC
Definition: fmt_routerstatus.h:27
dir_src_ent_t
Definition: dirvote.c:542
networkstatus_voter_info_t::legacy_id_digest
char legacy_id_digest[DIGEST_LEN]
Definition: networkstatus_voter_info_st.h:22
directory_get_from_all_authorities
void directory_get_from_all_authorities(uint8_t dir_purpose, uint8_t router_purpose, const char *resource)
Definition: dirclient.c:580
MIN_VOTES_FOR_PARAM
#define MIN_VOTES_FOR_PARAM
Definition: dirvote.c:915
config_line_t
Definition: confline.h:29
directory_post_to_dirservers
void directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose, dirinfo_type_t type, const char *payload, size_t payload_len, size_t extrainfo_len)
Definition: dirclient.c:229
config.h
Header file for config.c.
vote_microdesc_hash_t::next
struct vote_microdesc_hash_t * next
Definition: vote_microdesc_hash_st.h:20
update_total_bandwidth_weights
static void update_total_bandwidth_weights(const routerstatus_t *rs, int is_exit, int is_guard, int64_t *G, int64_t *M, int64_t *E, int64_t *D, int64_t *T)
Definition: dirvote.c:1337
dirvote_add_signatures_to_pending_consensus
static int dirvote_add_signatures_to_pending_consensus(pending_consensus_t *pc, ns_detached_signatures_t *sigs, const char *source, int severity, const char **msg_out)
Definition: dirvote.c:3567
LD_DIRSERV
#define LD_DIRSERV
Definition: log.h:90
dirvote_format_all_microdesc_vote_lines
vote_microdesc_hash_t * dirvote_format_all_microdesc_vote_lines(const routerinfo_t *ri, time_t now, smartlist_t *microdescriptors_out)
Definition: dirvote.c:4018
get_my_v3_legacy_signing_key
crypto_pk_t * get_my_v3_legacy_signing_key(void)
Definition: router.c:474
router_get_dirobj_signature
char * router_get_dirobj_signature(const char *digest, size_t digest_len, const crypto_pk_t *private_key)
Definition: signing.c:22
dirvote_perform_vote
static int dirvote_perform_vote(void)
Definition: dirvote.c:2964
dircollator_collate
void dircollator_collate(dircollator_t *dc, int consensus_method)
Definition: dircollate.c:211
DIRVOTE_OPTIONAL_FLAGS
const char DIRVOTE_OPTIONAL_FLAGS[]
Definition: dirvote.c:4582
dirvote_get_intermediate_param_value
STATIC int32_t dirvote_get_intermediate_param_value(const smartlist_t *param_list, const char *keyword, int32_t default_val)
Definition: dirvote.c:885
or_options_t::V3AuthVoteDelay
int V3AuthVoteDelay
Definition: or_options_st.h:711
smartlist_add_asprintf
void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern,...)
Definition: smartlist.c:36
networkstatus_compute_consensus
STATIC char * networkstatus_compute_consensus(smartlist_t *votes, int total_authorities, crypto_pk_t *identity_key, crypto_pk_t *signing_key, const char *legacy_id_key_digest, crypto_pk_t *legacy_signing_key, consensus_flavor_t flavor)
Definition: dirvote.c:1502
dirauth_sys.h
Header for dirauth_sys.c.
LD_NET
#define LD_NET
Definition: log.h:66
networkstatus_verify_bw_weights
int networkstatus_verify_bw_weights(networkstatus_t *ns, int)
Definition: ns_parse.c:608
tor_log
void tor_log(int severity, log_domain_mask_t domain, const char *format,...)
Definition: log.c:590
smartlist_uniq
void smartlist_uniq(smartlist_t *sl, int(*compare)(const void **a, const void **b), void(*free_fn)(void *a))
Definition: smartlist.c:390
format_networkstatus_vote
STATIC char * format_networkstatus_vote(crypto_pk_t *private_signing_key, networkstatus_t *v3_ns)
Definition: dirvote.c:223
signed_descriptor_t::published_on
time_t published_on
Definition: signed_descriptor_st.h:33
sa_family_t
uint16_t sa_family_t
Definition: inaddr_st.h:77
MAX_KNOWN_FLAGS_IN_VOTE
#define MAX_KNOWN_FLAGS_IN_VOTE
Definition: vote_routerstatus_st.h:23
vote_routerstatus_t::ed25519_reflects_consensus
unsigned int ed25519_reflects_consensus
Definition: vote_routerstatus_st.h:37
ROUTER_PURPOSE_GENERAL
#define ROUTER_PURPOSE_GENERAL
Definition: routerinfo_st.h:98
or_options_t
Definition: or_options_st.h:64
authority_cert_t::signing_key
crypto_pk_t * signing_key
Definition: authority_cert_st.h:25
dirvote_get_preferred_voting_intervals
static void dirvote_get_preferred_voting_intervals(vote_timing_t *timing_out)
Definition: dirvote.c:464
dirvote_get_vote
const cached_dir_t * dirvote_get_vote(const char *fp, int flags)
Definition: dirvote.c:3820
pending_consensus_signature_list
static smartlist_t * pending_consensus_signature_list
Definition: dirvote.c:2959
STATIC
#define STATIC
Definition: testsupport.h:32
networkstatus_format_signatures
static char * networkstatus_format_signatures(networkstatus_t *consensus, int for_detached_signatures)
Definition: dirvote.c:2690
digest_to_base64
void digest_to_base64(char *d64, const char *digest)
Definition: crypto_format.c:275
extract_param_buggy
STATIC int64_t extract_param_buggy(const char *params, const char *param_name, int64_t default_value)
Definition: dirvote.c:2436
routerstatus_t::is_hs_dir
unsigned int is_hs_dir
Definition: routerstatus_st.h:54
routerstatus_t::ipv6_orport
uint16_t ipv6_orport
Definition: routerstatus_st.h:36
dircollator_get_votes_for_router
vote_routerstatus_t ** dircollator_get_votes_for_router(dircollator_t *dc, int idx)
Definition: dircollate.c:320
routerstatus_format_type_t
routerstatus_format_type_t
Definition: fmt_routerstatus.h:17
signed_descriptor_t::signed_descriptor_body
char * signed_descriptor_body
Definition: signed_descriptor_st.h:22
signed_descriptor_t::signed_descriptor_len
size_t signed_descriptor_len
Definition: signed_descriptor_st.h:26
document_signature_dup
document_signature_t * document_signature_dup(const document_signature_t *sig)
Definition: networkstatus.c:337
networkstatus_t::fresh_until
time_t fresh_until
Definition: networkstatus_st.h:34
digest_algorithm_t
digest_algorithm_t
Definition: crypto_digest.h:44
dirserv_read_guardfraction_file
int dirserv_read_guardfraction_file(const char *fname, smartlist_t *vote_routerstatuses)
Definition: guardfraction.c:319
compute_consensus_package_lines
STATIC char * compute_consensus_package_lines(smartlist_t *votes)
Definition: dirvote.c:2478
LD_DIR
#define LD_DIR
Definition: log.h:88
ns_detached_signatures_t
Definition: ns_detached_signatures_st.h:17
networkstatus_st.h
Networkstatus consensus/vote structure.
MIN_METHOD_FOR_CORRECT_BWWEIGHTSCALE
#define MIN_METHOD_FOR_CORRECT_BWWEIGHTSCALE
Definition: dirvote.h:71
smartlist_sort
void smartlist_sort(smartlist_t *sl, int(*compare)(const void **a, const void **b))
Definition: smartlist.c:334
FINGERPRINT_LEN
#define FINGERPRINT_LEN
Definition: crypto_rsa.h:34
vote_timing_t::n_intervals_valid
int n_intervals_valid
Definition: vote_timing_st.h:21
routerstatus_t::identity_digest
char identity_digest[DIGEST_LEN]
Definition: routerstatus_st.h:27
cached_dir_t::dir
char * dir
Definition: cached_dir_st.h:18
networkstatus_t
Definition: networkstatus_st.h:26
dirvote_compute_consensuses
static int dirvote_compute_consensuses(void)
Definition: dirvote.c:3388
SAVED_NOWHERE
@ SAVED_NOWHERE
Definition: or.h:630
curve25519_public_to_base64
void curve25519_public_to_base64(char *output, const curve25519_public_key_t *pkey, bool pad)
Definition: crypto_format.c:144
node_t::is_running
unsigned int is_running
Definition: node_st.h:63
smartlist_t
Definition: smartlist_core.h:26
routerinfo_t::omit_from_vote
unsigned int omit_from_vote
Definition: routerinfo_st.h:90
smartlist_remove
void smartlist_remove(smartlist_t *sl, const void *element)
Definition: smartlist_core.c:151
smartlist_join_strings
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
Definition: smartlist.c:279
fast_memeq
#define fast_memeq(a, b, c)
Definition: di_ops.h:35
networkstatus_get_voter_by_id
networkstatus_voter_info_t * networkstatus_get_voter_by_id(networkstatus_t *vote, const char *identity)
Definition: networkstatus.c:428
vote_routerstatus_t::measured_bw_kb
uint32_t measured_bw_kb
Definition: vote_routerstatus_st.h:38
compute_consensus_method
static int compute_consensus_method(smartlist_t *votes)
Definition: dirvote.c:792
networkstatus_t::known_flags
smartlist_t * known_flags
Definition: networkstatus_st.h:70
rephist.h
Header file for rephist.c.
DIGESTMAP_FOREACH
#define DIGESTMAP_FOREACH(map, keyvar, valtype, valvar)
Definition: map.h:154
networkstatus_get_detached_signatures
STATIC char * networkstatus_get_detached_signatures(smartlist_t *consensuses)
Definition: dirvote.c:2751
networkstatus_t::net_params
smartlist_t * net_params
Definition: networkstatus_st.h:74
networkstatus_parse_detached_signatures
ns_detached_signatures_t * networkstatus_parse_detached_signatures(const char *s, const char *eos)
Definition: dsigs_parse.c:67
dirvote_add_signatures
int dirvote_add_signatures(const char *detached_signatures_body, const char *source, const char **msg)
Definition: dirvote.c:3720
tor_addr_copy
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src)
Definition: address.c:933
networkstatus_t::vote_seconds
int vote_seconds
Definition: networkstatus_st.h:49
routerinfo_t::onion_curve25519_pkey
struct curve25519_public_key_t * onion_curve25519_pkey
Definition: routerinfo_st.h:43
DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
#define DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
Definition: directory.h:51
NS_V3_VOTE
@ NS_V3_VOTE
Definition: fmt_routerstatus.h:23
vote_microdesc_hash_st.h
Microdescriptor-hash voting structure.
sr_get_string_for_vote
char * sr_get_string_for_vote(void)
Definition: shared_random.c:1130
routerstatus_t::is_named
unsigned int is_named
Definition: routerstatus_st.h:46
or.h
Master header file for Tor-specific functionality.
find_whitespace
const char * find_whitespace(const char *s)
Definition: util_string.c:353
routerconf_find_or_port
uint16_t routerconf_find_or_port(const or_options_t *options, sa_family_t family)
Definition: router.c:1502