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