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);
847 for (i = low; i <= high; ++i) {
866 int min = n_versioning / 2;
870 if (strchr(v,
' ')) {
871 log_warn(
LD_DIR,
"At least one authority has voted for a version %s "
872 "that contains a space. This probably wasn't intentional, and "
873 "is likely to cause trouble. Please tell them to stop it.",
876 } SMARTLIST_FOREACH_END(v);
880 smartlist_free(good);
893 unsigned int n_found = 0;
894 int32_t value = default_val;
897 if (!
strcmpstart(k_v_pair, keyword) && k_v_pair[strlen(keyword)] ==
'=') {
898 const char *integer_str = &k_v_pair[strlen(keyword)+1];
906 } SMARTLIST_FOREACH_END(k_v_pair);
911 tor_assert_nonfatal(n_found == 0);
919#define MIN_VOTES_FOR_PARAM 3
931 const char *cur_param;
934 const int n_votes = smartlist_len(votes);
944 vals = tor_calloc(n_votes,
sizeof(
int));
950 } SMARTLIST_FOREACH_END(v);
952 if (smartlist_len(param_list) == 0) {
959 cur_param = smartlist_get(param_list, 0);
960 eq = strchr(cur_param,
'=');
962 cur_param_len = (int)(eq+1 - cur_param);
970 const char *next_param;
972 eq = strchr(param,
'=');
974 vals[i++] = (int32_t)
978 if (param_sl_idx+1 == smartlist_len(param_list))
981 next_param = smartlist_get(param_list, param_sl_idx+1);
983 if (!next_param || strncmp(next_param, param, cur_param_len)) {
987 if (i > total_authorities/2 ||
989 int32_t median = median_int32(vals, i);
990 char *out_string = tor_malloc(64+cur_param_len);
991 memcpy(out_string, param, cur_param_len);
992 tor_snprintf(out_string+cur_param_len,64,
"%ld", (
long)median);
998 eq = strchr(next_param,
'=');
999 cur_param_len = (int)(eq+1 - next_param);
1002 } SMARTLIST_FOREACH_END(param);
1004 smartlist_free(param_list);
1009#define RANGE_CHECK(a,b,c,d,e,f,g,mx) \
1010 ((a) >= 0 && (a) <= (mx) && (b) >= 0 && (b) <= (mx) && \
1011 (c) >= 0 && (c) <= (mx) && (d) >= 0 && (d) <= (mx) && \
1012 (e) >= 0 && (e) <= (mx) && (f) >= 0 && (f) <= (mx) && \
1013 (g) >= 0 && (g) <= (mx))
1015#define CHECK_EQ(a, b, margin) \
1016 ((a)-(b) >= 0 ? (a)-(b) <= (margin) : (b)-(a) <= (margin))
1019 BW_WEIGHTS_NO_ERROR = 0,
1020 BW_WEIGHTS_RANGE_ERROR = 1,
1021 BW_WEIGHTS_SUMG_ERROR = 2,
1022 BW_WEIGHTS_SUME_ERROR = 3,
1023 BW_WEIGHTS_SUMD_ERROR = 4,
1024 BW_WEIGHTS_BALANCE_MID_ERROR = 5,
1025 BW_WEIGHTS_BALANCE_EG_ERROR = 6
1026} bw_weights_error_t;
1031static bw_weights_error_t
1033 int64_t Wme, int64_t Wmd, int64_t Wee,
1034 int64_t Wed, int64_t scale, int64_t G,
1035 int64_t M, int64_t E, int64_t D, int64_t
T,
1036 int64_t margin,
int do_balance) {
1037 bw_weights_error_t berr = BW_WEIGHTS_NO_ERROR;
1040 if (!CHECK_EQ(Wed + Wmd + Wgd, scale, margin)) {
1041 berr = BW_WEIGHTS_SUMD_ERROR;
1046 if (!CHECK_EQ(Wmg + Wgg, scale, margin)) {
1047 berr = BW_WEIGHTS_SUMG_ERROR;
1052 if (!CHECK_EQ(Wme + Wee, scale, margin)) {
1053 berr = BW_WEIGHTS_SUME_ERROR;
1058 if (!RANGE_CHECK(Wgg, Wgd, Wmg, Wme, Wmd, Wed, Wee, scale)) {
1059 berr = BW_WEIGHTS_RANGE_ERROR;
1065 if (!CHECK_EQ(Wgg*G + Wgd*D, Wee*E + Wed*D, (margin*
T)/3)) {
1066 berr = BW_WEIGHTS_BALANCE_EG_ERROR;
1071 if (!CHECK_EQ(Wgg*G + Wgd*D, M*scale + Wmd*D + Wme*E + Wmg*G,
1073 berr = BW_WEIGHTS_BALANCE_MID_ERROR;
1081 "Bw weight mismatch %d. G=%"PRId64
" M=%"PRId64
1082 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1083 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1084 " Wgd=%d Wgg=%d Wme=%d Wmg=%d",
1088 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1089 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg);
1102 int64_t M, int64_t E, int64_t D,
1103 int64_t
T, int64_t weight_scale)
1105 bw_weights_error_t berr = 0;
1106 int64_t Wgg = -1, Wgd = -1;
1107 int64_t Wmg = -1, Wme = -1, Wmd = -1;
1108 int64_t Wed = -1, Wee = -1;
1109 const char *casename;
1111 if (G <= 0 || M <= 0 || E <= 0 || D <= 0) {
1112 log_warn(
LD_DIR,
"Consensus with empty bandwidth: "
1113 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
1114 " D=%"PRId64
" T=%"PRId64,
1131 if (3*E >=
T && 3*G >=
T) {
1133 casename =
"Case 1 (Wgd=Wmd=Wed)";
1134 Wgd = weight_scale/3;
1135 Wed = weight_scale/3;
1136 Wmd = weight_scale/3;
1137 Wee = (weight_scale*(E+G+M))/(3*E);
1138 Wme = weight_scale - Wee;
1139 Wmg = (weight_scale*(2*G-E-M))/(3*G);
1140 Wgg = weight_scale - Wmg;
1143 weight_scale, G, M, E, D,
T, 10, 1);
1147 "Bw Weights error %d for %s v10. G=%"PRId64
" M=%"PRId64
1148 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1149 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1150 " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
1154 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1155 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1158 }
else if (3*E <
T && 3*G <
T) {
1159 int64_t R = MIN(E, G);
1160 int64_t S = MAX(E, G);
1173 casename =
"Case 2a (E scarce)";
1177 casename =
"Case 2a (G scarce)";
1182 casename =
"Case 2b1 (Wgg=weight_scale, Wmd=Wgd)";
1183 Wee = (weight_scale*(E - G + M))/E;
1184 Wed = (weight_scale*(D - 2*E + 4*G - 2*M))/(3*D);
1185 Wme = (weight_scale*(G-M))/E;
1188 Wmd = (weight_scale - Wed)/2;
1189 Wgd = (weight_scale - Wed)/2;
1192 weight_scale, G, M, E, D,
T, 10, 1);
1195 casename =
"Case 2b2 (Wgg=weight_scale, Wee=weight_scale)";
1198 Wed = (weight_scale*(D - 2*E + G + M))/(3*D);
1199 Wmd = (weight_scale*(D - 2*M + G + E))/(3*D);
1204 casename =
"Case 2b3 (Wmd=0)";
1207 "Too much Middle bandwidth on the network to calculate "
1208 "balanced bandwidth-weights. Consider increasing the "
1209 "number of Guard nodes by lowering the requirements.");
1211 Wgd = weight_scale - Wed - Wmd;
1213 Wed, weight_scale, G, M, E, D,
T, 10, 1);
1215 if (berr != BW_WEIGHTS_NO_ERROR &&
1216 berr != BW_WEIGHTS_BALANCE_MID_ERROR) {
1218 "Bw Weights error %d for %s v10. G=%"PRId64
" M=%"PRId64
1219 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1220 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1221 " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
1225 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1226 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1231 int64_t S = MIN(E, G);
1233 if (!(3*E <
T || 3*G <
T) || !(3*G >=
T || 3*E >=
T)) {
1235 "Bw-Weights Case 3 v10 but with G=%"PRId64
" M="
1236 "%"PRId64
" E=%"PRId64
" D=%"PRId64
" T=%"PRId64,
1243 casename =
"Case 3a (G scarce)";
1244 Wgg = Wgd = weight_scale;
1245 Wmd = Wed = Wmg = 0;
1249 else Wme = (weight_scale*(E-M))/(2*E);
1250 Wee = weight_scale-Wme;
1252 casename =
"Case 3a (E scarce)";
1253 Wee = Wed = weight_scale;
1254 Wmd = Wgd = Wme = 0;
1258 else Wmg = (weight_scale*(G-M))/(2*G);
1259 Wgg = weight_scale-Wmg;
1264 casename =
"Case 3bg (G scarce, Wgg=weight_scale, Wmd == Wed)";
1266 Wgd = (weight_scale*(D - 2*G + E + M))/(3*D);
1268 Wee = (weight_scale*(E+M))/(2*E);
1269 Wme = weight_scale - Wee;
1270 Wmd = (weight_scale - Wgd)/2;
1271 Wed = (weight_scale - Wgd)/2;
1274 Wed, weight_scale, G, M, E, D,
T, 10, 1);
1276 casename =
"Case 3be (E scarce, Wee=weight_scale, Wmd == Wgd)";
1278 Wed = (weight_scale*(D - 2*E + G + M))/(3*D);
1280 Wgg = (weight_scale*(G+M))/(2*G);
1281 Wmg = weight_scale - Wgg;
1282 Wmd = (weight_scale - Wed)/2;
1283 Wgd = (weight_scale - Wed)/2;
1286 Wed, weight_scale, G, M, E, D,
T, 10, 1);
1290 "Bw Weights error %d for %s v10. G=%"PRId64
" M=%"PRId64
1291 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1292 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1293 " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
1297 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1298 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1307 tor_assert(0 < weight_scale && weight_scale <= INT32_MAX);
1318 "bandwidth-weights Wbd=%d Wbe=%d Wbg=%d Wbm=%d "
1320 "Web=%d Wed=%d Wee=%d Weg=%d Wem=%d "
1321 "Wgb=%d Wgd=%d Wgg=%d Wgm=%d "
1322 "Wmb=%d Wmd=%d Wme=%d Wmg=%d Wmm=%d\n",
1323 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)weight_scale,
1325 (
int)weight_scale, (
int)Wed, (
int)Wee, (
int)Wed, (
int)Wee,
1326 (
int)weight_scale, (
int)Wgd, (
int)Wgg, (
int)Wgg,
1327 (
int)weight_scale, (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1329 log_notice(
LD_CIRC,
"Computed bandwidth weights for %s with v10: "
1330 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
1342 int is_exit,
int is_guard,
1343 int64_t *G, int64_t *M, int64_t *E, int64_t *D,
1347 int guardfraction_bandwidth = 0;
1350 log_info(
LD_BUG,
"Missing consensus bandwidth for router %s",
1381 guard_get_guardfraction_bandwidth(&guardfraction_bw,
1385 default_bandwidth = guardfraction_bw.
guard_bw;
1386 guardfraction_bandwidth = guardfraction_bw.
non_guard_bw;
1395 *
T += default_bandwidth;
1396 if (is_exit && is_guard) {
1398 *D += default_bandwidth;
1400 *E += guardfraction_bandwidth;
1403 }
else if (is_exit) {
1405 *E += default_bandwidth;
1407 }
else if (is_guard) {
1409 *G += default_bandwidth;
1411 *M += guardfraction_bandwidth;
1416 *M += default_bandwidth;
1428 case 0:
return vote->recommended_client_protocols;
1430 case 2:
return vote->required_client_protocols;
1431 case 3:
return vote->required_relay_protocols;
1433 tor_assert_unreached();
1445 const char *keyword;
1450 keyword =
"recommended-client-protocols";
1451 threshold = CEIL_DIV(n_voters, 2);
1454 keyword =
"recommended-relay-protocols";
1455 threshold = CEIL_DIV(n_voters, 2);
1458 keyword =
"required-client-protocols";
1459 threshold = CEIL_DIV(n_voters * 2, 3);
1462 keyword =
"required-relay-protocols";
1463 threshold = CEIL_DIV(n_voters * 2, 3);
1466 tor_assert_unreached();
1474 } SMARTLIST_FOREACH_END(ns);
1477 smartlist_free(proto_votes);
1479 char *result = NULL;
1522 int total_authorities,
1525 const char *legacy_id_key_digest,
1530 char *result = NULL;
1531 int consensus_method;
1532 time_t valid_after, fresh_until, valid_until;
1533 int vote_seconds, dist_seconds;
1534 char *client_versions = NULL, *server_versions = NULL;
1536 const char *flavor_name;
1538 int64_t G, M, E, D,
T;
1541 char *params = NULL;
1542 char *packages = NULL;
1543 int added_weights = 0;
1544 dircollator_t *collator = NULL;
1547 tor_assert(flavor == FLAV_NS || flavor == FLAV_MICRODESC);
1548 tor_assert(total_authorities >= smartlist_len(votes));
1553 if (!smartlist_len(votes)) {
1554 log_warn(
LD_DIR,
"Can't compute a consensus from no votes.");
1561 log_info(
LD_DIR,
"Generating consensus using method %d.",
1564 log_warn(
LD_DIR,
"The other authorities will use consensus method %d, "
1565 "which I don't support. Maybe I should upgrade!",
1580 int n_votes = smartlist_len(votes);
1581 time_t *va_times = tor_calloc(n_votes,
sizeof(time_t));
1582 time_t *fu_times = tor_calloc(n_votes,
sizeof(time_t));
1583 time_t *vu_times = tor_calloc(n_votes,
sizeof(time_t));
1584 int *votesec_list = tor_calloc(n_votes,
sizeof(
int));
1585 int *distsec_list = tor_calloc(n_votes,
sizeof(
int));
1586 int n_versioning_clients = 0, n_versioning_servers = 0;
1592 va_times[v_sl_idx] = v->valid_after;
1593 fu_times[v_sl_idx] = v->fresh_until;
1594 vu_times[v_sl_idx] = v->valid_until;
1595 votesec_list[v_sl_idx] = v->vote_seconds;
1596 distsec_list[v_sl_idx] = v->dist_seconds;
1597 if (v->client_versions) {
1599 ++n_versioning_clients;
1601 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1606 if (v->server_versions) {
1608 ++n_versioning_servers;
1610 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1617 } SMARTLIST_FOREACH_END(v);
1618 valid_after = median_time(va_times, n_votes);
1619 fresh_until = median_time(fu_times, n_votes);
1620 valid_until = median_time(vu_times, n_votes);
1621 vote_seconds = median_int(votesec_list, n_votes);
1622 dist_seconds = median_int(distsec_list, n_votes);
1634 n_versioning_servers);
1636 n_versioning_clients);
1639 packages = tor_strdup(
"");
1645 smartlist_free(combined_server_versions);
1646 smartlist_free(combined_client_versions);
1660 const bool badexit_flag_is_listed =
1666 char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
1667 vu_buf[ISO_TIME_LEN+1];
1675 "vote-status consensus\n",
1676 flavor == FLAV_NS ?
"" :
" ",
1677 flavor == FLAV_NS ?
"" : flavor_name);
1686 "voting-delay %d %d\n"
1687 "client-versions %s\n"
1688 "server-versions %s\n"
1691 va_buf, fu_buf, vu_buf,
1692 vote_seconds, dist_seconds,
1693 client_versions, server_versions,
1703 for (idx = 0; idx < 4; ++idx) {
1705 if (BUG(!proto_line))
1713 if (smartlist_len(param_list)) {
1725 int32_t num_srv_agreements =
1727 "AuthDirNumSRVAgreements",
1728 (num_dirauth * 2) / 3);
1731 if (srv_lines != NULL) {
1751 e_legacy->is_legacy = 1;
1754 } SMARTLIST_FOREACH_END(v);
1768 "dir-source %s%s %s %s %s %d %d\n",
1769 voter->
nickname, e->is_legacy ?
"-legacy" :
"",
1773 if (! e->is_legacy) {
1780 } SMARTLIST_FOREACH_END(e);
1782 smartlist_free(dir_sources);
1788 if (max_unmeasured_bw_kb < 1)
1789 max_unmeasured_bw_kb = 1;
1803 uint32_t *bandwidths_kb = tor_calloc(smartlist_len(votes),
1805 uint32_t *measured_bws_kb = tor_calloc(smartlist_len(votes),
1807 uint32_t *measured_guardfraction = tor_calloc(smartlist_len(votes),
1811 int num_guardfraction_inputs;
1821 int n_authorities_measuring_bandwidth;
1823 strmap_t *name_to_id_map = strmap_new();
1826 memset(conflict, 0,
sizeof(conflict));
1827 memset(unknown, 0xff,
sizeof(conflict));
1829 size = tor_calloc(smartlist_len(votes),
sizeof(
int));
1830 n_voter_flags = tor_calloc(smartlist_len(votes),
sizeof(
int));
1831 n_flag_voters = tor_calloc(smartlist_len(flags),
sizeof(
int));
1832 flag_map = tor_calloc(smartlist_len(votes),
sizeof(
int *));
1833 named_flag = tor_calloc(smartlist_len(votes),
sizeof(
int));
1834 unnamed_flag = tor_calloc(smartlist_len(votes),
sizeof(
int));
1835 for (i = 0; i < smartlist_len(votes); ++i)
1836 unnamed_flag[i] = named_flag[i] = -1;
1845 flag_map[v_sl_idx] = tor_calloc(smartlist_len(v->known_flags),
1848 log_warn(
LD_BUG,
"Somehow, a vote has %d entries in known_flags",
1849 smartlist_len(v->known_flags));
1854 flag_map[v_sl_idx][fl_sl_idx] = p;
1856 if (!strcmp(fl,
"Named"))
1857 named_flag[v_sl_idx] = fl_sl_idx;
1858 if (!strcmp(fl,
"Unnamed"))
1859 unnamed_flag[v_sl_idx] = fl_sl_idx;
1860 } SMARTLIST_FOREACH_END(fl);
1861 n_voter_flags[v_sl_idx] = smartlist_len(v->known_flags);
1862 size[v_sl_idx] = smartlist_len(v->routerstatus_list);
1863 } SMARTLIST_FOREACH_END(v);
1869 if (named_flag[v_sl_idx]<0)
1871 nf = UINT64_C(1) << named_flag[v_sl_idx];
1875 if ((rs->flags & nf) != 0) {
1876 const char *d =
strmap_get_lc(name_to_id_map, rs->status.nickname);
1880 rs->status.identity_digest);
1881 }
else if (d != conflict &&
1884 strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
1889 } SMARTLIST_FOREACH_END(rs);
1890 } SMARTLIST_FOREACH_END(v);
1894 if (unnamed_flag[v_sl_idx]<0)
1896 uf = UINT64_C(1) << unnamed_flag[v_sl_idx];
1899 if ((rs->flags & uf) != 0) {
1900 const char *d =
strmap_get_lc(name_to_id_map, rs->status.nickname);
1901 if (d == conflict || d == unknown) {
1905 strmap_set_lc(name_to_id_map, rs->status.nickname, unknown);
1908 strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
1913 } SMARTLIST_FOREACH_END(rs);
1914 } SMARTLIST_FOREACH_END(v);
1918 n_authorities_measuring_bandwidth = 0;
1920 if (v->has_measured_bws) {
1921 ++n_authorities_measuring_bandwidth;
1929 } SMARTLIST_FOREACH_END(v);
1934 flag_counts = tor_calloc(smartlist_len(flags),
sizeof(
int));
1936 for (i = 0; i < num_routers; ++i) {
1942 const char *current_rsa_id = NULL;
1943 const char *chosen_version;
1944 const char *chosen_protocol_list;
1945 const char *chosen_name = NULL;
1946 int exitsummary_disagreement = 0;
1947 int is_named = 0, is_unnamed = 0, is_running = 0, is_valid = 0;
1948 int is_guard = 0, is_exit = 0, is_bad_exit = 0, is_middle_only = 0;
1949 int naming_conflict = 0;
1954 memset(flag_counts, 0,
sizeof(
int)*smartlist_len(flags));
1961 num_guardfraction_inputs = 0;
1962 int ed_consensus = 0;
1963 const uint8_t *ed_consensus_val = NULL;
1966 for (
int voter_idx = 0; voter_idx < smartlist_len(votes); ++voter_idx) {
1967 if (vrs_lst[voter_idx] == NULL)
1969 rs = vrs_lst[voter_idx];
1985 for (
int flag = 0; flag < n_voter_flags[voter_idx]; ++flag) {
1986 if (rs->
flags & (UINT64_C(1) << flag))
1987 ++flag_counts[flag_map[voter_idx][flag]];
1989 if (named_flag[voter_idx] >= 0 &&
1990 (rs->
flags & (UINT64_C(1) << named_flag[voter_idx]))) {
1992 log_notice(
LD_DIR,
"Conflict on naming for router: %s vs %s",
1994 naming_conflict = 1;
2001 measured_guardfraction[num_guardfraction_inputs++] =
2015 if (ed_consensus_val) {
2026 if (n_listing <= total_authorities/2)
2029 if (ed_consensus > 0) {
2030 if (ed_consensus <= total_authorities / 2) {
2031 log_warn(
LD_BUG,
"Not enough entries had ed_consensus set; how "
2032 "can we have a consensus of %d?", ed_consensus);
2042 memset(microdesc_digest, 0,
sizeof(microdesc_digest));
2044 microdesc_digest, &alt_orport);
2046 memset(&rs_out, 0,
sizeof(rs_out));
2071 flavor == FLAV_MICRODESC) {
2075 if (chosen_name && !naming_conflict) {
2084 is_named = is_unnamed = 0;
2086 is_named = 1; is_unnamed = 0;
2088 is_named = 0; is_unnamed = 1;
2094 if (!strcmp(fl,
"Named")) {
2097 }
else if (!strcmp(fl,
"Unnamed")) {
2100 }
else if (!strcmp(fl,
"NoEdConsensus")) {
2101 if (ed_consensus <= total_authorities/2)
2104 if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2) {
2106 if (!strcmp(fl,
"Exit"))
2108 else if (!strcmp(fl,
"Guard"))
2110 else if (!strcmp(fl,
"Running"))
2112 else if (!strcmp(fl,
"BadExit"))
2114 else if (!strcmp(fl,
"MiddleOnly"))
2116 else if (!strcmp(fl,
"Valid"))
2120 } SMARTLIST_FOREACH_END(fl);
2135 if (is_middle_only) {
2140 is_exit = is_guard = 0;
2141 if (! is_bad_exit && badexit_flag_is_listed) {
2149 if (smartlist_len(versions)) {
2153 chosen_version = NULL;
2157 if (smartlist_len(protocols)) {
2161 chosen_protocol_list = NULL;
2166 if (is_guard && num_guardfraction_inputs > 2) {
2169 num_guardfraction_inputs);
2178 rs_out.
bandwidth_kb = median_uint32(measured_bws_kb, num_mbws);
2179 }
else if (num_bandwidths > 0) {
2182 rs_out.
bandwidth_kb = median_uint32(bandwidths_kb, num_bandwidths);
2183 if (n_authorities_measuring_bandwidth > 2) {
2192 is_exit = is_exit && !is_bad_exit;
2198 &G, &M, &E, &D, &
T);
2218 const char *chosen_exitsummary = NULL;
2224 vsr->status.identity_digest,
2226 if (vsr->status.has_exitsummary &&
2228 vsr->status.descriptor_digest,
2232 if (!chosen_exitsummary) {
2233 chosen_exitsummary = vsr->status.exitsummary;
2234 }
else if (strcmp(chosen_exitsummary, vsr->status.exitsummary)) {
2237 exitsummary_disagreement = 1;
2240 } SMARTLIST_FOREACH_END(vsr);
2242 if (exitsummary_disagreement) {
2247 log_warn(
LD_DIR,
"The voters disagreed on the exit policy summary "
2248 " for router %s with descriptor %s. This really shouldn't"
2249 " have happened.",
id, dd);
2253 }
else if (!chosen_exitsummary) {
2258 log_warn(
LD_DIR,
"Not one of the voters that made us select"
2259 "descriptor %s for router %s had an exit policy"
2267 if (vsr->status.has_exitsummary)
2273 if (!chosen_exitsummary)
2274 log_warn(
LD_DIR,
"Wow, not one of the voters had an exit "
2275 "policy summary for %s. Wow.",
id);
2278 if (chosen_exitsummary) {
2285 if (flavor == FLAV_MICRODESC &&
2295 buf = routerstatus_format_entry(&rs_out, NULL, NULL,
2296 rs_format, NULL, published_on);
2301 if (flavor == FLAV_MICRODESC &&
2309 smartlist_len(chosen_flags)?
" ":
"");
2313 if (chosen_version) {
2318 if (chosen_protocol_list) {
2323 char *guardfraction_str = NULL;
2333 unmeasured?
" Unmeasured=1":
"",
2334 guardfraction_str ? guardfraction_str :
"");
2350 for (i = 0; i < smartlist_len(votes); ++i)
2356 strmap_free(name_to_id_map, NULL);
2357 smartlist_free(matching_descs);
2358 smartlist_free(chosen_flags);
2359 smartlist_free(versions);
2360 smartlist_free(protocols);
2361 smartlist_free(exitsummaries);
2371 int64_t weight_scale;
2374 if (weight_scale < 1)
2386 char *filename = NULL;
2387 tor_asprintf(&filename,
"my-consensus-%s", flavor_name);
2388 char *fpath = get_datadir_fname(filename);
2389 write_str_to_file(fpath, unsigned_consensus, 0);
2401 flavor == FLAV_NS ? DIGEST_SHA1 : DIGEST_SHA256;
2410 crypto_digest_smartlist(digest, digest_len, chunks,
"", digest_alg);
2417 if (flavor == FLAV_NS) {
2419 signing_key_fingerprint);
2422 algname, fingerprint,
2423 signing_key_fingerprint);
2428 log_warn(
LD_BUG,
"Couldn't sign consensus networkstatus.");
2438 signing_key_fingerprint, 0);
2439 if (flavor == FLAV_NS) {
2441 signing_key_fingerprint);
2444 algname, fingerprint,
2445 signing_key_fingerprint);
2450 log_warn(
LD_BUG,
"Couldn't sign consensus networkstatus.");
2461 if (!(c = networkstatus_parse_vote_from_string(result, strlen(result),
2463 NS_TYPE_CONSENSUS))) {
2464 log_err(
LD_BUG,
"Generated a networkstatus consensus we couldn't "
2470 if (added_weights) {
2471 networkstatus_verify_bw_weights(c, consensus_method);
2473 networkstatus_vote_free(c);
2478 dircollator_free(collator);
2483 smartlist_free(flags);
2485 smartlist_free(chunks);
2487 smartlist_free(param_list);
2497 const int n_votes = smartlist_len(votes);
2503 strmap_t *package_status = strmap_new();
2506 if (! v->package_lines)
2513 const char *cp = strchr(line,
' ');
2516 cp = strchr(cp,
' ');
2519 char *key = tor_strndup(line, cp - line);
2521 const char **status = strmap_get(package_status, key);
2523 status = tor_calloc(n_votes,
sizeof(
const char *));
2524 strmap_set(package_status, key, status);
2526 status[v_sl_idx] = line;
2528 } SMARTLIST_FOREACH_END(line);
2529 } SMARTLIST_FOREACH_END(v);
2533 STRMAP_FOREACH(package_status, key,
const char **, values) {
2535 for (i = 0; i < n_votes; ++i) {
2540 int n_voting_for_entry = smartlist_len(entries);
2541 const char *most_frequent =
2544 if (n_voting_for_entry >= 3 && count > n_voting_for_entry / 2) {
2550 } STRMAP_FOREACH_END;
2557 smartlist_free(result_list);
2558 smartlist_free(entries);
2580 const char **msg_out)
2593 *msg_out =
"Valid-After times do not match "
2594 "when adding detached signatures to consensus";
2598 *msg_out =
"Fresh-until times do not match "
2599 "when adding detached signatures to consensus";
2603 *msg_out =
"Valid-until times do not match "
2604 "when adding detached signatures to consensus";
2607 siglist = strmap_get(sigs->
signatures, flavor);
2609 *msg_out =
"No signatures for given consensus flavor";
2619 *msg_out =
"No digests for given consensus flavor";
2628 *msg_out =
"Mismatched digest.";
2634 *msg_out =
"No recognized digests for given consensus flavor";
2644 const char *algorithm;
2651 log_info(
LD_DIR,
"Looking at signature from %s using %s", voter_identity,
2654 if (!target_voter) {
2655 log_info(
LD_DIR,
"We do not know any voter with ID %s", voter_identity);
2664 log_info(
LD_DIR,
"We already have a good signature from %s using %s",
2665 voter_identity, algorithm);
2670 if (!sig->good_signature && !sig->bad_signature) {
2672 sig->signing_key_digest);
2682 if (sig->good_signature || !old_sig || old_sig->
bad_signature) {
2683 log_info(
LD_DIR,
"Adding signature from %s with %s", voter_identity,
2685 tor_log(severity,
LD_DIR,
"Added a signature for %s from %s.",
2690 document_signature_free(old_sig);
2694 log_info(
LD_DIR,
"Not adding signature from %s", voter_identity);
2696 } SMARTLIST_FOREACH_END(sig);
2708 int for_detached_signatures)
2712 char *result = NULL;
2716 const char *keyword;
2718 if (for_detached_signatures && flavor != FLAV_NS)
2719 keyword =
"additional-signature";
2721 keyword =
"directory-signature";
2729 if (!sig->signature || sig->bad_signature)
2734 if (flavor == FLAV_NS) {
2736 "%s %s %s\n-----BEGIN SIGNATURE-----\n",
2739 const char *digest_name =
2742 "%s%s%s %s %s %s\n-----BEGIN SIGNATURE-----\n",
2744 for_detached_signatures ?
" " :
"",
2745 for_detached_signatures ? flavor_name :
"",
2746 digest_name, id, sk);
2748 base64_encode(buf,
sizeof(buf), sig->signature, sig->signature_len,
2749 BASE64_ENCODE_MULTILINE);
2750 strlcat(buf,
"-----END SIGNATURE-----\n",
sizeof(buf));
2752 } SMARTLIST_FOREACH_END(sig);
2753 } SMARTLIST_FOREACH_END(v);
2757 smartlist_free(elements);
2771 char *result = NULL, *sigs = NULL;
2778 if (ns && ns->flavor == FLAV_NS)
2781 if (!consensus_ns) {
2782 log_warn(
LD_BUG,
"No NS consensus given.");
2789 char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
2790 vu_buf[ISO_TIME_LEN+1];
2800 "consensus-digest %s\n"
2803 "valid-until %s\n", d, va_buf, fu_buf, vu_buf);
2810 if (ns->flavor == FLAV_NS)
2817 const char *alg_name =
2823 flavor_name, alg_name, d);
2825 } SMARTLIST_FOREACH_END(ns);
2829 char *sigs_on_this_consensus;
2830 if (ns->flavor == FLAV_NS)
2833 if (!sigs_on_this_consensus) {
2834 log_warn(
LD_DIR,
"Couldn't format signatures");
2838 } SMARTLIST_FOREACH_END(ns);
2849 smartlist_free(elements);
2863 for (flav = 0; flav < n_flavors; ++flav) {
2864 if (pending[flav].consensus)
2880 if (!authdir_mode_v3(options))
2882 tor_assert_nonfatal(voting_schedule.voting_starts);
2888 if (voting_schedule.created_on_demand) {
2891 log_notice(
LD_DIR,
"Scheduling voting. Known authority IDs are %s. "
2895 dirauth_sched_recalculate_timing(options, now);
2898#define IF_TIME_FOR_NEXT_ACTION(when_field, done_field) \
2899 if (! voting_schedule.done_field) { \
2900 if (voting_schedule.when_field > now) { \
2901 return voting_schedule.when_field; \
2907 IF_TIME_FOR_NEXT_ACTION(voting_starts, have_voted) {
2908 log_notice(
LD_DIR,
"Time to vote.");
2910 voting_schedule.have_voted = 1;
2912 IF_TIME_FOR_NEXT_ACTION(fetch_missing_votes, have_fetched_missing_votes) {
2913 log_notice(
LD_DIR,
"Time to fetch any votes that we're missing.");
2915 voting_schedule.have_fetched_missing_votes = 1;
2917 IF_TIME_FOR_NEXT_ACTION(voting_ends, have_built_consensus) {
2918 log_notice(
LD_DIR,
"Time to compute a consensus.");
2922 voting_schedule.have_built_consensus = 1;
2924 IF_TIME_FOR_NEXT_ACTION(fetch_missing_signatures,
2925 have_fetched_missing_signatures) {
2926 log_notice(
LD_DIR,
"Time to fetch any signatures that we're missing.");
2928 voting_schedule.have_fetched_missing_signatures = 1;
2930 IF_TIME_FOR_NEXT_ACTION(interval_starts,
2931 have_published_consensus) {
2932 log_notice(
LD_DIR,
"Time to publish the consensus and discard old votes");
2935 voting_schedule.have_published_consensus = 1;
2941 dirauth_sched_recalculate_timing(options, now);
2942 return voting_schedule.voting_starts;
2949#undef IF_TIME_FOR_NEXT_ACTION
2988 time_t now = time(NULL);
2991 const char *msg =
"";
2993 if (!cert || !key) {
2994 log_warn(
LD_NET,
"Didn't find key/certificate to generate v3 vote");
2996 }
else if (cert->
expires < now) {
2997 log_warn(
LD_NET,
"Can't generate v3 vote with expired certificate");
3004 networkstatus_vote_free(ns);
3010 if (!pending_vote) {
3011 log_warn(
LD_DIR,
"Couldn't store my own vote! (I told myself, '%s'.)",
3019 pending_vote->vote_body->
dir,
3020 pending_vote->vote_body->
dir_len, 0);
3021 log_notice(
LD_DIR,
"Vote posted.");
3039 DGV_BY_ID|DGV_INCLUDE_PENDING)) {
3045 } SMARTLIST_FOREACH_END(ds);
3047 if (!smartlist_len(missing_fps)) {
3048 smartlist_free(missing_fps);
3053 log_notice(
LOG_NOTICE,
"We're missing votes from %d authorities (%s). "
3054 "Asking every other authority for a copy.",
3055 smartlist_len(missing_fps), tmp);
3063 smartlist_free(missing_fps);
3116 v->vote_body = NULL;
3117 networkstatus_vote_free(v->vote);
3126 v->vote_body = NULL;
3127 networkstatus_vote_free(v->vote);
3160 smartlist_free(known_v3_keys);
3169 int any_sig_good = 0;
3171 if (sig->good_signature)
3186 TRUSTED_DIRS_CERTS_SRC_FROM_VOTE, 1 ,
3190 log_warn(
LD_BUG,
"We added a cert, but still couldn't find it.");
3202 const char *where_from,
3203 const char **msg_out,
int *status_out)
3209 const char *end_of_vote = NULL;
3221 vote = networkstatus_parse_vote_from_string(vote_body, strlen(vote_body),
3225 end_of_vote = vote_body + strlen(vote_body);
3227 log_warn(
LD_DIR,
"Couldn't parse vote: length was %d",
3228 (
int)strlen(vote_body));
3229 *msg_out =
"Unable to parse vote";
3234 assert_any_sig_good(vi);
3238 log_warn(
LD_DIR,
"Got a vote from an authority (nickname %s, address %s) "
3239 "with authority key ID %s. "
3240 "This key ID is not recognized. Known v3 key IDs are: %s",
3244 *msg_out =
"Vote not from a recognized v3 authority";
3247 add_new_cert_if_needed(vote->
cert);
3250 if (vote->
valid_after != voting_schedule.interval_starts) {
3251 char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1];
3254 log_warn(
LD_DIR,
"Rejecting vote from %s with valid-after time of %s; "
3255 "we were expecting %s", vi->
address, tbuf1, tbuf2);
3256 *msg_out =
"Bad valid-after time";
3261 log_notice(
LD_DIR,
"%s posted a vote to me from %s.",
3264 log_notice(
LD_DIR,
"Retrieved %s's vote from %s.",
3273 if (time_posted && time_posted > voting_schedule.fetch_missing_votes) {
3274 char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1];
3277 log_warn(
LD_DIR,
"Rejecting %s's posted vote from %s received at %s; "
3278 "our cutoff for received votes is %s. Check your clock, "
3279 "CPU load, and network load. Also check the authority that "
3281 *msg_out =
"Posted vote received too late, would be dangerous to count it";
3290 if (
fast_memeq(v->vote->cert->cache_info.identity_digest,
3296 log_notice(
LD_DIR,
"Discarding a vote we already have (from %s).",
3298 if (*status_out < 200)
3301 }
else if (v->vote->published < vote->
published) {
3302 log_notice(
LD_DIR,
"Replacing an older pending vote from this "
3303 "directory (%s)", vi->
address);
3305 networkstatus_vote_free(v->vote);
3307 end_of_vote-vote_body),
3311 !
strcmpstart(end_of_vote,
"network-status-version"))
3314 if (*status_out < 200)
3320 log_notice(
LD_DIR,
"Discarding vote from %s because we have "
3321 "a newer one already.", vi->
address);
3322 *msg_out =
"Already have a newer pending vote";
3326 } SMARTLIST_FOREACH_END(v);
3334 end_of_vote-vote_body),
3336 pending_vote->vote = vote;
3339 if (!
strcmpstart(end_of_vote,
"network-status-version ")) {
3340 vote_body = end_of_vote;
3349 *msg_out =
"Error adding vote";
3350 if (*status_out < 400)
3354 networkstatus_vote_free(vote);
3356 if (end_of_vote && !
strcmpstart(end_of_vote,
"network-status-version ")) {
3357 vote_body = end_of_vote;
3363 if (*status_out < 200)
3366 if (!any_failed && !pending_vote) {
3367 *msg_out =
"Duplicate discarded";
3373 return any_failed ? NULL : pending_vote;
3378write_v3_votes_to_disk(
const smartlist_t *pending_votes)
3381 char *votefile = NULL;
3386 c->bytes = v->vote_body->dir;
3387 c->len = v->vote_body->dir_len;
3391 votefile = get_datadir_fname(
"v3-status-votes");
3392 write_chunks_to_file(votefile, votestrings, 0, 0);
3393 log_debug(
LD_DIR,
"Wrote votes to disk (%s)!", votefile);
3397 smartlist_free(votestrings);
3408 int n_votes, n_voters, n_vote_running = 0;
3410 char *consensus_body = NULL, *signatures = NULL;
3416 memset(pending, 0,
sizeof(pending));
3434 if (n_votes <= n_voters/2) {
3435 log_warn(
LD_DIR,
"We don't have enough votes to generate a consensus: "
3436 "%d of %d", n_votes, n_voters/2+1);
3444 if (!n_vote_running) {
3446 log_warn(
LD_DIR,
"Nobody has voted on the Running flag. Generating "
3447 "and publishing a consensus without Running nodes "
3448 "would make many clients stop working. Not "
3449 "generating a consensus!");
3454 log_warn(
LD_DIR,
"Can't generate consensus without a certificate.");
3461 char *legacy_id_digest = NULL;
3462 int n_generated = 0;
3469 "Unable to compute digest of legacy v3 identity key");
3471 legacy_id_digest = legacy_dbuf;
3484 if (!consensus_body) {
3485 log_warn(
LD_DIR,
"Couldn't generate a %s consensus at all!",
3489 consensus = networkstatus_parse_vote_from_string(consensus_body,
3490 strlen(consensus_body),
3494 log_warn(
LD_DIR,
"Couldn't parse %s consensus we generated!",
3503 pending[flav].
body = consensus_body;
3507 consensus_body = NULL;
3511 log_warn(
LD_DIR,
"Couldn't generate any consensus flavors at all.");
3520 log_warn(
LD_DIR,
"Couldn't extract signatures.");
3525 memcpy(pending_consensuses, pending,
sizeof(pending));
3535 const char *msg = NULL;
3542 "Could not add queued signature to new consensus: %s",
3545 } SMARTLIST_FOREACH_END(sig);
3547 log_notice(
LD_DIR,
"Added %d pending signatures while building "
3548 "consensus.", n_sigs);
3552 log_notice(
LD_DIR,
"Consensus computed; uploading signature(s)");
3559 log_notice(
LD_DIR,
"Signature(s) posted.");
3561 smartlist_free(votes);
3564 smartlist_free(votes);
3567 networkstatus_vote_free(consensus);
3582 char *filename = NULL;
3583 tor_asprintf(&filename,
"my-consensus-%s", flavor_name);
3584 char *fpath_from = get_datadir_fname(filename);
3586 tor_asprintf(&filename,
"consensus-transparency-%s", flavor_name);
3587 char *fpath_to = get_datadir_fname(filename);
3590 replace_file(fpath_from, fpath_to);
3592 log_notice(
LD_DIR,
"Exported consensus transparency file %s.",
3608 const char **msg_out)
3610 const char *flavor_name;
3623 log_info(
LD_DIR,
"Have %d signatures for adding to %s consensus.",
3624 sig_list ? smartlist_len(sig_list) : 0, flavor_name);
3627 source, severity, msg_out);
3629 log_info(
LD_DIR,
"Added %d signatures to consensus.", r);
3632 "Unable to add signatures to consensus: %s",
3633 *msg_out ? *msg_out :
"(unknown)");
3637 char *new_signatures =
3639 char *dst, *dst_end;
3640 size_t new_consensus_len;
3641 if (!new_signatures) {
3642 *msg_out =
"No signatures to add";
3646 strlen(pc->
body) + strlen(new_signatures) + 1;
3647 pc->
body = tor_realloc(pc->
body, new_consensus_len);
3648 dst_end = pc->
body + new_consensus_len;
3651 strlcpy(dst, new_signatures, dst_end-dst);
3661 networkstatus_vote_free(v);
3663 *msg_out =
"Signatures added";
3675 }
else if (r == 0) {
3676 *msg_out =
"Signatures ignored";
3684 *msg_out =
"Unrecognized error while adding detached signatures.";
3699 const char *detached_signatures_body,
3701 const char **msg_out)
3703 int r=0, i, n_added = 0, errors = 0;
3709 if (!(sigs = networkstatus_parse_detached_signatures(
3710 detached_signatures_body, NULL))) {
3711 *msg_out =
"Couldn't parse detached signatures.";
3729 if (errors && !n_added) {
3734 if (n_added && pending_consensuses[FLAV_NS].consensus) {
3735 char *new_detached =
3748 *msg_out =
"Unrecognized error while adding detached signatures.";
3750 ns_detached_signatures_free(sigs);
3770 if (pending_consensuses[FLAV_NS].consensus) {
3771 log_notice(
LD_DIR,
"Got a signature from %s. "
3772 "Adding it to the pending consensus.", source);
3774 detached_signatures_body, source, msg);
3776 log_notice(
LD_DIR,
"Got a signature from %s. "
3777 "Queuing it for the next consensus.", source);
3781 detached_signatures_body);
3782 *msg =
"Signature queued";
3802 log_warn(
LD_DIR,
"Not enough info to publish pending %s consensus",
name);
3807 strlen(pending->
body),
3809 log_warn(
LD_DIR,
"Error publishing %s consensus",
name);
3811 log_notice(
LD_DIR,
"Published %s consensus",
name);
3846 return pending_consensuses[flav].
body;
3868 int by_id = flags & DGV_BY_ID;
3869 const int include_pending = flags & DGV_INCLUDE_PENDING;
3870 const int include_previous = flags & DGV_INCLUDE_PREVIOUS;
3886 return pv->vote_body);
3891 return pv->vote_body);
3897 return pv->vote_body);
3902 return pv->vote_body);
3914 (void) consensus_method;
3916 char *key = NULL, *summary = NULL, *family = NULL;
3919 char *output = NULL;
3955 if (summary && strcmp(summary,
"reject 1-65535"))
3963 if (p6 && strcmp(p6,
"reject 1-65535"))
3970 const char *keytype;
3973 keytype =
"ed25519";
3977 keytype =
"rsa1024";
3987 output+strlen(output), 0,
3989 if (smartlist_len(lst) != 1) {
3990 log_warn(
LD_DIR,
"We generated a microdescriptor we couldn't parse.");
3992 smartlist_free(lst);
3995 result = smartlist_get(lst, 0);
3996 smartlist_free(lst);
4000 crypto_pk_free(rsa_pubkey);
4007 smartlist_free(chunks);
4019 int consensus_method_low,
4020 int consensus_method_high)
4024 char *microdesc_consensus_methods =
4026 consensus_method_high,
4032 if (
tor_snprintf(out_buf, out_buf_len,
"m %s sha256=%s\n",
4033 microdesc_consensus_methods, d64)<0)
4036 ret = strlen(out_buf);
4039 tor_free(microdesc_consensus_methods);
4048} microdesc_consensus_methods[] = {
4077 for (cmr = microdesc_consensus_methods;
4078 cmr->low != -1 && cmr->high != -1;
4086 e->high = cmr->high;
4093 for (ep = entries; ep; ep = ep->next) {
4096 ep->low == ep->next->high + 1) {
4098 ep->low = next->low;
4099 microdesc_free(next->md);
4100 ep->next = next->next;
4106 while ((ep = entries)) {
4110 ep->low, ep->high) >= 0) {
4115 ep->md->last_listed = now;
4142 if (commits == NULL) {
4152 for (
int i = 0; i < tok->n_args; i++) {
4157 if (commit == NULL) {
4162 log_warn(
LD_DIR,
"SR: Unable to parse commit %s from vote of voter %s.",
4172 } SMARTLIST_FOREACH_END(tok);
4175 smartlist_free(chunks);
4176 smartlist_free(commits);
4204 smartlist_free(ns->
sr_info.commits);
4212dirvote_dirreq_get_status_vote(
const char *url,
smartlist_t *items,
4217 url += strlen(
"/tor/status-vote/");
4219 url = strchr(url,
'/');
4222 if (!strcmp(url,
"consensus")) {
4228 }
else if (!current && !strcmp(url,
"consensus-signatures")) {
4235 }
else if (!strcmp(url,
"authority")) {
4237 int flags = DGV_BY_ID |
4238 (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
4247 flags = DGV_INCLUDE_PENDING | DGV_INCLUDE_PREVIOUS;
4250 (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
4253 DSR_HEX|DSR_SORT_UNIQ);
4259 smartlist_free(fps);
4285 bw_kb = (uint32_t)mbw_kb;
4319 if (comparison == 0) {
4338 if (comparison == 0)
4354 int first_is_auth, second_is_auth;
4355 const node_t *node_first, *node_second;
4356 int first_is_running, second_is_running;
4357 uint32_t bw_kb_first, bw_kb_second;
4366 if (first_is_auth && !second_is_auth)
4368 else if (!first_is_auth && second_is_auth)
4373 first_is_running = node_first && node_first->
is_running;
4374 second_is_running = node_second && node_second->
is_running;
4375 if (first_is_running && !second_is_running)
4377 else if (!first_is_running && second_is_running)
4383 if (bw_kb_first > bw_kb_second)
4385 else if (bw_kb_first < bw_kb_second)
4404 digestmap_t *omit_as_sybil = digestmap_new();
4410 if (max_with_same_addr <= 0)
4411 max_with_same_addr = INT_MAX;
4414 if (family == AF_INET6)
4424 addrs_equal =
false;
4426 if (! addrs_equal) {
4429 }
else if (++addr_count > max_with_same_addr) {
4430 digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4432 } SMARTLIST_FOREACH_END(ri);
4433 smartlist_free(routers_by_ip);
4434 return omit_as_sybil;
4446 digestmap_t *omit_as_sybil_ipv4;
4447 digestmap_t *omit_as_sybil_ipv6;
4448 digestmap_t *omit_as_sybil = digestmap_new();
4459 } SMARTLIST_FOREACH_END(ri);
4465 digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4468 digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4471 smartlist_free(routers_ipv4);
4472 smartlist_free(routers_ipv6);
4473 digestmap_free(omit_as_sybil_ipv4, NULL);
4474 digestmap_free(omit_as_sybil_ipv6, NULL);
4476 return omit_as_sybil;
4493 return tor_strndup(platform, eos-platform);
4510 for ( ; ln; ln = ln->next) {
4512 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4519 if (strchr(v,
' ')) {
4521 log_warn(
LD_DIRSERV,
"Unexpected space in versions list member %s. "
4522 "(These are supposed to be comma-separated; I'll pretend you "
4523 "used commas instead.)",
escaped(v));
4526 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4529 } SMARTLIST_FOREACH_END(v);
4531 smartlist_free(more_versions);
4538 log_warn(
LD_DIRSERV,
"Recommended version %s does not look valid. "
4539 " (I'll include it anyway, since you told me to.)",
4542 } SMARTLIST_FOREACH_END(v);
4548 smartlist_free(versions);
4559 digest256map_t *by_ed_key = digest256map_new();
4562 ri->omit_from_vote = 0;
4563 if (ri->cache_info.signing_key_cert == NULL)
4565 const uint8_t *pk = ri->cache_info.signing_key_cert->signing_key.pubkey;
4566 if ((ri2 = digest256map_get(by_ed_key, pk))) {
4569 const time_t ri_pub = ri->cache_info.published_on;
4571 if (ri2_pub < ri_pub ||
4572 (ri2_pub == ri_pub &&
4573 fast_memcmp(ri->cache_info.signed_descriptor_digest,
4575 digest256map_set(by_ed_key, pk, ri);
4578 ri->omit_from_vote = 1;
4582 digest256map_set(by_ed_key, pk, ri);
4584 } SMARTLIST_FOREACH_END(ri);
4586 digest256map_free(by_ed_key, NULL);
4590 if (ri->omit_from_vote) {
4593 } SMARTLIST_FOREACH_END(ri);
4648 char *hostname = NULL, *client_versions = NULL, *server_versions = NULL;
4649 const char *contact;
4656 time_t now = time(NULL);
4669 log_err(
LD_BUG,
"Error computing signing key digest");
4673 log_err(
LD_BUG,
"Error computing identity key digest");
4677 log_warn(
LD_NET,
"Couldn't resolve my hostname");
4680 if (!hostname || !strchr(hostname,
'.')) {
4686 log_err(
LD_BUG,
"Failed to determine hostname AND duplicate address");
4721 dirserv_set_router_is_running(ri, now);
4745 if (ri->protocol_list &&
4749 if (ri->cache_info.published_on >= cutoff) {
4763 if (ri->cache_info.signing_key_cert) {
4765 ri->cache_info.signing_key_cert->signing_key.pubkey,
4768 if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
4771 if (!vote_on_reachability)
4775 if (ri->protocol_list) {
4776 vrs->
protocols = tor_strdup(ri->protocol_list);
4786 } SMARTLIST_FOREACH_END(ri);
4792 smartlist_free(added);
4793 smartlist_free(microdescriptors);
4796 smartlist_free(routers);
4797 digestmap_free(omit_as_sybil, NULL);
4810 routerstatuses, bw_file_headers,
4824 v3_out->
type = NS_TYPE_VOTE;
4828 char tbuf[ISO_TIME_LEN+1];
4831 long last_consensus_interval;
4832 if (current_consensus)
4833 last_consensus_interval = current_consensus->
fresh_until -
4839 (
int)last_consensus_interval,
4842 log_notice(
LD_DIR,
"Choosing valid-after time in vote as %s: "
4843 "consensus_set=%d, last_interval=%d",
4844 tbuf, current_consensus?1:0, (int)last_consensus_interval);
4856 v3_out->server_versions = server_versions;
4860 v3_out->recommended_client_protocols =
4862 v3_out->required_client_protocols =
4864 v3_out->required_relay_protocols =
4875 v3_out->recommended_client_protocols, NULL));
4880 0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4881 if (vote_on_reachability)
4885 if (list_middle_only)
4892 for ( ; paramline; paramline = paramline->next) {
4894 paramline->value, NULL, 0, 0);
4917 voter->
contact = tor_strdup(contact);
4922 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_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