Tor  0.4.5.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-2020, 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  char *max_unmeasured_param = NULL;
1761  /* XXXX Extract this code into a common function. Or don't! see #19011 */
1762  if (params) {
1763  if (strcmpstart(params, "maxunmeasuredbw=") == 0)
1764  max_unmeasured_param = params;
1765  else
1766  max_unmeasured_param = strstr(params, " maxunmeasuredbw=");
1767  }
1768  if (max_unmeasured_param) {
1769  int ok = 0;
1770  char *eq = strchr(max_unmeasured_param, '=');
1771  if (eq) {
1772  max_unmeasured_bw_kb = (uint32_t)
1773  tor_parse_ulong(eq+1, 10, 1, UINT32_MAX, &ok, NULL);
1774  if (!ok) {
1775  log_warn(LD_DIR, "Bad element '%s' in max unmeasured bw param",
1776  escaped(max_unmeasured_param));
1777  max_unmeasured_bw_kb = DEFAULT_MAX_UNMEASURED_BW_KB;
1778  }
1779  }
1780  }
1781  }
1782 
1783  /* Add the actual router entries. */
1784  {
1785  int *size; /* size[j] is the number of routerstatuses in votes[j]. */
1786  int *flag_counts; /* The number of voters that list flag[j] for the
1787  * currently considered router. */
1788  int i;
1789  smartlist_t *matching_descs = smartlist_new();
1790  smartlist_t *chosen_flags = smartlist_new();
1791  smartlist_t *versions = smartlist_new();
1792  smartlist_t *protocols = smartlist_new();
1793  smartlist_t *exitsummaries = smartlist_new();
1794  uint32_t *bandwidths_kb = tor_calloc(smartlist_len(votes),
1795  sizeof(uint32_t));
1796  uint32_t *measured_bws_kb = tor_calloc(smartlist_len(votes),
1797  sizeof(uint32_t));
1798  uint32_t *measured_guardfraction = tor_calloc(smartlist_len(votes),
1799  sizeof(uint32_t));
1800  int num_bandwidths;
1801  int num_mbws;
1802  int num_guardfraction_inputs;
1803 
1804  int *n_voter_flags; /* n_voter_flags[j] is the number of flags that
1805  * votes[j] knows about. */
1806  int *n_flag_voters; /* n_flag_voters[f] is the number of votes that care
1807  * about flags[f]. */
1808  int **flag_map; /* flag_map[j][b] is an index f such that flag_map[f]
1809  * is the same flag as votes[j]->known_flags[b]. */
1810  int *named_flag; /* Index of the flag "Named" for votes[j] */
1811  int *unnamed_flag; /* Index of the flag "Unnamed" for votes[j] */
1812  int n_authorities_measuring_bandwidth;
1813 
1814  strmap_t *name_to_id_map = strmap_new();
1815  char conflict[DIGEST_LEN];
1816  char unknown[DIGEST_LEN];
1817  memset(conflict, 0, sizeof(conflict));
1818  memset(unknown, 0xff, sizeof(conflict));
1819 
1820  size = tor_calloc(smartlist_len(votes), sizeof(int));
1821  n_voter_flags = tor_calloc(smartlist_len(votes), sizeof(int));
1822  n_flag_voters = tor_calloc(smartlist_len(flags), sizeof(int));
1823  flag_map = tor_calloc(smartlist_len(votes), sizeof(int *));
1824  named_flag = tor_calloc(smartlist_len(votes), sizeof(int));
1825  unnamed_flag = tor_calloc(smartlist_len(votes), sizeof(int));
1826  for (i = 0; i < smartlist_len(votes); ++i)
1827  unnamed_flag[i] = named_flag[i] = -1;
1828 
1829  /* Build the flag indexes. Note that no vote can have more than 64 members
1830  * for known_flags, so no value will be greater than 63, so it's safe to
1831  * do UINT64_C(1) << index on these values. But note also that
1832  * named_flag and unnamed_flag are initialized to -1, so we need to check
1833  * that they're actually set before doing UINT64_C(1) << index with
1834  * them.*/
1836  flag_map[v_sl_idx] = tor_calloc(smartlist_len(v->known_flags),
1837  sizeof(int));
1838  if (smartlist_len(v->known_flags) > MAX_KNOWN_FLAGS_IN_VOTE) {
1839  log_warn(LD_BUG, "Somehow, a vote has %d entries in known_flags",
1840  smartlist_len(v->known_flags));
1841  }
1842  SMARTLIST_FOREACH_BEGIN(v->known_flags, const char *, fl) {
1843  int p = smartlist_string_pos(flags, fl);
1844  tor_assert(p >= 0);
1845  flag_map[v_sl_idx][fl_sl_idx] = p;
1846  ++n_flag_voters[p];
1847  if (!strcmp(fl, "Named"))
1848  named_flag[v_sl_idx] = fl_sl_idx;
1849  if (!strcmp(fl, "Unnamed"))
1850  unnamed_flag[v_sl_idx] = fl_sl_idx;
1851  } SMARTLIST_FOREACH_END(fl);
1852  n_voter_flags[v_sl_idx] = smartlist_len(v->known_flags);
1853  size[v_sl_idx] = smartlist_len(v->routerstatus_list);
1854  } SMARTLIST_FOREACH_END(v);
1855 
1856  /* Named and Unnamed get treated specially */
1857  {
1859  uint64_t nf;
1860  if (named_flag[v_sl_idx]<0)
1861  continue;
1862  nf = UINT64_C(1) << named_flag[v_sl_idx];
1863  SMARTLIST_FOREACH_BEGIN(v->routerstatus_list,
1864  vote_routerstatus_t *, rs) {
1865 
1866  if ((rs->flags & nf) != 0) {
1867  const char *d = strmap_get_lc(name_to_id_map, rs->status.nickname);
1868  if (!d) {
1869  /* We have no name officially mapped to this digest. */
1870  strmap_set_lc(name_to_id_map, rs->status.nickname,
1871  rs->status.identity_digest);
1872  } else if (d != conflict &&
1873  fast_memcmp(d, rs->status.identity_digest, DIGEST_LEN)) {
1874  /* Authorities disagree about this nickname. */
1875  strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
1876  } else {
1877  /* It's already a conflict, or it's already this ID. */
1878  }
1879  }
1880  } SMARTLIST_FOREACH_END(rs);
1881  } SMARTLIST_FOREACH_END(v);
1882 
1884  uint64_t uf;
1885  if (unnamed_flag[v_sl_idx]<0)
1886  continue;
1887  uf = UINT64_C(1) << unnamed_flag[v_sl_idx];
1888  SMARTLIST_FOREACH_BEGIN(v->routerstatus_list,
1889  vote_routerstatus_t *, rs) {
1890  if ((rs->flags & uf) != 0) {
1891  const char *d = strmap_get_lc(name_to_id_map, rs->status.nickname);
1892  if (d == conflict || d == unknown) {
1893  /* Leave it alone; we know what it is. */
1894  } else if (!d) {
1895  /* We have no name officially mapped to this digest. */
1896  strmap_set_lc(name_to_id_map, rs->status.nickname, unknown);
1897  } else if (fast_memeq(d, rs->status.identity_digest, DIGEST_LEN)) {
1898  /* Authorities disagree about this nickname. */
1899  strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
1900  } else {
1901  /* It's mapped to a different name. */
1902  }
1903  }
1904  } SMARTLIST_FOREACH_END(rs);
1905  } SMARTLIST_FOREACH_END(v);
1906  }
1907 
1908  /* We need to know how many votes measure bandwidth. */
1909  n_authorities_measuring_bandwidth = 0;
1910  SMARTLIST_FOREACH(votes, const networkstatus_t *, v,
1911  if (v->has_measured_bws) {
1912  ++n_authorities_measuring_bandwidth;
1913  }
1914  );
1915 
1916  /* Populate the collator */
1917  collator = dircollator_new(smartlist_len(votes), total_authorities);
1919  dircollator_add_vote(collator, v);
1920  } SMARTLIST_FOREACH_END(v);
1921 
1922  dircollator_collate(collator, consensus_method);
1923 
1924  /* Now go through all the votes */
1925  flag_counts = tor_calloc(smartlist_len(flags), sizeof(int));
1926  const int num_routers = dircollator_n_routers(collator);
1927  for (i = 0; i < num_routers; ++i) {
1928  vote_routerstatus_t **vrs_lst =
1929  dircollator_get_votes_for_router(collator, i);
1930 
1931  vote_routerstatus_t *rs;
1932  routerstatus_t rs_out;
1933  const char *current_rsa_id = NULL;
1934  const char *chosen_version;
1935  const char *chosen_protocol_list;
1936  const char *chosen_name = NULL;
1937  int exitsummary_disagreement = 0;
1938  int is_named = 0, is_unnamed = 0, is_running = 0, is_valid = 0;
1939  int is_guard = 0, is_exit = 0, is_bad_exit = 0;
1940  int naming_conflict = 0;
1941  int n_listing = 0;
1942  char microdesc_digest[DIGEST256_LEN];
1943  tor_addr_port_t alt_orport = {TOR_ADDR_NULL, 0};
1944 
1945  memset(flag_counts, 0, sizeof(int)*smartlist_len(flags));
1946  smartlist_clear(matching_descs);
1947  smartlist_clear(chosen_flags);
1948  smartlist_clear(versions);
1949  smartlist_clear(protocols);
1950  num_bandwidths = 0;
1951  num_mbws = 0;
1952  num_guardfraction_inputs = 0;
1953  int ed_consensus = 0;
1954  const uint8_t *ed_consensus_val = NULL;
1955 
1956  /* Okay, go through all the entries for this digest. */
1957  for (int voter_idx = 0; voter_idx < smartlist_len(votes); ++voter_idx) {
1958  if (vrs_lst[voter_idx] == NULL)
1959  continue; /* This voter had nothing to say about this entry. */
1960  rs = vrs_lst[voter_idx];
1961  ++n_listing;
1962 
1963  current_rsa_id = rs->status.identity_digest;
1964 
1965  smartlist_add(matching_descs, rs);
1966  if (rs->version && rs->version[0])
1967  smartlist_add(versions, rs->version);
1968 
1969  if (rs->protocols) {
1970  /* We include this one even if it's empty: voting for an
1971  * empty protocol list actually is meaningful. */
1972  smartlist_add(protocols, rs->protocols);
1973  }
1974 
1975  /* Tally up all the flags. */
1976  for (int flag = 0; flag < n_voter_flags[voter_idx]; ++flag) {
1977  if (rs->flags & (UINT64_C(1) << flag))
1978  ++flag_counts[flag_map[voter_idx][flag]];
1979  }
1980  if (named_flag[voter_idx] >= 0 &&
1981  (rs->flags & (UINT64_C(1) << named_flag[voter_idx]))) {
1982  if (chosen_name && strcmp(chosen_name, rs->status.nickname)) {
1983  log_notice(LD_DIR, "Conflict on naming for router: %s vs %s",
1984  chosen_name, rs->status.nickname);
1985  naming_conflict = 1;
1986  }
1987  chosen_name = rs->status.nickname;
1988  }
1989 
1990  /* Count guardfraction votes and note down the values. */
1991  if (rs->status.has_guardfraction) {
1992  measured_guardfraction[num_guardfraction_inputs++] =
1994  }
1995 
1996  /* count bandwidths */
1997  if (rs->has_measured_bw)
1998  measured_bws_kb[num_mbws++] = rs->measured_bw_kb;
1999 
2000  if (rs->status.has_bandwidth)
2001  bandwidths_kb[num_bandwidths++] = rs->status.bandwidth_kb;
2002 
2003  /* Count number for which ed25519 is canonical. */
2004  if (rs->ed25519_reflects_consensus) {
2005  ++ed_consensus;
2006  if (ed_consensus_val) {
2007  tor_assert(fast_memeq(ed_consensus_val, rs->ed25519_id,
2009  } else {
2010  ed_consensus_val = rs->ed25519_id;
2011  }
2012  }
2013  }
2014 
2015  /* We don't include this router at all unless more than half of
2016  * the authorities we believe in list it. */
2017  if (n_listing <= total_authorities/2)
2018  continue;
2019 
2020  if (ed_consensus > 0) {
2021  if (ed_consensus <= total_authorities / 2) {
2022  log_warn(LD_BUG, "Not enough entries had ed_consensus set; how "
2023  "can we have a consensus of %d?", ed_consensus);
2024  }
2025  }
2026 
2027  /* The clangalyzer can't figure out that this will never be NULL
2028  * if n_listing is at least 1 */
2029  tor_assert(current_rsa_id);
2030 
2031  /* Figure out the most popular opinion of what the most recent
2032  * routerinfo and its contents are. */
2033  memset(microdesc_digest, 0, sizeof(microdesc_digest));
2034  rs = compute_routerstatus_consensus(matching_descs, consensus_method,
2035  microdesc_digest, &alt_orport);
2036  /* Copy bits of that into rs_out. */
2037  memset(&rs_out, 0, sizeof(rs_out));
2038  tor_assert(fast_memeq(current_rsa_id,
2040  memcpy(rs_out.identity_digest, current_rsa_id, DIGEST_LEN);
2041  memcpy(rs_out.descriptor_digest, rs->status.descriptor_digest,
2042  DIGEST_LEN);
2043  tor_addr_copy(&rs_out.ipv4_addr, &rs->status.ipv4_addr);
2044  rs_out.published_on = rs->status.published_on;
2045  rs_out.ipv4_dirport = rs->status.ipv4_dirport;
2046  rs_out.ipv4_orport = rs->status.ipv4_orport;
2047  tor_addr_copy(&rs_out.ipv6_addr, &alt_orport.addr);
2048  rs_out.ipv6_orport = alt_orport.port;
2049  rs_out.has_bandwidth = 0;
2050  rs_out.has_exitsummary = 0;
2051 
2052  if (chosen_name && !naming_conflict) {
2053  strlcpy(rs_out.nickname, chosen_name, sizeof(rs_out.nickname));
2054  } else {
2055  strlcpy(rs_out.nickname, rs->status.nickname, sizeof(rs_out.nickname));
2056  }
2057 
2058  {
2059  const char *d = strmap_get_lc(name_to_id_map, rs_out.nickname);
2060  if (!d) {
2061  is_named = is_unnamed = 0;
2062  } else if (fast_memeq(d, current_rsa_id, DIGEST_LEN)) {
2063  is_named = 1; is_unnamed = 0;
2064  } else {
2065  is_named = 0; is_unnamed = 1;
2066  }
2067  }
2068 
2069  /* Set the flags. */
2070  smartlist_add(chosen_flags, (char*)"s"); /* for the start of the line. */
2071  SMARTLIST_FOREACH_BEGIN(flags, const char *, fl) {
2072  if (!strcmp(fl, "Named")) {
2073  if (is_named)
2074  smartlist_add(chosen_flags, (char*)fl);
2075  } else if (!strcmp(fl, "Unnamed")) {
2076  if (is_unnamed)
2077  smartlist_add(chosen_flags, (char*)fl);
2078  } else if (!strcmp(fl, "NoEdConsensus")) {
2079  if (ed_consensus <= total_authorities/2)
2080  smartlist_add(chosen_flags, (char*)fl);
2081  } else {
2082  if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2) {
2083  smartlist_add(chosen_flags, (char*)fl);
2084  if (!strcmp(fl, "Exit"))
2085  is_exit = 1;
2086  else if (!strcmp(fl, "Guard"))
2087  is_guard = 1;
2088  else if (!strcmp(fl, "Running"))
2089  is_running = 1;
2090  else if (!strcmp(fl, "BadExit"))
2091  is_bad_exit = 1;
2092  else if (!strcmp(fl, "Valid"))
2093  is_valid = 1;
2094  }
2095  }
2096  } SMARTLIST_FOREACH_END(fl);
2097 
2098  /* Starting with consensus method 4 we do not list servers
2099  * that are not running in a consensus. See Proposal 138 */
2100  if (!is_running)
2101  continue;
2102 
2103  /* Starting with consensus method 24, we don't list servers
2104  * that are not valid in a consensus. See Proposal 272 */
2105  if (!is_valid)
2106  continue;
2107 
2108  /* Pick the version. */
2109  if (smartlist_len(versions)) {
2110  sort_version_list(versions, 0);
2111  chosen_version = get_most_frequent_member(versions);
2112  } else {
2113  chosen_version = NULL;
2114  }
2115 
2116  /* Pick the protocol list */
2117  if (smartlist_len(protocols)) {
2118  smartlist_sort_strings(protocols);
2119  chosen_protocol_list = get_most_frequent_member(protocols);
2120  } else {
2121  chosen_protocol_list = NULL;
2122  }
2123 
2124  /* If it's a guard and we have enough guardfraction votes,
2125  calculate its consensus guardfraction value. */
2126  if (is_guard && num_guardfraction_inputs > 2) {
2127  rs_out.has_guardfraction = 1;
2128  rs_out.guardfraction_percentage = median_uint32(measured_guardfraction,
2129  num_guardfraction_inputs);
2130  /* final value should be an integer percentage! */
2131  tor_assert(rs_out.guardfraction_percentage <= 100);
2132  }
2133 
2134  /* Pick a bandwidth */
2135  if (num_mbws > 2) {
2136  rs_out.has_bandwidth = 1;
2137  rs_out.bw_is_unmeasured = 0;
2138  rs_out.bandwidth_kb = median_uint32(measured_bws_kb, num_mbws);
2139  } else if (num_bandwidths > 0) {
2140  rs_out.has_bandwidth = 1;
2141  rs_out.bw_is_unmeasured = 1;
2142  rs_out.bandwidth_kb = median_uint32(bandwidths_kb, num_bandwidths);
2143  if (n_authorities_measuring_bandwidth > 2) {
2144  /* Cap non-measured bandwidths. */
2145  if (rs_out.bandwidth_kb > max_unmeasured_bw_kb) {
2146  rs_out.bandwidth_kb = max_unmeasured_bw_kb;
2147  }
2148  }
2149  }
2150 
2151  /* Fix bug 2203: Do not count BadExit nodes as Exits for bw weights */
2152  is_exit = is_exit && !is_bad_exit;
2153 
2154  /* Update total bandwidth weights with the bandwidths of this router. */
2155  {
2157  is_exit, is_guard,
2158  &G, &M, &E, &D, &T);
2159  }
2160 
2161  /* Ok, we already picked a descriptor digest we want to list
2162  * previously. Now we want to use the exit policy summary from
2163  * that descriptor. If everybody plays nice all the voters who
2164  * listed that descriptor will have the same summary. If not then
2165  * something is fishy and we'll use the most common one (breaking
2166  * ties in favor of lexicographically larger one (only because it
2167  * lets me reuse more existing code)).
2168  *
2169  * The other case that can happen is that no authority that voted
2170  * for that descriptor has an exit policy summary. That's
2171  * probably quite unlikely but can happen. In that case we use
2172  * the policy that was most often listed in votes, again breaking
2173  * ties like in the previous case.
2174  */
2175  {
2176  /* Okay, go through all the votes for this router. We prepared
2177  * that list previously */
2178  const char *chosen_exitsummary = NULL;
2179  smartlist_clear(exitsummaries);
2180  SMARTLIST_FOREACH_BEGIN(matching_descs, vote_routerstatus_t *, vsr) {
2181  /* Check if the vote where this status comes from had the
2182  * proper descriptor */
2184  vsr->status.identity_digest,
2185  DIGEST_LEN));
2186  if (vsr->status.has_exitsummary &&
2188  vsr->status.descriptor_digest,
2189  DIGEST_LEN)) {
2190  tor_assert(vsr->status.exitsummary);
2191  smartlist_add(exitsummaries, vsr->status.exitsummary);
2192  if (!chosen_exitsummary) {
2193  chosen_exitsummary = vsr->status.exitsummary;
2194  } else if (strcmp(chosen_exitsummary, vsr->status.exitsummary)) {
2195  /* Great. There's disagreement among the voters. That
2196  * really shouldn't be */
2197  exitsummary_disagreement = 1;
2198  }
2199  }
2200  } SMARTLIST_FOREACH_END(vsr);
2201 
2202  if (exitsummary_disagreement) {
2203  char id[HEX_DIGEST_LEN+1];
2204  char dd[HEX_DIGEST_LEN+1];
2205  base16_encode(id, sizeof(dd), rs_out.identity_digest, DIGEST_LEN);
2206  base16_encode(dd, sizeof(dd), rs_out.descriptor_digest, DIGEST_LEN);
2207  log_warn(LD_DIR, "The voters disagreed on the exit policy summary "
2208  " for router %s with descriptor %s. This really shouldn't"
2209  " have happened.", id, dd);
2210 
2211  smartlist_sort_strings(exitsummaries);
2212  chosen_exitsummary = get_most_frequent_member(exitsummaries);
2213  } else if (!chosen_exitsummary) {
2214  char id[HEX_DIGEST_LEN+1];
2215  char dd[HEX_DIGEST_LEN+1];
2216  base16_encode(id, sizeof(dd), rs_out.identity_digest, DIGEST_LEN);
2217  base16_encode(dd, sizeof(dd), rs_out.descriptor_digest, DIGEST_LEN);
2218  log_warn(LD_DIR, "Not one of the voters that made us select"
2219  "descriptor %s for router %s had an exit policy"
2220  "summary", dd, id);
2221 
2222  /* Ok, none of those voting for the digest we chose had an
2223  * exit policy for us. Well, that kinda sucks.
2224  */
2225  smartlist_clear(exitsummaries);
2226  SMARTLIST_FOREACH(matching_descs, vote_routerstatus_t *, vsr, {
2227  if (vsr->status.has_exitsummary)
2228  smartlist_add(exitsummaries, vsr->status.exitsummary);
2229  });
2230  smartlist_sort_strings(exitsummaries);
2231  chosen_exitsummary = get_most_frequent_member(exitsummaries);
2232 
2233  if (!chosen_exitsummary)
2234  log_warn(LD_DIR, "Wow, not one of the voters had an exit "
2235  "policy summary for %s. Wow.", id);
2236  }
2237 
2238  if (chosen_exitsummary) {
2239  rs_out.has_exitsummary = 1;
2240  /* yea, discards the const */
2241  rs_out.exitsummary = (char *)chosen_exitsummary;
2242  }
2243  }
2244 
2245  if (flavor == FLAV_MICRODESC &&
2246  tor_digest256_is_zero(microdesc_digest)) {
2247  /* With no microdescriptor digest, we omit the entry entirely. */
2248  continue;
2249  }
2250 
2251  {
2252  char *buf;
2253  /* Okay!! Now we can write the descriptor... */
2254  /* First line goes into "buf". */
2255  buf = routerstatus_format_entry(&rs_out, NULL, NULL,
2256  rs_format, NULL);
2257  if (buf)
2258  smartlist_add(chunks, buf);
2259  }
2260  /* Now an m line, if applicable. */
2261  if (flavor == FLAV_MICRODESC &&
2262  !tor_digest256_is_zero(microdesc_digest)) {
2263  char m[BASE64_DIGEST256_LEN+1];
2264  digest256_to_base64(m, microdesc_digest);
2265  smartlist_add_asprintf(chunks, "m %s\n", m);
2266  }
2267  /* Next line is all flags. The "\n" is missing. */
2268  smartlist_add(chunks,
2269  smartlist_join_strings(chosen_flags, " ", 0, NULL));
2270  /* Now the version line. */
2271  if (chosen_version) {
2272  smartlist_add_strdup(chunks, "\nv ");
2273  smartlist_add_strdup(chunks, chosen_version);
2274  }
2275  smartlist_add_strdup(chunks, "\n");
2276  if (chosen_protocol_list) {
2277  smartlist_add_asprintf(chunks, "pr %s\n", chosen_protocol_list);
2278  }
2279  /* Now the weight line. */
2280  if (rs_out.has_bandwidth) {
2281  char *guardfraction_str = NULL;
2282  int unmeasured = rs_out.bw_is_unmeasured;
2283 
2284  /* If we have guardfraction info, include it in the 'w' line. */
2285  if (rs_out.has_guardfraction) {
2286  tor_asprintf(&guardfraction_str,
2287  " GuardFraction=%u", rs_out.guardfraction_percentage);
2288  }
2289  smartlist_add_asprintf(chunks, "w Bandwidth=%d%s%s\n",
2290  rs_out.bandwidth_kb,
2291  unmeasured?" Unmeasured=1":"",
2292  guardfraction_str ? guardfraction_str : "");
2293 
2294  tor_free(guardfraction_str);
2295  }
2296 
2297  /* Now the exitpolicy summary line. */
2298  if (rs_out.has_exitsummary && flavor == FLAV_NS) {
2299  smartlist_add_asprintf(chunks, "p %s\n", rs_out.exitsummary);
2300  }
2301 
2302  /* And the loop is over and we move on to the next router */
2303  }
2304 
2305  tor_free(size);
2306  tor_free(n_voter_flags);
2307  tor_free(n_flag_voters);
2308  for (i = 0; i < smartlist_len(votes); ++i)
2309  tor_free(flag_map[i]);
2310  tor_free(flag_map);
2311  tor_free(flag_counts);
2312  tor_free(named_flag);
2313  tor_free(unnamed_flag);
2314  strmap_free(name_to_id_map, NULL);
2315  smartlist_free(matching_descs);
2316  smartlist_free(chosen_flags);
2317  smartlist_free(versions);
2318  smartlist_free(protocols);
2319  smartlist_free(exitsummaries);
2320  tor_free(bandwidths_kb);
2321  tor_free(measured_bws_kb);
2322  tor_free(measured_guardfraction);
2323  }
2324 
2325  /* Mark the directory footer region */
2326  smartlist_add_strdup(chunks, "directory-footer\n");
2327 
2328  {
2329  int64_t weight_scale = BW_WEIGHT_SCALE;
2330  char *bw_weight_param = NULL;
2331 
2332  // Parse params, extract BW_WEIGHT_SCALE if present
2333  // DO NOT use consensus_param_bw_weight_scale() in this code!
2334  // The consensus is not formed yet!
2335  /* XXXX Extract this code into a common function. Or not: #19011. */
2336  if (params) {
2337  if (strcmpstart(params, "bwweightscale=") == 0)
2338  bw_weight_param = params;
2339  else
2340  bw_weight_param = strstr(params, " bwweightscale=");
2341  }
2342 
2343  if (bw_weight_param) {
2344  int ok=0;
2345  char *eq = strchr(bw_weight_param, '=');
2346  if (eq) {
2347  weight_scale = tor_parse_long(eq+1, 10, 1, INT32_MAX, &ok,
2348  NULL);
2349  if (!ok) {
2350  log_warn(LD_DIR, "Bad element '%s' in bw weight param",
2351  escaped(bw_weight_param));
2352  weight_scale = BW_WEIGHT_SCALE;
2353  }
2354  } else {
2355  log_warn(LD_DIR, "Bad element '%s' in bw weight param",
2356  escaped(bw_weight_param));
2357  weight_scale = BW_WEIGHT_SCALE;
2358  }
2359  }
2360 
2361  added_weights = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D,
2362  T, weight_scale);
2363  }
2364 
2365  /* Add a signature. */
2366  {
2367  char digest[DIGEST256_LEN];
2368  char fingerprint[HEX_DIGEST_LEN+1];
2369  char signing_key_fingerprint[HEX_DIGEST_LEN+1];
2370  digest_algorithm_t digest_alg =
2371  flavor == FLAV_NS ? DIGEST_SHA1 : DIGEST_SHA256;
2372  size_t digest_len =
2373  flavor == FLAV_NS ? DIGEST_LEN : DIGEST256_LEN;
2374  const char *algname = crypto_digest_algorithm_get_name(digest_alg);
2375  char *signature;
2376 
2377  smartlist_add_strdup(chunks, "directory-signature ");
2378 
2379  /* Compute the hash of the chunks. */
2380  crypto_digest_smartlist(digest, digest_len, chunks, "", digest_alg);
2381 
2382  /* Get the fingerprints */
2383  crypto_pk_get_fingerprint(identity_key, fingerprint, 0);
2384  crypto_pk_get_fingerprint(signing_key, signing_key_fingerprint, 0);
2385 
2386  /* add the junk that will go at the end of the line. */
2387  if (flavor == FLAV_NS) {
2388  smartlist_add_asprintf(chunks, "%s %s\n", fingerprint,
2389  signing_key_fingerprint);
2390  } else {
2391  smartlist_add_asprintf(chunks, "%s %s %s\n",
2392  algname, fingerprint,
2393  signing_key_fingerprint);
2394  }
2395  /* And the signature. */
2396  if (!(signature = router_get_dirobj_signature(digest, digest_len,
2397  signing_key))) {
2398  log_warn(LD_BUG, "Couldn't sign consensus networkstatus.");
2399  goto done;
2400  }
2401  smartlist_add(chunks, signature);
2402 
2403  if (legacy_id_key_digest && legacy_signing_key) {
2404  smartlist_add_strdup(chunks, "directory-signature ");
2405  base16_encode(fingerprint, sizeof(fingerprint),
2406  legacy_id_key_digest, DIGEST_LEN);
2408  signing_key_fingerprint, 0);
2409  if (flavor == FLAV_NS) {
2410  smartlist_add_asprintf(chunks, "%s %s\n", fingerprint,
2411  signing_key_fingerprint);
2412  } else {
2413  smartlist_add_asprintf(chunks, "%s %s %s\n",
2414  algname, fingerprint,
2415  signing_key_fingerprint);
2416  }
2417 
2418  if (!(signature = router_get_dirobj_signature(digest, digest_len,
2419  legacy_signing_key))) {
2420  log_warn(LD_BUG, "Couldn't sign consensus networkstatus.");
2421  goto done;
2422  }
2423  smartlist_add(chunks, signature);
2424  }
2425  }
2426 
2427  result = smartlist_join_strings(chunks, "", 0, NULL);
2428 
2429  {
2430  networkstatus_t *c;
2431  if (!(c = networkstatus_parse_vote_from_string(result, strlen(result),
2432  NULL,
2433  NS_TYPE_CONSENSUS))) {
2434  log_err(LD_BUG, "Generated a networkstatus consensus we couldn't "
2435  "parse.");
2436  tor_free(result);
2437  goto done;
2438  }
2439  // Verify balancing parameters
2440  if (added_weights) {
2441  networkstatus_verify_bw_weights(c, consensus_method);
2442  }
2443  networkstatus_vote_free(c);
2444  }
2445 
2446  done:
2447 
2448  dircollator_free(collator);
2449  tor_free(client_versions);
2450  tor_free(server_versions);
2451  tor_free(packages);
2452  SMARTLIST_FOREACH(flags, char *, cp, tor_free(cp));
2453  smartlist_free(flags);
2454  SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2455  smartlist_free(chunks);
2456  SMARTLIST_FOREACH(param_list, char *, cp, tor_free(cp));
2457  smartlist_free(param_list);
2458 
2459  return result;
2460 }
2461 
2462 /** Given a list of networkstatus_t for each vote, return a newly allocated
2463  * string containing the "package" lines for the vote. */
2464 STATIC char *
2466 {
2467  const int n_votes = smartlist_len(votes);
2468 
2469  /* This will be a map from "packagename version" strings to arrays
2470  * of const char *, with the i'th member of the array corresponding to the
2471  * package line from the i'th vote.
2472  */
2473  strmap_t *package_status = strmap_new();
2474 
2476  if (! v->package_lines)
2477  continue;
2478  SMARTLIST_FOREACH_BEGIN(v->package_lines, const char *, line) {
2480  continue;
2481 
2482  /* Skip 'cp' to the second space in the line. */
2483  const char *cp = strchr(line, ' ');
2484  if (!cp) continue;
2485  ++cp;
2486  cp = strchr(cp, ' ');
2487  if (!cp) continue;
2488 
2489  char *key = tor_strndup(line, cp - line);
2490 
2491  const char **status = strmap_get(package_status, key);
2492  if (!status) {
2493  status = tor_calloc(n_votes, sizeof(const char *));
2494  strmap_set(package_status, key, status);
2495  }
2496  status[v_sl_idx] = line; /* overwrite old value */
2497  tor_free(key);
2498  } SMARTLIST_FOREACH_END(line);
2499  } SMARTLIST_FOREACH_END(v);
2500 
2501  smartlist_t *entries = smartlist_new(); /* temporary */
2502  smartlist_t *result_list = smartlist_new(); /* output */
2503  STRMAP_FOREACH(package_status, key, const char **, values) {
2504  int i, count=-1;
2505  for (i = 0; i < n_votes; ++i) {
2506  if (values[i])
2507  smartlist_add(entries, (void*) values[i]);
2508  }
2509  smartlist_sort_strings(entries);
2510  int n_voting_for_entry = smartlist_len(entries);
2511  const char *most_frequent =
2512  smartlist_get_most_frequent_string_(entries, &count);
2513 
2514  if (n_voting_for_entry >= 3 && count > n_voting_for_entry / 2) {
2515  smartlist_add_asprintf(result_list, "package %s\n", most_frequent);
2516  }
2517 
2518  smartlist_clear(entries);
2519 
2520  } STRMAP_FOREACH_END;
2521 
2522  smartlist_sort_strings(result_list);
2523 
2524  char *result = smartlist_join_strings(result_list, "", 0, NULL);
2525 
2526  SMARTLIST_FOREACH(result_list, char *, cp, tor_free(cp));
2527  smartlist_free(result_list);
2528  smartlist_free(entries);
2529  strmap_free(package_status, tor_free_);
2530 
2531  return result;
2532 }
2533 
2534 /** Given a consensus vote <b>target</b> and a set of detached signatures in
2535  * <b>sigs</b> that correspond to the same consensus, check whether there are
2536  * any new signatures in <b>src_voter_list</b> that should be added to
2537  * <b>target</b>. (A signature should be added if we have no signature for that
2538  * voter in <b>target</b> yet, or if we have no verifiable signature and the
2539  * new signature is verifiable.)
2540  *
2541  * Return the number of signatures added or changed, or -1 if the document
2542  * signatures are invalid. Sets *<b>msg_out</b> to a string constant
2543  * describing the signature status.
2544  */
2545 STATIC int
2548  const char *source,
2549  int severity,
2550  const char **msg_out)
2551 {
2552  int r = 0;
2553  const char *flavor;
2554  smartlist_t *siglist;
2555  tor_assert(sigs);
2556  tor_assert(target);
2557  tor_assert(target->type == NS_TYPE_CONSENSUS);
2558 
2559  flavor = networkstatus_get_flavor_name(target->flavor);
2560 
2561  /* Do the times seem right? */
2562  if (target->valid_after != sigs->valid_after) {
2563  *msg_out = "Valid-After times do not match "
2564  "when adding detached signatures to consensus";
2565  return -1;
2566  }
2567  if (target->fresh_until != sigs->fresh_until) {
2568  *msg_out = "Fresh-until times do not match "
2569  "when adding detached signatures to consensus";
2570  return -1;
2571  }
2572  if (target->valid_until != sigs->valid_until) {
2573  *msg_out = "Valid-until times do not match "
2574  "when adding detached signatures to consensus";
2575  return -1;
2576  }
2577  siglist = strmap_get(sigs->signatures, flavor);
2578  if (!siglist) {
2579  *msg_out = "No signatures for given consensus flavor";
2580  return -1;
2581  }
2582 
2583  /** Make sure all the digests we know match, and at least one matches. */
2584  {
2585  common_digests_t *digests = strmap_get(sigs->digests, flavor);
2586  int n_matches = 0;
2587  int alg;
2588  if (!digests) {
2589  *msg_out = "No digests for given consensus flavor";
2590  return -1;
2591  }
2592  for (alg = DIGEST_SHA1; alg < N_COMMON_DIGEST_ALGORITHMS; ++alg) {
2593  if (!fast_mem_is_zero(digests->d[alg], DIGEST256_LEN)) {
2594  if (fast_memeq(target->digests.d[alg], digests->d[alg],
2595  DIGEST256_LEN)) {
2596  ++n_matches;
2597  } else {
2598  *msg_out = "Mismatched digest.";
2599  return -1;
2600  }
2601  }
2602  }
2603  if (!n_matches) {
2604  *msg_out = "No recognized digests for given consensus flavor";
2605  }
2606  }
2607 
2608  /* For each voter in src... */
2610  char voter_identity[HEX_DIGEST_LEN+1];
2611  networkstatus_voter_info_t *target_voter =
2612  networkstatus_get_voter_by_id(target, sig->identity_digest);
2613  authority_cert_t *cert = NULL;
2614  const char *algorithm;
2615  document_signature_t *old_sig = NULL;
2616 
2617  algorithm = crypto_digest_algorithm_get_name(sig->alg);
2618 
2619  base16_encode(voter_identity, sizeof(voter_identity),
2620  sig->identity_digest, DIGEST_LEN);
2621  log_info(LD_DIR, "Looking at signature from %s using %s", voter_identity,
2622  algorithm);
2623  /* If the target doesn't know about this voter, then forget it. */
2624  if (!target_voter) {
2625  log_info(LD_DIR, "We do not know any voter with ID %s", voter_identity);
2626  continue;
2627  }
2628 
2629  old_sig = networkstatus_get_voter_sig_by_alg(target_voter, sig->alg);
2630 
2631  /* If the target already has a good signature from this voter, then skip
2632  * this one. */
2633  if (old_sig && old_sig->good_signature) {
2634  log_info(LD_DIR, "We already have a good signature from %s using %s",
2635  voter_identity, algorithm);
2636  continue;
2637  }
2638 
2639  /* Try checking the signature if we haven't already. */
2640  if (!sig->good_signature && !sig->bad_signature) {
2641  cert = authority_cert_get_by_digests(sig->identity_digest,
2642  sig->signing_key_digest);
2643  if (cert) {
2644  /* Not checking the return value here, since we are going to look
2645  * at the status of sig->good_signature in a moment. */
2646  (void) networkstatus_check_document_signature(target, sig, cert);
2647  }
2648  }
2649 
2650  /* If this signature is good, or we don't have any signature yet,
2651  * then maybe add it. */
2652  if (sig->good_signature || !old_sig || old_sig->bad_signature) {
2653  log_info(LD_DIR, "Adding signature from %s with %s", voter_identity,
2654  algorithm);
2655  tor_log(severity, LD_DIR, "Added a signature for %s from %s.",
2656  target_voter->nickname, source);
2657  ++r;
2658  if (old_sig) {
2659  smartlist_remove(target_voter->sigs, old_sig);
2660  document_signature_free(old_sig);
2661  }
2662  smartlist_add(target_voter->sigs, document_signature_dup(sig));
2663  } else {
2664  log_info(LD_DIR, "Not adding signature from %s", voter_identity);
2665  }
2666  } SMARTLIST_FOREACH_END(sig);
2667 
2668  return r;
2669 }
2670 
2671 /** Return a newly allocated string containing all the signatures on
2672  * <b>consensus</b> by all voters. If <b>for_detached_signatures</b> is true,
2673  * then the signatures will be put in a detached signatures document, so
2674  * prefix any non-NS-flavored signatures with "additional-signature" rather
2675  * than "directory-signature". */
2676 static char *
2678  int for_detached_signatures)
2679 {
2680  smartlist_t *elements;
2681  char buf[4096];
2682  char *result = NULL;
2683  int n_sigs = 0;
2684  const consensus_flavor_t flavor = consensus->flavor;
2685  const char *flavor_name = networkstatus_get_flavor_name(flavor);
2686  const char *keyword;
2687 
2688  if (for_detached_signatures && flavor != FLAV_NS)
2689  keyword = "additional-signature";
2690  else
2691  keyword = "directory-signature";
2692 
2693  elements = smartlist_new();
2694 
2697  char sk[HEX_DIGEST_LEN+1];
2698  char id[HEX_DIGEST_LEN+1];
2699  if (!sig->signature || sig->bad_signature)
2700  continue;
2701  ++n_sigs;
2702  base16_encode(sk, sizeof(sk), sig->signing_key_digest, DIGEST_LEN);
2703  base16_encode(id, sizeof(id), sig->identity_digest, DIGEST_LEN);
2704  if (flavor == FLAV_NS) {
2705  smartlist_add_asprintf(elements,
2706  "%s %s %s\n-----BEGIN SIGNATURE-----\n",
2707  keyword, id, sk);
2708  } else {
2709  const char *digest_name =
2711  smartlist_add_asprintf(elements,
2712  "%s%s%s %s %s %s\n-----BEGIN SIGNATURE-----\n",
2713  keyword,
2714  for_detached_signatures ? " " : "",
2715  for_detached_signatures ? flavor_name : "",
2716  digest_name, id, sk);
2717  }
2718  base64_encode(buf, sizeof(buf), sig->signature, sig->signature_len,
2719  BASE64_ENCODE_MULTILINE);
2720  strlcat(buf, "-----END SIGNATURE-----\n", sizeof(buf));
2721  smartlist_add_strdup(elements, buf);
2722  } SMARTLIST_FOREACH_END(sig);
2723  } SMARTLIST_FOREACH_END(v);
2724 
2725  result = smartlist_join_strings(elements, "", 0, NULL);
2726  SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2727  smartlist_free(elements);
2728  if (!n_sigs)
2729  tor_free(result);
2730  return result;
2731 }
2732 
2733 /** Return a newly allocated string holding the detached-signatures document
2734  * corresponding to the signatures on <b>consensuses</b>, which must contain
2735  * exactly one FLAV_NS consensus, and no more than one consensus for each
2736  * other flavor. */
2737 STATIC char *
2739 {
2740  smartlist_t *elements;
2741  char *result = NULL, *sigs = NULL;
2742  networkstatus_t *consensus_ns = NULL;
2743  tor_assert(consensuses);
2744 
2745  SMARTLIST_FOREACH(consensuses, networkstatus_t *, ns, {
2746  tor_assert(ns);
2747  tor_assert(ns->type == NS_TYPE_CONSENSUS);
2748  if (ns && ns->flavor == FLAV_NS)
2749  consensus_ns = ns;
2750  });
2751  if (!consensus_ns) {
2752  log_warn(LD_BUG, "No NS consensus given.");
2753  return NULL;
2754  }
2755 
2756  elements = smartlist_new();
2757 
2758  {
2759  char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
2760  vu_buf[ISO_TIME_LEN+1];
2761  char d[HEX_DIGEST_LEN+1];
2762 
2763  base16_encode(d, sizeof(d),
2764  consensus_ns->digests.d[DIGEST_SHA1], DIGEST_LEN);
2765  format_iso_time(va_buf, consensus_ns->valid_after);
2766  format_iso_time(fu_buf, consensus_ns->fresh_until);
2767  format_iso_time(vu_buf, consensus_ns->valid_until);
2768 
2769  smartlist_add_asprintf(elements,
2770  "consensus-digest %s\n"
2771  "valid-after %s\n"
2772  "fresh-until %s\n"
2773  "valid-until %s\n", d, va_buf, fu_buf, vu_buf);
2774  }
2775 
2776  /* Get all the digests for the non-FLAV_NS consensuses */
2777  SMARTLIST_FOREACH_BEGIN(consensuses, networkstatus_t *, ns) {
2778  const char *flavor_name = networkstatus_get_flavor_name(ns->flavor);
2779  int alg;
2780  if (ns->flavor == FLAV_NS)
2781  continue;
2782 
2783  /* start with SHA256; we don't include SHA1 for anything but the basic
2784  * consensus. */
2785  for (alg = DIGEST_SHA256; alg < N_COMMON_DIGEST_ALGORITHMS; ++alg) {
2786  char d[HEX_DIGEST256_LEN+1];
2787  const char *alg_name =
2789  if (fast_mem_is_zero(ns->digests.d[alg], DIGEST256_LEN))
2790  continue;
2791  base16_encode(d, sizeof(d), ns->digests.d[alg], DIGEST256_LEN);
2792  smartlist_add_asprintf(elements, "additional-digest %s %s %s\n",
2793  flavor_name, alg_name, d);
2794  }
2795  } SMARTLIST_FOREACH_END(ns);
2796 
2797  /* Now get all the sigs for non-FLAV_NS consensuses */
2798  SMARTLIST_FOREACH_BEGIN(consensuses, networkstatus_t *, ns) {
2799  char *sigs_on_this_consensus;
2800  if (ns->flavor == FLAV_NS)
2801  continue;
2802  sigs_on_this_consensus = networkstatus_format_signatures(ns, 1);
2803  if (!sigs_on_this_consensus) {
2804  log_warn(LD_DIR, "Couldn't format signatures");
2805  goto err;
2806  }
2807  smartlist_add(elements, sigs_on_this_consensus);
2808  } SMARTLIST_FOREACH_END(ns);
2809 
2810  /* Now add the FLAV_NS consensus signatrures. */
2811  sigs = networkstatus_format_signatures(consensus_ns, 1);
2812  if (!sigs)
2813  goto err;
2814  smartlist_add(elements, sigs);
2815 
2816  result = smartlist_join_strings(elements, "", 0, NULL);
2817  err:
2818  SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2819  smartlist_free(elements);
2820  return result;
2821 }
2822 
2823 /** Return a newly allocated string holding a detached-signatures document for
2824  * all of the in-progress consensuses in the <b>n_flavors</b>-element array at
2825  * <b>pending</b>. */
2826 static char *
2828  int n_flavors)
2829 {
2830  int flav;
2831  char *signatures;
2832  smartlist_t *c = smartlist_new();
2833  for (flav = 0; flav < n_flavors; ++flav) {
2834  if (pending[flav].consensus)
2835  smartlist_add(c, pending[flav].consensus);
2836  }
2837  signatures = networkstatus_get_detached_signatures(c);
2838  smartlist_free(c);
2839  return signatures;
2840 }
2841 
2842 /**
2843  * Entry point: Take whatever voting actions are pending as of <b>now</b>.
2844  *
2845  * Return the time at which the next action should be taken.
2846  */
2847 time_t
2848 dirvote_act(const or_options_t *options, time_t now)
2849 {
2850  if (!authdir_mode_v3(options))
2851  return TIME_MAX;
2852  tor_assert_nonfatal(voting_schedule.voting_starts);
2853  /* If we haven't initialized this object through this codeflow, we need to
2854  * recalculate the timings to match our vote. The reason to do that is if we
2855  * have a voting schedule initialized 1 minute ago, the voting timings might
2856  * not be aligned to what we should expect with "now". This is especially
2857  * true for TestingTorNetwork using smaller timings. */
2858  if (voting_schedule.created_on_demand) {
2859  char *keys = list_v3_auth_ids();
2861  log_notice(LD_DIR, "Scheduling voting. Known authority IDs are %s. "
2862  "Mine is %s.",
2864  tor_free(keys);
2865  dirauth_sched_recalculate_timing(options, now);
2866  }
2867 
2868 #define IF_TIME_FOR_NEXT_ACTION(when_field, done_field) \
2869  if (! voting_schedule.done_field) { \
2870  if (voting_schedule.when_field > now) { \
2871  return voting_schedule.when_field; \
2872  } else {
2873 #define ENDIF \
2874  } \
2875  }
2876 
2877  IF_TIME_FOR_NEXT_ACTION(voting_starts, have_voted) {
2878  log_notice(LD_DIR, "Time to vote.");
2880  voting_schedule.have_voted = 1;
2881  } ENDIF
2882  IF_TIME_FOR_NEXT_ACTION(fetch_missing_votes, have_fetched_missing_votes) {
2883  log_notice(LD_DIR, "Time to fetch any votes that we're missing.");
2885  voting_schedule.have_fetched_missing_votes = 1;
2886  } ENDIF
2887  IF_TIME_FOR_NEXT_ACTION(voting_ends, have_built_consensus) {
2888  log_notice(LD_DIR, "Time to compute a consensus.");
2890  /* XXXX We will want to try again later if we haven't got enough
2891  * votes yet. Implement this if it turns out to ever happen. */
2892  voting_schedule.have_built_consensus = 1;
2893  } ENDIF
2894  IF_TIME_FOR_NEXT_ACTION(fetch_missing_signatures,
2895  have_fetched_missing_signatures) {
2896  log_notice(LD_DIR, "Time to fetch any signatures that we're missing.");
2898  voting_schedule.have_fetched_missing_signatures = 1;
2899  } ENDIF
2900  IF_TIME_FOR_NEXT_ACTION(interval_starts,
2901  have_published_consensus) {
2902  log_notice(LD_DIR, "Time to publish the consensus and discard old votes");
2905  voting_schedule.have_published_consensus = 1;
2906  /* Update our shared random state with the consensus just published. */
2909  /* XXXX We will want to try again later if we haven't got enough
2910  * signatures yet. Implement this if it turns out to ever happen. */
2911  dirauth_sched_recalculate_timing(options, now);
2912  return voting_schedule.voting_starts;
2913  } ENDIF
2914 
2916  return now + 1;
2917 
2918 #undef ENDIF
2919 #undef IF_TIME_FOR_NEXT_ACTION
2920 }
2921 
2922 /** A vote networkstatus_t and its unparsed body: held around so we can
2923  * use it to generate a consensus (at voting_ends) and so we can serve it to
2924  * other authorities that might want it. */
2925 typedef struct pending_vote_t {
2926  cached_dir_t *vote_body;
2927  networkstatus_t *vote;
2928 } pending_vote_t;
2929 
2930 /** List of pending_vote_t for the current vote. Before we've used them to
2931  * build a consensus, the votes go here. */
2933 /** List of pending_vote_t for the previous vote. After we've used them to
2934  * build a consensus, the votes go here for the next period. */
2936 
2937 /* DOCDOC pending_consensuses */
2938 static pending_consensus_t pending_consensuses[N_CONSENSUS_FLAVORS];
2939 
2940 /** The detached signatures for the consensus that we're currently
2941  * building. */
2942 static char *pending_consensus_signatures = NULL;
2943 
2944 /** List of ns_detached_signatures_t: hold signatures that get posted to us
2945  * before we have generated the consensus on our own. */
2947 
2948 /** Generate a networkstatus vote and post it to all the v3 authorities.
2949  * (V3 Authority only) */
2950 static int
2952 {
2955  networkstatus_t *ns;
2956  char *contents;
2957  pending_vote_t *pending_vote;
2958  time_t now = time(NULL);
2959 
2960  int status;
2961  const char *msg = "";
2962 
2963  if (!cert || !key) {
2964  log_warn(LD_NET, "Didn't find key/certificate to generate v3 vote");
2965  return -1;
2966  } else if (cert->expires < now) {
2967  log_warn(LD_NET, "Can't generate v3 vote with expired certificate");
2968  return -1;
2969  }
2970  if (!(ns = dirserv_generate_networkstatus_vote_obj(key, cert)))
2971  return -1;
2972 
2973  contents = format_networkstatus_vote(key, ns);
2974  networkstatus_vote_free(ns);
2975  if (!contents)
2976  return -1;
2977 
2978  pending_vote = dirvote_add_vote(contents, 0, &msg, &status);
2979  tor_free(contents);
2980  if (!pending_vote) {
2981  log_warn(LD_DIR, "Couldn't store my own vote! (I told myself, '%s'.)",
2982  msg);
2983  return -1;
2984  }
2985 
2988  V3_DIRINFO,
2989  pending_vote->vote_body->dir,
2990  pending_vote->vote_body->dir_len, 0);
2991  log_notice(LD_DIR, "Vote posted.");
2992  return 0;
2993 }
2994 
2995 /** Send an HTTP request to every other v3 authority, for the votes of every
2996  * authority for which we haven't received a vote yet in this period. (V3
2997  * authority only) */
2998 static void
3000 {
3001  smartlist_t *missing_fps = smartlist_new();
3002  char *resource;
3003 
3004  SMARTLIST_FOREACH_BEGIN(router_get_trusted_dir_servers(),
3005  dir_server_t *, ds) {
3006  if (!(ds->type & V3_DIRINFO))
3007  continue;
3008  if (!dirvote_get_vote(ds->v3_identity_digest,
3009  DGV_BY_ID|DGV_INCLUDE_PENDING)) {
3010  char *cp = tor_malloc(HEX_DIGEST_LEN+1);
3011  base16_encode(cp, HEX_DIGEST_LEN+1, ds->v3_identity_digest,
3012  DIGEST_LEN);
3013  smartlist_add(missing_fps, cp);
3014  }
3015  } SMARTLIST_FOREACH_END(ds);
3016 
3017  if (!smartlist_len(missing_fps)) {
3018  smartlist_free(missing_fps);
3019  return;
3020  }
3021  {
3022  char *tmp = smartlist_join_strings(missing_fps, " ", 0, NULL);
3023  log_notice(LOG_NOTICE, "We're missing votes from %d authorities (%s). "
3024  "Asking every other authority for a copy.",
3025  smartlist_len(missing_fps), tmp);
3026  tor_free(tmp);
3027  }
3028  resource = smartlist_join_strings(missing_fps, "+", 0, NULL);
3030  0, resource);
3031  tor_free(resource);
3032  SMARTLIST_FOREACH(missing_fps, char *, cp, tor_free(cp));
3033  smartlist_free(missing_fps);
3034 }
3035 
3036 /** Send a request to every other authority for its detached signatures,
3037  * unless we have signatures from all other v3 authorities already. */
3038 static void
3040 {
3041  int need_any = 0;
3042  int i;
3043  for (i=0; i < N_CONSENSUS_FLAVORS; ++i) {
3044  networkstatus_t *consensus = pending_consensuses[i].consensus;
3045  if (!consensus ||
3046  networkstatus_check_consensus_signature(consensus, -1) == 1) {
3047  /* We have no consensus, or we have one that's signed by everybody. */
3048  continue;
3049  }
3050  need_any = 1;
3051  }
3052  if (!need_any)
3053  return;
3054 
3056  0, NULL);
3057 }
3058 
3059 /** Release all storage held by pending consensuses (those waiting for
3060  * signatures). */
3061 static void
3063 {
3064  int i;
3065  for (i = 0; i < N_CONSENSUS_FLAVORS; ++i) {
3066  pending_consensus_t *pc = &pending_consensuses[i];
3067  tor_free(pc->body);
3068 
3069  networkstatus_vote_free(pc->consensus);
3070  pc->consensus = NULL;
3071  }
3072 }
3073 
3074 /** Drop all currently pending votes, consensus, and detached signatures. */
3075 static void
3076 dirvote_clear_votes(int all_votes)
3077 {
3078  if (!previous_vote_list)
3080  if (!pending_vote_list)
3082 
3083  /* All "previous" votes are now junk. */
3085  cached_dir_decref(v->vote_body);
3086  v->vote_body = NULL;
3087  networkstatus_vote_free(v->vote);
3088  tor_free(v);
3089  });
3091 
3092  if (all_votes) {
3093  /* If we're dumping all the votes, we delete the pending ones. */
3095  cached_dir_decref(v->vote_body);
3096  v->vote_body = NULL;
3097  networkstatus_vote_free(v->vote);
3098  tor_free(v);
3099  });
3100  } else {
3101  /* Otherwise, we move them into "previous". */
3103  }
3105 
3108  tor_free(cp));
3110  }
3113 }
3114 
3115 /** Return a newly allocated string containing the hex-encoded v3 authority
3116  identity digest of every recognized v3 authority. */
3117 static char *
3119 {
3120  smartlist_t *known_v3_keys = smartlist_new();
3121  char *keys;
3122  SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
3123  dir_server_t *, ds,
3124  if ((ds->type & V3_DIRINFO) &&
3125  !tor_digest_is_zero(ds->v3_identity_digest))
3126  smartlist_add(known_v3_keys,
3127  tor_strdup(hex_str(ds->v3_identity_digest, DIGEST_LEN))));
3128  keys = smartlist_join_strings(known_v3_keys, ", ", 0, NULL);
3129  SMARTLIST_FOREACH(known_v3_keys, char *, cp, tor_free(cp));
3130  smartlist_free(known_v3_keys);
3131  return keys;
3132 }
3133 
3134 /* Check the voter information <b>vi</b>, and assert that at least one
3135  * signature is good. Asserts on failure. */
3136 static void
3137 assert_any_sig_good(const networkstatus_voter_info_t *vi)
3138 {
3139  int any_sig_good = 0;
3141  if (sig->good_signature)
3142  any_sig_good = 1);
3143  tor_assert(any_sig_good);
3144 }
3145 
3146 /* Add <b>cert</b> to our list of known authority certificates. */
3147 static void
3148 add_new_cert_if_needed(const struct authority_cert_t *cert)
3149 {
3150  tor_assert(cert);
3152  cert->signing_key_digest)) {
3153  /* Hey, it's a new cert! */
3156  TRUSTED_DIRS_CERTS_SRC_FROM_VOTE, 1 /*flush*/,
3157  NULL);
3159  cert->signing_key_digest)) {
3160  log_warn(LD_BUG, "We added a cert, but still couldn't find it.");
3161  }
3162  }
3163 }
3164 
3165 /** Called when we have received a networkstatus vote in <b>vote_body</b>.
3166  * Parse and validate it, and on success store it as a pending vote (which we
3167  * then return). Return NULL on failure. Sets *<b>msg_out</b> and
3168  * *<b>status_out</b> to an HTTP response and status code. (V3 authority
3169  * only) */
3171 dirvote_add_vote(const char *vote_body, time_t time_posted,
3172  const char **msg_out, int *status_out)
3173 {
3174  networkstatus_t *vote;
3176  dir_server_t *ds;
3177  pending_vote_t *pending_vote = NULL;
3178  const char *end_of_vote = NULL;
3179  int any_failed = 0;
3180  tor_assert(vote_body);
3181  tor_assert(msg_out);
3182  tor_assert(status_out);
3183 
3184  if (!pending_vote_list)
3186  *status_out = 0;
3187  *msg_out = NULL;
3188 
3189  again:
3190  vote = networkstatus_parse_vote_from_string(vote_body, strlen(vote_body),
3191  &end_of_vote,
3192  NS_TYPE_VOTE);
3193  if (!end_of_vote)
3194  end_of_vote = vote_body + strlen(vote_body);
3195  if (!vote) {
3196  log_warn(LD_DIR, "Couldn't parse vote: length was %d",
3197  (int)strlen(vote_body));
3198  *msg_out = "Unable to parse vote";
3199  goto err;
3200  }
3201  tor_assert(smartlist_len(vote->voters) == 1);
3202  vi = get_voter(vote);
3203  assert_any_sig_good(vi);
3205  if (!ds) {
3206  char *keys = list_v3_auth_ids();
3207  log_warn(LD_DIR, "Got a vote from an authority (nickname %s, address %s) "
3208  "with authority key ID %s. "
3209  "This key ID is not recognized. Known v3 key IDs are: %s",
3210  vi->nickname, vi->address,
3211  hex_str(vi->identity_digest, DIGEST_LEN), keys);
3212  tor_free(keys);
3213  *msg_out = "Vote not from a recognized v3 authority";
3214  goto err;
3215  }
3216  add_new_cert_if_needed(vote->cert);
3217 
3218  /* Is it for the right period? */
3219  if (vote->valid_after != voting_schedule.interval_starts) {
3220  char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1];
3221  format_iso_time(tbuf1, vote->valid_after);
3222  format_iso_time(tbuf2, voting_schedule.interval_starts);
3223  log_warn(LD_DIR, "Rejecting vote from %s with valid-after time of %s; "
3224  "we were expecting %s", vi->address, tbuf1, tbuf2);
3225  *msg_out = "Bad valid-after time";
3226  goto err;
3227  }
3228 
3229  /* Check if we received it, as a post, after the cutoff when we
3230  * start asking other dir auths for it. If we do, the best plan
3231  * is to discard it, because using it greatly increases the chances
3232  * of a split vote for this round (some dir auths got it in time,
3233  * some didn't). */
3234  if (time_posted && time_posted > voting_schedule.fetch_missing_votes) {
3235  char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1];
3236  format_iso_time(tbuf1, time_posted);
3237  format_iso_time(tbuf2, voting_schedule.fetch_missing_votes);
3238  log_warn(LD_DIR, "Rejecting posted vote from %s received at %s; "
3239  "our cutoff for received votes is %s. Check your clock, "
3240  "CPU load, and network load. Also check the authority that "
3241  "posted the vote.", vi->address, tbuf1, tbuf2);
3242  *msg_out = "Posted vote received too late, would be dangerous to count it";
3243  goto err;
3244  }
3245 
3246  /* Fetch any new router descriptors we just learned about */
3247  update_consensus_router_descriptor_downloads(time(NULL), 1, vote);
3248 
3249  /* Now see whether we already have a vote from this authority. */
3251  if (fast_memeq(v->vote->cert->cache_info.identity_digest,
3253  DIGEST_LEN)) {
3254  networkstatus_voter_info_t *vi_old = get_voter(v->vote);
3255  if (fast_memeq(vi_old->vote_digest, vi->vote_digest, DIGEST_LEN)) {
3256  /* Ah, it's the same vote. Not a problem. */
3257  log_info(LD_DIR, "Discarding a vote we already have (from %s).",
3258  vi->address);
3259  if (*status_out < 200)
3260  *status_out = 200;
3261  goto discard;
3262  } else if (v->vote->published < vote->published) {
3263  log_notice(LD_DIR, "Replacing an older pending vote from this "
3264  "directory (%s)", vi->address);
3265  cached_dir_decref(v->vote_body);
3266  networkstatus_vote_free(v->vote);
3267  v->vote_body = new_cached_dir(tor_strndup(vote_body,
3268  end_of_vote-vote_body),
3269  vote->published);
3270  v->vote = vote;
3271  if (end_of_vote &&
3272  !strcmpstart(end_of_vote, "network-status-version"))
3273  goto again;
3274 
3275  if (*status_out < 200)
3276  *status_out = 200;
3277  if (!*msg_out)
3278  *msg_out = "OK";
3279  return v;
3280  } else {
3281  *msg_out = "Already have a newer pending vote";
3282  goto err;
3283  }
3284  }
3285  } SMARTLIST_FOREACH_END(v);
3286 
3287  /* This a valid vote, update our shared random state. */
3288  sr_handle_received_commits(vote->sr_info.commits,
3289  vote->cert->identity_key);
3290 
3291  pending_vote = tor_malloc_zero(sizeof(pending_vote_t));
3292  pending_vote->vote_body = new_cached_dir(tor_strndup(vote_body,
3293  end_of_vote-vote_body),
3294  vote->published);
3295  pending_vote->vote = vote;
3296  smartlist_add(pending_vote_list, pending_vote);
3297 
3298  if (!strcmpstart(end_of_vote, "network-status-version ")) {
3299  vote_body = end_of_vote;
3300  goto again;
3301  }
3302 
3303  goto done;
3304 
3305  err:
3306  any_failed = 1;
3307  if (!*msg_out)
3308  *msg_out = "Error adding vote";
3309  if (*status_out < 400)
3310  *status_out = 400;
3311 
3312  discard:
3313  networkstatus_vote_free(vote);
3314 
3315  if (end_of_vote && !strcmpstart(end_of_vote, "network-status-version ")) {
3316  vote_body = end_of_vote;
3317  goto again;
3318  }
3319 
3320  done:
3321 
3322  if (*status_out < 200)
3323  *status_out = 200;
3324  if (!*msg_out) {
3325  if (!any_failed && !pending_vote) {
3326  *msg_out = "Duplicate discarded";
3327  } else {
3328  *msg_out = "ok";
3329  }
3330  }
3331 
3332  return any_failed ? NULL : pending_vote;
3333 }
3334 
3335 /* Write the votes in <b>pending_vote_list</b> to disk. */
3336 static void
3337 write_v3_votes_to_disk(const smartlist_t *pending_votes)
3338 {
3339  smartlist_t *votestrings = smartlist_new();
3340  char *votefile = NULL;
3341 
3342  SMARTLIST_FOREACH(pending_votes, pending_vote_t *, v,
3343  {
3344  sized_chunk_t *c = tor_malloc(sizeof(sized_chunk_t));
3345  c->bytes = v->vote_body->dir;
3346  c->len = v->vote_body->dir_len;
3347  smartlist_add(votestrings, c); /* collect strings to write to disk */
3348  });
3349 
3350  votefile = get_datadir_fname("v3-status-votes");
3351  write_chunks_to_file(votefile, votestrings, 0, 0);
3352  log_debug(LD_DIR, "Wrote votes to disk (%s)!", votefile);
3353 
3354  tor_free(votefile);
3355  SMARTLIST_FOREACH(votestrings, sized_chunk_t *, c, tor_free(c));
3356  smartlist_free(votestrings);
3357 }
3358 
3359 /** Try to compute a v3 networkstatus consensus from the currently pending
3360  * votes. Return 0 on success, -1 on failure. Store the consensus in
3361  * pending_consensus: it won't be ready to be published until we have
3362  * everybody else's signatures collected too. (V3 Authority only) */
3363 static int
3365 {
3366  /* Have we got enough votes to try? */
3367  int n_votes, n_voters, n_vote_running = 0;
3368  smartlist_t *votes = NULL;
3369  char *consensus_body = NULL, *signatures = NULL;
3370  networkstatus_t *consensus = NULL;
3371  authority_cert_t *my_cert;
3373  int flav;
3374 
3375  memset(pending, 0, sizeof(pending));
3376 
3377  if (!pending_vote_list)
3379 
3380  /* Write votes to disk */
3381  write_v3_votes_to_disk(pending_vote_list);
3382 
3383  /* Setup votes smartlist */
3384  votes = smartlist_new();
3386  {
3387  smartlist_add(votes, v->vote); /* collect votes to compute consensus */
3388  });
3389 
3390  /* See if consensus managed to achieve majority */
3391  n_voters = get_n_authorities(V3_DIRINFO);
3392  n_votes = smartlist_len(pending_vote_list);
3393  if (n_votes <= n_voters/2) {
3394  log_warn(LD_DIR, "We don't have enough votes to generate a consensus: "
3395  "%d of %d", n_votes, n_voters/2+1);
3396  goto err;
3397  }
3400  if (smartlist_contains_string(v->vote->known_flags, "Running"))
3401  n_vote_running++;
3402  });
3403  if (!n_vote_running) {
3404  /* See task 1066. */
3405  log_warn(LD_DIR, "Nobody has voted on the Running flag. Generating "
3406  "and publishing a consensus without Running nodes "
3407  "would make many clients stop working. Not "
3408  "generating a consensus!");
3409  goto err;
3410  }
3411 
3412  if (!(my_cert = get_my_v3_authority_cert())) {
3413  log_warn(LD_DIR, "Can't generate consensus without a certificate.");
3414  goto err;
3415  }
3416 
3417  {
3418  char legacy_dbuf[DIGEST_LEN];
3419  crypto_pk_t *legacy_sign=NULL;
3420  char *legacy_id_digest = NULL;
3421  int n_generated = 0;
3422  if (get_options()->V3AuthUseLegacyKey) {
3424  legacy_sign = get_my_v3_legacy_signing_key();
3425  if (cert) {
3426  if (crypto_pk_get_digest(cert->identity_key, legacy_dbuf)) {
3427  log_warn(LD_BUG,
3428  "Unable to compute digest of legacy v3 identity key");
3429  } else {
3430  legacy_id_digest = legacy_dbuf;
3431  }
3432  }
3433  }
3434 
3435  for (flav = 0; flav < N_CONSENSUS_FLAVORS; ++flav) {
3436  const char *flavor_name = networkstatus_get_flavor_name(flav);
3437  consensus_body = networkstatus_compute_consensus(
3438  votes, n_voters,
3439  my_cert->identity_key,
3440  get_my_v3_authority_signing_key(), legacy_id_digest, legacy_sign,
3441  flav);
3442 
3443  if (!consensus_body) {
3444  log_warn(LD_DIR, "Couldn't generate a %s consensus at all!",
3445  flavor_name);
3446  continue;
3447  }
3448  consensus = networkstatus_parse_vote_from_string(consensus_body,
3449  strlen(consensus_body),
3450  NULL,
3451  NS_TYPE_CONSENSUS);
3452  if (!consensus) {
3453  log_warn(LD_DIR, "Couldn't parse %s consensus we generated!",
3454  flavor_name);
3455  tor_free(consensus_body);
3456  continue;
3457  }
3458 
3459  /* 'Check' our own signature, to mark it valid. */
3461 
3462  pending[flav].body = consensus_body;
3463  pending[flav].consensus = consensus;
3464  n_generated++;
3465  consensus_body = NULL;
3466  consensus = NULL;
3467  }
3468  if (!n_generated) {
3469  log_warn(LD_DIR, "Couldn't generate any consensus flavors at all.");
3470  goto err;
3471  }
3472  }
3473 
3475  pending, N_CONSENSUS_FLAVORS);
3476 
3477  if (!signatures) {
3478  log_warn(LD_DIR, "Couldn't extract signatures.");
3479  goto err;
3480  }
3481 
3483  memcpy(pending_consensuses, pending, sizeof(pending));
3484 
3486  pending_consensus_signatures = signatures;
3487 
3489  int n_sigs = 0;
3490  /* we may have gotten signatures for this consensus before we built
3491  * it ourself. Add them now. */
3493  const char *msg = NULL;
3495  "pending", &msg);
3496  if (r >= 0)
3497  n_sigs += r;
3498  else
3499  log_warn(LD_DIR,
3500  "Could not add queued signature to new consensus: %s",
3501  msg);
3502  tor_free(sig);
3503  } SMARTLIST_FOREACH_END(sig);
3504  if (n_sigs)
3505  log_notice(LD_DIR, "Added %d pending signatures while building "
3506  "consensus.", n_sigs);
3508  }
3509 
3510  log_notice(LD_DIR, "Consensus computed; uploading signature(s)");
3511 
3514  V3_DIRINFO,
3516  strlen(pending_consensus_signatures), 0);
3517  log_notice(LD_DIR, "Signature(s) posted.");
3518 
3519  smartlist_free(votes);
3520  return 0;
3521  err:
3522  smartlist_free(votes);
3523  tor_free(consensus_body);
3524  tor_free(signatures);
3525  networkstatus_vote_free(consensus);
3526 
3527  return -1;
3528 }
3529 
3530 /** Helper: we just got the <b>detached_signatures_body</b> sent to us as
3531  * signatures on the currently pending consensus. Add them to <b>pc</b>
3532  * as appropriate. Return the number of signatures added. (?) */
3533 static int
3535  pending_consensus_t *pc,
3537  const char *source,
3538  int severity,
3539  const char **msg_out)
3540 {
3541  const char *flavor_name;
3542  int r = -1;
3543 
3544  /* Only call if we have a pending consensus right now. */
3545  tor_assert(pc->consensus);
3546  tor_assert(pc->body);
3548 
3549  flavor_name = networkstatus_get_flavor_name(pc->consensus->flavor);
3550  *msg_out = NULL;
3551 
3552  {
3553  smartlist_t *sig_list = strmap_get(sigs->signatures, flavor_name);
3554  log_info(LD_DIR, "Have %d signatures for adding to %s consensus.",
3555  sig_list ? smartlist_len(sig_list) : 0, flavor_name);
3556  }
3558  source, severity, msg_out);
3559  if (r >= 0) {
3560  log_info(LD_DIR,"Added %d signatures to consensus.", r);
3561  } else {
3562  log_fn(LOG_PROTOCOL_WARN, LD_DIR,
3563  "Unable to add signatures to consensus: %s",
3564  *msg_out ? *msg_out : "(unknown)");
3565  }
3566 
3567  if (r >= 1) {
3568  char *new_signatures =
3570  char *dst, *dst_end;
3571  size_t new_consensus_len;
3572  if (!new_signatures) {
3573  *msg_out = "No signatures to add";
3574  goto err;
3575  }
3576  new_consensus_len =
3577  strlen(pc->body) + strlen(new_signatures) + 1;
3578  pc->body = tor_realloc(pc->body, new_consensus_len);
3579  dst_end = pc->body + new_consensus_len;
3580  dst = strstr(pc->body, "directory-signature ");
3581  tor_assert(dst);
3582  strlcpy(dst, new_signatures, dst_end-dst);
3583 
3584  /* We remove this block once it has failed to crash for a while. But
3585  * unless it shows up in profiles, we're probably better leaving it in,
3586  * just in case we break detached signature processing at some point. */
3587  {
3589  pc->body, strlen(pc->body), NULL,
3590  NS_TYPE_CONSENSUS);
3591  tor_assert(v);
3592  networkstatus_vote_free(v);
3593  }
3594  *msg_out = "Signatures added";
3595  tor_free(new_signatures);
3596  } else if (r == 0) {
3597  *msg_out = "Signatures ignored";
3598  } else {
3599  goto err;
3600  }
3601 
3602  goto done;
3603  err:
3604  if (!*msg_out)
3605  *msg_out = "Unrecognized error while adding detached signatures.";
3606  done:
3607  return r;
3608 }
3609 
3610 /** Helper: we just got the <b>detached_signatures_body</b> sent to us as
3611  * signatures on the currently pending consensus. Add them to the pending
3612  * consensus (if we have one).
3613  *
3614  * Set *<b>msg</b> to a string constant describing the status, regardless of
3615  * success or failure.
3616  *
3617  * Return negative on failure, nonnegative on success. */
3618 static int
3620  const char *detached_signatures_body,
3621  const char *source,
3622  const char **msg_out)
3623 {
3624  int r=0, i, n_added = 0, errors = 0;
3626  tor_assert(detached_signatures_body);
3627  tor_assert(msg_out);
3629 
3631  detached_signatures_body, NULL))) {
3632  *msg_out = "Couldn't parse detached signatures.";
3633  goto err;
3634  }
3635 
3636  for (i = 0; i < N_CONSENSUS_FLAVORS; ++i) {
3637  int res;
3638  int severity = i == FLAV_NS ? LOG_NOTICE : LOG_INFO;
3639  pending_consensus_t *pc = &pending_consensuses[i];
3640  if (!pc->consensus)
3641  continue;
3642  res = dirvote_add_signatures_to_pending_consensus(pc, sigs, source,
3643  severity, msg_out);
3644  if (res < 0)
3645  errors++;
3646  else
3647  n_added += res;
3648  }
3649 
3650  if (errors && !n_added) {
3651  r = -1;
3652  goto err;
3653  }
3654 
3655  if (n_added && pending_consensuses[FLAV_NS].consensus) {
3656  char *new_detached =
3658  pending_consensuses, N_CONSENSUS_FLAVORS);
3659  if (new_detached) {
3661  pending_consensus_signatures = new_detached;
3662  }
3663  }
3664 
3665  r = n_added;
3666  goto done;
3667  err:
3668  if (!*msg_out)
3669  *msg_out = "Unrecognized error while adding detached signatures.";
3670  done:
3671  ns_detached_signatures_free(sigs);
3672  /* XXXX NM Check how return is used. We can now have an error *and*
3673  signatures added. */
3674  return r;
3675 }
3676 
3677 /** Helper: we just got the <b>detached_signatures_body</b> sent to us as
3678  * signatures on the currently pending consensus. Add them to the pending
3679  * consensus (if we have one); otherwise queue them until we have a
3680  * consensus.
3681  *
3682  * Set *<b>msg</b> to a string constant describing the status, regardless of
3683  * success or failure.
3684  *
3685  * Return negative on failure, nonnegative on success. */
3686 int
3687 dirvote_add_signatures(const char *detached_signatures_body,
3688  const char *source,
3689  const char **msg)
3690 {
3691  if (pending_consensuses[FLAV_NS].consensus) {
3692  log_notice(LD_DIR, "Got a signature from %s. "
3693  "Adding it to the pending consensus.", source);
3695  detached_signatures_body, source, msg);
3696  } else {
3697  log_notice(LD_DIR, "Got a signature from %s. "
3698  "Queuing it for the next consensus.", source);
3702  detached_signatures_body);
3703  *msg = "Signature queued";
3704  return 0;
3705  }
3706 }
3707 
3708 /** Replace the consensus that we're currently serving with the one that we've
3709  * been building. (V3 Authority only) */
3710 static int
3712 {
3713  int i;
3714 
3715  /* Now remember all the other consensuses as if we were a directory cache. */
3716  for (i = 0; i < N_CONSENSUS_FLAVORS; ++i) {
3717  pending_consensus_t *pending = &pending_consensuses[i];
3718  const char *name;
3720  tor_assert(name);
3721  if (!pending->consensus ||
3723  log_warn(LD_DIR, "Not enough info to publish pending %s consensus",name);
3724  continue;
3725  }
3726 
3728  strlen(pending->body),
3729  name, 0, NULL))
3730  log_warn(LD_DIR, "Error publishing %s consensus", name);
3731  else
3732  log_notice(LD_DIR, "Published %s consensus", name);
3733  }
3734 
3735  return 0;
3736 }
3737 
3738 /** Release all static storage held in dirvote.c */
3739 void
3741 {
3743  /* now empty as a result of dirvote_clear_votes(). */
3744  smartlist_free(pending_vote_list);
3745  pending_vote_list = NULL;
3746  smartlist_free(previous_vote_list);
3747  previous_vote_list = NULL;
3748 
3752  /* now empty as a result of dirvote_clear_votes(). */
3753  smartlist_free(pending_consensus_signature_list);
3755  }
3756 }
3757 
3758 /* ====
3759  * Access to pending items.
3760  * ==== */
3761 
3762 /** Return the body of the consensus that we're currently trying to build. */
3763 MOCK_IMPL(const char *,
3765 {
3766  tor_assert(((int)flav) >= 0 && (int)flav < N_CONSENSUS_FLAVORS);
3767  return pending_consensuses[flav].body;
3768 }
3769 
3770 /** Return the signatures that we know for the consensus that we're currently
3771  * trying to build. */
3772 MOCK_IMPL(const char *,
3774 {
3776 }
3777 
3778 /** Return a given vote specified by <b>fp</b>. If <b>by_id</b>, return the
3779  * vote for the authority with the v3 authority identity key digest <b>fp</b>;
3780  * if <b>by_id</b> is false, return the vote whose digest is <b>fp</b>. If
3781  * <b>fp</b> is NULL, return our own vote. If <b>include_previous</b> is
3782  * false, do not consider any votes for a consensus that's already been built.
3783  * If <b>include_pending</b> is false, do not consider any votes for the
3784  * consensus that's in progress. May return NULL if we have no vote for the
3785  * authority in question. */
3786 const cached_dir_t *
3787 dirvote_get_vote(const char *fp, int flags)
3788 {
3789  int by_id = flags & DGV_BY_ID;
3790  const int include_pending = flags & DGV_INCLUDE_PENDING;
3791  const int include_previous = flags & DGV_INCLUDE_PREVIOUS;
3792 
3794  return NULL;
3795  if (fp == NULL) {
3797  if (c) {
3798  fp = c->cache_info.identity_digest;
3799  by_id = 1;
3800  } else
3801  return NULL;
3802  }
3803  if (by_id) {
3804  if (pending_vote_list && include_pending) {
3806  if (fast_memeq(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
3807  return pv->vote_body);
3808  }
3809  if (previous_vote_list && include_previous) {
3811  if (fast_memeq(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
3812  return pv->vote_body);
3813  }
3814  } else {
3815  if (pending_vote_list && include_pending) {
3817  if (fast_memeq(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN))
3818  return pv->vote_body);
3819  }
3820  if (previous_vote_list && include_previous) {
3822  if (fast_memeq(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN))
3823  return pv->vote_body);
3824  }
3825  }
3826  return NULL;
3827 }
3828 
3829 /** Construct and return a new microdescriptor from a routerinfo <b>ri</b>
3830  * according to <b>consensus_method</b>.
3831  **/
3833 dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method)
3834 {
3835  microdesc_t *result = NULL;
3836  char *key = NULL, *summary = NULL, *family = NULL;
3837  size_t keylen;
3838  smartlist_t *chunks = smartlist_new();
3839  char *output = NULL;
3840  crypto_pk_t *rsa_pubkey = router_get_rsa_onion_pkey(ri->onion_pkey,
3841  ri->onion_pkey_len);
3842 
3843  if (crypto_pk_write_public_key_to_string(rsa_pubkey, &key, &keylen)<0)
3844  goto done;
3845  summary = policy_summarize(ri->exit_policy, AF_INET);
3846  if (ri->declared_family)
3847  family = smartlist_join_strings(ri->declared_family, " ", 0, NULL);
3848 
3849  smartlist_add_asprintf(chunks, "onion-key\n%s", key);
3850 
3851  if (ri->onion_curve25519_pkey) {
3852  char kbuf[CURVE25519_BASE64_PADDED_LEN + 1];
3853  bool add_padding = (consensus_method < MIN_METHOD_FOR_UNPADDED_NTOR_KEY);
3854  curve25519_public_to_base64(kbuf, ri->onion_curve25519_pkey, add_padding);
3855  smartlist_add_asprintf(chunks, "ntor-onion-key %s\n", kbuf);
3856  }
3857 
3858  if (family) {
3859  if (consensus_method < MIN_METHOD_FOR_CANONICAL_FAMILIES_IN_MICRODESCS) {
3860  smartlist_add_asprintf(chunks, "family %s\n", family);
3861  } else {
3862  const uint8_t *id = (const uint8_t *)ri->cache_info.identity_digest;
3863  char *canonical_family = nodefamily_canonicalize(family, id, 0);
3864  smartlist_add_asprintf(chunks, "family %s\n", canonical_family);
3865  tor_free(canonical_family);
3866  }
3867  }
3868 
3869  if (summary && strcmp(summary, "reject 1-65535"))
3870  smartlist_add_asprintf(chunks, "p %s\n", summary);
3871 
3872  if (ri->ipv6_exit_policy) {
3873  /* XXXX+++ This doesn't match proposal 208, which says these should
3874  * be taken unchanged from the routerinfo. That's bogosity, IMO:
3875  * the proposal should have said to do this instead.*/
3876  char *p6 = write_short_policy(ri->ipv6_exit_policy);
3877  if (p6 && strcmp(p6, "reject 1-65535"))
3878  smartlist_add_asprintf(chunks, "p6 %s\n", p6);
3879  tor_free(p6);
3880  }
3881 
3882  {
3883  char idbuf[ED25519_BASE64_LEN+1];
3884  const char *keytype;
3885  if (ri->cache_info.signing_key_cert &&
3886  ri->cache_info.signing_key_cert->signing_key_included) {
3887  keytype = "ed25519";
3889  &ri->cache_info.signing_key_cert->signing_key);
3890  } else {
3891  keytype = "rsa1024";
3892  digest_to_base64(idbuf, ri->cache_info.identity_digest);
3893  }
3894  smartlist_add_asprintf(chunks, "id %s %s\n", keytype, idbuf);
3895  }
3896 
3897  output = smartlist_join_strings(chunks, "", 0, NULL);
3898 
3899  {
3901  output+strlen(output), 0,
3902  SAVED_NOWHERE, NULL);
3903  if (smartlist_len(lst) != 1) {
3904  log_warn(LD_DIR, "We generated a microdescriptor we couldn't parse.");
3905  SMARTLIST_FOREACH(lst, microdesc_t *, md, microdesc_free(md));
3906  smartlist_free(lst);
3907  goto done;
3908  }
3909  result = smartlist_get(lst, 0);
3910  smartlist_free(lst);
3911  }
3912 
3913  done:
3914  crypto_pk_free(rsa_pubkey);
3915  tor_free(output);
3916  tor_free(key);
3917  tor_free(summary);
3918  tor_free(family);
3919  if (chunks) {
3920  SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3921  smartlist_free(chunks);
3922  }
3923  return result;
3924 }
3925 
3926 /** Format the appropriate vote line to describe the microdescriptor <b>md</b>
3927  * in a consensus vote document. Write it into the <b>out_len</b>-byte buffer
3928  * in <b>out</b>. Return -1 on failure and the number of characters written
3929  * on success. */
3930 static ssize_t
3931 dirvote_format_microdesc_vote_line(char *out_buf, size_t out_buf_len,
3932  const microdesc_t *md,
3933  int consensus_method_low,
3934  int consensus_method_high)
3935 {
3936  ssize_t ret = -1;
3937  char d64[BASE64_DIGEST256_LEN+1];
3938  char *microdesc_consensus_methods =
3939  make_consensus_method_list(consensus_method_low,
3940  consensus_method_high,
3941  ",");
3942  tor_assert(microdesc_consensus_methods);
3943 
3944  digest256_to_base64(d64, md->digest);
3945 
3946  if (tor_snprintf(out_buf, out_buf_len, "m %s sha256=%s\n",
3947  microdesc_consensus_methods, d64)<0)
3948  goto out;
3949 
3950  ret = strlen(out_buf);
3951 
3952  out:
3953  tor_free(microdesc_consensus_methods);
3954  return ret;
3955 }
3956 
3957 /** Array of start and end of consensus methods used for supported
3958  microdescriptor formats. */
3959 static const struct consensus_method_range_t {
3960  int low;
3961  int high;
3962 } microdesc_consensus_methods[] = {
3969  {-1, -1}
3970 };
3971 
3972 /** Helper type used when generating the microdescriptor lines in a directory
3973  * vote. */
3974 typedef struct microdesc_vote_line_t {
3975  int low;
3976  int high;
3977  microdesc_t *md;
3978  struct microdesc_vote_line_t *next;
3980 
3981 /** Generate and return a linked list of all the lines that should appear to
3982  * describe a router's microdescriptor versions in a directory vote.
3983  * Add the generated microdescriptors to <b>microdescriptors_out</b>. */
3986  smartlist_t *microdescriptors_out)
3987 {
3988  const struct consensus_method_range_t *cmr;
3989  microdesc_vote_line_t *entries = NULL, *ep;
3990  vote_microdesc_hash_t *result = NULL;
3991 
3992  /* Generate the microdescriptors. */
3993  for (cmr = microdesc_consensus_methods;
3994  cmr->low != -1 && cmr->high != -1;
3995  cmr++) {
3996  microdesc_t *md = dirvote_create_microdescriptor(ri, cmr->low);
3997  if (md) {
3999  tor_malloc_zero(sizeof(microdesc_vote_line_t));
4000  e->md = md;
4001  e->low = cmr->low;
4002  e->high = cmr->high;
4003  e->next = entries;
4004  entries = e;
4005  }
4006  }
4007 
4008  /* Compress adjacent identical ones */
4009  for (ep = entries; ep; ep = ep->next) {
4010  while (ep->next &&
4011  fast_memeq(ep->md->digest, ep->next->md->digest, DIGEST256_LEN) &&
4012  ep->low == ep->next->high + 1) {
4013  microdesc_vote_line_t *next = ep->next;
4014  ep->low = next->low;
4015  microdesc_free(next->md);
4016  ep->next = next->next;
4017  tor_free(next);
4018  }
4019  }
4020 
4021  /* Format them into vote_microdesc_hash_t, and add to microdescriptors_out.*/
4022  while ((ep = entries)) {
4023  char buf[128];
4025  if (dirvote_format_microdesc_vote_line(buf, sizeof(buf), ep->md,
4026  ep->low, ep->high) >= 0) {
4027  h = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
4028  h->microdesc_hash_line = tor_strdup(buf);
4029  h->next = result;
4030  result = h;
4031  ep->md->last_listed = now;
4032  smartlist_add(microdescriptors_out, ep->md);
4033  }
4034  entries = ep->next;
4035  tor_free(ep);
4036  }
4037 
4038  return result;
4039 }
4040 
4041 /** Parse and extract all SR commits from <b>tokens</b> and place them in
4042  * <b>ns</b>. */
4043 static void
4045 {
4046  smartlist_t *chunks = NULL;
4047 
4048  tor_assert(ns);
4049  tor_assert(tokens);
4050  /* Commits are only present in a vote. */
4051  tor_assert(ns->type == NS_TYPE_VOTE);
4052 
4053  ns->sr_info.commits = smartlist_new();
4054 
4055  smartlist_t *commits = find_all_by_keyword(tokens, K_COMMIT);
4056  /* It's normal that a vote might contain no commits even if it participates
4057  * in the SR protocol. Don't treat it as an error. */
4058  if (commits == NULL) {
4059  goto end;
4060  }
4061 
4062  /* Parse the commit. We do NO validation of number of arguments or ordering
4063  * for forward compatibility, it's the parse commit job to inform us if it's
4064  * supported or not. */
4065  chunks = smartlist_new();
4066  SMARTLIST_FOREACH_BEGIN(commits, directory_token_t *, tok) {
4067  /* Extract all arguments and put them in the chunks list. */
4068  for (int i = 0; i < tok->n_args; i++) {
4069  smartlist_add(chunks, tok->args[i]);
4070  }
4071  sr_commit_t *commit = sr_parse_commit(chunks);
4072  smartlist_clear(chunks);
4073  if (commit == NULL) {
4074  /* Get voter identity so we can warn that this dirauth vote contains
4075  * commit we can't parse. */
4076  networkstatus_voter_info_t *voter = smartlist_get(ns->voters, 0);
4077  tor_assert(voter);
4078  log_warn(LD_DIR, "SR: Unable to parse commit %s from vote of voter %s.",
4079  escaped(tok->object_body),
4080  hex_str(voter->identity_digest,
4081  sizeof(voter->identity_digest)));
4082  /* Commitment couldn't be parsed. Continue onto the next commit because
4083  * this one could be unsupported for instance. */
4084  continue;
4085  }
4086  /* Add newly created commit object to the vote. */
4087  smartlist_add(ns->sr_info.commits, commit);
4088  } SMARTLIST_FOREACH_END(tok);
4089 
4090  end:
4091  smartlist_free(chunks);
4092  smartlist_free(commits);
4093 }
4094 
4095 /* Using the given directory tokens in tokens, parse the shared random commits
4096  * and put them in the given vote document ns.
4097  *
4098  * This also sets the SR participation flag if present in the vote. */
4099 void
4100 dirvote_parse_sr_commits(networkstatus_t *ns, const smartlist_t *tokens)
4101 {
4102  /* Does this authority participates in the SR protocol? */
4103  directory_token_t *tok = find_opt_by_keyword(tokens, K_SR_FLAG);
4104  if (tok) {
4105  ns->sr_info.participate = 1;
4106  /* Get the SR commitments and reveals from the vote. */
4107  extract_shared_random_commits(ns, tokens);
4108  }
4109 }
4110 
4111 /* For the given vote, free the shared random commits if any. */
4112 void
4113 dirvote_clear_commits(networkstatus_t *ns)
4114 {
4115  tor_assert(ns->type == NS_TYPE_VOTE);
4116 
4117  if (ns->sr_info.commits) {
4118  SMARTLIST_FOREACH(ns->sr_info.commits, sr_commit_t *, c,
4119  sr_commit_free(c));
4120  smartlist_free(ns->sr_info.commits);
4121  }
4122 }
4123 
4124 /* The given url is the /tor/status-vote GET directory request. Populates the
4125  * items list with strings that we can compress on the fly and dir_items with
4126  * cached_dir_t objects that have a precompressed deflated version. */
4127 void
4128 dirvote_dirreq_get_status_vote(const char *url, smartlist_t *items,
4129  smartlist_t *dir_items)
4130 {
4131  int current;
4132 
4133  url += strlen("/tor/status-vote/");
4134  current = !strcmpstart(url, "current/");
4135  url = strchr(url, '/');
4136  tor_assert(url);
4137  ++url;
4138  if (!strcmp(url, "consensus")) {
4139  const char *item;
4140  tor_assert(!current); /* we handle current consensus specially above,
4141  * since it wants to be spooled. */
4142  if ((item = dirvote_get_pending_consensus(FLAV_NS)))
4143  smartlist_add(items, (char*)item);
4144  } else if (!current && !strcmp(url, "consensus-signatures")) {
4145  /* XXXX the spec says that we should implement
4146  * current/consensus-signatures too. It doesn't seem to be needed,
4147  * though. */
4148  const char *item;
4150  smartlist_add(items, (char*)item);
4151  } else if (!strcmp(url, "authority")) {
4152  const cached_dir_t *d;
4153  int flags = DGV_BY_ID |
4154  (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
4155  if ((d=dirvote_get_vote(NULL, flags)))
4156  smartlist_add(dir_items, (cached_dir_t*)d);
4157  } else {
4158  const cached_dir_t *d;
4159  smartlist_t *fps = smartlist_new();
4160  int flags;
4161  if (!strcmpstart(url, "d/")) {
4162  url += 2;
4163  flags = DGV_INCLUDE_PENDING | DGV_INCLUDE_PREVIOUS;
4164  } else {
4165  flags = DGV_BY_ID |
4166  (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
4167  }
4168  dir_split_resource_into_fingerprints(url, fps, NULL,
4169  DSR_HEX|DSR_SORT_UNIQ);
4170  SMARTLIST_FOREACH(fps, char *, fp, {
4171  if ((d = dirvote_get_vote(fp, flags)))
4172  smartlist_add(dir_items, (cached_dir_t*)d);
4173  tor_free(fp);
4174  });
4175  smartlist_free(fps);
4176  }
4177 }
4178 
4179 /** Get the best estimate of a router's bandwidth for dirauth purposes,
4180  * preferring measured to advertised values if available. */
4182  (const routerinfo_t *ri))
4183 {
4184  uint32_t bw_kb = 0;
4185  /*
4186  * Yeah, measured bandwidths in measured_bw_line_t are (implicitly
4187  * signed) longs and the ones router_get_advertised_bandwidth() returns
4188  * are uint32_t.
4189  */
4190  long mbw_kb = 0;
4191 
4192  if (ri) {
4193  /*
4194  * * First try to see if we have a measured bandwidth; don't bother with
4195  * as_of_out here, on the theory that a stale measured bandwidth is still
4196  * better to trust than an advertised one.
4197  */
4199  &mbw_kb, NULL)) {
4200  /* Got one! */
4201  bw_kb = (uint32_t)mbw_kb;
4202  } else {
4203  /* If not, fall back to advertised */
4204  bw_kb = router_get_advertised_bandwidth(ri) / 1000;
4205  }
4206  }
4207 
4208  return bw_kb;
4209 }
4210 
4211 /**
4212  * Helper: compare the address of family `family` in `a` with the address in
4213  * `b`. The family must be one of `AF_INET` and `AF_INET6`.
4214  **/
4215 static int
4217  const routerinfo_t *b,
4218  int family)
4219 {
4220  const tor_addr_t *addr1 = (family==AF_INET) ? &a->ipv4_addr : &a->ipv6_addr;
4221  const tor_addr_t *addr2 = (family==AF_INET) ? &b->ipv4_addr : &b->ipv6_addr;
4222  const int maskbits = (family==AF_INET) ? 32 : 64;
4223  return tor_addr_compare_masked(addr1, addr2, maskbits, CMP_EXACT);
4224 }
4225 
4226 /** Helper for sorting: compares two ipv4 routerinfos first by ipv4 address,
4227  * and then by descending order of "usefulness"
4228  * (see compare_routerinfo_usefulness)
4229  **/
4230 STATIC int
4231 compare_routerinfo_by_ipv4(const void **a, const void **b)
4232 {
4233  const routerinfo_t *first = *(const routerinfo_t **)a;
4234  const routerinfo_t *second = *(const routerinfo_t **)b;
4235  int comparison = compare_routerinfo_addrs_by_family(first, second, AF_INET);
4236  if (comparison == 0) {
4237  // If addresses are equal, use other comparison criteria
4238  return compare_routerinfo_usefulness(first, second);
4239  } else {
4240  return comparison;
4241  }
4242 }
4243 
4244 /** Helper for sorting: compares two ipv6 routerinfos first by ipv6 address,
4245  * and then by descending order of "usefulness"
4246  * (see compare_routerinfo_usefulness)
4247  **/
4248 STATIC int
4249 compare_routerinfo_by_ipv6(const void **a, const void **b)
4250 {
4251  const routerinfo_t *first = *(const routerinfo_t **)a;
4252  const routerinfo_t *second = *(const routerinfo_t **)b;
4253  int comparison = compare_routerinfo_addrs_by_family(first, second, AF_INET6);
4254  // If addresses are equal, use other comparison criteria
4255  if (comparison == 0)
4256  return compare_routerinfo_usefulness(first, second);
4257  else
4258  return comparison;
4259 }
4260 
4261 /**
4262 * Compare routerinfos by descending order of "usefulness" :
4263 * An authority is more useful than a non-authority; a running router is
4264 * more useful than a non-running router; and a router with more bandwidth
4265 * is more useful than one with less.
4266 **/
4267 STATIC int
4269  const routerinfo_t *second)
4270 {
4271  int first_is_auth, second_is_auth;
4272  const node_t *node_first, *node_second;
4273  int first_is_running, second_is_running;
4274  uint32_t bw_kb_first, bw_kb_second;
4275  /* Potentially, this next bit could cause k n lg n memeq calls. But in
4276  * reality, we will almost never get here, since addresses will usually be
4277  * different. */
4278  first_is_auth =
4279  router_digest_is_trusted_dir(first->cache_info.identity_digest);
4280  second_is_auth =
4281  router_digest_is_trusted_dir(second->cache_info.identity_digest);
4282 
4283  if (first_is_auth && !second_is_auth)
4284  return -1;
4285  else if (!first_is_auth && second_is_auth)
4286  return 1;
4287 
4288  node_first = node_get_by_id(first->cache_info.identity_digest);
4289  node_second = node_get_by_id(second->cache_info.identity_digest);
4290  first_is_running = node_first && node_first->is_running;
4291  second_is_running = node_second && node_second->is_running;
4292  if (first_is_running && !second_is_running)
4293  return -1;
4294  else if (!first_is_running && second_is_running)
4295  return 1;
4296 
4297  bw_kb_first = dirserv_get_bandwidth_for_router_kb(first);
4298  bw_kb_second = dirserv_get_bandwidth_for_router_kb(second);
4299 
4300  if (bw_kb_first > bw_kb_second)
4301  return -1;
4302  else if (bw_kb_first < bw_kb_second)
4303  return 1;
4304 
4305  /* They're equal! Compare by identity digest, so there's a
4306  * deterministic order and we avoid flapping. */
4307  return fast_memcmp(first->cache_info.identity_digest,
4308  second->cache_info.identity_digest,
4309  DIGEST_LEN);
4310 }
4311 
4312 /** Given a list of routerinfo_t in <b>routers</b> that all use the same
4313  * IP version, specified in <b>family</b>, return a new digestmap_t whose keys
4314  * are the identity digests of those routers that we're going to exclude for
4315  * Sybil-like appearance.
4316  */
4317 STATIC digestmap_t *
4319 {
4320  const dirauth_options_t *options = dirauth_get_options();
4321  digestmap_t *omit_as_sybil = digestmap_new();
4322  smartlist_t *routers_by_ip = smartlist_new();
4323  int addr_count = 0;
4324  routerinfo_t *last_ri = NULL;
4325  /* Allow at most this number of Tor servers on a single IP address, ... */
4326  int max_with_same_addr = options->AuthDirMaxServersPerAddr;
4327  if (max_with_same_addr <= 0)
4328  max_with_same_addr = INT_MAX;
4329 
4330  smartlist_add_all(routers_by_ip, routers);
4331  if (family == AF_INET6)
4333  else
4335 
4336  SMARTLIST_FOREACH_BEGIN(routers_by_ip, routerinfo_t *, ri) {
4337  bool addrs_equal;
4338  if (last_ri)
4339  addrs_equal = !compare_routerinfo_addrs_by_family(last_ri, ri, family);
4340  else
4341  addrs_equal = false;
4342 
4343  if (! addrs_equal) {
4344  last_ri = ri;
4345  addr_count = 1;
4346  } else if (++addr_count > max_with_same_addr) {
4347  digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4348  }
4349  } SMARTLIST_FOREACH_END(ri);
4350  smartlist_free(routers_by_ip);
4351  return omit_as_sybil;
4352 }
4353 
4354 /** Given a list of routerinfo_t in <b>routers</b>, return a new digestmap_t
4355  * whose keys are the identity digests of those routers that we're going to
4356  * exclude for Sybil-like appearance. */
4357 STATIC digestmap_t *
4359 {
4360  smartlist_t *routers_ipv6, *routers_ipv4;
4361  routers_ipv6 = smartlist_new();
4362  routers_ipv4 = smartlist_new();
4363  digestmap_t *omit_as_sybil_ipv4;
4364  digestmap_t *omit_as_sybil_ipv6;
4365  digestmap_t *omit_as_sybil = digestmap_new();
4366  // Sort the routers in two lists depending on their IP version
4367  SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
4368  // If the router has an IPv6 address
4369  if (tor_addr_family(&(ri->ipv6_addr)) == AF_INET6) {
4370  smartlist_add(routers_ipv6, ri);
4371  }
4372  // If the router has an IPv4 address
4373  if (tor_addr_family(&(ri->ipv4_addr)) == AF_INET) {
4374  smartlist_add(routers_ipv4, ri);
4375  }
4376  } SMARTLIST_FOREACH_END(ri);
4377  omit_as_sybil_ipv4 = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
4378  omit_as_sybil_ipv6 = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
4379 
4380  // Add all possible sybils to the common digestmap
4381  DIGESTMAP_FOREACH (omit_as_sybil_ipv4, sybil_id, routerinfo_t *, ri) {
4382  digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4384  DIGESTMAP_FOREACH (omit_as_sybil_ipv6, sybil_id, routerinfo_t *, ri) {
4385  digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4387  // Clean the temp variables
4388  smartlist_free(routers_ipv4);
4389  smartlist_free(routers_ipv6);
4390  digestmap_free(omit_as_sybil_ipv4, NULL);
4391  digestmap_free(omit_as_sybil_ipv6, NULL);
4392  // Return the digestmap: it now contains all the possible sybils
4393  return omit_as_sybil;
4394 }
4395 /** Given a platform string as in a routerinfo_t (possibly null), return a
4396  * newly allocated version string for a networkstatus document, or NULL if the
4397  * platform doesn't give a Tor version. */
4398 static char *
4399 version_from_platform(const char *platform)
4400 {
4401  if (platform && !strcmpstart(platform, "Tor ")) {
4402  const char *eos = find_whitespace(platform+4);
4403  if (eos && !strcmpstart(eos, " (r")) {
4404  /* XXXX Unify this logic with the other version extraction
4405  * logic in routerparse.c. */
4406  eos = find_whitespace(eos+1);
4407  }
4408  if (eos) {
4409  return tor_strndup(platform, eos-platform);
4410  }
4411  }
4412  return NULL;
4413 }
4414 
4415 /** Given a (possibly empty) list of config_line_t, each line of which contains
4416  * a list of comma-separated version numbers surrounded by optional space,
4417  * allocate and return a new string containing the version numbers, in order,
4418  * separated by commas. Used to generate Recommended(Client|Server)?Versions
4419  */
4420 char *
4422 {
4423  smartlist_t *versions;
4424  char *result;
4425  versions = smartlist_new();
4426  for ( ; ln; ln = ln->next) {
4427  smartlist_split_string(versions, ln->value, ",",
4428  SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4429  }
4430 
4431  /* Handle the case where a dirauth operator has accidentally made some
4432  * versions space-separated instead of comma-separated. */
4433  smartlist_t *more_versions = smartlist_new();
4434  SMARTLIST_FOREACH_BEGIN(versions, char *, v) {
4435  if (strchr(v, ' ')) {
4436  if (warn)
4437  log_warn(LD_DIRSERV, "Unexpected space in versions list member %s. "
4438  "(These are supposed to be comma-separated; I'll pretend you "
4439  "used commas instead.)", escaped(v));
4440  SMARTLIST_DEL_CURRENT(versions, v);
4441  smartlist_split_string(more_versions, v, NULL,
4442  SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4443  tor_free(v);
4444  }
4445  } SMARTLIST_FOREACH_END(v);
4446  smartlist_add_all(versions, more_versions);
4447  smartlist_free(more_versions);
4448 
4449  /* Check to make sure everything looks like a version. */
4450  if (warn) {
4451  SMARTLIST_FOREACH_BEGIN(versions, const char *, v) {
4452  tor_version_t ver;
4453  if (tor_version_parse(v, &ver) < 0) {
4454  log_warn(LD_DIRSERV, "Recommended version %s does not look valid. "
4455  " (I'll include it anyway, since you told me to.)",
4456  escaped(v));
4457  }
4458  } SMARTLIST_FOREACH_END(v);
4459  }
4460 
4461  sort_version_list(versions, 1);
4462  result = smartlist_join_strings(versions,",",0,NULL);
4463  SMARTLIST_FOREACH(versions,char *,s,tor_free(s));
4464  smartlist_free(versions);
4465  return result;
4466 }
4467 
4468 /** If there are entries in <b>routers</b> with exactly the same ed25519 keys,
4469  * remove the older one. If they are exactly the same age, remove the one
4470  * with the greater descriptor digest. May alter the order of the list. */
4471 static void
4473 {
4474  routerinfo_t *ri2;
4475  digest256map_t *by_ed_key = digest256map_new();
4476 
4477  SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
4478  ri->omit_from_vote = 0;
4479  if (ri->cache_info.signing_key_cert == NULL)
4480  continue; /* No ed key */
4481  const uint8_t *pk = ri->cache_info.signing_key_cert->signing_key.pubkey;
4482  if ((ri2 = digest256map_get(by_ed_key, pk))) {
4483  /* Duplicate; must omit one. Set the omit_from_vote flag in whichever
4484  * one has the earlier published_on. */
4485  const time_t ri_pub = ri->cache_info.published_on;
4486  const time_t ri2_pub = ri2->cache_info.published_on;
4487  if (ri2_pub < ri_pub ||
4488  (ri2_pub == ri_pub &&
4489  fast_memcmp(ri->cache_info.signed_descriptor_digest,
4490  ri2->cache_info.signed_descriptor_digest,DIGEST_LEN)<0)) {
4491  digest256map_set(by_ed_key, pk, ri);
4492  ri2->omit_from_vote = 1;
4493  } else {
4494  ri->omit_from_vote = 1;
4495  }
4496  } else {
4497  /* Add to map */
4498  digest256map_set(by_ed_key, pk, ri);
4499  }
4500  } SMARTLIST_FOREACH_END(ri);
4501 
4502  digest256map_free(by_ed_key, NULL);
4503 
4504  /* Now remove every router where the omit_from_vote flag got set. */
4505  SMARTLIST_FOREACH_BEGIN(routers, const routerinfo_t *, ri) {
4506  if (ri->omit_from_vote) {
4507  SMARTLIST_DEL_CURRENT(routers, ri);
4508  }
4509  } SMARTLIST_FOREACH_END(ri);
4510 }
4511 
4512 /** Routerstatus <b>rs</b> is part of a group of routers that are on
4513  * too narrow an IP-space. Clear out its flags since we don't want it be used
4514  * because of its Sybil-like appearance.
4515  *
4516  * Leave its BadExit flag alone though, since if we think it's a bad exit,
4517  * we want to vote that way in case all the other authorities are voting
4518  * Running and Exit.
4519  */
4520 static void
4522 {
4523  rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
4524  rs->is_flagged_running = rs->is_named = rs->is_valid =
4525  rs->is_hs_dir = rs->is_v2_dir = rs->is_possible_guard = 0;
4526  /* FFFF we might want some mechanism to check later on if we
4527  * missed zeroing any flags: it's easy to add a new flag but
4528  * forget to add it to this clause. */
4529 }
4530 
4531 /** Space-separated list of all the flags that we will always vote on. */
4533  "Authority "
4534  "Exit "
4535  "Fast "
4536  "Guard "
4537  "HSDir "
4538  "Stable "
4539  "StaleDesc "
4540  "V2Dir "
4541  "Valid";
4542 /** Space-separated list of all flags that we may or may not vote on,
4543  * depending on our configuration. */
4545  "BadExit "
4546  "Running";
4547 
4548 /** Return a new networkstatus_t* containing our current opinion. (For v3
4549  * authorities) */
4552  authority_cert_t *cert)
4553 {
4554  const or_options_t *options = get_options();
4555  const dirauth_options_t *d_options = dirauth_get_options();
4556  networkstatus_t *v3_out = NULL;
4557  tor_addr_t addr;
4558  char *hostname = NULL, *client_versions = NULL, *server_versions = NULL;
4559  const char *contact;
4560  smartlist_t *routers, *routerstatuses;
4561  char identity_digest[DIGEST_LEN];
4562  char signing_key_digest[DIGEST_LEN];
4563  const int listbadexits = d_options->AuthDirListBadExits;
4565  time_t now = time(NULL);
4566  time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
4567  networkstatus_voter_info_t *voter = NULL;
4568  vote_timing_t timing;
4569  const int vote_on_reachability = running_long_enough_to_decide_unreachable();
4570  smartlist_t *microdescriptors = NULL;
4571  smartlist_t *bw_file_headers = NULL;
4572  uint8_t bw_file_digest256[DIGEST256_LEN] = {0};
4573 
4574  tor_assert(private_key);
4575  tor_assert(cert);
4576 
4577  if (crypto_pk_get_digest(private_key, signing_key_digest)<0) {
4578  log_err(LD_BUG, "Error computing signing key digest");
4579  return NULL;
4580  }
4581  if (crypto_pk_get_digest(cert->identity_key, identity_digest)<0) {
4582  log_err(LD_BUG, "Error computing identity key digest");
4583  return NULL;
4584  }
4585  if (!find_my_address(options, AF_INET, LOG_WARN, &addr, NULL, &hostname)) {
4586  log_warn(LD_NET, "Couldn't resolve my hostname");
4587  return NULL;
4588  }
4589  if (!hostname || !strchr(hostname, '.')) {
4590  tor_free(hostname);
4591  hostname = tor_addr_to_str_dup(&addr);
4592  }
4593 
4594  if (!hostname) {
4595  log_err(LD_BUG, "Failed to determine hostname AND duplicate address");
4596  return NULL;
4597  }
4598 
4599  if (d_options->VersioningAuthoritativeDirectory) {
4600  client_versions =
4602  server_versions =
4604  }
4605 
4606  contact = get_options()->ContactInfo;
4607  if (!contact)
4608  contact = "(none)";
4609 
4610  /*
4611  * Do this so dirserv_compute_performance_thresholds() and
4612  * set_routerstatus_from_routerinfo() see up-to-date bandwidth info.
4613  */
4614  if (options->V3BandwidthsFile) {
4616  NULL);
4617  } else {
4618  /*
4619  * No bandwidths file; clear the measured bandwidth cache in case we had
4620  * one last time around.
4621  */
4624  }
4625  }
4626 
4627  /* precompute this part, since we need it to decide what "stable"
4628  * means. */
4629  SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
4630  dirserv_set_router_is_running(ri, now);
4631  });
4632 
4633  routers = smartlist_new();
4634  smartlist_add_all(routers, rl->routers);
4635  routers_make_ed_keys_unique(routers);
4636  /* After this point, don't use rl->routers; use 'routers' instead. */
4637  routers_sort_by_identity(routers);
4638  /* Get a digestmap of possible sybil routers, IPv4 or IPv6 */
4639  digestmap_t *omit_as_sybil = get_all_possible_sybil(routers);
4640  DIGESTMAP_FOREACH (omit_as_sybil, sybil_id, void *, ignore) {
4641  (void)ignore;
4642  rep_hist_make_router_pessimal(sybil_id, now);
4644  /* Count how many have measured bandwidths so we know how to assign flags;
4645  * this must come before dirserv_compute_performance_thresholds() */
4646  dirserv_count_measured_bws(routers);
4648  routerstatuses = smartlist_new();
4649  microdescriptors = smartlist_new();
4650 
4651  SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
4652  /* If it has a protover list and contains a protocol name greater than
4653  * MAX_PROTOCOL_NAME_LENGTH, skip it. */
4654  if (ri->protocol_list &&
4655  protover_list_is_invalid(ri->protocol_list)) {
4656  continue;
4657  }
4658  if (ri->cache_info.published_on >= cutoff) {
4659  routerstatus_t *rs;
4660  vote_routerstatus_t *vrs;
4661  node_t *node = node_get_mutable_by_id(ri->cache_info.identity_digest);
4662  if (!node)
4663  continue;
4664 
4665  vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
4666  rs = &vrs->status;
4667  dirauth_set_routerstatus_from_routerinfo(rs, node, ri, now,
4668  listbadexits);
4669 
4670  if (ri->cache_info.signing_key_cert) {
4671  memcpy(vrs->ed25519_id,
4672  ri->cache_info.signing_key_cert->signing_key.pubkey,
4674  }
4675  if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
4677 
4678  if (!vote_on_reachability)
4679  rs->is_flagged_running = 0;
4680 
4681  vrs->version = version_from_platform(ri->platform);
4682  if (ri->protocol_list) {
4683  vrs->protocols = tor_strdup(ri->protocol_list);
4684  } else {
4685  vrs->protocols = tor_strdup(
4687  }
4689  microdescriptors);
4690 
4691  smartlist_add(routerstatuses, vrs);
4692  }
4693  } SMARTLIST_FOREACH_END(ri);
4694 
4695  {
4696  smartlist_t *added =
4698  microdescriptors, SAVED_NOWHERE, 0);
4699  smartlist_free(added);
4700  smartlist_free(microdescriptors);
4701  }
4702 
4703  smartlist_free(routers);
4704  digestmap_free(omit_as_sybil, NULL);
4705 
4706  /* Apply guardfraction information to routerstatuses. */
4707  if (options->GuardfractionFile) {
4709  routerstatuses);
4710  }
4711 
4712  /* This pass through applies the measured bw lines to the routerstatuses */
4713  if (options->V3BandwidthsFile) {
4714  /* Only set bw_file_headers when V3BandwidthsFile is configured */
4715  bw_file_headers = smartlist_new();
4717  routerstatuses, bw_file_headers,
4718  bw_file_digest256);
4719 
4720  } else {
4721  /*
4722  * No bandwidths file; clear the measured bandwidth cache in case we had
4723  * one last time around.
4724  */
4727  }
4728  }
4729 
4730  v3_out = tor_malloc_zero(sizeof(networkstatus_t));
4731 
4732  v3_out->type = NS_TYPE_VOTE;
4734  v3_out->published = now;
4735  {
4736  char tbuf[ISO_TIME_LEN+1];
4737  networkstatus_t *current_consensus =
4739  long last_consensus_interval; /* only used to pick a valid_after */
4740  if (current_consensus)
4741  last_consensus_interval = current_consensus->fresh_until -
4742  current_consensus->valid_after;
4743  else
4744  last_consensus_interval = options->TestingV3AuthInitialVotingInterval;
4745  v3_out->valid_after =
4747  (int)last_consensus_interval,
4749  format_iso_time(tbuf, v3_out->valid_after);
4750  log_notice(LD_DIR,"Choosing valid-after time in vote as %s: "
4751  "consensus_set=%d, last_interval=%d",
4752  tbuf, current_consensus?1:0, (int)last_consensus_interval);
4753  }
4754  v3_out->fresh_until = v3_out->valid_after + timing.vote_interval;
4755  v3_out->valid_until = v3_out->valid_after +
4756  (timing.vote_interval * timing.n_intervals_valid);
4757  v3_out->vote_seconds = timing.vote_delay;
4758  v3_out->dist_seconds = timing.dist_delay;
4759  tor_assert(v3_out->vote_seconds > 0);
4760  tor_assert(v3_out->dist_seconds > 0);
4761  tor_assert(timing.n_intervals_valid > 0);
4762 
4763  v3_out->client_versions = client_versions;
4764  v3_out->server_versions = server_versions;
4765 
4766  /* These are hardwired, to avoid disaster. */
4767  v3_out->recommended_relay_protocols =
4768  tor_strdup(DIRVOTE_RECOMMEND_RELAY_PROTO);
4769  v3_out->recommended_client_protocols =
4770  tor_strdup(DIRVOTE_RECOMMEND_CLIENT_PROTO);
4771 
4772  v3_out->required_relay_protocols =
4773  tor_strdup(DIRVOTE_REQUIRE_RELAY_PROTO);
4774  v3_out->required_client_protocols =
4775  tor_strdup(DIRVOTE_REQUIRE_CLIENT_PROTO);
4776 
4777  /* We are not allowed to vote to require anything we don't have. */
4778  tor_assert(protover_all_supported(v3_out->required_relay_protocols, NULL));
4779  tor_assert(protover_all_supported(v3_out->required_client_protocols, NULL));
4780 
4781  /* We should not recommend anything we don't have. */
4782  tor_assert_nonfatal(protover_all_supported(
4783  v3_out->recommended_relay_protocols, NULL));
4784  tor_assert_nonfatal(protover_all_supported(
4785  v3_out->recommended_client_protocols, NULL));
4786 
4787  v3_out->known_flags = smartlist_new();
4790  0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4791  if (vote_on_reachability)
4792  smartlist_add_strdup(v3_out->known_flags, "Running");
4793  if (listbadexits)
4794  smartlist_add_strdup(v3_out->known_flags, "BadExit");
4796 
4797  if (d_options->ConsensusParams) {
4798  v3_out->net_params = smartlist_new();
4800  d_options->ConsensusParams, NULL, 0, 0);
4802  }
4803  v3_out->bw_file_headers = bw_file_headers;
4804  memcpy(v3_out->bw_file_digest256, bw_file_digest256, DIGEST256_LEN);
4805 
4806  voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
4807  voter->nickname = tor_strdup(options->Nickname);
4808  memcpy(voter->identity_digest, identity_digest, DIGEST_LEN);
4809  voter->sigs = smartlist_new();
4810  voter->address = hostname;
4811  tor_addr_copy(&voter->ipv4_addr, &addr);
4812  voter->ipv4_dirport = routerconf_find_dir_port(options, 0);
4813  voter->ipv4_orport = routerconf_find_or_port(options, AF_INET);
4814  voter->contact = tor_strdup(contact);
4815  if (options->V3AuthUseLegacyKey) {
4817  if (c) {
4819  log_warn(LD_BUG, "Unable to compute digest of legacy v3 identity key");
4820  memset(voter->legacy_id_digest, 0, DIGEST_LEN);
4821  }
4822  }
4823  }
4824 
4825  v3_out->voters = smartlist_new();
4826  smartlist_add(v3_out->voters, voter);
4827  v3_out->cert = authority_cert_dup(cert);
4828  v3_out->routerstatus_list = routerstatuses;
4829  /* Note: networkstatus_digest is unset; it won't get set until we actually
4830  * format the vote. */
4831 
4832  return v3_out;
4833 }
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:4268
routerinfo_t
Definition: routerinfo_st.h:20
dirvote_fetch_missing_signatures
static void dirvote_fetch_missing_signatures(void)
Definition: dirvote.c:3039
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:738
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
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
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:2999
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:3764
pending_vote_list
static smartlist_t * pending_vote_list
Definition: dirvote.c:2932
name
const char * name
Definition: config.c:2444
networkstatus_t::digests
common_digests_t digests
Definition: networkstatus_st.h:88
or_options_t::V3AuthDistDelay
int V3AuthDistDelay
Definition: or_options_st.h:710
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:1024
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:706
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:4318
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:2935
routers_sort_by_identity
void routers_sort_by_identity(smartlist_t *routers)
Definition: routerlist.c:3323
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:3118
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:4216
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:726
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:78
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:434
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_add_vote
pending_vote_t * dirvote_add_vote(const char *vote_body, time_t time_posted, const char **msg_out, int *status_out)
Definition: dirvote.c:3171
dirvote_get_pending_detached_signatures
const char * dirvote_get_pending_detached_signatures(void)
Definition: dirvote.c:3773
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:223
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:74
dirauth_options_t::ConsensusParams
STRING ConsensusParams
Definition: dirauth_options.inc:56
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:3076
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:2785
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:695
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:2925
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:2942
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:2848
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:644
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:62
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:3711
dirserv_get_bandwidth_for_router_kb
uint32_t dirserv_get_bandwidth_for_router_kb(const routerinfo_t *ri)
Definition: dirvote.c:4182
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:4399
dirlist.h
Header file for dirlist.c.
consensus_flavor_t
consensus_flavor_t
Definition: or.h:881
DIR_PURPOSE_UPLOAD_VOTE
#define DIR_PURPOSE_UPLOAD_VOTE
Definition: directory.h:46
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:4551
get_n_authorities
int get_n_authorities(dirinfo_type_t type)
Definition: dirlist.c:87
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:4358
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
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:1566
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:3931
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:194
document_signature_t
Definition: document_signature_st.h:16
or_options_t::V3AuthNIntervalsValid
int V3AuthNIntervalsValid
Definition: or_options_st.h:712
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:4231
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:48
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
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:451
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:4249
extract_shared_random_commits
static void extract_shared_random_commits(networkstatus_t *ns, const smartlist_t *tokens)
Definition: dirvote.c:4044
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:442
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:3959
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:684
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:64
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:3062
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:51
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:63
dirauth_options_t
Definition: dirauth_options.inc:13
microdesc_vote_line_t
Definition: dirvote.c:3974
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:3619
policy_summarize
char * policy_summarize(smartlist_t *policy, sa_family_t family)
Definition: policies.c:2543
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:722
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:716
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:929
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:764
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:642
rep_hist_make_router_pessimal
void rep_hist_make_router_pessimal(const char *id, time_t when)
Definition: rephist.c:355
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:887
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:2756
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:1087
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:76
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:4521
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:199
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:250
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:382
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:2827
MAX_BW_FILE_HEADERS_LINE_LEN
#define MAX_BW_FILE_HEADERS_LINE_LEN
Definition: dirvote.h:79
V3_DIRINFO
@ V3_DIRINFO
Definition: or.h:908
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:71
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:3833
dirvote_free_all
void dirvote_free_all(void)
Definition: dirvote.c:3740
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:719
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:2546
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:918
routerstatus_t::bandwidth_kb
uint32_t bandwidth_kb
Definition: routerstatus_st.h:70
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:894
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:307
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:4472
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:4532
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:4421
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
tor_parse_ulong
unsigned long tor_parse_ulong(const char *s, int base, unsigned long min, unsigned long max, int *ok, char **next)
Definition: parse_int.c:78
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:588
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:237
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:3534
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:3985
get_my_v3_legacy_signing_key
crypto_pk_t * get_my_v3_legacy_signing_key(void)
Definition: router.c:459
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:2951
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:4544
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:708
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:606
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:3787
pending_consensus_signature_list
static smartlist_t * pending_consensus_signature_list
Definition: dirvote.c:2946
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:2677
digest_to_base64
void digest_to_base64(char *d64, const char *digest)
Definition: crypto_format.c:275
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:2465
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.
tor_addr_compare_masked
int tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2, maskbits_t mbits, tor_addr_comparison_t how)
Definition: address.c:1005
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:3364
SAVED_NOWHERE
@ SAVED_NOWHERE
Definition: or.h:750
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:2738
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:3687
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:54
NS_V3_VOTE
@ NS_V3_VOTE
Definition: fmt_routerstatus.h:23
vote_microdesc_hash_st.h
Microdescriptor-hash voting strcture.
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:1461