69#define DIGEST_ALG_BW_FILE DIGEST_SHA256
125 const char *detached_signatures_body,
127 const char **msg_out);
133 const char **msg_out);
173format_line_if_present(
const char *keyword,
const char *opt_value)
180 return tor_strdup(
"");
189 char *recommended_relay_protocols_line = NULL;
190 char *recommended_client_protocols_line = NULL;
191 char *required_relay_protocols_line = NULL;
192 char *required_client_protocols_line = NULL;
194 recommended_relay_protocols_line =
195 format_line_if_present(
"recommended-relay-protocols",
197 recommended_client_protocols_line =
198 format_line_if_present(
"recommended-client-protocols",
199 v3_ns->recommended_client_protocols);
200 required_relay_protocols_line =
201 format_line_if_present(
"required-relay-protocols",
202 v3_ns->required_relay_protocols);
203 required_client_protocols_line =
204 format_line_if_present(
"required-client-protocols",
205 v3_ns->required_client_protocols);
209 recommended_relay_protocols_line,
210 recommended_client_protocols_line,
211 required_relay_protocols_line,
212 required_client_protocols_line);
214 tor_free(recommended_relay_protocols_line);
215 tor_free(recommended_client_protocols_line);
216 tor_free(required_relay_protocols_line);
217 tor_free(required_client_protocols_line);
232 char *protocols_lines = NULL;
233 char *client_versions_line = NULL, *server_versions_line = NULL;
234 char *shared_random_vote_str = NULL;
241 voter = smartlist_get(v3_ns->
voters, 0);
246 client_versions_line = format_line_if_present(
"client-versions",
248 server_versions_line = format_line_if_present(
"server-versions",
249 v3_ns->server_versions);
256 char published[ISO_TIME_LEN+1];
257 char va[ISO_TIME_LEN+1];
258 char fu[ISO_TIME_LEN+1];
259 char vu[ISO_TIME_LEN+1];
264 char *bw_headers_line = NULL;
265 char *bw_file_digest = NULL;
278 params = tor_strdup(
"");
284 char *bw_file_headers = NULL;
295 if (!bw_file_headers) {
297 bw_file_headers = tor_strdup(
"");
300 bw_headers_line = format_line_if_present(
"bandwidth-file-headers",
316 char *digest_algo_b64_digest_bw_file = NULL;
321 bw_file_digest = format_line_if_present(
322 "bandwidth-file-digest", digest_algo_b64_digest_bw_file);
323 tor_free(digest_algo_b64_digest_bw_file);
326 const char *ip_str =
fmt_addr(&voter->ipv4_addr);
330 "network-status-version 3\n"
332 "consensus-methods %s\n"
337 "voting-delay %d %d\n"
341 "flag-thresholds %s\n"
345 "dir-source %s %s %s %s %d %d\n"
349 v3_ns->
type == NS_TYPE_VOTE ?
"vote" :
"opinion",
351 published, va, fu, vu,
353 client_versions_line,
354 server_versions_line,
359 bw_headers_line ? bw_headers_line :
"",
360 bw_file_digest ? bw_file_digest:
"",
364 shared_random_vote_str ?
365 shared_random_vote_str :
"");
376 if (ip_str[0] ==
'\0')
393 rsf = routerstatus_format_entry(&vrs->status,
394 vrs->version, vrs->protocols,
401 for (h = vrs->microdesc; h; h = h->
next) {
404 } SMARTLIST_FOREACH_END(vrs);
410 crypto_digest_smartlist(digest,
DIGEST_LEN, chunks,
411 "directory-signature ", DIGEST_SHA1);
416 signing_key_fingerprint, 0)<0) {
417 log_warn(
LD_BUG,
"Unable to get fingerprint for signing key");
422 signing_key_fingerprint);
427 private_signing_key);
429 log_warn(
LD_BUG,
"Unable to sign networkstatus vote.");
439 if (!(v = networkstatus_parse_vote_from_string(status, strlen(status),
442 log_err(
LD_BUG,
"Generated a networkstatus %s we couldn't parse: "
444 v3_ns->
type == NS_TYPE_VOTE ?
"vote" :
"opinion", status);
447 networkstatus_vote_free(v);
460 smartlist_free(chunks);
510 num_len = strspn(cp,
"1234567890");
511 if (num_len == mlen &&
fast_memeq(mstr, cp, mlen)) {
516 cp = strstr(cp, dstr);
520 strlcpy(buf, cp,
sizeof(buf));
523 if (num_len == 0 || cp[num_len] !=
',')
540 return smartlist_get(vote->
voters, 0);
571 const char *a_id, *b_id;
573 b_id = b->is_legacy ? b_v->legacy_id_digest : b_v->identity_digest;
586 if (cur && !strcmp(cp, cur)) {
594 } SMARTLIST_FOREACH_END(cp);
601#define get_most_frequent_member(lst) \
602 smartlist_get_most_frequent_string(lst)
624#define CMP_FIELD(utype, itype, field) do { \
625 utype aval = (utype) (itype) a->field; \
626 utype bval = (utype) (itype) b->field; \
627 utype u = bval - aval; \
628 itype r2 = (itype) u; \
631 } else if (r2 > 0) { \
636 CMP_FIELD(uint64_t, int64_t, published_on);
645 CMP_FIELD(
unsigned,
int, status.ipv4_orport);
646 CMP_FIELD(
unsigned,
int, status.ipv4_dirport);
668 if ((r = (((
int) b->port) - ((
int) a->port))))
681 char *microdesc_digest256_out,
685 int most_n = 0, cur_n = 0;
686 time_t most_published = 0;
697 if (cur && (cur_n > most_n ||
699 cur->published_on > most_published))) {
707 } SMARTLIST_FOREACH_END(rs);
709 if (cur_n > most_n ||
710 (cur && cur_n == most_n && cur->published_on > most_published)) {
723 if (best_alt_orport_out) {
731 && rs->status.ipv6_orport) {
733 rs->status.ipv6_orport));
735 } SMARTLIST_FOREACH_END(rs);
738 most_alt_orport = smartlist_get_most_frequent(alt_orports,
740 if (most_alt_orport) {
742 log_debug(
LD_DIR,
"\"a\" line winner for %s is %s",
744 fmt_addrport(&most_alt_orport->addr, most_alt_orport->port));
748 smartlist_free(alt_orports);
751 if (microdesc_digest256_out) {
753 const uint8_t *best_microdesc_digest;
761 } SMARTLIST_FOREACH_END(rs);
764 if (best_microdesc_digest)
765 memcpy(microdesc_digest256_out, best_microdesc_digest,
DIGEST256_LEN);
767 smartlist_free(digests);
779 const char *a = *_a, *b = *_b;
801 int min = (smartlist_len(votes) * 2) / 3;
816 n_ok = smartlist_len(acceptable_methods);
818 const char *best = smartlist_get(acceptable_methods, n_ok-1);
824 smartlist_free(all_methods);
825 smartlist_free(acceptable_methods);
852 for (i = low; i <= high; ++i) {
871 int min = n_versioning / 2;
875 if (strchr(v,
' ')) {
876 log_warn(
LD_DIR,
"At least one authority has voted for a version %s "
877 "that contains a space. This probably wasn't intentional, and "
878 "is likely to cause trouble. Please tell them to stop it.",
881 } SMARTLIST_FOREACH_END(v);
885 smartlist_free(good);
898 unsigned int n_found = 0;
899 int32_t value = default_val;
902 if (!
strcmpstart(k_v_pair, keyword) && k_v_pair[strlen(keyword)] ==
'=') {
903 const char *integer_str = &k_v_pair[strlen(keyword)+1];
911 } SMARTLIST_FOREACH_END(k_v_pair);
916 tor_assert_nonfatal(n_found == 0);
924#define MIN_VOTES_FOR_PARAM 3
936 const char *cur_param;
939 const int n_votes = smartlist_len(votes);
949 vals = tor_calloc(n_votes,
sizeof(
int));
955 } SMARTLIST_FOREACH_END(v);
957 if (smartlist_len(param_list) == 0) {
964 cur_param = smartlist_get(param_list, 0);
965 eq = strchr(cur_param,
'=');
967 cur_param_len = (int)(eq+1 - cur_param);
975 const char *next_param;
977 eq = strchr(param,
'=');
979 vals[i++] = (int32_t)
983 if (param_sl_idx+1 == smartlist_len(param_list))
986 next_param = smartlist_get(param_list, param_sl_idx+1);
988 if (!next_param || strncmp(next_param, param, cur_param_len)) {
992 if (i > total_authorities/2 ||
994 int32_t median = median_int32(vals, i);
995 char *out_string = tor_malloc(64+cur_param_len);
996 memcpy(out_string, param, cur_param_len);
997 tor_snprintf(out_string+cur_param_len,64,
"%ld", (
long)median);
1003 eq = strchr(next_param,
'=');
1004 cur_param_len = (int)(eq+1 - next_param);
1007 } SMARTLIST_FOREACH_END(param);
1009 smartlist_free(param_list);
1014#define RANGE_CHECK(a,b,c,d,e,f,g,mx) \
1015 ((a) >= 0 && (a) <= (mx) && (b) >= 0 && (b) <= (mx) && \
1016 (c) >= 0 && (c) <= (mx) && (d) >= 0 && (d) <= (mx) && \
1017 (e) >= 0 && (e) <= (mx) && (f) >= 0 && (f) <= (mx) && \
1018 (g) >= 0 && (g) <= (mx))
1020#define CHECK_EQ(a, b, margin) \
1021 ((a)-(b) >= 0 ? (a)-(b) <= (margin) : (b)-(a) <= (margin))
1024 BW_WEIGHTS_NO_ERROR = 0,
1025 BW_WEIGHTS_RANGE_ERROR = 1,
1026 BW_WEIGHTS_SUMG_ERROR = 2,
1027 BW_WEIGHTS_SUME_ERROR = 3,
1028 BW_WEIGHTS_SUMD_ERROR = 4,
1029 BW_WEIGHTS_BALANCE_MID_ERROR = 5,
1030 BW_WEIGHTS_BALANCE_EG_ERROR = 6
1031} bw_weights_error_t;
1036static bw_weights_error_t
1038 int64_t Wme, int64_t Wmd, int64_t Wee,
1039 int64_t Wed, int64_t scale, int64_t G,
1040 int64_t M, int64_t E, int64_t D, int64_t
T,
1041 int64_t margin,
int do_balance) {
1042 bw_weights_error_t berr = BW_WEIGHTS_NO_ERROR;
1045 if (!CHECK_EQ(Wed + Wmd + Wgd, scale, margin)) {
1046 berr = BW_WEIGHTS_SUMD_ERROR;
1051 if (!CHECK_EQ(Wmg + Wgg, scale, margin)) {
1052 berr = BW_WEIGHTS_SUMG_ERROR;
1057 if (!CHECK_EQ(Wme + Wee, scale, margin)) {
1058 berr = BW_WEIGHTS_SUME_ERROR;
1063 if (!RANGE_CHECK(Wgg, Wgd, Wmg, Wme, Wmd, Wed, Wee, scale)) {
1064 berr = BW_WEIGHTS_RANGE_ERROR;
1070 if (!CHECK_EQ(Wgg*G + Wgd*D, Wee*E + Wed*D, (margin*
T)/3)) {
1071 berr = BW_WEIGHTS_BALANCE_EG_ERROR;
1076 if (!CHECK_EQ(Wgg*G + Wgd*D, M*scale + Wmd*D + Wme*E + Wmg*G,
1078 berr = BW_WEIGHTS_BALANCE_MID_ERROR;
1086 "Bw weight mismatch %d. G=%"PRId64
" M=%"PRId64
1087 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1088 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1089 " Wgd=%d Wgg=%d Wme=%d Wmg=%d",
1093 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1094 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg);
1107 int64_t M, int64_t E, int64_t D,
1108 int64_t
T, int64_t weight_scale)
1110 bw_weights_error_t berr = 0;
1111 int64_t Wgg = -1, Wgd = -1;
1112 int64_t Wmg = -1, Wme = -1, Wmd = -1;
1113 int64_t Wed = -1, Wee = -1;
1114 const char *casename;
1116 if (G <= 0 || M <= 0 || E <= 0 || D <= 0) {
1117 log_warn(
LD_DIR,
"Consensus with empty bandwidth: "
1118 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
1119 " D=%"PRId64
" T=%"PRId64,
1136 if (3*E >=
T && 3*G >=
T) {
1138 casename =
"Case 1 (Wgd=Wmd=Wed)";
1139 Wgd = weight_scale/3;
1140 Wed = weight_scale/3;
1141 Wmd = weight_scale/3;
1142 Wee = (weight_scale*(E+G+M))/(3*E);
1143 Wme = weight_scale - Wee;
1144 Wmg = (weight_scale*(2*G-E-M))/(3*G);
1145 Wgg = weight_scale - Wmg;
1148 weight_scale, G, M, E, D,
T, 10, 1);
1152 "Bw Weights error %d for %s v10. G=%"PRId64
" M=%"PRId64
1153 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1154 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1155 " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
1159 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1160 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1163 }
else if (3*E <
T && 3*G <
T) {
1164 int64_t R = MIN(E, G);
1165 int64_t S = MAX(E, G);
1178 casename =
"Case 2a (E scarce)";
1182 casename =
"Case 2a (G scarce)";
1187 casename =
"Case 2b1 (Wgg=weight_scale, Wmd=Wgd)";
1188 Wee = (weight_scale*(E - G + M))/E;
1189 Wed = (weight_scale*(D - 2*E + 4*G - 2*M))/(3*D);
1190 Wme = (weight_scale*(G-M))/E;
1193 Wmd = (weight_scale - Wed)/2;
1194 Wgd = (weight_scale - Wed)/2;
1197 weight_scale, G, M, E, D,
T, 10, 1);
1200 casename =
"Case 2b2 (Wgg=weight_scale, Wee=weight_scale)";
1203 Wed = (weight_scale*(D - 2*E + G + M))/(3*D);
1204 Wmd = (weight_scale*(D - 2*M + G + E))/(3*D);
1209 casename =
"Case 2b3 (Wmd=0)";
1212 "Too much Middle bandwidth on the network to calculate "
1213 "balanced bandwidth-weights. Consider increasing the "
1214 "number of Guard nodes by lowering the requirements.");
1216 Wgd = weight_scale - Wed - Wmd;
1218 Wed, weight_scale, G, M, E, D,
T, 10, 1);
1220 if (berr != BW_WEIGHTS_NO_ERROR &&
1221 berr != BW_WEIGHTS_BALANCE_MID_ERROR) {
1223 "Bw Weights error %d for %s v10. G=%"PRId64
" M=%"PRId64
1224 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1225 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1226 " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
1230 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1231 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1236 int64_t S = MIN(E, G);
1238 if (!(3*E <
T || 3*G <
T) || !(3*G >=
T || 3*E >=
T)) {
1240 "Bw-Weights Case 3 v10 but with G=%"PRId64
" M="
1241 "%"PRId64
" E=%"PRId64
" D=%"PRId64
" T=%"PRId64,
1248 casename =
"Case 3a (G scarce)";
1249 Wgg = Wgd = weight_scale;
1250 Wmd = Wed = Wmg = 0;
1254 else Wme = (weight_scale*(E-M))/(2*E);
1255 Wee = weight_scale-Wme;
1257 casename =
"Case 3a (E scarce)";
1258 Wee = Wed = weight_scale;
1259 Wmd = Wgd = Wme = 0;
1263 else Wmg = (weight_scale*(G-M))/(2*G);
1264 Wgg = weight_scale-Wmg;
1269 casename =
"Case 3bg (G scarce, Wgg=weight_scale, Wmd == Wed)";
1271 Wgd = (weight_scale*(D - 2*G + E + M))/(3*D);
1273 Wee = (weight_scale*(E+M))/(2*E);
1274 Wme = weight_scale - Wee;
1275 Wmd = (weight_scale - Wgd)/2;
1276 Wed = (weight_scale - Wgd)/2;
1279 Wed, weight_scale, G, M, E, D,
T, 10, 1);
1281 casename =
"Case 3be (E scarce, Wee=weight_scale, Wmd == Wgd)";
1283 Wed = (weight_scale*(D - 2*E + G + M))/(3*D);
1285 Wgg = (weight_scale*(G+M))/(2*G);
1286 Wmg = weight_scale - Wgg;
1287 Wmd = (weight_scale - Wed)/2;
1288 Wgd = (weight_scale - Wed)/2;
1291 Wed, weight_scale, G, M, E, D,
T, 10, 1);
1295 "Bw Weights error %d for %s v10. G=%"PRId64
" M=%"PRId64
1296 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1297 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1298 " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
1302 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1303 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1312 tor_assert(0 < weight_scale && weight_scale <= INT32_MAX);
1323 "bandwidth-weights Wbd=%d Wbe=%d Wbg=%d Wbm=%d "
1325 "Web=%d Wed=%d Wee=%d Weg=%d Wem=%d "
1326 "Wgb=%d Wgd=%d Wgg=%d Wgm=%d "
1327 "Wmb=%d Wmd=%d Wme=%d Wmg=%d Wmm=%d\n",
1328 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)weight_scale,
1330 (
int)weight_scale, (
int)Wed, (
int)Wee, (
int)Wed, (
int)Wee,
1331 (
int)weight_scale, (
int)Wgd, (
int)Wgg, (
int)Wgg,
1332 (
int)weight_scale, (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1334 log_notice(
LD_CIRC,
"Computed bandwidth weights for %s with v10: "
1335 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
1347 int is_exit,
int is_guard,
1348 int64_t *G, int64_t *M, int64_t *E, int64_t *D,
1352 int guardfraction_bandwidth = 0;
1355 log_info(
LD_BUG,
"Missing consensus bandwidth for router %s",
1386 guard_get_guardfraction_bandwidth(&guardfraction_bw,
1390 default_bandwidth = guardfraction_bw.
guard_bw;
1391 guardfraction_bandwidth = guardfraction_bw.
non_guard_bw;
1400 *
T += default_bandwidth;
1401 if (is_exit && is_guard) {
1403 *D += default_bandwidth;
1405 *E += guardfraction_bandwidth;
1408 }
else if (is_exit) {
1410 *E += default_bandwidth;
1412 }
else if (is_guard) {
1414 *G += default_bandwidth;
1416 *M += guardfraction_bandwidth;
1421 *M += default_bandwidth;
1433 case 0:
return vote->recommended_client_protocols;
1435 case 2:
return vote->required_client_protocols;
1436 case 3:
return vote->required_relay_protocols;
1438 tor_assert_unreached();
1450 const char *keyword;
1455 keyword =
"recommended-client-protocols";
1456 threshold = CEIL_DIV(n_voters, 2);
1459 keyword =
"recommended-relay-protocols";
1460 threshold = CEIL_DIV(n_voters, 2);
1463 keyword =
"required-client-protocols";
1464 threshold = CEIL_DIV(n_voters * 2, 3);
1467 keyword =
"required-relay-protocols";
1468 threshold = CEIL_DIV(n_voters * 2, 3);
1471 tor_assert_unreached();
1479 } SMARTLIST_FOREACH_END(ns);
1482 smartlist_free(proto_votes);
1484 char *result = NULL;
1527 int total_authorities,
1530 const char *legacy_id_key_digest,
1535 char *result = NULL;
1536 int consensus_method;
1537 time_t valid_after, fresh_until, valid_until;
1538 int vote_seconds, dist_seconds;
1539 char *client_versions = NULL, *server_versions = NULL;
1541 const char *flavor_name;
1543 int64_t G, M, E, D,
T;
1546 char *params = NULL;
1547 char *packages = NULL;
1548 int added_weights = 0;
1549 dircollator_t *collator = NULL;
1552 tor_assert(flavor == FLAV_NS || flavor == FLAV_MICRODESC);
1553 tor_assert(total_authorities >= smartlist_len(votes));
1558 if (!smartlist_len(votes)) {
1559 log_warn(
LD_DIR,
"Can't compute a consensus from no votes.");
1566 log_info(
LD_DIR,
"Generating consensus using method %d.",
1569 log_warn(
LD_DIR,
"The other authorities will use consensus method %d, "
1570 "which I don't support. Maybe I should upgrade!",
1585 int n_votes = smartlist_len(votes);
1586 time_t *va_times = tor_calloc(n_votes,
sizeof(time_t));
1587 time_t *fu_times = tor_calloc(n_votes,
sizeof(time_t));
1588 time_t *vu_times = tor_calloc(n_votes,
sizeof(time_t));
1589 int *votesec_list = tor_calloc(n_votes,
sizeof(
int));
1590 int *distsec_list = tor_calloc(n_votes,
sizeof(
int));
1591 int n_versioning_clients = 0, n_versioning_servers = 0;
1597 va_times[v_sl_idx] = v->valid_after;
1598 fu_times[v_sl_idx] = v->fresh_until;
1599 vu_times[v_sl_idx] = v->valid_until;
1600 votesec_list[v_sl_idx] = v->vote_seconds;
1601 distsec_list[v_sl_idx] = v->dist_seconds;
1602 if (v->client_versions) {
1604 ++n_versioning_clients;
1606 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1611 if (v->server_versions) {
1613 ++n_versioning_servers;
1615 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1622 } SMARTLIST_FOREACH_END(v);
1623 valid_after = median_time(va_times, n_votes);
1624 fresh_until = median_time(fu_times, n_votes);
1625 valid_until = median_time(vu_times, n_votes);
1626 vote_seconds = median_int(votesec_list, n_votes);
1627 dist_seconds = median_int(distsec_list, n_votes);
1639 n_versioning_servers);
1641 n_versioning_clients);
1644 packages = tor_strdup(
"");
1650 smartlist_free(combined_server_versions);
1651 smartlist_free(combined_client_versions);
1665 const bool badexit_flag_is_listed =
1671 char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
1672 vu_buf[ISO_TIME_LEN+1];
1680 "vote-status consensus\n",
1681 flavor == FLAV_NS ?
"" :
" ",
1682 flavor == FLAV_NS ?
"" : flavor_name);
1691 "voting-delay %d %d\n"
1692 "client-versions %s\n"
1693 "server-versions %s\n"
1696 va_buf, fu_buf, vu_buf,
1697 vote_seconds, dist_seconds,
1698 client_versions, server_versions,
1708 for (idx = 0; idx < 4; ++idx) {
1710 if (BUG(!proto_line))
1718 if (smartlist_len(param_list)) {
1730 int32_t num_srv_agreements =
1732 "AuthDirNumSRVAgreements",
1733 (num_dirauth * 2) / 3);
1736 if (srv_lines != NULL) {
1756 e_legacy->is_legacy = 1;
1759 } SMARTLIST_FOREACH_END(v);
1773 "dir-source %s%s %s %s %s %d %d\n",
1774 voter->
nickname, e->is_legacy ?
"-legacy" :
"",
1778 if (! e->is_legacy) {
1785 } SMARTLIST_FOREACH_END(e);
1787 smartlist_free(dir_sources);
1793 if (max_unmeasured_bw_kb < 1)
1794 max_unmeasured_bw_kb = 1;
1808 uint32_t *bandwidths_kb = tor_calloc(smartlist_len(votes),
1810 uint32_t *measured_bws_kb = tor_calloc(smartlist_len(votes),
1812 uint32_t *measured_guardfraction = tor_calloc(smartlist_len(votes),
1816 int num_guardfraction_inputs;
1826 int n_authorities_measuring_bandwidth;
1828 strmap_t *name_to_id_map = strmap_new();
1831 memset(conflict, 0,
sizeof(conflict));
1832 memset(unknown, 0xff,
sizeof(conflict));
1834 size = tor_calloc(smartlist_len(votes),
sizeof(
int));
1835 n_voter_flags = tor_calloc(smartlist_len(votes),
sizeof(
int));
1836 n_flag_voters = tor_calloc(smartlist_len(flags),
sizeof(
int));
1837 flag_map = tor_calloc(smartlist_len(votes),
sizeof(
int *));
1838 named_flag = tor_calloc(smartlist_len(votes),
sizeof(
int));
1839 unnamed_flag = tor_calloc(smartlist_len(votes),
sizeof(
int));
1840 for (i = 0; i < smartlist_len(votes); ++i)
1841 unnamed_flag[i] = named_flag[i] = -1;
1850 flag_map[v_sl_idx] = tor_calloc(smartlist_len(v->known_flags),
1853 log_warn(
LD_BUG,
"Somehow, a vote has %d entries in known_flags",
1854 smartlist_len(v->known_flags));
1859 flag_map[v_sl_idx][fl_sl_idx] = p;
1861 if (!strcmp(fl,
"Named"))
1862 named_flag[v_sl_idx] = fl_sl_idx;
1863 if (!strcmp(fl,
"Unnamed"))
1864 unnamed_flag[v_sl_idx] = fl_sl_idx;
1865 } SMARTLIST_FOREACH_END(fl);
1866 n_voter_flags[v_sl_idx] = smartlist_len(v->known_flags);
1867 size[v_sl_idx] = smartlist_len(v->routerstatus_list);
1868 } SMARTLIST_FOREACH_END(v);
1874 if (named_flag[v_sl_idx]<0)
1876 nf = UINT64_C(1) << named_flag[v_sl_idx];
1880 if ((rs->flags & nf) != 0) {
1881 const char *d =
strmap_get_lc(name_to_id_map, rs->status.nickname);
1885 rs->status.identity_digest);
1886 }
else if (d != conflict &&
1889 strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
1894 } SMARTLIST_FOREACH_END(rs);
1895 } SMARTLIST_FOREACH_END(v);
1899 if (unnamed_flag[v_sl_idx]<0)
1901 uf = UINT64_C(1) << unnamed_flag[v_sl_idx];
1904 if ((rs->flags & uf) != 0) {
1905 const char *d =
strmap_get_lc(name_to_id_map, rs->status.nickname);
1906 if (d == conflict || d == unknown) {
1910 strmap_set_lc(name_to_id_map, rs->status.nickname, unknown);
1913 strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
1918 } SMARTLIST_FOREACH_END(rs);
1919 } SMARTLIST_FOREACH_END(v);
1923 n_authorities_measuring_bandwidth = 0;
1925 if (v->has_measured_bws) {
1926 ++n_authorities_measuring_bandwidth;
1934 } SMARTLIST_FOREACH_END(v);
1939 flag_counts = tor_calloc(smartlist_len(flags),
sizeof(
int));
1941 for (i = 0; i < num_routers; ++i) {
1947 const char *current_rsa_id = NULL;
1948 const char *chosen_version;
1949 const char *chosen_protocol_list;
1950 const char *chosen_name = NULL;
1951 int exitsummary_disagreement = 0;
1952 int is_named = 0, is_unnamed = 0, is_running = 0, is_valid = 0;
1953 int is_guard = 0, is_exit = 0, is_bad_exit = 0, is_middle_only = 0;
1954 int naming_conflict = 0;
1959 memset(flag_counts, 0,
sizeof(
int)*smartlist_len(flags));
1966 num_guardfraction_inputs = 0;
1967 int ed_consensus = 0;
1968 const uint8_t *ed_consensus_val = NULL;
1971 for (
int voter_idx = 0; voter_idx < smartlist_len(votes); ++voter_idx) {
1972 if (vrs_lst[voter_idx] == NULL)
1974 rs = vrs_lst[voter_idx];
1990 for (
int flag = 0; flag < n_voter_flags[voter_idx]; ++flag) {
1991 if (rs->
flags & (UINT64_C(1) << flag))
1992 ++flag_counts[flag_map[voter_idx][flag]];
1994 if (named_flag[voter_idx] >= 0 &&
1995 (rs->
flags & (UINT64_C(1) << named_flag[voter_idx]))) {
1997 log_notice(
LD_DIR,
"Conflict on naming for router: %s vs %s",
1999 naming_conflict = 1;
2006 measured_guardfraction[num_guardfraction_inputs++] =
2020 if (ed_consensus_val) {
2031 if (n_listing <= total_authorities/2)
2034 if (ed_consensus > 0) {
2035 if (ed_consensus <= total_authorities / 2) {
2036 log_warn(
LD_BUG,
"Not enough entries had ed_consensus set; how "
2037 "can we have a consensus of %d?", ed_consensus);
2047 memset(microdesc_digest, 0,
sizeof(microdesc_digest));
2049 microdesc_digest, &alt_orport);
2051 memset(&rs_out, 0,
sizeof(rs_out));
2076 flavor == FLAV_MICRODESC) {
2080 if (chosen_name && !naming_conflict) {
2089 is_named = is_unnamed = 0;
2091 is_named = 1; is_unnamed = 0;
2093 is_named = 0; is_unnamed = 1;
2099 if (!strcmp(fl,
"Named")) {
2102 }
else if (!strcmp(fl,
"Unnamed")) {
2105 }
else if (!strcmp(fl,
"NoEdConsensus")) {
2106 if (ed_consensus <= total_authorities/2)
2109 if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2) {
2111 if (!strcmp(fl,
"Exit"))
2113 else if (!strcmp(fl,
"Guard"))
2115 else if (!strcmp(fl,
"Running"))
2117 else if (!strcmp(fl,
"BadExit"))
2119 else if (!strcmp(fl,
"MiddleOnly"))
2121 else if (!strcmp(fl,
"Valid"))
2125 } SMARTLIST_FOREACH_END(fl);
2140 if (is_middle_only) {
2145 is_exit = is_guard = 0;
2146 if (! is_bad_exit && badexit_flag_is_listed) {
2154 if (smartlist_len(versions)) {
2158 chosen_version = NULL;
2162 if (smartlist_len(protocols)) {
2166 chosen_protocol_list = NULL;
2171 if (is_guard && num_guardfraction_inputs > 2) {
2174 num_guardfraction_inputs);
2183 rs_out.
bandwidth_kb = median_uint32(measured_bws_kb, num_mbws);
2184 }
else if (num_bandwidths > 0) {
2187 rs_out.
bandwidth_kb = median_uint32(bandwidths_kb, num_bandwidths);
2188 if (n_authorities_measuring_bandwidth > 2) {
2197 is_exit = is_exit && !is_bad_exit;
2203 &G, &M, &E, &D, &
T);
2223 const char *chosen_exitsummary = NULL;
2229 vsr->status.identity_digest,
2231 if (vsr->status.has_exitsummary &&
2233 vsr->status.descriptor_digest,
2237 if (!chosen_exitsummary) {
2238 chosen_exitsummary = vsr->status.exitsummary;
2239 }
else if (strcmp(chosen_exitsummary, vsr->status.exitsummary)) {
2242 exitsummary_disagreement = 1;
2245 } SMARTLIST_FOREACH_END(vsr);
2247 if (exitsummary_disagreement) {
2252 log_warn(
LD_DIR,
"The voters disagreed on the exit policy summary "
2253 " for router %s with descriptor %s. This really shouldn't"
2254 " have happened.",
id, dd);
2258 }
else if (!chosen_exitsummary) {
2263 log_warn(
LD_DIR,
"Not one of the voters that made us select"
2264 "descriptor %s for router %s had an exit policy"
2272 if (vsr->status.has_exitsummary)
2278 if (!chosen_exitsummary)
2279 log_warn(
LD_DIR,
"Wow, not one of the voters had an exit "
2280 "policy summary for %s. Wow.",
id);
2283 if (chosen_exitsummary) {
2290 if (flavor == FLAV_MICRODESC &&
2300 buf = routerstatus_format_entry(&rs_out, NULL, NULL,
2301 rs_format, NULL, published_on);
2306 if (flavor == FLAV_MICRODESC &&
2314 smartlist_len(chosen_flags)?
" ":
"");
2318 if (chosen_version) {
2323 if (chosen_protocol_list) {
2328 char *guardfraction_str = NULL;
2338 unmeasured?
" Unmeasured=1":
"",
2339 guardfraction_str ? guardfraction_str :
"");
2355 for (i = 0; i < smartlist_len(votes); ++i)
2361 strmap_free(name_to_id_map, NULL);
2362 smartlist_free(matching_descs);
2363 smartlist_free(chosen_flags);
2364 smartlist_free(versions);
2365 smartlist_free(protocols);
2366 smartlist_free(exitsummaries);
2376 int64_t weight_scale;
2379 if (weight_scale < 1)
2391 char *filename = NULL;
2392 tor_asprintf(&filename,
"my-consensus-%s", flavor_name);
2393 char *fpath = get_datadir_fname(filename);
2394 write_str_to_file(fpath, unsigned_consensus, 0);
2406 flavor == FLAV_NS ? DIGEST_SHA1 : DIGEST_SHA256;
2415 crypto_digest_smartlist(digest, digest_len, chunks,
"", digest_alg);
2422 if (flavor == FLAV_NS) {
2424 signing_key_fingerprint);
2427 algname, fingerprint,
2428 signing_key_fingerprint);
2433 log_warn(
LD_BUG,
"Couldn't sign consensus networkstatus.");
2443 signing_key_fingerprint, 0);
2444 if (flavor == FLAV_NS) {
2446 signing_key_fingerprint);
2449 algname, fingerprint,
2450 signing_key_fingerprint);
2455 log_warn(
LD_BUG,
"Couldn't sign consensus networkstatus.");
2466 if (!(c = networkstatus_parse_vote_from_string(result, strlen(result),
2468 NS_TYPE_CONSENSUS))) {
2469 log_err(
LD_BUG,
"Generated a networkstatus consensus we couldn't "
2475 if (added_weights) {
2476 networkstatus_verify_bw_weights(c, consensus_method);
2478 networkstatus_vote_free(c);
2483 dircollator_free(collator);
2488 smartlist_free(flags);
2490 smartlist_free(chunks);
2492 smartlist_free(param_list);
2502 const int n_votes = smartlist_len(votes);
2508 strmap_t *package_status = strmap_new();
2511 if (! v->package_lines)
2518 const char *cp = strchr(line,
' ');
2521 cp = strchr(cp,
' ');
2524 char *key = tor_strndup(line, cp - line);
2526 const char **status = strmap_get(package_status, key);
2528 status = tor_calloc(n_votes,
sizeof(
const char *));
2529 strmap_set(package_status, key, status);
2531 status[v_sl_idx] = line;
2533 } SMARTLIST_FOREACH_END(line);
2534 } SMARTLIST_FOREACH_END(v);
2538 STRMAP_FOREACH(package_status, key,
const char **, values) {
2540 for (i = 0; i < n_votes; ++i) {
2545 int n_voting_for_entry = smartlist_len(entries);
2546 const char *most_frequent =
2549 if (n_voting_for_entry >= 3 && count > n_voting_for_entry / 2) {
2555 } STRMAP_FOREACH_END;
2562 smartlist_free(result_list);
2563 smartlist_free(entries);
2585 const char **msg_out)
2598 *msg_out =
"Valid-After times do not match "
2599 "when adding detached signatures to consensus";
2603 *msg_out =
"Fresh-until times do not match "
2604 "when adding detached signatures to consensus";
2608 *msg_out =
"Valid-until times do not match "
2609 "when adding detached signatures to consensus";
2612 siglist = strmap_get(sigs->
signatures, flavor);
2614 *msg_out =
"No signatures for given consensus flavor";
2624 *msg_out =
"No digests for given consensus flavor";
2633 *msg_out =
"Mismatched digest.";
2639 *msg_out =
"No recognized digests for given consensus flavor";
2649 const char *algorithm;
2656 log_info(
LD_DIR,
"Looking at signature from %s using %s", voter_identity,
2659 if (!target_voter) {
2660 log_info(
LD_DIR,
"We do not know any voter with ID %s", voter_identity);
2669 log_info(
LD_DIR,
"We already have a good signature from %s using %s",
2670 voter_identity, algorithm);
2675 if (!sig->good_signature && !sig->bad_signature) {
2677 sig->signing_key_digest);
2687 if (sig->good_signature || !old_sig || old_sig->
bad_signature) {
2688 log_info(
LD_DIR,
"Adding signature from %s with %s", voter_identity,
2690 tor_log(severity,
LD_DIR,
"Added a signature for %s from %s.",
2695 document_signature_free(old_sig);
2699 log_info(
LD_DIR,
"Not adding signature from %s", voter_identity);
2701 } SMARTLIST_FOREACH_END(sig);
2713 int for_detached_signatures)
2717 char *result = NULL;
2721 const char *keyword;
2723 if (for_detached_signatures && flavor != FLAV_NS)
2724 keyword =
"additional-signature";
2726 keyword =
"directory-signature";
2734 if (!sig->signature || sig->bad_signature)
2739 if (flavor == FLAV_NS) {
2741 "%s %s %s\n-----BEGIN SIGNATURE-----\n",
2744 const char *digest_name =
2747 "%s%s%s %s %s %s\n-----BEGIN SIGNATURE-----\n",
2749 for_detached_signatures ?
" " :
"",
2750 for_detached_signatures ? flavor_name :
"",
2751 digest_name,
id, sk);
2753 base64_encode(buf,
sizeof(buf), sig->signature, sig->signature_len,
2754 BASE64_ENCODE_MULTILINE);
2755 strlcat(buf,
"-----END SIGNATURE-----\n",
sizeof(buf));
2757 } SMARTLIST_FOREACH_END(sig);
2758 } SMARTLIST_FOREACH_END(v);
2762 smartlist_free(elements);
2776 char *result = NULL, *sigs = NULL;
2783 if (ns && ns->flavor == FLAV_NS)
2786 if (!consensus_ns) {
2787 log_warn(
LD_BUG,
"No NS consensus given.");
2794 char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
2795 vu_buf[ISO_TIME_LEN+1];
2805 "consensus-digest %s\n"
2808 "valid-until %s\n", d, va_buf, fu_buf, vu_buf);
2815 if (ns->flavor == FLAV_NS)
2822 const char *alg_name =
2828 flavor_name, alg_name, d);
2830 } SMARTLIST_FOREACH_END(ns);
2834 char *sigs_on_this_consensus;
2835 if (ns->flavor == FLAV_NS)
2838 if (!sigs_on_this_consensus) {
2839 log_warn(
LD_DIR,
"Couldn't format signatures");
2843 } SMARTLIST_FOREACH_END(ns);
2854 smartlist_free(elements);
2868 for (flav = 0; flav < n_flavors; ++flav) {
2869 if (pending[flav].consensus)
2885 if (!authdir_mode_v3(options))
2887 tor_assert_nonfatal(voting_schedule.voting_starts);
2893 if (voting_schedule.created_on_demand) {
2896 log_notice(
LD_DIR,
"Scheduling voting. Known authority IDs are %s. "
2900 dirauth_sched_recalculate_timing(options, now);
2903#define IF_TIME_FOR_NEXT_ACTION(when_field, done_field) \
2904 if (! voting_schedule.done_field) { \
2905 if (voting_schedule.when_field > now) { \
2906 return voting_schedule.when_field; \
2912 IF_TIME_FOR_NEXT_ACTION(voting_starts, have_voted) {
2913 log_notice(
LD_DIR,
"Time to vote.");
2915 voting_schedule.have_voted = 1;
2917 IF_TIME_FOR_NEXT_ACTION(fetch_missing_votes, have_fetched_missing_votes) {
2918 log_notice(
LD_DIR,
"Time to fetch any votes that we're missing.");
2920 voting_schedule.have_fetched_missing_votes = 1;
2922 IF_TIME_FOR_NEXT_ACTION(voting_ends, have_built_consensus) {
2923 log_notice(
LD_DIR,
"Time to compute a consensus.");
2927 voting_schedule.have_built_consensus = 1;
2929 IF_TIME_FOR_NEXT_ACTION(fetch_missing_signatures,
2930 have_fetched_missing_signatures) {
2931 log_notice(
LD_DIR,
"Time to fetch any signatures that we're missing.");
2933 voting_schedule.have_fetched_missing_signatures = 1;
2935 IF_TIME_FOR_NEXT_ACTION(interval_starts,
2936 have_published_consensus) {
2937 log_notice(
LD_DIR,
"Time to publish the consensus and discard old votes");
2940 voting_schedule.have_published_consensus = 1;
2946 dirauth_sched_recalculate_timing(options, now);
2947 return voting_schedule.voting_starts;
2954#undef IF_TIME_FOR_NEXT_ACTION
2993 time_t now = time(NULL);
2996 const char *msg =
"";
2998 if (!cert || !key) {
2999 log_warn(
LD_NET,
"Didn't find key/certificate to generate v3 vote");
3001 }
else if (cert->
expires < now) {
3002 log_warn(
LD_NET,
"Can't generate v3 vote with expired certificate");
3009 networkstatus_vote_free(ns);
3015 if (!pending_vote) {
3016 log_warn(
LD_DIR,
"Couldn't store my own vote! (I told myself, '%s'.)",
3024 pending_vote->vote_body->
dir,
3025 pending_vote->vote_body->
dir_len, 0);
3026 log_notice(
LD_DIR,
"Vote posted.");
3044 DGV_BY_ID|DGV_INCLUDE_PENDING)) {
3050 } SMARTLIST_FOREACH_END(ds);
3052 if (!smartlist_len(missing_fps)) {
3053 smartlist_free(missing_fps);
3058 log_notice(
LOG_NOTICE,
"We're missing votes from %d authorities (%s). "
3059 "Asking every other authority for a copy.",
3060 smartlist_len(missing_fps), tmp);
3068 smartlist_free(missing_fps);
3121 v->vote_body = NULL;
3122 networkstatus_vote_free(v->vote);
3131 v->vote_body = NULL;
3132 networkstatus_vote_free(v->vote);
3165 smartlist_free(known_v3_keys);
3174 int any_sig_good = 0;
3176 if (sig->good_signature)
3191 TRUSTED_DIRS_CERTS_SRC_FROM_VOTE, 1 ,
3195 log_warn(
LD_BUG,
"We added a cert, but still couldn't find it.");
3207 const char *where_from,
3208 const char **msg_out,
int *status_out)
3214 const char *end_of_vote = NULL;
3226 vote = networkstatus_parse_vote_from_string(vote_body, strlen(vote_body),
3230 end_of_vote = vote_body + strlen(vote_body);
3232 log_warn(
LD_DIR,
"Couldn't parse vote: length was %d",
3233 (
int)strlen(vote_body));
3234 *msg_out =
"Unable to parse vote";
3239 assert_any_sig_good(vi);
3243 log_warn(
LD_DIR,
"Got a vote from an authority (nickname %s, address %s) "
3244 "with authority key ID %s. "
3245 "This key ID is not recognized. Known v3 key IDs are: %s",
3249 *msg_out =
"Vote not from a recognized v3 authority";
3252 add_new_cert_if_needed(vote->
cert);
3255 if (vote->
valid_after != voting_schedule.interval_starts) {
3256 char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1];
3259 log_warn(
LD_DIR,
"Rejecting vote from %s with valid-after time of %s; "
3260 "we were expecting %s", vi->
address, tbuf1, tbuf2);
3261 *msg_out =
"Bad valid-after time";
3266 log_notice(
LD_DIR,
"%s posted a vote to me from %s.",
3269 log_notice(
LD_DIR,
"Retrieved %s's vote from %s.",
3278 if (time_posted && time_posted > voting_schedule.fetch_missing_votes) {
3279 char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1];
3282 log_warn(
LD_DIR,
"Rejecting %s's posted vote from %s received at %s; "
3283 "our cutoff for received votes is %s. Check your clock, "
3284 "CPU load, and network load. Also check the authority that "
3286 *msg_out =
"Posted vote received too late, would be dangerous to count it";
3295 if (
fast_memeq(v->vote->cert->cache_info.identity_digest,
3301 log_notice(
LD_DIR,
"Discarding a vote we already have (from %s).",
3303 if (*status_out < 200)
3306 }
else if (v->vote->published < vote->
published) {
3307 log_notice(
LD_DIR,
"Replacing an older pending vote from this "
3308 "directory (%s)", vi->
address);
3310 networkstatus_vote_free(v->vote);
3312 end_of_vote-vote_body),
3316 !
strcmpstart(end_of_vote,
"network-status-version"))
3319 if (*status_out < 200)
3325 log_notice(
LD_DIR,
"Discarding vote from %s because we have "
3326 "a newer one already.", vi->
address);
3327 *msg_out =
"Already have a newer pending vote";
3331 } SMARTLIST_FOREACH_END(v);
3339 end_of_vote-vote_body),
3341 pending_vote->vote = vote;
3344 if (!
strcmpstart(end_of_vote,
"network-status-version ")) {
3345 vote_body = end_of_vote;
3354 *msg_out =
"Error adding vote";
3355 if (*status_out < 400)
3359 networkstatus_vote_free(vote);
3361 if (end_of_vote && !
strcmpstart(end_of_vote,
"network-status-version ")) {
3362 vote_body = end_of_vote;
3368 if (*status_out < 200)
3371 if (!any_failed && !pending_vote) {
3372 *msg_out =
"Duplicate discarded";
3378 return any_failed ? NULL : pending_vote;
3383write_v3_votes_to_disk(
const smartlist_t *pending_votes)
3386 char *votefile = NULL;
3391 c->bytes = v->vote_body->dir;
3392 c->len = v->vote_body->dir_len;
3396 votefile = get_datadir_fname(
"v3-status-votes");
3397 write_chunks_to_file(votefile, votestrings, 0, 0);
3398 log_debug(
LD_DIR,
"Wrote votes to disk (%s)!", votefile);
3402 smartlist_free(votestrings);
3413 int n_votes, n_voters, n_vote_running = 0;
3415 char *consensus_body = NULL, *signatures = NULL;
3421 memset(pending, 0,
sizeof(pending));
3439 if (n_votes <= n_voters/2) {
3440 log_warn(
LD_DIR,
"We don't have enough votes to generate a consensus: "
3441 "%d of %d", n_votes, n_voters/2+1);
3449 if (!n_vote_running) {
3451 log_warn(
LD_DIR,
"Nobody has voted on the Running flag. Generating "
3452 "and publishing a consensus without Running nodes "
3453 "would make many clients stop working. Not "
3454 "generating a consensus!");
3459 log_warn(
LD_DIR,
"Can't generate consensus without a certificate.");
3466 char *legacy_id_digest = NULL;
3467 int n_generated = 0;
3474 "Unable to compute digest of legacy v3 identity key");
3476 legacy_id_digest = legacy_dbuf;
3489 if (!consensus_body) {
3490 log_warn(
LD_DIR,
"Couldn't generate a %s consensus at all!",
3494 consensus = networkstatus_parse_vote_from_string(consensus_body,
3495 strlen(consensus_body),
3499 log_warn(
LD_DIR,
"Couldn't parse %s consensus we generated!",
3508 pending[flav].
body = consensus_body;
3512 consensus_body = NULL;
3516 log_warn(
LD_DIR,
"Couldn't generate any consensus flavors at all.");
3525 log_warn(
LD_DIR,
"Couldn't extract signatures.");
3530 memcpy(pending_consensuses, pending,
sizeof(pending));
3540 const char *msg = NULL;
3547 "Could not add queued signature to new consensus: %s",
3550 } SMARTLIST_FOREACH_END(sig);
3552 log_notice(
LD_DIR,
"Added %d pending signatures while building "
3553 "consensus.", n_sigs);
3557 log_notice(
LD_DIR,
"Consensus computed; uploading signature(s)");
3564 log_notice(
LD_DIR,
"Signature(s) posted.");
3566 smartlist_free(votes);
3569 smartlist_free(votes);
3572 networkstatus_vote_free(consensus);
3587 char *filename = NULL;
3588 tor_asprintf(&filename,
"my-consensus-%s", flavor_name);
3589 char *fpath_from = get_datadir_fname(filename);
3591 tor_asprintf(&filename,
"consensus-transparency-%s", flavor_name);
3592 char *fpath_to = get_datadir_fname(filename);
3595 replace_file(fpath_from, fpath_to);
3597 log_notice(
LD_DIR,
"Exported consensus transparency file %s.",
3613 const char **msg_out)
3615 const char *flavor_name;
3628 log_info(
LD_DIR,
"Have %d signatures for adding to %s consensus.",
3629 sig_list ? smartlist_len(sig_list) : 0, flavor_name);
3632 source, severity, msg_out);
3634 log_info(
LD_DIR,
"Added %d signatures to consensus.", r);
3637 "Unable to add signatures to consensus: %s",
3638 *msg_out ? *msg_out :
"(unknown)");
3642 char *new_signatures =
3644 char *dst, *dst_end;
3645 size_t new_consensus_len;
3646 if (!new_signatures) {
3647 *msg_out =
"No signatures to add";
3651 strlen(pc->
body) + strlen(new_signatures) + 1;
3652 pc->
body = tor_realloc(pc->
body, new_consensus_len);
3653 dst_end = pc->
body + new_consensus_len;
3656 strlcpy(dst, new_signatures, dst_end-dst);
3666 networkstatus_vote_free(v);
3668 *msg_out =
"Signatures added";
3680 }
else if (r == 0) {
3681 *msg_out =
"Signatures ignored";
3689 *msg_out =
"Unrecognized error while adding detached signatures.";
3704 const char *detached_signatures_body,
3706 const char **msg_out)
3708 int r=0, i, n_added = 0, errors = 0;
3714 if (!(sigs = networkstatus_parse_detached_signatures(
3715 detached_signatures_body, NULL))) {
3716 *msg_out =
"Couldn't parse detached signatures.";
3734 if (errors && !n_added) {
3739 if (n_added && pending_consensuses[FLAV_NS].consensus) {
3740 char *new_detached =
3753 *msg_out =
"Unrecognized error while adding detached signatures.";
3755 ns_detached_signatures_free(sigs);
3775 if (pending_consensuses[FLAV_NS].consensus) {
3776 log_notice(
LD_DIR,
"Got a signature from %s. "
3777 "Adding it to the pending consensus.", source);
3779 detached_signatures_body, source, msg);
3781 log_notice(
LD_DIR,
"Got a signature from %s. "
3782 "Queuing it for the next consensus.", source);
3786 detached_signatures_body);
3787 *msg =
"Signature queued";
3807 log_warn(
LD_DIR,
"Not enough info to publish pending %s consensus",
name);
3812 strlen(pending->
body),
3814 log_warn(
LD_DIR,
"Error publishing %s consensus",
name);
3816 log_notice(
LD_DIR,
"Published %s consensus",
name);
3851 return pending_consensuses[flav].
body;
3873 int by_id = flags & DGV_BY_ID;
3874 const int include_pending = flags & DGV_INCLUDE_PENDING;
3875 const int include_previous = flags & DGV_INCLUDE_PREVIOUS;
3891 return pv->vote_body);
3896 return pv->vote_body);
3902 return pv->vote_body);
3907 return pv->vote_body);
3919 (void) consensus_method;
3921 char *key = NULL, *summary = NULL, *family = NULL;
3924 char *output = NULL;
3932 key = tor_strdup(
"");
3964 if (summary && strcmp(summary,
"reject 1-65535"))
3972 if (p6 && strcmp(p6,
"reject 1-65535"))
3979 const char *keytype;
3982 keytype =
"ed25519";
3986 keytype =
"rsa1024";
3996 output+strlen(output), 0,
3998 if (smartlist_len(lst) != 1) {
3999 log_warn(
LD_DIR,
"We generated a microdescriptor we couldn't parse.");
4001 smartlist_free(lst);
4004 result = smartlist_get(lst, 0);
4005 smartlist_free(lst);
4009 crypto_pk_free(rsa_pubkey);
4016 smartlist_free(chunks);
4028 int consensus_method_low,
4029 int consensus_method_high)
4033 char *microdesc_consensus_methods =
4035 consensus_method_high,
4041 if (
tor_snprintf(out_buf, out_buf_len,
"m %s sha256=%s\n",
4042 microdesc_consensus_methods, d64)<0)
4045 ret = strlen(out_buf);
4048 tor_free(microdesc_consensus_methods);
4057} microdesc_consensus_methods[] = {
4088 for (cmr = microdesc_consensus_methods;
4089 cmr->low != -1 && cmr->high != -1;
4100 e->high = cmr->high;
4107 for (ep = entries; ep; ep = ep->next) {
4110 ep->low == ep->next->high + 1) {
4112 ep->low = next->low;
4113 microdesc_free(next->md);
4114 ep->next = next->next;
4120 while ((ep = entries)) {
4124 ep->low, ep->high) >= 0) {
4129 ep->md->last_listed = now;
4156 if (commits == NULL) {
4166 for (
int i = 0; i < tok->n_args; i++) {
4171 if (commit == NULL) {
4176 log_warn(
LD_DIR,
"SR: Unable to parse commit %s from vote of voter %s.",
4186 } SMARTLIST_FOREACH_END(tok);
4189 smartlist_free(chunks);
4190 smartlist_free(commits);
4218 smartlist_free(ns->
sr_info.commits);
4226dirvote_dirreq_get_status_vote(
const char *url,
smartlist_t *items,
4231 url += strlen(
"/tor/status-vote/");
4233 url = strchr(url,
'/');
4236 if (!strcmp(url,
"consensus")) {
4242 }
else if (!current && !strcmp(url,
"consensus-signatures")) {
4249 }
else if (!strcmp(url,
"authority")) {
4251 int flags = DGV_BY_ID |
4252 (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
4261 flags = DGV_INCLUDE_PENDING | DGV_INCLUDE_PREVIOUS;
4264 (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
4267 DSR_HEX|DSR_SORT_UNIQ);
4273 smartlist_free(fps);
4299 bw_kb = (uint32_t)mbw_kb;
4333 if (comparison == 0) {
4352 if (comparison == 0)
4368 int first_is_auth, second_is_auth;
4369 const node_t *node_first, *node_second;
4370 int first_is_running, second_is_running;
4371 uint32_t bw_kb_first, bw_kb_second;
4380 if (first_is_auth && !second_is_auth)
4382 else if (!first_is_auth && second_is_auth)
4387 first_is_running = node_first && node_first->
is_running;
4388 second_is_running = node_second && node_second->
is_running;
4389 if (first_is_running && !second_is_running)
4391 else if (!first_is_running && second_is_running)
4397 if (bw_kb_first > bw_kb_second)
4399 else if (bw_kb_first < bw_kb_second)
4418 digestmap_t *omit_as_sybil = digestmap_new();
4424 if (max_with_same_addr <= 0)
4425 max_with_same_addr = INT_MAX;
4428 if (family == AF_INET6)
4438 addrs_equal =
false;
4440 if (! addrs_equal) {
4443 }
else if (++addr_count > max_with_same_addr) {
4444 digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4446 } SMARTLIST_FOREACH_END(ri);
4447 smartlist_free(routers_by_ip);
4448 return omit_as_sybil;
4460 digestmap_t *omit_as_sybil_ipv4;
4461 digestmap_t *omit_as_sybil_ipv6;
4462 digestmap_t *omit_as_sybil = digestmap_new();
4473 } SMARTLIST_FOREACH_END(ri);
4479 digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4482 digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4485 smartlist_free(routers_ipv4);
4486 smartlist_free(routers_ipv6);
4487 digestmap_free(omit_as_sybil_ipv4, NULL);
4488 digestmap_free(omit_as_sybil_ipv6, NULL);
4490 return omit_as_sybil;
4507 return tor_strndup(platform, eos-platform);
4524 for ( ; ln; ln = ln->next) {
4526 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4533 if (strchr(v,
' ')) {
4535 log_warn(
LD_DIRSERV,
"Unexpected space in versions list member %s. "
4536 "(These are supposed to be comma-separated; I'll pretend you "
4537 "used commas instead.)",
escaped(v));
4540 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4543 } SMARTLIST_FOREACH_END(v);
4545 smartlist_free(more_versions);
4552 log_warn(
LD_DIRSERV,
"Recommended version %s does not look valid. "
4553 " (I'll include it anyway, since you told me to.)",
4556 } SMARTLIST_FOREACH_END(v);
4562 smartlist_free(versions);
4573 digest256map_t *by_ed_key = digest256map_new();
4576 ri->omit_from_vote = 0;
4577 if (ri->cache_info.signing_key_cert == NULL)
4579 const uint8_t *pk = ri->cache_info.signing_key_cert->signing_key.pubkey;
4580 if ((ri2 = digest256map_get(by_ed_key, pk))) {
4583 const time_t ri_pub = ri->cache_info.published_on;
4585 if (ri2_pub < ri_pub ||
4586 (ri2_pub == ri_pub &&
4587 fast_memcmp(ri->cache_info.signed_descriptor_digest,
4589 digest256map_set(by_ed_key, pk, ri);
4592 ri->omit_from_vote = 1;
4596 digest256map_set(by_ed_key, pk, ri);
4598 } SMARTLIST_FOREACH_END(ri);
4600 digest256map_free(by_ed_key, NULL);
4604 if (ri->omit_from_vote) {
4607 } SMARTLIST_FOREACH_END(ri);
4662 char *hostname = NULL, *client_versions = NULL, *server_versions = NULL;
4663 const char *contact;
4670 time_t now = time(NULL);
4683 log_err(
LD_BUG,
"Error computing signing key digest");
4687 log_err(
LD_BUG,
"Error computing identity key digest");
4691 log_warn(
LD_NET,
"Couldn't resolve my hostname");
4694 if (!hostname || !strchr(hostname,
'.')) {
4700 log_err(
LD_BUG,
"Failed to determine hostname AND duplicate address");
4735 dirserv_set_router_is_running(ri, now);
4759 if (ri->protocol_list &&
4763 if (ri->cache_info.published_on >= cutoff) {
4777 if (ri->cache_info.signing_key_cert) {
4779 ri->cache_info.signing_key_cert->signing_key.pubkey,
4782 if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
4785 if (!vote_on_reachability)
4789 if (ri->protocol_list) {
4790 vrs->
protocols = tor_strdup(ri->protocol_list);
4800 } SMARTLIST_FOREACH_END(ri);
4806 smartlist_free(added);
4807 smartlist_free(microdescriptors);
4810 smartlist_free(routers);
4811 digestmap_free(omit_as_sybil, NULL);
4824 routerstatuses, bw_file_headers,
4838 v3_out->
type = NS_TYPE_VOTE;
4842 char tbuf[ISO_TIME_LEN+1];
4845 long last_consensus_interval;
4846 if (current_consensus)
4847 last_consensus_interval = current_consensus->
fresh_until -
4853 (
int)last_consensus_interval,
4856 log_notice(
LD_DIR,
"Choosing valid-after time in vote as %s: "
4857 "consensus_set=%d, last_interval=%d",
4858 tbuf, current_consensus?1:0, (
int)last_consensus_interval);
4870 v3_out->server_versions = server_versions;
4874 v3_out->recommended_client_protocols =
4876 v3_out->required_client_protocols =
4878 v3_out->required_relay_protocols =
4889 v3_out->recommended_client_protocols, NULL));
4894 0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4895 if (vote_on_reachability)
4899 if (list_middle_only)
4906 for ( ; paramline; paramline = paramline->next) {
4908 paramline->value, NULL, 0, 0);
4931 voter->
contact = tor_strdup(contact);
4936 log_warn(
LD_BUG,
"Unable to compute digest of legacy v3 identity key");
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src)
tor_addr_port_t * tor_addr_port_new(const tor_addr_t *addr, uint16_t port)
int tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2, tor_addr_comparison_t how)
int tor_addr_is_null(const tor_addr_t *addr)
char * tor_addr_to_str_dup(const tor_addr_t *addr)
const char * fmt_addrport(const tor_addr_t *addr, uint16_t port)
static sa_family_t tor_addr_family(const tor_addr_t *a)
int trusted_dirs_load_certs_from_string(const char *contents, int source, int flush, const char *source_dir)
authority_cert_t * authority_cert_get_by_digests(const char *id_digest, const char *sk_digest)
Header file for authcert.c.
Header file for directory authority mode.
Authority certificate structure.
const char * hex_str(const char *from, size_t fromlen)
int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen, int flags)
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
int dirserv_get_measured_bw_cache_size(void)
int dirserv_read_measured_bandwidths(const char *from_file, smartlist_t *routerstatuses, smartlist_t *bw_file_headers, uint8_t *digest_out)
void dirserv_count_measured_bws(const smartlist_t *routers)
int dirserv_query_measured_bw_cache_kb(const char *node_id, long *bw_kb_out, time_t *as_of_out)
void dirserv_clear_measured_bw_cache(void)
Header file for bwauth.c.
#define MAX_BW_FILE_HEADER_COUNT_IN_VOTE
Cached large directory object structure.
const or_options_t * get_options(void)
Header file for config.c.
void curve25519_public_to_base64(char *output, const curve25519_public_key_t *pkey, bool pad)
const char * crypto_digest_algorithm_get_name(digest_algorithm_t alg)
#define BASE64_DIGEST256_LEN
#define HEX_DIGEST256_LEN
#define N_COMMON_DIGEST_ALGORITHMS
int crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out, int add_space)
int crypto_pk_write_public_key_to_string(crypto_pk_t *env, char **dest, size_t *len)
int crypto_pk_get_digest(const crypto_pk_t *pk, char *digest_out)
crypto_pk_t * crypto_pk_dup_key(crypto_pk_t *orig)
#define fast_memeq(a, b, c)
#define fast_memcmp(a, b, c)
Trusted/fallback directory server structure.
Structure dirauth_options_t to hold directory authority options.
Header for dirauth_sys.c.
void directory_get_from_all_authorities(uint8_t dir_purpose, uint8_t router_purpose, const char *resource)
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)
Header file for dirclient.c.
int dircollator_n_routers(dircollator_t *dc)
dircollator_t * dircollator_new(int n_votes, int n_authorities)
void dircollator_collate(dircollator_t *dc, int consensus_method)
void dircollator_add_vote(dircollator_t *dc, networkstatus_t *v)
vote_routerstatus_t ** dircollator_get_votes_for_router(dircollator_t *dc, int idx)
Header file for dircollate.c.
int dir_split_resource_into_fingerprints(const char *resource, smartlist_t *fp_out, int *compressed_out, int flags)
Header file for directory.c.
#define DIR_PURPOSE_UPLOAD_VOTE
#define DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
#define DIR_PURPOSE_UPLOAD_SIGNATURES
#define DIR_PURPOSE_FETCH_STATUS_VOTE
int get_n_authorities(dirinfo_type_t type)
dir_server_t * trusteddirserver_get_by_v3_auth_digest(const char *digest)
Header file for dirlist.c.
void cached_dir_decref(cached_dir_t *d)
cached_dir_t * new_cached_dir(char *s, time_t published)
Header file for dirserv.c.
static char * networkstatus_format_signatures(networkstatus_t *consensus, int for_detached_signatures)
STATIC microdesc_t * dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method)
static int dirvote_add_signatures_to_all_pending_consensuses(const char *detached_signatures_body, const char *source, const char **msg_out)
static void dirvote_fetch_missing_signatures(void)
static void dirvote_clear_pending_consensuses(void)
STATIC int compare_routerinfo_usefulness(const routerinfo_t *first, const routerinfo_t *second)
static int cmp_int_strings_(const void **_a, const void **_b)
networkstatus_t * dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, authority_cert_t *cert)
static void export_consensus_for_transparency(const char *flavor_name)
pending_vote_t * dirvote_add_vote(const char *vote_body, time_t time_posted, const char *where_from, const char **msg_out, int *status_out)
static int consensus_method_is_supported(int method)
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)
char * format_recommended_version_list(const config_line_t *ln, int warn)
static void get_frequent_members(smartlist_t *out, smartlist_t *in, int min)
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)
static void remove_flag(smartlist_t *sl, const char *flag)
static int compare_routerinfo_addrs_by_family(const routerinfo_t *a, const routerinfo_t *b, int family)
STATIC authority_cert_t * authority_cert_dup(authority_cert_t *cert)
STATIC int compare_routerinfo_by_ipv6(const void **a, const void **b)
static int dirvote_perform_vote(void)
STATIC char * make_consensus_method_list(int low, int high, const char *separator)
static int compare_orports_(const void **_a, const void **_b)
STATIC digestmap_t * get_all_possible_sybil(const smartlist_t *routers)
static char * format_protocols_lines_for_vote(const networkstatus_t *v3_ns)
static void extract_shared_random_commits(networkstatus_t *ns, const smartlist_t *tokens)
time_t dirvote_act(const or_options_t *options, time_t now)
const cached_dir_t * dirvote_get_vote(const char *fp, int flags)
static void dirvote_clear_votes(int all_votes)
static char * compute_nth_protocol_set(int n, int n_voters, const smartlist_t *votes)
static char * pending_consensus_signatures
STATIC char * format_networkstatus_vote(crypto_pk_t *private_signing_key, networkstatus_t *v3_ns)
STATIC int32_t dirvote_get_intermediate_param_value(const smartlist_t *param_list, const char *keyword, int32_t default_val)
const char * dirvote_get_pending_consensus(consensus_flavor_t flav)
static int dirvote_publish_consensus(void)
static const char * get_nth_protocol_set_vote(int n, const networkstatus_t *vote)
void dirvote_free_all(void)
static int compare_votes_by_authority_id_(const void **_a, const void **_b)
STATIC smartlist_t * dirvote_compute_params(smartlist_t *votes, int method, int total_authorities)
static char * version_from_platform(const char *platform)
static int vote_routerstatus_find_microdesc_hash(char *digest256_out, const vote_routerstatus_t *vrs, int method, digest_algorithm_t alg)
static int compare_vote_rs_(const void **_a, const void **_b)
int dirvote_add_signatures(const char *detached_signatures_body, const char *source, const char **msg)
static void dirvote_fetch_missing_votes(void)
STATIC char * networkstatus_get_detached_signatures(smartlist_t *consensuses)
static char * compute_consensus_versions_list(smartlist_t *lst, int n_versioning)
static char * get_detached_signatures_from_pending_consensuses(pending_consensus_t *pending, int n_flavors)
uint32_t dirserv_get_bandwidth_for_router_kb(const routerinfo_t *ri)
static void routers_make_ed_keys_unique(smartlist_t *routers)
static void dirvote_get_preferred_voting_intervals(vote_timing_t *timing_out)
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)
static char * list_v3_auth_ids(void)
#define get_most_frequent_member(lst)
STATIC int networkstatus_add_detached_signatures(networkstatus_t *target, ns_detached_signatures_t *sigs, const char *source, int severity, const char **msg_out)
static smartlist_t * pending_vote_list
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)
const char DIRVOTE_OPTIONAL_FLAGS[]
STATIC char * compute_consensus_package_lines(smartlist_t *votes)
#define MIN_VOTES_FOR_PARAM
STATIC digestmap_t * get_sybil_list_by_ip_version(const smartlist_t *routers, sa_family_t family)
static smartlist_t * pending_consensus_signature_list
static void clear_status_flags_on_sybil(routerstatus_t *rs)
const char * dirvote_get_pending_detached_signatures(void)
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)
static int dirvote_compute_consensuses(void)
static int compute_consensus_method(smartlist_t *votes)
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)
STATIC int compare_routerinfo_by_ipv4(const void **a, const void **b)
static smartlist_t * previous_vote_list
static int compare_vote_rs(const vote_routerstatus_t *a, const vote_routerstatus_t *b)
static int compare_dir_src_ents_by_authority_id_(const void **_a, const void **_b)
const char DIRVOTE_UNIVERSAL_FLAGS[]
vote_microdesc_hash_t * dirvote_format_all_microdesc_vote_lines(const routerinfo_t *ri, time_t now, smartlist_t *microdescriptors_out)
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)
static networkstatus_voter_info_t * get_voter(const networkstatus_t *vote)
Header file for dirvote.c.
#define MIN_VOTE_INTERVAL_TESTING
#define MIN_VOTE_INTERVAL
#define MIN_METHOD_TO_SUPPRESS_MD_PUBLISHED
#define MIN_METHOD_TO_PERMIT_ABSENT_TAP_KEYS
#define MIN_SUPPORTED_CONSENSUS_METHOD
#define MIN_METHOD_FOR_FAMILY_IDS
#define MIN_METHOD_TO_OMIT_PACKAGE_FINGERPRINTS
#define DEFAULT_MAX_UNMEASURED_BW_KB
#define MAX_BW_FILE_HEADERS_LINE_LEN
#define MAX_SUPPORTED_CONSENSUS_METHOD
Authority signature structure.
Code to parse and validate detached-signature objects.
Header file for circuitbuild.c.
const char * escaped(const char *s)
Format routerstatus entries for controller, vote, or consensus.
routerstatus_format_type_t
@ NS_V3_CONSENSUS_MICRODESC
Header file for guardfraction.c.
void tor_log(int severity, log_domain_mask_t domain, const char *format,...)
#define log_fn(severity, domain, args,...)
void tor_free_(void *mem)
void * strmap_get_lc(const strmap_t *map, const char *key)
void * strmap_set_lc(strmap_t *map, const char *key, void *val)
#define DIGESTMAP_FOREACH_END
#define DIGESTMAP_FOREACH(map, keyvar, valtype, valvar)
smartlist_t * microdescs_add_list_to_cache(microdesc_cache_t *cache, smartlist_t *descriptors, saved_location_t where, int no_save)
microdesc_cache_t * get_microdesc_cache(void)
Header file for microdesc.c.
smartlist_t * microdescs_parse_from_string(const char *s, const char *eos, int allow_annotations, saved_location_t where, smartlist_t *invalid_digests_out)
Header file for microdesc_parse.c.
Microdescriptor structure.
networkstatus_t * networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
int networkstatus_check_document_signature(const networkstatus_t *consensus, document_signature_t *sig, const authority_cert_t *cert)
const char * networkstatus_get_flavor_name(consensus_flavor_t flav)
int networkstatus_set_current_consensus(const char *consensus, size_t consensus_len, const char *flavor, unsigned flags, const char *source_dir)
document_signature_t * networkstatus_get_voter_sig_by_alg(const networkstatus_voter_info_t *voter, digest_algorithm_t alg)
time_t voting_sched_get_start_of_interval_after(time_t now, int interval, int offset)
networkstatus_voter_info_t * networkstatus_get_voter_by_id(networkstatus_t *vote, const char *identity)
int networkstatus_check_consensus_signature(networkstatus_t *consensus, int warn)
document_signature_t * document_signature_dup(const document_signature_t *sig)
networkstatus_t * networkstatus_get_live_consensus(time_t now)
Header file for networkstatus.c.
Networkstatus consensus/vote structure.
Single consensus voter structure.
Node information structure.
char * nodefamily_canonicalize(const char *s, const uint8_t *rsa_id_self, unsigned flags)
Header file for nodefamily.c.
const node_t * node_get_by_id(const char *identity_digest)
node_t * node_get_mutable_by_id(const char *identity_digest)
Header file for nodelist.c.
Detached consensus signatures structure.
Header file for ns_parse.c.
Master header file for Tor-specific functionality.
#define ROUTER_MAX_AGE_TO_PUBLISH
#define N_CONSENSUS_FLAVORS
long tor_parse_long(const char *s, int base, long min, long max, int *ok, char **next)
smartlist_t * find_all_by_keyword(const smartlist_t *s, directory_keyword k)
directory_token_t * find_opt_by_keyword(const smartlist_t *s, directory_keyword keyword)
Header file for parsecommon.c.
char * write_short_policy(const short_policy_t *policy)
char * policy_summarize(smartlist_t *policy, sa_family_t family)
Header file for policies.c.
int tor_asprintf(char **strp, const char *fmt,...)
int tor_snprintf(char *str, size_t size, const char *format,...)
bool protover_list_is_invalid(const char *s)
const char * protover_get_recommended_relay_protocols(void)
const char * protover_get_required_relay_protocols(void)
const char * protover_get_required_client_protocols(void)
const char * protover_get_recommended_client_protocols(void)
char * protover_compute_vote(const smartlist_t *list_of_proto_strings, int threshold)
const char * protover_compute_for_old_tor(const char *version)
C_RUST_COUPLED: src/rust/protover/protover.rs compute_for_old_tor
int protover_all_supported(const char *s, char **missing_out)
Headers and type declarations for protover.c.
int validate_recommended_package_line(const char *line)
Header file for recommend_pkg.c.
void rep_hist_make_router_pessimal(const char *id, time_t when)
Header file for rephist.c.
bool find_my_address(const or_options_t *options, int family, int warn_severity, tor_addr_t *addr_out, resolved_addr_method_t *method_out, char **hostname_out)
Attempt to find our IP address that can be used as our external reachable address.
Header file for resolve_addr.c.
uint16_t routerconf_find_or_port(const or_options_t *options, sa_family_t family)
crypto_pk_t * get_my_v3_legacy_signing_key(void)
crypto_pk_t * get_my_v3_authority_signing_key(void)
static crypto_pk_t * legacy_signing_key
authority_cert_t * get_my_v3_authority_cert(void)
uint16_t routerconf_find_dir_port(const or_options_t *options, uint16_t dirport)
authority_cert_t * get_my_v3_legacy_cert(void)
Header file for router.c.
Router descriptor structure.
#define ROUTER_PURPOSE_GENERAL
void update_consensus_router_descriptor_downloads(time_t now, int is_vote, networkstatus_t *consensus)
routerlist_t * router_get_routerlist(void)
uint32_t router_get_advertised_bandwidth(const routerinfo_t *router)
void routers_sort_by_identity(smartlist_t *routers)
Header file for routerlist.c.
Router descriptor list structure.
char * sr_get_string_for_consensus(const smartlist_t *votes, int32_t num_srv_agreements)
char * sr_get_string_for_vote(void)
void sr_act_post_consensus(const networkstatus_t *consensus)
void sr_handle_received_commits(smartlist_t *commits, crypto_pk_t *voter_key)
sr_commit_t * sr_parse_commit(const smartlist_t *args)
Header for shared_random_state.c.
char * router_get_dirobj_signature(const char *digest, size_t digest_len, const crypto_pk_t *private_key)
Header file for signing.c.
void smartlist_sort_digests256(smartlist_t *sl)
const uint8_t * smartlist_get_most_frequent_digest256(smartlist_t *sl)
void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern,...)
void smartlist_uniq_strings(smartlist_t *sl)
void smartlist_sort_strings(smartlist_t *sl)
int smartlist_contains_string(const smartlist_t *sl, const char *element)
const char * smartlist_get_most_frequent_string_(smartlist_t *sl, int *count_out)
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
void smartlist_sort(smartlist_t *sl, int(*compare)(const void **a, const void **b))
int smartlist_string_pos(const smartlist_t *sl, const char *element)
void smartlist_uniq(smartlist_t *sl, int(*compare)(const void **a, const void **b), void(*free_fn)(void *a))
void smartlist_add_all(smartlist_t *s1, const smartlist_t *s2)
void smartlist_add_strdup(struct smartlist_t *sl, const char *string)
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
void smartlist_clear(smartlist_t *sl)
void smartlist_remove(smartlist_t *sl, const void *element)
void smartlist_del_keeporder(smartlist_t *sl, int idx)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
#define SMARTLIST_DEL_CURRENT(sl, var)
int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep, int flags, int max)
crypto_pk_t * identity_key
crypto_pk_t * signing_key
char signing_key_digest[DIGEST_LEN]
signed_descriptor_t cache_info
char d[N_COMMON_DIGEST_ALGORITHMS][DIGEST256_LEN]
BOOL AuthDirListMiddleOnly
LINELIST RecommendedServerVersions
BOOL VersioningAuthoritativeDirectory
LINELIST RecommendedClientVersions
POSINT AuthDirMaxServersPerAddr
unsigned int good_signature
unsigned int bad_signature
char digest[DIGEST256_LEN]
smartlist_t * known_flags
char * recommended_relay_protocols
smartlist_t * routerstatus_list
uint8_t bw_file_digest256[DIGEST256_LEN]
networkstatus_sr_info_t sr_info
struct authority_cert_t * cert
consensus_flavor_t flavor
networkstatus_type_t type
smartlist_t * bw_file_headers
char legacy_id_digest[DIGEST_LEN]
char identity_digest[DIGEST_LEN]
char vote_digest[DIGEST_LEN]
int V3AuthNIntervalsValid
int TestingV3AuthInitialVotingInterval
int TestingV3AuthVotingStartOffset
networkstatus_t * consensus
bool have_exported_for_transparency
unsigned int omit_from_vote
smartlist_t * exit_policy
smartlist_t * declared_family
size_t tap_onion_pkey_len
struct curve25519_public_key_t * onion_curve25519_pkey
struct smartlist_t * family_ids
struct short_policy_t * ipv6_exit_policy
char descriptor_digest[DIGEST256_LEN]
unsigned int has_exitsummary
char identity_digest[DIGEST_LEN]
unsigned int has_guardfraction
unsigned int bw_is_unmeasured
char nickname[MAX_NICKNAME_LEN+1]
unsigned int has_bandwidth
unsigned int is_possible_guard
unsigned int is_flagged_running
unsigned int is_authority
uint32_t guardfraction_percentage
char signed_descriptor_digest[DIGEST_LEN]
char identity_digest[DIGEST_LEN]
struct tor_cert_st * signing_key_cert
char * signed_descriptor_body
size_t signed_descriptor_len
saved_location_t saved_location
struct vote_microdesc_hash_t * next
char * microdesc_hash_line
uint8_t ed25519_id[ED25519_PUBKEY_LEN]
vote_microdesc_hash_t * microdesc
unsigned int ed25519_reflects_consensus
unsigned int has_measured_bw
#define MOCK_IMPL(rv, funcname, arglist)
void format_iso_time(char *buf, time_t t)
Parsed Tor version structure.
#define tor_assert_nonfatal_unreached()
int strcmpstart(const char *s1, const char *s2)
const char * find_whitespace(const char *s)
int tor_digest256_is_zero(const char *digest)
int fast_mem_is_zero(const char *mem, size_t len)
const char * find_str_at_start_of_line(const char *haystack, const char *needle)
int tor_digest_is_zero(const char *digest)
void sort_version_list(smartlist_t *versions, int remove_duplicates)
int tor_version_parse(const char *s, tor_version_t *out)
Header file for versions.c.
Microdescriptor-hash voting structure.
Routerstatus (vote entry) structure.
#define MAX_KNOWN_FLAGS_IN_VOTE
Directory voting schedule structure.
int running_long_enough_to_decide_unreachable(void)
void dirserv_compute_performance_thresholds(digestmap_t *omit_as_sybil)
void dirauth_set_routerstatus_from_routerinfo(routerstatus_t *rs, node_t *node, const routerinfo_t *ri, time_t now, int listbadexits, int listmiddleonly)
char * dirserv_get_flag_thresholds_line(void)
Header file for voteflags.c.
Header file for voting_schedule.c.
#define CURVE25519_BASE64_PADDED_LEN
#define ED25519_BASE64_LEN
#define ED25519_PUBKEY_LEN