6 #define DIRVOTE_PRIVATE
69 #define DIGEST_ALG_BW_FILE DIGEST_SHA256
122 const char *detached_signatures_body,
124 const char **msg_out);
130 const char **msg_out);
170 format_line_if_present(
const char *keyword,
const char *opt_value)
177 return tor_strdup(
"");
186 char *recommended_relay_protocols_line = NULL;
187 char *recommended_client_protocols_line = NULL;
188 char *required_relay_protocols_line = NULL;
189 char *required_client_protocols_line = NULL;
191 recommended_relay_protocols_line =
192 format_line_if_present(
"recommended-relay-protocols",
194 recommended_client_protocols_line =
195 format_line_if_present(
"recommended-client-protocols",
196 v3_ns->recommended_client_protocols);
197 required_relay_protocols_line =
198 format_line_if_present(
"required-relay-protocols",
199 v3_ns->required_relay_protocols);
200 required_client_protocols_line =
201 format_line_if_present(
"required-client-protocols",
202 v3_ns->required_client_protocols);
206 recommended_relay_protocols_line,
207 recommended_client_protocols_line,
208 required_relay_protocols_line,
209 required_client_protocols_line);
211 tor_free(recommended_relay_protocols_line);
212 tor_free(recommended_client_protocols_line);
213 tor_free(required_relay_protocols_line);
214 tor_free(required_client_protocols_line);
229 char *protocols_lines = NULL;
230 char *client_versions_line = NULL, *server_versions_line = NULL;
231 char *shared_random_vote_str = NULL;
238 voter = smartlist_get(v3_ns->
voters, 0);
243 client_versions_line = format_line_if_present(
"client-versions",
245 server_versions_line = format_line_if_present(
"server-versions",
246 v3_ns->server_versions);
253 char published[ISO_TIME_LEN+1];
254 char va[ISO_TIME_LEN+1];
255 char fu[ISO_TIME_LEN+1];
256 char vu[ISO_TIME_LEN+1];
261 char *bw_headers_line = NULL;
262 char *bw_file_digest = NULL;
275 params = tor_strdup(
"");
281 char *bw_file_headers = NULL;
292 if (!bw_file_headers) {
294 bw_file_headers = tor_strdup(
"");
297 bw_headers_line = format_line_if_present(
"bandwidth-file-headers",
313 char *digest_algo_b64_digest_bw_file = NULL;
318 bw_file_digest = format_line_if_present(
319 "bandwidth-file-digest", digest_algo_b64_digest_bw_file);
320 tor_free(digest_algo_b64_digest_bw_file);
323 const char *ip_str =
fmt_addr(&voter->ipv4_addr);
327 "network-status-version 3\n"
329 "consensus-methods %s\n"
334 "voting-delay %d %d\n"
338 "flag-thresholds %s\n"
342 "dir-source %s %s %s %s %d %d\n"
346 v3_ns->
type == NS_TYPE_VOTE ?
"vote" :
"opinion",
348 published, va, fu, vu,
350 client_versions_line,
351 server_versions_line,
356 bw_headers_line ? bw_headers_line :
"",
357 bw_file_digest ? bw_file_digest:
"",
361 shared_random_vote_str ?
362 shared_random_vote_str :
"");
373 if (ip_str[0] ==
'\0')
391 vrs->version, vrs->protocols,
397 for (h = vrs->microdesc; h; h = h->
next) {
400 } SMARTLIST_FOREACH_END(vrs);
406 crypto_digest_smartlist(digest,
DIGEST_LEN, chunks,
407 "directory-signature ", DIGEST_SHA1);
412 signing_key_fingerprint, 0)<0) {
413 log_warn(
LD_BUG,
"Unable to get fingerprint for signing key");
418 signing_key_fingerprint);
423 private_signing_key);
425 log_warn(
LD_BUG,
"Unable to sign networkstatus vote.");
438 log_err(
LD_BUG,
"Generated a networkstatus %s we couldn't parse: "
440 v3_ns->
type == NS_TYPE_VOTE ?
"vote" :
"opinion", status);
443 networkstatus_vote_free(v);
456 smartlist_free(chunks);
506 num_len = strspn(cp,
"1234567890");
507 if (num_len == mlen &&
fast_memeq(mstr, cp, mlen)) {
512 cp = strstr(cp, dstr);
516 strlcpy(buf, cp,
sizeof(buf));
519 if (num_len == 0 || cp[num_len] !=
',')
536 return smartlist_get(vote->
voters, 0);
567 const char *a_id, *b_id;
569 b_id = b->is_legacy ? b_v->legacy_id_digest : b_v->identity_digest;
582 if (cur && !strcmp(cp, cur)) {
590 } SMARTLIST_FOREACH_END(cp);
597 #define get_most_frequent_member(lst) \
598 smartlist_get_most_frequent_string(lst)
620 #define CMP_FIELD(utype, itype, field) do { \
621 utype aval = (utype) (itype) a->status.field; \
622 utype bval = (utype) (itype) b->status.field; \
623 utype u = bval - aval; \
624 itype r2 = (itype) u; \
627 } else if (r2 > 0) { \
632 CMP_FIELD(uint64_t, int64_t, published_on);
641 CMP_FIELD(
unsigned,
int, ipv4_orport);
642 CMP_FIELD(
unsigned,
int, ipv4_dirport);
664 if ((r = (((
int) b->port) - ((
int) a->port))))
677 char *microdesc_digest256_out,
681 int most_n = 0, cur_n = 0;
682 time_t most_published = 0;
693 if (cur && (cur_n > most_n ||
695 cur->status.published_on > most_published))) {
703 } SMARTLIST_FOREACH_END(rs);
705 if (cur_n > most_n ||
706 (cur && cur_n == most_n && cur->status.published_on > most_published)) {
719 if (best_alt_orport_out) {
727 && rs->status.ipv6_orport) {
729 rs->status.ipv6_orport));
731 } SMARTLIST_FOREACH_END(rs);
734 most_alt_orport = smartlist_get_most_frequent(alt_orports,
736 if (most_alt_orport) {
738 log_debug(
LD_DIR,
"\"a\" line winner for %s is %s",
740 fmt_addrport(&most_alt_orport->addr, most_alt_orport->port));
744 smartlist_free(alt_orports);
747 if (microdesc_digest256_out) {
749 const uint8_t *best_microdesc_digest;
757 } SMARTLIST_FOREACH_END(rs);
760 if (best_microdesc_digest)
761 memcpy(microdesc_digest256_out, best_microdesc_digest,
DIGEST256_LEN);
763 smartlist_free(digests);
775 const char *a = *_a, *b = *_b;
797 int min = (smartlist_len(votes) * 2) / 3;
812 n_ok = smartlist_len(acceptable_methods);
814 const char *best = smartlist_get(acceptable_methods, n_ok-1);
820 smartlist_free(all_methods);
821 smartlist_free(acceptable_methods);
843 for (i = low; i <= high; ++i) {
862 int min = n_versioning / 2;
866 if (strchr(v,
' ')) {
867 log_warn(
LD_DIR,
"At least one authority has voted for a version %s "
868 "that contains a space. This probably wasn't intentional, and "
869 "is likely to cause trouble. Please tell them to stop it.",
872 } SMARTLIST_FOREACH_END(v);
876 smartlist_free(good);
889 unsigned int n_found = 0;
890 int32_t value = default_val;
893 if (!
strcmpstart(k_v_pair, keyword) && k_v_pair[strlen(keyword)] ==
'=') {
894 const char *integer_str = &k_v_pair[strlen(keyword)+1];
902 } SMARTLIST_FOREACH_END(k_v_pair);
907 tor_assert_nonfatal(n_found == 0);
915 #define MIN_VOTES_FOR_PARAM 3
927 const char *cur_param;
930 const int n_votes = smartlist_len(votes);
940 vals = tor_calloc(n_votes,
sizeof(
int));
946 } SMARTLIST_FOREACH_END(v);
948 if (smartlist_len(param_list) == 0) {
955 cur_param = smartlist_get(param_list, 0);
956 eq = strchr(cur_param,
'=');
958 cur_param_len = (int)(eq+1 - cur_param);
966 const char *next_param;
968 eq = strchr(param,
'=');
970 vals[i++] = (int32_t)
974 if (param_sl_idx+1 == smartlist_len(param_list))
977 next_param = smartlist_get(param_list, param_sl_idx+1);
979 if (!next_param || strncmp(next_param, param, cur_param_len)) {
983 if (i > total_authorities/2 ||
985 int32_t median = median_int32(vals, i);
986 char *out_string = tor_malloc(64+cur_param_len);
987 memcpy(out_string, param, cur_param_len);
988 tor_snprintf(out_string+cur_param_len,64,
"%ld", (
long)median);
994 eq = strchr(next_param,
'=');
995 cur_param_len = (int)(eq+1 - next_param);
998 } SMARTLIST_FOREACH_END(param);
1000 smartlist_free(param_list);
1005 #define RANGE_CHECK(a,b,c,d,e,f,g,mx) \
1006 ((a) >= 0 && (a) <= (mx) && (b) >= 0 && (b) <= (mx) && \
1007 (c) >= 0 && (c) <= (mx) && (d) >= 0 && (d) <= (mx) && \
1008 (e) >= 0 && (e) <= (mx) && (f) >= 0 && (f) <= (mx) && \
1009 (g) >= 0 && (g) <= (mx))
1011 #define CHECK_EQ(a, b, margin) \
1012 ((a)-(b) >= 0 ? (a)-(b) <= (margin) : (b)-(a) <= (margin))
1015 BW_WEIGHTS_NO_ERROR = 0,
1016 BW_WEIGHTS_RANGE_ERROR = 1,
1017 BW_WEIGHTS_SUMG_ERROR = 2,
1018 BW_WEIGHTS_SUME_ERROR = 3,
1019 BW_WEIGHTS_SUMD_ERROR = 4,
1020 BW_WEIGHTS_BALANCE_MID_ERROR = 5,
1021 BW_WEIGHTS_BALANCE_EG_ERROR = 6
1022 } bw_weights_error_t;
1027 static bw_weights_error_t
1029 int64_t Wme, int64_t Wmd, int64_t Wee,
1030 int64_t Wed, int64_t scale, int64_t G,
1031 int64_t M, int64_t E, int64_t D, int64_t
T,
1032 int64_t margin,
int do_balance) {
1033 bw_weights_error_t berr = BW_WEIGHTS_NO_ERROR;
1036 if (!CHECK_EQ(Wed + Wmd + Wgd, scale, margin)) {
1037 berr = BW_WEIGHTS_SUMD_ERROR;
1042 if (!CHECK_EQ(Wmg + Wgg, scale, margin)) {
1043 berr = BW_WEIGHTS_SUMG_ERROR;
1048 if (!CHECK_EQ(Wme + Wee, scale, margin)) {
1049 berr = BW_WEIGHTS_SUME_ERROR;
1054 if (!RANGE_CHECK(Wgg, Wgd, Wmg, Wme, Wmd, Wed, Wee, scale)) {
1055 berr = BW_WEIGHTS_RANGE_ERROR;
1061 if (!CHECK_EQ(Wgg*G + Wgd*D, Wee*E + Wed*D, (margin*
T)/3)) {
1062 berr = BW_WEIGHTS_BALANCE_EG_ERROR;
1067 if (!CHECK_EQ(Wgg*G + Wgd*D, M*scale + Wmd*D + Wme*E + Wmg*G,
1069 berr = BW_WEIGHTS_BALANCE_MID_ERROR;
1077 "Bw weight mismatch %d. G=%"PRId64
" M=%"PRId64
1078 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1079 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1080 " Wgd=%d Wgg=%d Wme=%d Wmg=%d",
1084 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1085 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg);
1098 int64_t M, int64_t E, int64_t D,
1099 int64_t
T, int64_t weight_scale)
1101 bw_weights_error_t berr = 0;
1102 int64_t Wgg = -1, Wgd = -1;
1103 int64_t Wmg = -1, Wme = -1, Wmd = -1;
1104 int64_t Wed = -1, Wee = -1;
1105 const char *casename;
1107 if (G <= 0 || M <= 0 || E <= 0 || D <= 0) {
1108 log_warn(
LD_DIR,
"Consensus with empty bandwidth: "
1109 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
1110 " D=%"PRId64
" T=%"PRId64,
1127 if (3*E >=
T && 3*G >=
T) {
1129 casename =
"Case 1 (Wgd=Wmd=Wed)";
1130 Wgd = weight_scale/3;
1131 Wed = weight_scale/3;
1132 Wmd = weight_scale/3;
1133 Wee = (weight_scale*(E+G+M))/(3*E);
1134 Wme = weight_scale - Wee;
1135 Wmg = (weight_scale*(2*G-E-M))/(3*G);
1136 Wgg = weight_scale - Wmg;
1139 weight_scale, G, M, E, D,
T, 10, 1);
1143 "Bw Weights error %d for %s v10. G=%"PRId64
" M=%"PRId64
1144 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1145 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1146 " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
1150 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1151 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1154 }
else if (3*E <
T && 3*G <
T) {
1155 int64_t R = MIN(E, G);
1156 int64_t S =
MAX(E, G);
1169 casename =
"Case 2a (E scarce)";
1173 casename =
"Case 2a (G scarce)";
1178 casename =
"Case 2b1 (Wgg=weight_scale, Wmd=Wgd)";
1179 Wee = (weight_scale*(E - G + M))/E;
1180 Wed = (weight_scale*(D - 2*E + 4*G - 2*M))/(3*D);
1181 Wme = (weight_scale*(G-M))/E;
1184 Wmd = (weight_scale - Wed)/2;
1185 Wgd = (weight_scale - Wed)/2;
1188 weight_scale, G, M, E, D,
T, 10, 1);
1191 casename =
"Case 2b2 (Wgg=weight_scale, Wee=weight_scale)";
1194 Wed = (weight_scale*(D - 2*E + G + M))/(3*D);
1195 Wmd = (weight_scale*(D - 2*M + G + E))/(3*D);
1200 casename =
"Case 2b3 (Wmd=0)";
1203 "Too much Middle bandwidth on the network to calculate "
1204 "balanced bandwidth-weights. Consider increasing the "
1205 "number of Guard nodes by lowering the requirements.");
1207 Wgd = weight_scale - Wed - Wmd;
1209 Wed, weight_scale, G, M, E, D,
T, 10, 1);
1211 if (berr != BW_WEIGHTS_NO_ERROR &&
1212 berr != BW_WEIGHTS_BALANCE_MID_ERROR) {
1214 "Bw Weights error %d for %s v10. G=%"PRId64
" M=%"PRId64
1215 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1216 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1217 " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
1221 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1222 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1227 int64_t S = MIN(E, G);
1229 if (!(3*E <
T || 3*G <
T) || !(3*G >=
T || 3*E >=
T)) {
1231 "Bw-Weights Case 3 v10 but with G=%"PRId64
" M="
1232 "%"PRId64
" E=%"PRId64
" D=%"PRId64
" T=%"PRId64,
1239 casename =
"Case 3a (G scarce)";
1240 Wgg = Wgd = weight_scale;
1241 Wmd = Wed = Wmg = 0;
1245 else Wme = (weight_scale*(E-M))/(2*E);
1246 Wee = weight_scale-Wme;
1248 casename =
"Case 3a (E scarce)";
1249 Wee = Wed = weight_scale;
1250 Wmd = Wgd = Wme = 0;
1254 else Wmg = (weight_scale*(G-M))/(2*G);
1255 Wgg = weight_scale-Wmg;
1260 casename =
"Case 3bg (G scarce, Wgg=weight_scale, Wmd == Wed)";
1262 Wgd = (weight_scale*(D - 2*G + E + M))/(3*D);
1264 Wee = (weight_scale*(E+M))/(2*E);
1265 Wme = weight_scale - Wee;
1266 Wmd = (weight_scale - Wgd)/2;
1267 Wed = (weight_scale - Wgd)/2;
1270 Wed, weight_scale, G, M, E, D,
T, 10, 1);
1272 casename =
"Case 3be (E scarce, Wee=weight_scale, Wmd == Wgd)";
1274 Wed = (weight_scale*(D - 2*E + G + M))/(3*D);
1276 Wgg = (weight_scale*(G+M))/(2*G);
1277 Wmg = weight_scale - Wgg;
1278 Wmd = (weight_scale - Wed)/2;
1279 Wgd = (weight_scale - Wed)/2;
1282 Wed, weight_scale, G, M, E, D,
T, 10, 1);
1286 "Bw Weights error %d for %s v10. G=%"PRId64
" M=%"PRId64
1287 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1288 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1289 " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
1293 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1294 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1303 tor_assert(0 < weight_scale && weight_scale <= INT32_MAX);
1314 "bandwidth-weights Wbd=%d Wbe=%d Wbg=%d Wbm=%d "
1316 "Web=%d Wed=%d Wee=%d Weg=%d Wem=%d "
1317 "Wgb=%d Wgd=%d Wgg=%d Wgm=%d "
1318 "Wmb=%d Wmd=%d Wme=%d Wmg=%d Wmm=%d\n",
1319 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)weight_scale,
1321 (
int)weight_scale, (
int)Wed, (
int)Wee, (
int)Wed, (
int)Wee,
1322 (
int)weight_scale, (
int)Wgd, (
int)Wgg, (
int)Wgg,
1323 (
int)weight_scale, (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1325 log_notice(
LD_CIRC,
"Computed bandwidth weights for %s with v10: "
1326 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
1338 int is_exit,
int is_guard,
1339 int64_t *G, int64_t *M, int64_t *E, int64_t *D,
1343 int guardfraction_bandwidth = 0;
1346 log_info(
LD_BUG,
"Missing consensus bandwidth for router %s",
1377 guard_get_guardfraction_bandwidth(&guardfraction_bw,
1381 default_bandwidth = guardfraction_bw.
guard_bw;
1382 guardfraction_bandwidth = guardfraction_bw.
non_guard_bw;
1391 *
T += default_bandwidth;
1392 if (is_exit && is_guard) {
1394 *D += default_bandwidth;
1396 *E += guardfraction_bandwidth;
1399 }
else if (is_exit) {
1401 *E += default_bandwidth;
1403 }
else if (is_guard) {
1405 *G += default_bandwidth;
1407 *M += guardfraction_bandwidth;
1412 *M += default_bandwidth;
1424 case 0:
return vote->recommended_client_protocols;
1426 case 2:
return vote->required_client_protocols;
1427 case 3:
return vote->required_relay_protocols;
1429 tor_assert_unreached();
1441 const char *keyword;
1446 keyword =
"recommended-client-protocols";
1447 threshold = CEIL_DIV(n_voters, 2);
1450 keyword =
"recommended-relay-protocols";
1451 threshold = CEIL_DIV(n_voters, 2);
1454 keyword =
"required-client-protocols";
1455 threshold = CEIL_DIV(n_voters * 2, 3);
1458 keyword =
"required-relay-protocols";
1459 threshold = CEIL_DIV(n_voters * 2, 3);
1462 tor_assert_unreached();
1470 } SMARTLIST_FOREACH_END(ns);
1473 smartlist_free(proto_votes);
1475 char *result = NULL;
1503 int total_authorities,
1506 const char *legacy_id_key_digest,
1511 char *result = NULL;
1512 int consensus_method;
1513 time_t valid_after, fresh_until, valid_until;
1514 int vote_seconds, dist_seconds;
1515 char *client_versions = NULL, *server_versions = NULL;
1517 const char *flavor_name;
1519 int64_t G, M, E, D,
T;
1522 char *params = NULL;
1523 char *packages = NULL;
1524 int added_weights = 0;
1525 dircollator_t *collator = NULL;
1528 tor_assert(flavor == FLAV_NS || flavor == FLAV_MICRODESC);
1529 tor_assert(total_authorities >= smartlist_len(votes));
1534 if (!smartlist_len(votes)) {
1535 log_warn(
LD_DIR,
"Can't compute a consensus from no votes.");
1542 log_info(
LD_DIR,
"Generating consensus using method %d.",
1545 log_warn(
LD_DIR,
"The other authorities will use consensus method %d, "
1546 "which I don't support. Maybe I should upgrade!",
1561 int n_votes = smartlist_len(votes);
1562 time_t *va_times = tor_calloc(n_votes,
sizeof(time_t));
1563 time_t *fu_times = tor_calloc(n_votes,
sizeof(time_t));
1564 time_t *vu_times = tor_calloc(n_votes,
sizeof(time_t));
1565 int *votesec_list = tor_calloc(n_votes,
sizeof(
int));
1566 int *distsec_list = tor_calloc(n_votes,
sizeof(
int));
1567 int n_versioning_clients = 0, n_versioning_servers = 0;
1573 va_times[v_sl_idx] = v->valid_after;
1574 fu_times[v_sl_idx] = v->fresh_until;
1575 vu_times[v_sl_idx] = v->valid_until;
1576 votesec_list[v_sl_idx] = v->vote_seconds;
1577 distsec_list[v_sl_idx] = v->dist_seconds;
1578 if (v->client_versions) {
1580 ++n_versioning_clients;
1582 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1587 if (v->server_versions) {
1589 ++n_versioning_servers;
1591 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1598 } SMARTLIST_FOREACH_END(v);
1599 valid_after = median_time(va_times, n_votes);
1600 fresh_until = median_time(fu_times, n_votes);
1601 valid_until = median_time(vu_times, n_votes);
1602 vote_seconds = median_int(votesec_list, n_votes);
1603 dist_seconds = median_int(distsec_list, n_votes);
1615 n_versioning_servers);
1617 n_versioning_clients);
1622 smartlist_free(combined_server_versions);
1623 smartlist_free(combined_client_versions);
1640 char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
1641 vu_buf[ISO_TIME_LEN+1];
1649 "vote-status consensus\n",
1650 flavor == FLAV_NS ?
"" :
" ",
1651 flavor == FLAV_NS ?
"" : flavor_name);
1660 "voting-delay %d %d\n"
1661 "client-versions %s\n"
1662 "server-versions %s\n"
1665 va_buf, fu_buf, vu_buf,
1666 vote_seconds, dist_seconds,
1667 client_versions, server_versions,
1677 for (idx = 0; idx < 4; ++idx) {
1679 if (BUG(!proto_line))
1687 if (smartlist_len(param_list)) {
1699 int32_t num_srv_agreements =
1701 "AuthDirNumSRVAgreements",
1702 (num_dirauth * 2) / 3);
1705 if (srv_lines != NULL) {
1725 e_legacy->is_legacy = 1;
1728 } SMARTLIST_FOREACH_END(v);
1742 "dir-source %s%s %s %s %s %d %d\n",
1743 voter->
nickname, e->is_legacy ?
"-legacy" :
"",
1747 if (! e->is_legacy) {
1754 } SMARTLIST_FOREACH_END(e);
1756 smartlist_free(dir_sources);
1766 if (max_unmeasured_bw_kb < 1)
1767 max_unmeasured_bw_kb = 1;
1782 uint32_t *bandwidths_kb = tor_calloc(smartlist_len(votes),
1784 uint32_t *measured_bws_kb = tor_calloc(smartlist_len(votes),
1786 uint32_t *measured_guardfraction = tor_calloc(smartlist_len(votes),
1790 int num_guardfraction_inputs;
1800 int n_authorities_measuring_bandwidth;
1802 strmap_t *name_to_id_map = strmap_new();
1805 memset(conflict, 0,
sizeof(conflict));
1806 memset(unknown, 0xff,
sizeof(conflict));
1808 size = tor_calloc(smartlist_len(votes),
sizeof(
int));
1809 n_voter_flags = tor_calloc(smartlist_len(votes),
sizeof(
int));
1810 n_flag_voters = tor_calloc(smartlist_len(flags),
sizeof(
int));
1811 flag_map = tor_calloc(smartlist_len(votes),
sizeof(
int *));
1812 named_flag = tor_calloc(smartlist_len(votes),
sizeof(
int));
1813 unnamed_flag = tor_calloc(smartlist_len(votes),
sizeof(
int));
1814 for (i = 0; i < smartlist_len(votes); ++i)
1815 unnamed_flag[i] = named_flag[i] = -1;
1824 flag_map[v_sl_idx] = tor_calloc(smartlist_len(v->known_flags),
1827 log_warn(
LD_BUG,
"Somehow, a vote has %d entries in known_flags",
1828 smartlist_len(v->known_flags));
1833 flag_map[v_sl_idx][fl_sl_idx] = p;
1835 if (!strcmp(fl,
"Named"))
1836 named_flag[v_sl_idx] = fl_sl_idx;
1837 if (!strcmp(fl,
"Unnamed"))
1838 unnamed_flag[v_sl_idx] = fl_sl_idx;
1839 } SMARTLIST_FOREACH_END(fl);
1840 n_voter_flags[v_sl_idx] = smartlist_len(v->known_flags);
1841 size[v_sl_idx] = smartlist_len(v->routerstatus_list);
1842 } SMARTLIST_FOREACH_END(v);
1848 if (named_flag[v_sl_idx]<0)
1850 nf = UINT64_C(1) << named_flag[v_sl_idx];
1854 if ((rs->flags & nf) != 0) {
1855 const char *d =
strmap_get_lc(name_to_id_map, rs->status.nickname);
1859 rs->status.identity_digest);
1860 }
else if (d != conflict &&
1863 strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
1868 } SMARTLIST_FOREACH_END(rs);
1869 } SMARTLIST_FOREACH_END(v);
1873 if (unnamed_flag[v_sl_idx]<0)
1875 uf = UINT64_C(1) << unnamed_flag[v_sl_idx];
1878 if ((rs->flags & uf) != 0) {
1879 const char *d =
strmap_get_lc(name_to_id_map, rs->status.nickname);
1880 if (d == conflict || d == unknown) {
1884 strmap_set_lc(name_to_id_map, rs->status.nickname, unknown);
1887 strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
1892 } SMARTLIST_FOREACH_END(rs);
1893 } SMARTLIST_FOREACH_END(v);
1897 n_authorities_measuring_bandwidth = 0;
1899 if (v->has_measured_bws) {
1900 ++n_authorities_measuring_bandwidth;
1908 } SMARTLIST_FOREACH_END(v);
1913 flag_counts = tor_calloc(smartlist_len(flags),
sizeof(
int));
1915 for (i = 0; i < num_routers; ++i) {
1921 const char *current_rsa_id = NULL;
1922 const char *chosen_version;
1923 const char *chosen_protocol_list;
1924 const char *chosen_name = NULL;
1925 int exitsummary_disagreement = 0;
1926 int is_named = 0, is_unnamed = 0, is_running = 0, is_valid = 0;
1927 int is_guard = 0, is_exit = 0, is_bad_exit = 0;
1928 int naming_conflict = 0;
1933 memset(flag_counts, 0,
sizeof(
int)*smartlist_len(flags));
1940 num_guardfraction_inputs = 0;
1941 int ed_consensus = 0;
1942 const uint8_t *ed_consensus_val = NULL;
1945 for (
int voter_idx = 0; voter_idx < smartlist_len(votes); ++voter_idx) {
1946 if (vrs_lst[voter_idx] == NULL)
1948 rs = vrs_lst[voter_idx];
1964 for (
int flag = 0; flag < n_voter_flags[voter_idx]; ++flag) {
1965 if (rs->
flags & (UINT64_C(1) << flag))
1966 ++flag_counts[flag_map[voter_idx][flag]];
1968 if (named_flag[voter_idx] >= 0 &&
1969 (rs->
flags & (UINT64_C(1) << named_flag[voter_idx]))) {
1971 log_notice(
LD_DIR,
"Conflict on naming for router: %s vs %s",
1973 naming_conflict = 1;
1980 measured_guardfraction[num_guardfraction_inputs++] =
1994 if (ed_consensus_val) {
2005 if (n_listing <= total_authorities/2)
2008 if (ed_consensus > 0) {
2009 if (ed_consensus <= total_authorities / 2) {
2010 log_warn(
LD_BUG,
"Not enough entries had ed_consensus set; how "
2011 "can we have a consensus of %d?", ed_consensus);
2021 memset(microdesc_digest, 0,
sizeof(microdesc_digest));
2023 microdesc_digest, &alt_orport);
2025 memset(&rs_out, 0,
sizeof(rs_out));
2040 if (chosen_name && !naming_conflict) {
2049 is_named = is_unnamed = 0;
2051 is_named = 1; is_unnamed = 0;
2053 is_named = 0; is_unnamed = 1;
2060 if (!strcmp(fl,
"Named")) {
2063 }
else if (!strcmp(fl,
"Unnamed")) {
2066 }
else if (!strcmp(fl,
"NoEdConsensus")) {
2067 if (ed_consensus <= total_authorities/2)
2070 if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2) {
2072 if (!strcmp(fl,
"Exit"))
2074 else if (!strcmp(fl,
"Guard"))
2076 else if (!strcmp(fl,
"Running"))
2078 else if (!strcmp(fl,
"BadExit"))
2080 else if (!strcmp(fl,
"Valid"))
2084 } SMARTLIST_FOREACH_END(fl);
2097 if (smartlist_len(versions)) {
2101 chosen_version = NULL;
2105 if (smartlist_len(protocols)) {
2109 chosen_protocol_list = NULL;
2114 if (is_guard && num_guardfraction_inputs > 2) {
2117 num_guardfraction_inputs);
2126 rs_out.
bandwidth_kb = median_uint32(measured_bws_kb, num_mbws);
2127 }
else if (num_bandwidths > 0) {
2130 rs_out.
bandwidth_kb = median_uint32(bandwidths_kb, num_bandwidths);
2131 if (n_authorities_measuring_bandwidth > 2) {
2140 is_exit = is_exit && !is_bad_exit;
2146 &G, &M, &E, &D, &
T);
2166 const char *chosen_exitsummary = NULL;
2172 vsr->status.identity_digest,
2174 if (vsr->status.has_exitsummary &&
2176 vsr->status.descriptor_digest,
2180 if (!chosen_exitsummary) {
2181 chosen_exitsummary = vsr->status.exitsummary;
2182 }
else if (strcmp(chosen_exitsummary, vsr->status.exitsummary)) {
2185 exitsummary_disagreement = 1;
2188 } SMARTLIST_FOREACH_END(vsr);
2190 if (exitsummary_disagreement) {
2195 log_warn(
LD_DIR,
"The voters disagreed on the exit policy summary "
2196 " for router %s with descriptor %s. This really shouldn't"
2197 " have happened.",
id, dd);
2201 }
else if (!chosen_exitsummary) {
2206 log_warn(
LD_DIR,
"Not one of the voters that made us select"
2207 "descriptor %s for router %s had an exit policy"
2215 if (vsr->status.has_exitsummary)
2221 if (!chosen_exitsummary)
2222 log_warn(
LD_DIR,
"Wow, not one of the voters had an exit "
2223 "policy summary for %s. Wow.",
id);
2226 if (chosen_exitsummary) {
2233 if (flavor == FLAV_MICRODESC &&
2249 if (flavor == FLAV_MICRODESC &&
2259 if (chosen_version) {
2264 if (chosen_protocol_list) {
2269 char *guardfraction_str = NULL;
2279 unmeasured?
" Unmeasured=1":
"",
2280 guardfraction_str ? guardfraction_str :
"");
2296 for (i = 0; i < smartlist_len(votes); ++i)
2302 strmap_free(name_to_id_map, NULL);
2303 smartlist_free(matching_descs);
2304 smartlist_free(chosen_flags);
2305 smartlist_free(versions);
2306 smartlist_free(protocols);
2307 smartlist_free(exitsummaries);
2317 int64_t weight_scale;
2324 if (weight_scale < 1)
2337 flavor == FLAV_NS ? DIGEST_SHA1 : DIGEST_SHA256;
2346 crypto_digest_smartlist(digest, digest_len, chunks,
"", digest_alg);
2353 if (flavor == FLAV_NS) {
2355 signing_key_fingerprint);
2358 algname, fingerprint,
2359 signing_key_fingerprint);
2364 log_warn(
LD_BUG,
"Couldn't sign consensus networkstatus.");
2374 signing_key_fingerprint, 0);
2375 if (flavor == FLAV_NS) {
2377 signing_key_fingerprint);
2380 algname, fingerprint,
2381 signing_key_fingerprint);
2386 log_warn(
LD_BUG,
"Couldn't sign consensus networkstatus.");
2399 NS_TYPE_CONSENSUS))) {
2400 log_err(
LD_BUG,
"Generated a networkstatus consensus we couldn't "
2406 if (added_weights) {
2409 networkstatus_vote_free(c);
2414 dircollator_free(collator);
2419 smartlist_free(flags);
2421 smartlist_free(chunks);
2423 smartlist_free(param_list);
2437 const char *param_name,
2438 int64_t default_value)
2440 int64_t value = default_value;
2441 const char *param_str = NULL;
2444 char *prefix1 = NULL, *prefix2=NULL;
2450 param_str = strstr(params, prefix2);
2457 char *eq = strchr(param_str,
'=');
2461 log_warn(
LD_DIR,
"Bad element '%s' in %s",
2462 escaped(param_str), param_name);
2463 value = default_value;
2466 log_warn(
LD_DIR,
"Bad element '%s' in %s",
2467 escaped(param_str), param_name);
2468 value = default_value;
2480 const int n_votes = smartlist_len(votes);
2486 strmap_t *package_status = strmap_new();
2489 if (! v->package_lines)
2496 const char *cp = strchr(line,
' ');
2499 cp = strchr(cp,
' ');
2502 char *key = tor_strndup(line, cp - line);
2504 const char **status = strmap_get(package_status, key);
2506 status = tor_calloc(n_votes,
sizeof(
const char *));
2507 strmap_set(package_status, key, status);
2509 status[v_sl_idx] = line;
2511 } SMARTLIST_FOREACH_END(line);
2512 } SMARTLIST_FOREACH_END(v);
2516 STRMAP_FOREACH(package_status, key,
const char **, values) {
2518 for (i = 0; i < n_votes; ++i) {
2523 int n_voting_for_entry = smartlist_len(entries);
2524 const char *most_frequent =
2527 if (n_voting_for_entry >= 3 && count > n_voting_for_entry / 2) {
2533 } STRMAP_FOREACH_END;
2540 smartlist_free(result_list);
2541 smartlist_free(entries);
2563 const char **msg_out)
2576 *msg_out =
"Valid-After times do not match "
2577 "when adding detached signatures to consensus";
2581 *msg_out =
"Fresh-until times do not match "
2582 "when adding detached signatures to consensus";
2586 *msg_out =
"Valid-until times do not match "
2587 "when adding detached signatures to consensus";
2590 siglist = strmap_get(sigs->
signatures, flavor);
2592 *msg_out =
"No signatures for given consensus flavor";
2602 *msg_out =
"No digests for given consensus flavor";
2611 *msg_out =
"Mismatched digest.";
2617 *msg_out =
"No recognized digests for given consensus flavor";
2627 const char *algorithm;
2634 log_info(
LD_DIR,
"Looking at signature from %s using %s", voter_identity,
2637 if (!target_voter) {
2638 log_info(
LD_DIR,
"We do not know any voter with ID %s", voter_identity);
2647 log_info(
LD_DIR,
"We already have a good signature from %s using %s",
2648 voter_identity, algorithm);
2653 if (!sig->good_signature && !sig->bad_signature) {
2655 sig->signing_key_digest);
2665 if (sig->good_signature || !old_sig || old_sig->
bad_signature) {
2666 log_info(
LD_DIR,
"Adding signature from %s with %s", voter_identity,
2668 tor_log(severity,
LD_DIR,
"Added a signature for %s from %s.",
2673 document_signature_free(old_sig);
2677 log_info(
LD_DIR,
"Not adding signature from %s", voter_identity);
2679 } SMARTLIST_FOREACH_END(sig);
2691 int for_detached_signatures)
2695 char *result = NULL;
2699 const char *keyword;
2701 if (for_detached_signatures && flavor != FLAV_NS)
2702 keyword =
"additional-signature";
2704 keyword =
"directory-signature";
2712 if (!sig->signature || sig->bad_signature)
2717 if (flavor == FLAV_NS) {
2719 "%s %s %s\n-----BEGIN SIGNATURE-----\n",
2722 const char *digest_name =
2725 "%s%s%s %s %s %s\n-----BEGIN SIGNATURE-----\n",
2727 for_detached_signatures ?
" " :
"",
2728 for_detached_signatures ? flavor_name :
"",
2729 digest_name,
id, sk);
2731 base64_encode(buf,
sizeof(buf), sig->signature, sig->signature_len,
2732 BASE64_ENCODE_MULTILINE);
2733 strlcat(buf,
"-----END SIGNATURE-----\n",
sizeof(buf));
2735 } SMARTLIST_FOREACH_END(sig);
2736 } SMARTLIST_FOREACH_END(v);
2740 smartlist_free(elements);
2754 char *result = NULL, *sigs = NULL;
2761 if (ns && ns->flavor == FLAV_NS)
2764 if (!consensus_ns) {
2765 log_warn(
LD_BUG,
"No NS consensus given.");
2772 char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
2773 vu_buf[ISO_TIME_LEN+1];
2783 "consensus-digest %s\n"
2786 "valid-until %s\n", d, va_buf, fu_buf, vu_buf);
2793 if (ns->flavor == FLAV_NS)
2800 const char *alg_name =
2806 flavor_name, alg_name, d);
2808 } SMARTLIST_FOREACH_END(ns);
2812 char *sigs_on_this_consensus;
2813 if (ns->flavor == FLAV_NS)
2816 if (!sigs_on_this_consensus) {
2817 log_warn(
LD_DIR,
"Couldn't format signatures");
2821 } SMARTLIST_FOREACH_END(ns);
2832 smartlist_free(elements);
2846 for (flav = 0; flav < n_flavors; ++flav) {
2847 if (pending[flav].consensus)
2863 if (!authdir_mode_v3(options))
2865 tor_assert_nonfatal(voting_schedule.voting_starts);
2871 if (voting_schedule.created_on_demand) {
2874 log_notice(
LD_DIR,
"Scheduling voting. Known authority IDs are %s. "
2881 #define IF_TIME_FOR_NEXT_ACTION(when_field, done_field) \
2882 if (! voting_schedule.done_field) { \
2883 if (voting_schedule.when_field > now) { \
2884 return voting_schedule.when_field; \
2890 IF_TIME_FOR_NEXT_ACTION(voting_starts, have_voted) {
2891 log_notice(
LD_DIR,
"Time to vote.");
2893 voting_schedule.have_voted = 1;
2895 IF_TIME_FOR_NEXT_ACTION(fetch_missing_votes, have_fetched_missing_votes) {
2896 log_notice(
LD_DIR,
"Time to fetch any votes that we're missing.");
2898 voting_schedule.have_fetched_missing_votes = 1;
2900 IF_TIME_FOR_NEXT_ACTION(voting_ends, have_built_consensus) {
2901 log_notice(
LD_DIR,
"Time to compute a consensus.");
2905 voting_schedule.have_built_consensus = 1;
2907 IF_TIME_FOR_NEXT_ACTION(fetch_missing_signatures,
2908 have_fetched_missing_signatures) {
2909 log_notice(
LD_DIR,
"Time to fetch any signatures that we're missing.");
2911 voting_schedule.have_fetched_missing_signatures = 1;
2913 IF_TIME_FOR_NEXT_ACTION(interval_starts,
2914 have_published_consensus) {
2915 log_notice(
LD_DIR,
"Time to publish the consensus and discard old votes");
2918 voting_schedule.have_published_consensus = 1;
2925 return voting_schedule.voting_starts;
2932 #undef IF_TIME_FOR_NEXT_ACTION
2971 time_t now = time(NULL);
2974 const char *msg =
"";
2976 if (!cert || !key) {
2977 log_warn(
LD_NET,
"Didn't find key/certificate to generate v3 vote");
2979 }
else if (cert->
expires < now) {
2980 log_warn(
LD_NET,
"Can't generate v3 vote with expired certificate");
2987 networkstatus_vote_free(ns);
2993 if (!pending_vote) {
2994 log_warn(
LD_DIR,
"Couldn't store my own vote! (I told myself, '%s'.)",
3002 pending_vote->vote_body->
dir,
3003 pending_vote->vote_body->
dir_len, 0);
3004 log_notice(
LD_DIR,
"Vote posted.");
3022 DGV_BY_ID|DGV_INCLUDE_PENDING)) {
3028 } SMARTLIST_FOREACH_END(ds);
3030 if (!smartlist_len(missing_fps)) {
3031 smartlist_free(missing_fps);
3036 log_notice(
LOG_NOTICE,
"We're missing votes from %d authorities (%s). "
3037 "Asking every other authority for a copy.",
3038 smartlist_len(missing_fps), tmp);
3046 smartlist_free(missing_fps);
3099 v->vote_body = NULL;
3100 networkstatus_vote_free(v->vote);
3109 v->vote_body = NULL;
3110 networkstatus_vote_free(v->vote);
3143 smartlist_free(known_v3_keys);
3152 int any_sig_good = 0;
3154 if (sig->good_signature)
3169 TRUSTED_DIRS_CERTS_SRC_FROM_VOTE, 1 ,
3173 log_warn(
LD_BUG,
"We added a cert, but still couldn't find it.");
3185 const char *where_from,
3186 const char **msg_out,
int *status_out)
3192 const char *end_of_vote = NULL;
3208 end_of_vote = vote_body + strlen(vote_body);
3210 log_warn(
LD_DIR,
"Couldn't parse vote: length was %d",
3211 (
int)strlen(vote_body));
3212 *msg_out =
"Unable to parse vote";
3217 assert_any_sig_good(vi);
3221 log_warn(
LD_DIR,
"Got a vote from an authority (nickname %s, address %s) "
3222 "with authority key ID %s. "
3223 "This key ID is not recognized. Known v3 key IDs are: %s",
3227 *msg_out =
"Vote not from a recognized v3 authority";
3230 add_new_cert_if_needed(vote->
cert);
3233 if (vote->
valid_after != voting_schedule.interval_starts) {
3234 char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1];
3237 log_warn(
LD_DIR,
"Rejecting vote from %s with valid-after time of %s; "
3238 "we were expecting %s", vi->
address, tbuf1, tbuf2);
3239 *msg_out =
"Bad valid-after time";
3244 log_notice(
LD_DIR,
"%s posted a vote to me from %s.",
3247 log_notice(
LD_DIR,
"Retrieved %s's vote from %s.",
3256 if (time_posted && time_posted > voting_schedule.fetch_missing_votes) {
3257 char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1];
3260 log_warn(
LD_DIR,
"Rejecting %s's posted vote from %s received at %s; "
3261 "our cutoff for received votes is %s. Check your clock, "
3262 "CPU load, and network load. Also check the authority that "
3264 *msg_out =
"Posted vote received too late, would be dangerous to count it";
3273 if (
fast_memeq(v->vote->cert->cache_info.identity_digest,
3279 log_notice(
LD_DIR,
"Discarding a vote we already have (from %s).",
3281 if (*status_out < 200)
3284 }
else if (v->vote->published < vote->
published) {
3285 log_notice(
LD_DIR,
"Replacing an older pending vote from this "
3286 "directory (%s)", vi->
address);
3288 networkstatus_vote_free(v->vote);
3290 end_of_vote-vote_body),
3294 !
strcmpstart(end_of_vote,
"network-status-version"))
3297 if (*status_out < 200)
3303 log_notice(
LD_DIR,
"Discarding vote from %s because we have "
3304 "a newer one already.", vi->
address);
3305 *msg_out =
"Already have a newer pending vote";
3309 } SMARTLIST_FOREACH_END(v);
3317 end_of_vote-vote_body),
3319 pending_vote->vote = vote;
3322 if (!
strcmpstart(end_of_vote,
"network-status-version ")) {
3323 vote_body = end_of_vote;
3332 *msg_out =
"Error adding vote";
3333 if (*status_out < 400)
3337 networkstatus_vote_free(vote);
3339 if (end_of_vote && !
strcmpstart(end_of_vote,
"network-status-version ")) {
3340 vote_body = end_of_vote;
3346 if (*status_out < 200)
3349 if (!any_failed && !pending_vote) {
3350 *msg_out =
"Duplicate discarded";
3356 return any_failed ? NULL : pending_vote;
3361 write_v3_votes_to_disk(
const smartlist_t *pending_votes)
3364 char *votefile = NULL;
3369 c->bytes = v->vote_body->dir;
3370 c->len = v->vote_body->dir_len;
3374 votefile = get_datadir_fname(
"v3-status-votes");
3375 write_chunks_to_file(votefile, votestrings, 0, 0);
3376 log_debug(
LD_DIR,
"Wrote votes to disk (%s)!", votefile);
3380 smartlist_free(votestrings);
3391 int n_votes, n_voters, n_vote_running = 0;
3393 char *consensus_body = NULL, *signatures = NULL;
3399 memset(pending, 0,
sizeof(pending));
3417 if (n_votes <= n_voters/2) {
3418 log_warn(
LD_DIR,
"We don't have enough votes to generate a consensus: "
3419 "%d of %d", n_votes, n_voters/2+1);
3427 if (!n_vote_running) {
3429 log_warn(
LD_DIR,
"Nobody has voted on the Running flag. Generating "
3430 "and publishing a consensus without Running nodes "
3431 "would make many clients stop working. Not "
3432 "generating a consensus!");
3437 log_warn(
LD_DIR,
"Can't generate consensus without a certificate.");
3444 char *legacy_id_digest = NULL;
3445 int n_generated = 0;
3452 "Unable to compute digest of legacy v3 identity key");
3454 legacy_id_digest = legacy_dbuf;
3467 if (!consensus_body) {
3468 log_warn(
LD_DIR,
"Couldn't generate a %s consensus at all!",
3473 strlen(consensus_body),
3477 log_warn(
LD_DIR,
"Couldn't parse %s consensus we generated!",
3486 pending[flav].
body = consensus_body;
3493 tor_asprintf(&filename,
"my-consensus-%s", flavor_name);
3498 consensus_body = NULL;
3502 log_warn(
LD_DIR,
"Couldn't generate any consensus flavors at all.");
3511 log_warn(
LD_DIR,
"Couldn't extract signatures.");
3516 memcpy(pending_consensuses, pending,
sizeof(pending));
3526 const char *msg = NULL;
3533 "Could not add queued signature to new consensus: %s",
3536 } SMARTLIST_FOREACH_END(sig);
3538 log_notice(
LD_DIR,
"Added %d pending signatures while building "
3539 "consensus.", n_sigs);
3543 log_notice(
LD_DIR,
"Consensus computed; uploading signature(s)");
3550 log_notice(
LD_DIR,
"Signature(s) posted.");
3552 smartlist_free(votes);
3555 smartlist_free(votes);
3558 networkstatus_vote_free(consensus);
3572 const char **msg_out)
3574 const char *flavor_name;
3587 log_info(
LD_DIR,
"Have %d signatures for adding to %s consensus.",
3588 sig_list ? smartlist_len(sig_list) : 0, flavor_name);
3591 source, severity, msg_out);
3593 log_info(
LD_DIR,
"Added %d signatures to consensus.", r);
3596 "Unable to add signatures to consensus: %s",
3597 *msg_out ? *msg_out :
"(unknown)");
3601 char *new_signatures =
3603 char *dst, *dst_end;
3604 size_t new_consensus_len;
3605 if (!new_signatures) {
3606 *msg_out =
"No signatures to add";
3610 strlen(pc->
body) + strlen(new_signatures) + 1;
3611 pc->
body = tor_realloc(pc->
body, new_consensus_len);
3612 dst_end = pc->
body + new_consensus_len;
3615 strlcpy(dst, new_signatures, dst_end-dst);
3625 networkstatus_vote_free(v);
3627 *msg_out =
"Signatures added";
3629 }
else if (r == 0) {
3630 *msg_out =
"Signatures ignored";
3638 *msg_out =
"Unrecognized error while adding detached signatures.";
3653 const char *detached_signatures_body,
3655 const char **msg_out)
3657 int r=0, i, n_added = 0, errors = 0;
3664 detached_signatures_body, NULL))) {
3665 *msg_out =
"Couldn't parse detached signatures.";
3683 if (errors && !n_added) {
3688 if (n_added && pending_consensuses[FLAV_NS].consensus) {
3689 char *new_detached =
3702 *msg_out =
"Unrecognized error while adding detached signatures.";
3704 ns_detached_signatures_free(sigs);
3724 if (pending_consensuses[FLAV_NS].consensus) {
3725 log_notice(
LD_DIR,
"Got a signature from %s. "
3726 "Adding it to the pending consensus.", source);
3728 detached_signatures_body, source, msg);
3730 log_notice(
LD_DIR,
"Got a signature from %s. "
3731 "Queuing it for the next consensus.", source);
3735 detached_signatures_body);
3736 *msg =
"Signature queued";
3756 log_warn(
LD_DIR,
"Not enough info to publish pending %s consensus",
name);
3761 strlen(pending->
body),
3763 log_warn(
LD_DIR,
"Error publishing %s consensus",
name);
3765 log_notice(
LD_DIR,
"Published %s consensus",
name);
3800 return pending_consensuses[flav].
body;
3822 int by_id = flags & DGV_BY_ID;
3823 const int include_pending = flags & DGV_INCLUDE_PENDING;
3824 const int include_previous = flags & DGV_INCLUDE_PREVIOUS;
3840 return pv->vote_body);
3845 return pv->vote_body);
3851 return pv->vote_body);
3856 return pv->vote_body);
3869 char *key = NULL, *summary = NULL, *family = NULL;
3872 char *output = NULL;
3902 if (summary && strcmp(summary,
"reject 1-65535"))
3910 if (p6 && strcmp(p6,
"reject 1-65535"))
3917 const char *keytype;
3920 keytype =
"ed25519";
3924 keytype =
"rsa1024";
3934 output+strlen(output), 0,
3936 if (smartlist_len(lst) != 1) {
3937 log_warn(
LD_DIR,
"We generated a microdescriptor we couldn't parse.");
3939 smartlist_free(lst);
3942 result = smartlist_get(lst, 0);
3943 smartlist_free(lst);
3947 crypto_pk_free(rsa_pubkey);
3954 smartlist_free(chunks);
3966 int consensus_method_low,
3967 int consensus_method_high)
3971 char *microdesc_consensus_methods =
3973 consensus_method_high,
3979 if (
tor_snprintf(out_buf, out_buf_len,
"m %s sha256=%s\n",
3980 microdesc_consensus_methods, d64)<0)
3983 ret = strlen(out_buf);
3986 tor_free(microdesc_consensus_methods);
3995 } microdesc_consensus_methods[] = {
4026 for (cmr = microdesc_consensus_methods;
4027 cmr->low != -1 && cmr->high != -1;
4035 e->high = cmr->high;
4042 for (ep = entries; ep; ep = ep->next) {
4045 ep->low == ep->next->high + 1) {
4047 ep->low = next->low;
4048 microdesc_free(next->md);
4049 ep->next = next->next;
4055 while ((ep = entries)) {
4059 ep->low, ep->high) >= 0) {
4064 ep->md->last_listed = now;
4091 if (commits == NULL) {
4101 for (
int i = 0; i < tok->n_args; i++) {
4106 if (commit == NULL) {
4111 log_warn(
LD_DIR,
"SR: Unable to parse commit %s from vote of voter %s.",
4121 } SMARTLIST_FOREACH_END(tok);
4124 smartlist_free(chunks);
4125 smartlist_free(commits);
4153 smartlist_free(ns->
sr_info.commits);
4161 dirvote_dirreq_get_status_vote(
const char *url,
smartlist_t *items,
4166 url += strlen(
"/tor/status-vote/");
4168 url = strchr(url,
'/');
4171 if (!strcmp(url,
"consensus")) {
4177 }
else if (!current && !strcmp(url,
"consensus-signatures")) {
4184 }
else if (!strcmp(url,
"authority")) {
4186 int flags = DGV_BY_ID |
4187 (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
4196 flags = DGV_INCLUDE_PENDING | DGV_INCLUDE_PREVIOUS;
4199 (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
4202 DSR_HEX|DSR_SORT_UNIQ);
4208 smartlist_free(fps);
4234 bw_kb = (uint32_t)mbw_kb;
4268 if (comparison == 0) {
4287 if (comparison == 0)
4303 int first_is_auth, second_is_auth;
4304 const node_t *node_first, *node_second;
4305 int first_is_running, second_is_running;
4306 uint32_t bw_kb_first, bw_kb_second;
4315 if (first_is_auth && !second_is_auth)
4317 else if (!first_is_auth && second_is_auth)
4322 first_is_running = node_first && node_first->
is_running;
4323 second_is_running = node_second && node_second->
is_running;
4324 if (first_is_running && !second_is_running)
4326 else if (!first_is_running && second_is_running)
4332 if (bw_kb_first > bw_kb_second)
4334 else if (bw_kb_first < bw_kb_second)
4353 digestmap_t *omit_as_sybil = digestmap_new();
4359 if (max_with_same_addr <= 0)
4360 max_with_same_addr = INT_MAX;
4363 if (family == AF_INET6)
4373 addrs_equal =
false;
4375 if (! addrs_equal) {
4378 }
else if (++addr_count > max_with_same_addr) {
4379 digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4381 } SMARTLIST_FOREACH_END(ri);
4382 smartlist_free(routers_by_ip);
4383 return omit_as_sybil;
4395 digestmap_t *omit_as_sybil_ipv4;
4396 digestmap_t *omit_as_sybil_ipv6;
4397 digestmap_t *omit_as_sybil = digestmap_new();
4408 } SMARTLIST_FOREACH_END(ri);
4414 digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4417 digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4420 smartlist_free(routers_ipv4);
4421 smartlist_free(routers_ipv6);
4422 digestmap_free(omit_as_sybil_ipv4, NULL);
4423 digestmap_free(omit_as_sybil_ipv6, NULL);
4425 return omit_as_sybil;
4442 return tor_strndup(platform, eos-platform);
4459 for ( ; ln; ln = ln->next) {
4461 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4468 if (strchr(v,
' ')) {
4470 log_warn(
LD_DIRSERV,
"Unexpected space in versions list member %s. "
4471 "(These are supposed to be comma-separated; I'll pretend you "
4472 "used commas instead.)",
escaped(v));
4475 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4478 } SMARTLIST_FOREACH_END(v);
4480 smartlist_free(more_versions);
4487 log_warn(
LD_DIRSERV,
"Recommended version %s does not look valid. "
4488 " (I'll include it anyway, since you told me to.)",
4491 } SMARTLIST_FOREACH_END(v);
4497 smartlist_free(versions);
4508 digest256map_t *by_ed_key = digest256map_new();
4511 ri->omit_from_vote = 0;
4512 if (ri->cache_info.signing_key_cert == NULL)
4514 const uint8_t *pk = ri->cache_info.signing_key_cert->signing_key.pubkey;
4515 if ((ri2 = digest256map_get(by_ed_key, pk))) {
4518 const time_t ri_pub = ri->cache_info.published_on;
4520 if (ri2_pub < ri_pub ||
4521 (ri2_pub == ri_pub &&
4522 fast_memcmp(ri->cache_info.signed_descriptor_digest,
4524 digest256map_set(by_ed_key, pk, ri);
4527 ri->omit_from_vote = 1;
4531 digest256map_set(by_ed_key, pk, ri);
4533 } SMARTLIST_FOREACH_END(ri);
4535 digest256map_free(by_ed_key, NULL);
4539 if (ri->omit_from_vote) {
4542 } SMARTLIST_FOREACH_END(ri);
4596 char *hostname = NULL, *client_versions = NULL, *server_versions = NULL;
4597 const char *contact;
4603 time_t now = time(NULL);
4607 const int vote_on_reachability = running_long_enough_to_decide_unreachable();
4616 log_err(
LD_BUG,
"Error computing signing key digest");
4620 log_err(
LD_BUG,
"Error computing identity key digest");
4624 log_warn(
LD_NET,
"Couldn't resolve my hostname");
4627 if (!hostname || !strchr(hostname,
'.')) {
4633 log_err(
LD_BUG,
"Failed to determine hostname AND duplicate address");
4668 dirserv_set_router_is_running(ri, now);
4692 if (ri->protocol_list &&
4696 if (ri->cache_info.published_on >= cutoff) {
4708 if (ri->cache_info.signing_key_cert) {
4710 ri->cache_info.signing_key_cert->signing_key.pubkey,
4713 if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
4716 if (!vote_on_reachability)
4720 if (ri->protocol_list) {
4721 vrs->
protocols = tor_strdup(ri->protocol_list);
4731 } SMARTLIST_FOREACH_END(ri);
4737 smartlist_free(added);
4738 smartlist_free(microdescriptors);
4741 smartlist_free(routers);
4742 digestmap_free(omit_as_sybil, NULL);
4755 routerstatuses, bw_file_headers,
4769 v3_out->
type = NS_TYPE_VOTE;
4773 char tbuf[ISO_TIME_LEN+1];
4776 long last_consensus_interval;
4777 if (current_consensus)
4778 last_consensus_interval = current_consensus->
fresh_until -
4784 (
int)last_consensus_interval,
4787 log_notice(
LD_DIR,
"Choosing valid-after time in vote as %s: "
4788 "consensus_set=%d, last_interval=%d",
4789 tbuf, current_consensus?1:0, (
int)last_consensus_interval);
4801 v3_out->server_versions = server_versions;
4805 tor_strdup(DIRVOTE_RECOMMEND_RELAY_PROTO);
4806 v3_out->recommended_client_protocols =
4807 tor_strdup(DIRVOTE_RECOMMEND_CLIENT_PROTO);
4809 v3_out->required_relay_protocols =
4810 tor_strdup(DIRVOTE_REQUIRE_RELAY_PROTO);
4811 v3_out->required_client_protocols =
4812 tor_strdup(DIRVOTE_REQUIRE_CLIENT_PROTO);
4822 v3_out->recommended_client_protocols, NULL));
4827 0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4828 if (vote_on_reachability)
4837 for ( ; paramline; paramline = paramline->next) {
4839 paramline->value, NULL, 0, 0);
4854 voter->
contact = tor_strdup(contact);
4859 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)
const char * fmt_addrport(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)
char * tor_addr_to_str_dup(const tor_addr_t *addr)
int tor_addr_is_null(const tor_addr_t *addr)
tor_addr_port_t * tor_addr_port_new(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)
void dircollator_collate(dircollator_t *dc, int consensus_method)
void dircollator_add_vote(dircollator_t *dc, networkstatus_t *v)
dircollator_t * dircollator_new(int n_votes, int n_authorities)
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 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 microdesc_t * dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method)
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)
static int consensus_method_is_supported(int method)
STATIC char * make_consensus_method_list(int low, int high, const char *separator)
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 int compare_routerinfo_addrs_by_family(const routerinfo_t *a, const routerinfo_t *b, int family)
const char * dirvote_get_pending_detached_signatures(void)
static char * get_detached_signatures_from_pending_consensuses(pending_consensus_t *pending, int n_flavors)
STATIC int compare_routerinfo_by_ipv6(const void **a, const void **b)
static int dirvote_perform_vote(void)
static int compare_orports_(const void **_a, const void **_b)
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)
static void dirvote_clear_votes(int all_votes)
static char * pending_consensus_signatures
STATIC authority_cert_t * authority_cert_dup(authority_cert_t *cert)
STATIC int32_t dirvote_get_intermediate_param_value(const smartlist_t *param_list, const char *keyword, int32_t default_val)
static int dirvote_publish_consensus(void)
void dirvote_free_all(void)
static int compare_votes_by_authority_id_(const void **_a, const void **_b)
STATIC char * networkstatus_get_detached_signatures(smartlist_t *consensuses)
static char * format_protocols_lines_for_vote(const networkstatus_t *v3_ns)
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)
const cached_dir_t * dirvote_get_vote(const char *fp, int flags)
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)
int dirvote_add_signatures(const char *detached_signatures_body, const char *source, const char **msg)
static void dirvote_fetch_missing_votes(void)
const char * dirvote_get_pending_consensus(consensus_flavor_t flav)
static networkstatus_voter_info_t * get_voter(const networkstatus_t *vote)
STATIC char * format_networkstatus_vote(crypto_pk_t *private_signing_key, networkstatus_t *v3_ns)
vote_microdesc_hash_t * dirvote_format_all_microdesc_vote_lines(const routerinfo_t *ri, time_t now, smartlist_t *microdescriptors_out)
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)
static const char * get_nth_protocol_set_vote(int n, const networkstatus_t *vote)
#define get_most_frequent_member(lst)
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)
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[]
#define MIN_VOTES_FOR_PARAM
static char * version_from_platform(const char *platform)
static char * compute_nth_protocol_set(int n, int n_voters, const smartlist_t *votes)
STATIC char * compute_consensus_package_lines(smartlist_t *votes)
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 digestmap_t * get_all_possible_sybil(const smartlist_t *routers)
STATIC int64_t extract_param_buggy(const char *params, const char *param_name, int64_t default_value)
static smartlist_t * pending_consensus_signature_list
static void clear_status_flags_on_sybil(routerstatus_t *rs)
STATIC digestmap_t * get_sybil_list_by_ip_version(const smartlist_t *routers, sa_family_t family)
static char * networkstatus_format_signatures(networkstatus_t *consensus, int for_detached_signatures)
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)
networkstatus_t * dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, authority_cert_t *cert)
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 char * compute_consensus_versions_list(smartlist_t *lst, int n_versioning)
STATIC smartlist_t * dirvote_compute_params(smartlist_t *votes, int method, int total_authorities)
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[]
char * format_recommended_version_list(const config_line_t *ln, int warn)
Header file for dirvote.c.
#define MIN_METHOD_FOR_CORRECT_BWWEIGHTSCALE
#define MIN_VOTE_INTERVAL_TESTING
#define MIN_VOTE_INTERVAL
#define MIN_SUPPORTED_CONSENSUS_METHOD
#define MIN_METHOD_FOR_CANONICAL_FAMILIES_IN_MICRODESCS
#define DEFAULT_MAX_UNMEASURED_BW_KB
#define MAX_BW_FILE_HEADERS_LINE_LEN
#define MIN_METHOD_FOR_UNPADDED_NTOR_KEY
#define MAX_SUPPORTED_CONSENSUS_METHOD
Authority signature structure.
Code to parse and validate detached-signature objects.
ns_detached_signatures_t * networkstatus_parse_detached_signatures(const char *s, const char *eos)
Header file for circuitbuild.c.
const char * escaped(const char *s)
int write_str_to_file(const char *fname, const char *str, int bin)
Format routerstatus entries for controller, vote, or consensus.
routerstatus_format_type_t
@ NS_V3_CONSENSUS_MICRODESC
char * routerstatus_format_entry(const routerstatus_t *rs, const char *version, const char *protocols, routerstatus_format_type_t format, const vote_routerstatus_t *vrs)
Header file for guardfraction.c.
int dirserv_read_guardfraction_file(const char *fname, smartlist_t *vote_routerstatuses)
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.
int networkstatus_check_document_signature(const networkstatus_t *consensus, document_signature_t *sig, const authority_cert_t *cert)
networkstatus_t * networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
int networkstatus_set_current_consensus(const char *consensus, size_t consensus_len, const char *flavor, unsigned flags, const char *source_dir)
const char * networkstatus_get_flavor_name(consensus_flavor_t flav)
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)
document_signature_t * networkstatus_get_voter_sig_by_alg(const networkstatus_voter_info_t *voter, digest_algorithm_t alg)
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.
node_t * node_get_mutable_by_id(const char *identity_digest)
const node_t * node_get_by_id(const char *identity_digest)
Header file for nodelist.c.
Detached consensus signatures structure.
Header file for ns_parse.c.
networkstatus_t * networkstatus_parse_vote_from_string(const char *s, size_t len, const char **eos_out, enum networkstatus_type_t ns_type)
int networkstatus_verify_bw_weights(networkstatus_t *ns, int)
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)
directory_token_t * find_opt_by_keyword(const smartlist_t *s, directory_keyword keyword)
smartlist_t * find_all_by_keyword(const smartlist_t *s, directory_keyword k)
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,...)
const char * protover_compute_for_old_tor(const char *version)
C_RUST_COUPLED: src/rust/protover/protover.rs compute_for_old_tor
bool protover_list_is_invalid(const char *s)
char * protover_compute_vote(const smartlist_t *list_of_proto_strings, int threshold)
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.
crypto_pk_t * get_my_v3_authority_signing_key(void)
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)
authority_cert_t * get_my_v3_legacy_cert(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)
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)
uint32_t router_get_advertised_bandwidth(const routerinfo_t *router)
routerlist_t * router_get_routerlist(void)
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)
sr_commit_t * sr_parse_commit(const smartlist_t *args)
void sr_act_post_consensus(const networkstatus_t *consensus)
void sr_handle_received_commits(smartlist_t *commits, crypto_pk_t *voter_key)
char * sr_get_string_for_vote(void)
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 char * smartlist_get_most_frequent_string_(smartlist_t *sl, int *count_out)
void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern,...)
const uint8_t * smartlist_get_most_frequent_digest256(smartlist_t *sl)
void smartlist_uniq_strings(smartlist_t *sl)
void smartlist_sort_strings(smartlist_t *sl)
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
int smartlist_contains_string(const smartlist_t *sl, const char *element)
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)
smartlist_t * smartlist_new(void)
void smartlist_add_strdup(struct smartlist_t *sl, const char *string)
void smartlist_add(smartlist_t *sl, void *element)
void smartlist_clear(smartlist_t *sl)
void smartlist_remove(smartlist_t *sl, const void *element)
#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]
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
unsigned int omit_from_vote
smartlist_t * exit_policy
smartlist_t * declared_family
struct curve25519_public_key_t * onion_curve25519_pkey
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.
void dirauth_set_routerstatus_from_routerinfo(routerstatus_t *rs, node_t *node, const routerinfo_t *ri, time_t now, int listbadexits)
char * dirserv_get_flag_thresholds_line(void)
void dirserv_compute_performance_thresholds(digestmap_t *omit_as_sybil)
Header file for voteflags.c.
void dirauth_sched_recalculate_timing(const or_options_t *options, time_t now)
Header file for voting_schedule.c.
#define CURVE25519_BASE64_PADDED_LEN
#define ED25519_BASE64_LEN
#define ED25519_PUBKEY_LEN