69#define DIGEST_ALG_BW_FILE DIGEST_SHA256
122 const char *detached_signatures_body,
124 const char **msg_out);
130 const char **msg_out);
170format_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,
398 for (h = vrs->microdesc; h; h = h->
next) {
401 } SMARTLIST_FOREACH_END(vrs);
407 crypto_digest_smartlist(digest,
DIGEST_LEN, chunks,
408 "directory-signature ", DIGEST_SHA1);
413 signing_key_fingerprint, 0)<0) {
414 log_warn(
LD_BUG,
"Unable to get fingerprint for signing key");
419 signing_key_fingerprint);
424 private_signing_key);
426 log_warn(
LD_BUG,
"Unable to sign networkstatus vote.");
439 log_err(
LD_BUG,
"Generated a networkstatus %s we couldn't parse: "
441 v3_ns->
type == NS_TYPE_VOTE ?
"vote" :
"opinion", status);
444 networkstatus_vote_free(v);
457 smartlist_free(chunks);
507 num_len = strspn(cp,
"1234567890");
508 if (num_len == mlen &&
fast_memeq(mstr, cp, mlen)) {
513 cp = strstr(cp, dstr);
517 strlcpy(buf, cp,
sizeof(buf));
520 if (num_len == 0 || cp[num_len] !=
',')
537 return smartlist_get(vote->
voters, 0);
568 const char *a_id, *b_id;
570 b_id = b->is_legacy ? b_v->legacy_id_digest : b_v->identity_digest;
583 if (cur && !strcmp(cp, cur)) {
591 } SMARTLIST_FOREACH_END(cp);
598#define get_most_frequent_member(lst) \
599 smartlist_get_most_frequent_string(lst)
621#define CMP_FIELD(utype, itype, field) do { \
622 utype aval = (utype) (itype) a->field; \
623 utype bval = (utype) (itype) b->field; \
624 utype u = bval - aval; \
625 itype r2 = (itype) u; \
628 } else if (r2 > 0) { \
633 CMP_FIELD(uint64_t, int64_t, published_on);
642 CMP_FIELD(
unsigned,
int, status.ipv4_orport);
643 CMP_FIELD(
unsigned,
int, status.ipv4_dirport);
665 if ((r = (((
int) b->port) - ((
int) a->port))))
678 char *microdesc_digest256_out,
682 int most_n = 0, cur_n = 0;
683 time_t most_published = 0;
694 if (cur && (cur_n > most_n ||
696 cur->published_on > most_published))) {
704 } SMARTLIST_FOREACH_END(rs);
706 if (cur_n > most_n ||
707 (cur && cur_n == most_n && cur->published_on > most_published)) {
720 if (best_alt_orport_out) {
728 && rs->status.ipv6_orport) {
730 rs->status.ipv6_orport));
732 } SMARTLIST_FOREACH_END(rs);
735 most_alt_orport = smartlist_get_most_frequent(alt_orports,
737 if (most_alt_orport) {
739 log_debug(
LD_DIR,
"\"a\" line winner for %s is %s",
741 fmt_addrport(&most_alt_orport->addr, most_alt_orport->port));
745 smartlist_free(alt_orports);
748 if (microdesc_digest256_out) {
750 const uint8_t *best_microdesc_digest;
758 } SMARTLIST_FOREACH_END(rs);
761 if (best_microdesc_digest)
762 memcpy(microdesc_digest256_out, best_microdesc_digest,
DIGEST256_LEN);
764 smartlist_free(digests);
776 const char *a = *_a, *b = *_b;
798 int min = (smartlist_len(votes) * 2) / 3;
813 n_ok = smartlist_len(acceptable_methods);
815 const char *best = smartlist_get(acceptable_methods, n_ok-1);
821 smartlist_free(all_methods);
822 smartlist_free(acceptable_methods);
844 for (i = low; i <= high; ++i) {
863 int min = n_versioning / 2;
867 if (strchr(v,
' ')) {
868 log_warn(
LD_DIR,
"At least one authority has voted for a version %s "
869 "that contains a space. This probably wasn't intentional, and "
870 "is likely to cause trouble. Please tell them to stop it.",
873 } SMARTLIST_FOREACH_END(v);
877 smartlist_free(good);
890 unsigned int n_found = 0;
891 int32_t value = default_val;
894 if (!
strcmpstart(k_v_pair, keyword) && k_v_pair[strlen(keyword)] ==
'=') {
895 const char *integer_str = &k_v_pair[strlen(keyword)+1];
903 } SMARTLIST_FOREACH_END(k_v_pair);
908 tor_assert_nonfatal(n_found == 0);
916#define MIN_VOTES_FOR_PARAM 3
928 const char *cur_param;
931 const int n_votes = smartlist_len(votes);
941 vals = tor_calloc(n_votes,
sizeof(
int));
947 } SMARTLIST_FOREACH_END(v);
949 if (smartlist_len(param_list) == 0) {
956 cur_param = smartlist_get(param_list, 0);
957 eq = strchr(cur_param,
'=');
959 cur_param_len = (int)(eq+1 - cur_param);
967 const char *next_param;
969 eq = strchr(param,
'=');
971 vals[i++] = (int32_t)
975 if (param_sl_idx+1 == smartlist_len(param_list))
978 next_param = smartlist_get(param_list, param_sl_idx+1);
980 if (!next_param || strncmp(next_param, param, cur_param_len)) {
984 if (i > total_authorities/2 ||
986 int32_t median = median_int32(vals, i);
987 char *out_string = tor_malloc(64+cur_param_len);
988 memcpy(out_string, param, cur_param_len);
989 tor_snprintf(out_string+cur_param_len,64,
"%ld", (
long)median);
995 eq = strchr(next_param,
'=');
996 cur_param_len = (int)(eq+1 - next_param);
999 } SMARTLIST_FOREACH_END(param);
1001 smartlist_free(param_list);
1006#define RANGE_CHECK(a,b,c,d,e,f,g,mx) \
1007 ((a) >= 0 && (a) <= (mx) && (b) >= 0 && (b) <= (mx) && \
1008 (c) >= 0 && (c) <= (mx) && (d) >= 0 && (d) <= (mx) && \
1009 (e) >= 0 && (e) <= (mx) && (f) >= 0 && (f) <= (mx) && \
1010 (g) >= 0 && (g) <= (mx))
1012#define CHECK_EQ(a, b, margin) \
1013 ((a)-(b) >= 0 ? (a)-(b) <= (margin) : (b)-(a) <= (margin))
1016 BW_WEIGHTS_NO_ERROR = 0,
1017 BW_WEIGHTS_RANGE_ERROR = 1,
1018 BW_WEIGHTS_SUMG_ERROR = 2,
1019 BW_WEIGHTS_SUME_ERROR = 3,
1020 BW_WEIGHTS_SUMD_ERROR = 4,
1021 BW_WEIGHTS_BALANCE_MID_ERROR = 5,
1022 BW_WEIGHTS_BALANCE_EG_ERROR = 6
1023} bw_weights_error_t;
1028static bw_weights_error_t
1030 int64_t Wme, int64_t Wmd, int64_t Wee,
1031 int64_t Wed, int64_t scale, int64_t G,
1032 int64_t M, int64_t E, int64_t D, int64_t
T,
1033 int64_t margin,
int do_balance) {
1034 bw_weights_error_t berr = BW_WEIGHTS_NO_ERROR;
1037 if (!CHECK_EQ(Wed + Wmd + Wgd, scale, margin)) {
1038 berr = BW_WEIGHTS_SUMD_ERROR;
1043 if (!CHECK_EQ(Wmg + Wgg, scale, margin)) {
1044 berr = BW_WEIGHTS_SUMG_ERROR;
1049 if (!CHECK_EQ(Wme + Wee, scale, margin)) {
1050 berr = BW_WEIGHTS_SUME_ERROR;
1055 if (!RANGE_CHECK(Wgg, Wgd, Wmg, Wme, Wmd, Wed, Wee, scale)) {
1056 berr = BW_WEIGHTS_RANGE_ERROR;
1062 if (!CHECK_EQ(Wgg*G + Wgd*D, Wee*E + Wed*D, (margin*
T)/3)) {
1063 berr = BW_WEIGHTS_BALANCE_EG_ERROR;
1068 if (!CHECK_EQ(Wgg*G + Wgd*D, M*scale + Wmd*D + Wme*E + Wmg*G,
1070 berr = BW_WEIGHTS_BALANCE_MID_ERROR;
1078 "Bw weight mismatch %d. G=%"PRId64
" M=%"PRId64
1079 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1080 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1081 " Wgd=%d Wgg=%d Wme=%d Wmg=%d",
1085 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1086 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg);
1099 int64_t M, int64_t E, int64_t D,
1100 int64_t
T, int64_t weight_scale)
1102 bw_weights_error_t berr = 0;
1103 int64_t Wgg = -1, Wgd = -1;
1104 int64_t Wmg = -1, Wme = -1, Wmd = -1;
1105 int64_t Wed = -1, Wee = -1;
1106 const char *casename;
1108 if (G <= 0 || M <= 0 || E <= 0 || D <= 0) {
1109 log_warn(
LD_DIR,
"Consensus with empty bandwidth: "
1110 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
1111 " D=%"PRId64
" T=%"PRId64,
1128 if (3*E >=
T && 3*G >=
T) {
1130 casename =
"Case 1 (Wgd=Wmd=Wed)";
1131 Wgd = weight_scale/3;
1132 Wed = weight_scale/3;
1133 Wmd = weight_scale/3;
1134 Wee = (weight_scale*(E+G+M))/(3*E);
1135 Wme = weight_scale - Wee;
1136 Wmg = (weight_scale*(2*G-E-M))/(3*G);
1137 Wgg = weight_scale - Wmg;
1140 weight_scale, G, M, E, D,
T, 10, 1);
1144 "Bw Weights error %d for %s v10. G=%"PRId64
" M=%"PRId64
1145 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1146 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1147 " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
1151 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1152 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1155 }
else if (3*E <
T && 3*G <
T) {
1156 int64_t R = MIN(E, G);
1157 int64_t S =
MAX(E, G);
1170 casename =
"Case 2a (E scarce)";
1174 casename =
"Case 2a (G scarce)";
1179 casename =
"Case 2b1 (Wgg=weight_scale, Wmd=Wgd)";
1180 Wee = (weight_scale*(E - G + M))/E;
1181 Wed = (weight_scale*(D - 2*E + 4*G - 2*M))/(3*D);
1182 Wme = (weight_scale*(G-M))/E;
1185 Wmd = (weight_scale - Wed)/2;
1186 Wgd = (weight_scale - Wed)/2;
1189 weight_scale, G, M, E, D,
T, 10, 1);
1192 casename =
"Case 2b2 (Wgg=weight_scale, Wee=weight_scale)";
1195 Wed = (weight_scale*(D - 2*E + G + M))/(3*D);
1196 Wmd = (weight_scale*(D - 2*M + G + E))/(3*D);
1201 casename =
"Case 2b3 (Wmd=0)";
1204 "Too much Middle bandwidth on the network to calculate "
1205 "balanced bandwidth-weights. Consider increasing the "
1206 "number of Guard nodes by lowering the requirements.");
1208 Wgd = weight_scale - Wed - Wmd;
1210 Wed, weight_scale, G, M, E, D,
T, 10, 1);
1212 if (berr != BW_WEIGHTS_NO_ERROR &&
1213 berr != BW_WEIGHTS_BALANCE_MID_ERROR) {
1215 "Bw Weights error %d for %s v10. G=%"PRId64
" M=%"PRId64
1216 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1217 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1218 " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
1222 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1223 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1228 int64_t S = MIN(E, G);
1230 if (!(3*E <
T || 3*G <
T) || !(3*G >=
T || 3*E >=
T)) {
1232 "Bw-Weights Case 3 v10 but with G=%"PRId64
" M="
1233 "%"PRId64
" E=%"PRId64
" D=%"PRId64
" T=%"PRId64,
1240 casename =
"Case 3a (G scarce)";
1241 Wgg = Wgd = weight_scale;
1242 Wmd = Wed = Wmg = 0;
1246 else Wme = (weight_scale*(E-M))/(2*E);
1247 Wee = weight_scale-Wme;
1249 casename =
"Case 3a (E scarce)";
1250 Wee = Wed = weight_scale;
1251 Wmd = Wgd = Wme = 0;
1255 else Wmg = (weight_scale*(G-M))/(2*G);
1256 Wgg = weight_scale-Wmg;
1261 casename =
"Case 3bg (G scarce, Wgg=weight_scale, Wmd == Wed)";
1263 Wgd = (weight_scale*(D - 2*G + E + M))/(3*D);
1265 Wee = (weight_scale*(E+M))/(2*E);
1266 Wme = weight_scale - Wee;
1267 Wmd = (weight_scale - Wgd)/2;
1268 Wed = (weight_scale - Wgd)/2;
1271 Wed, weight_scale, G, M, E, D,
T, 10, 1);
1273 casename =
"Case 3be (E scarce, Wee=weight_scale, Wmd == Wgd)";
1275 Wed = (weight_scale*(D - 2*E + G + M))/(3*D);
1277 Wgg = (weight_scale*(G+M))/(2*G);
1278 Wmg = weight_scale - Wgg;
1279 Wmd = (weight_scale - Wed)/2;
1280 Wgd = (weight_scale - Wed)/2;
1283 Wed, weight_scale, G, M, E, D,
T, 10, 1);
1287 "Bw Weights error %d for %s v10. G=%"PRId64
" M=%"PRId64
1288 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
1289 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d"
1290 " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d",
1294 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)Wed, (
int)Wee,
1295 (
int)Wgd, (
int)Wgg, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1304 tor_assert(0 < weight_scale && weight_scale <= INT32_MAX);
1315 "bandwidth-weights Wbd=%d Wbe=%d Wbg=%d Wbm=%d "
1317 "Web=%d Wed=%d Wee=%d Weg=%d Wem=%d "
1318 "Wgb=%d Wgd=%d Wgg=%d Wgm=%d "
1319 "Wmb=%d Wmd=%d Wme=%d Wmg=%d Wmm=%d\n",
1320 (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)weight_scale,
1322 (
int)weight_scale, (
int)Wed, (
int)Wee, (
int)Wed, (
int)Wee,
1323 (
int)weight_scale, (
int)Wgd, (
int)Wgg, (
int)Wgg,
1324 (
int)weight_scale, (
int)Wmd, (
int)Wme, (
int)Wmg, (
int)weight_scale);
1326 log_notice(
LD_CIRC,
"Computed bandwidth weights for %s with v10: "
1327 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
1339 int is_exit,
int is_guard,
1340 int64_t *G, int64_t *M, int64_t *E, int64_t *D,
1344 int guardfraction_bandwidth = 0;
1347 log_info(
LD_BUG,
"Missing consensus bandwidth for router %s",
1378 guard_get_guardfraction_bandwidth(&guardfraction_bw,
1382 default_bandwidth = guardfraction_bw.
guard_bw;
1383 guardfraction_bandwidth = guardfraction_bw.
non_guard_bw;
1392 *
T += default_bandwidth;
1393 if (is_exit && is_guard) {
1395 *D += default_bandwidth;
1397 *E += guardfraction_bandwidth;
1400 }
else if (is_exit) {
1402 *E += default_bandwidth;
1404 }
else if (is_guard) {
1406 *G += default_bandwidth;
1408 *M += guardfraction_bandwidth;
1413 *M += default_bandwidth;
1425 case 0:
return vote->recommended_client_protocols;
1427 case 2:
return vote->required_client_protocols;
1428 case 3:
return vote->required_relay_protocols;
1430 tor_assert_unreached();
1442 const char *keyword;
1447 keyword =
"recommended-client-protocols";
1448 threshold = CEIL_DIV(n_voters, 2);
1451 keyword =
"recommended-relay-protocols";
1452 threshold = CEIL_DIV(n_voters, 2);
1455 keyword =
"required-client-protocols";
1456 threshold = CEIL_DIV(n_voters * 2, 3);
1459 keyword =
"required-relay-protocols";
1460 threshold = CEIL_DIV(n_voters * 2, 3);
1463 tor_assert_unreached();
1471 } SMARTLIST_FOREACH_END(ns);
1474 smartlist_free(proto_votes);
1476 char *result = NULL;
1519 int total_authorities,
1522 const char *legacy_id_key_digest,
1527 char *result = NULL;
1528 int consensus_method;
1529 time_t valid_after, fresh_until, valid_until;
1530 int vote_seconds, dist_seconds;
1531 char *client_versions = NULL, *server_versions = NULL;
1533 const char *flavor_name;
1535 int64_t G, M, E, D,
T;
1538 char *params = NULL;
1539 char *packages = NULL;
1540 int added_weights = 0;
1541 dircollator_t *collator = NULL;
1544 tor_assert(flavor == FLAV_NS || flavor == FLAV_MICRODESC);
1545 tor_assert(total_authorities >= smartlist_len(votes));
1550 if (!smartlist_len(votes)) {
1551 log_warn(
LD_DIR,
"Can't compute a consensus from no votes.");
1558 log_info(
LD_DIR,
"Generating consensus using method %d.",
1561 log_warn(
LD_DIR,
"The other authorities will use consensus method %d, "
1562 "which I don't support. Maybe I should upgrade!",
1577 int n_votes = smartlist_len(votes);
1578 time_t *va_times = tor_calloc(n_votes,
sizeof(time_t));
1579 time_t *fu_times = tor_calloc(n_votes,
sizeof(time_t));
1580 time_t *vu_times = tor_calloc(n_votes,
sizeof(time_t));
1581 int *votesec_list = tor_calloc(n_votes,
sizeof(
int));
1582 int *distsec_list = tor_calloc(n_votes,
sizeof(
int));
1583 int n_versioning_clients = 0, n_versioning_servers = 0;
1589 va_times[v_sl_idx] = v->valid_after;
1590 fu_times[v_sl_idx] = v->fresh_until;
1591 vu_times[v_sl_idx] = v->valid_until;
1592 votesec_list[v_sl_idx] = v->vote_seconds;
1593 distsec_list[v_sl_idx] = v->dist_seconds;
1594 if (v->client_versions) {
1596 ++n_versioning_clients;
1598 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1603 if (v->server_versions) {
1605 ++n_versioning_servers;
1607 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1614 } SMARTLIST_FOREACH_END(v);
1615 valid_after = median_time(va_times, n_votes);
1616 fresh_until = median_time(fu_times, n_votes);
1617 valid_until = median_time(vu_times, n_votes);
1618 vote_seconds = median_int(votesec_list, n_votes);
1619 dist_seconds = median_int(distsec_list, n_votes);
1631 n_versioning_servers);
1633 n_versioning_clients);
1636 packages = tor_strdup(
"");
1642 smartlist_free(combined_server_versions);
1643 smartlist_free(combined_client_versions);
1657 const bool badexit_flag_is_listed =
1663 char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
1664 vu_buf[ISO_TIME_LEN+1];
1672 "vote-status consensus\n",
1673 flavor == FLAV_NS ?
"" :
" ",
1674 flavor == FLAV_NS ?
"" : flavor_name);
1683 "voting-delay %d %d\n"
1684 "client-versions %s\n"
1685 "server-versions %s\n"
1688 va_buf, fu_buf, vu_buf,
1689 vote_seconds, dist_seconds,
1690 client_versions, server_versions,
1700 for (idx = 0; idx < 4; ++idx) {
1702 if (BUG(!proto_line))
1710 if (smartlist_len(param_list)) {
1722 int32_t num_srv_agreements =
1724 "AuthDirNumSRVAgreements",
1725 (num_dirauth * 2) / 3);
1728 if (srv_lines != NULL) {
1748 e_legacy->is_legacy = 1;
1751 } SMARTLIST_FOREACH_END(v);
1765 "dir-source %s%s %s %s %s %d %d\n",
1766 voter->
nickname, e->is_legacy ?
"-legacy" :
"",
1770 if (! e->is_legacy) {
1777 } SMARTLIST_FOREACH_END(e);
1779 smartlist_free(dir_sources);
1785 if (max_unmeasured_bw_kb < 1)
1786 max_unmeasured_bw_kb = 1;
1800 uint32_t *bandwidths_kb = tor_calloc(smartlist_len(votes),
1802 uint32_t *measured_bws_kb = tor_calloc(smartlist_len(votes),
1804 uint32_t *measured_guardfraction = tor_calloc(smartlist_len(votes),
1808 int num_guardfraction_inputs;
1818 int n_authorities_measuring_bandwidth;
1820 strmap_t *name_to_id_map = strmap_new();
1823 memset(conflict, 0,
sizeof(conflict));
1824 memset(unknown, 0xff,
sizeof(conflict));
1826 size = tor_calloc(smartlist_len(votes),
sizeof(
int));
1827 n_voter_flags = tor_calloc(smartlist_len(votes),
sizeof(
int));
1828 n_flag_voters = tor_calloc(smartlist_len(flags),
sizeof(
int));
1829 flag_map = tor_calloc(smartlist_len(votes),
sizeof(
int *));
1830 named_flag = tor_calloc(smartlist_len(votes),
sizeof(
int));
1831 unnamed_flag = tor_calloc(smartlist_len(votes),
sizeof(
int));
1832 for (i = 0; i < smartlist_len(votes); ++i)
1833 unnamed_flag[i] = named_flag[i] = -1;
1842 flag_map[v_sl_idx] = tor_calloc(smartlist_len(v->known_flags),
1845 log_warn(
LD_BUG,
"Somehow, a vote has %d entries in known_flags",
1846 smartlist_len(v->known_flags));
1851 flag_map[v_sl_idx][fl_sl_idx] = p;
1853 if (!strcmp(fl,
"Named"))
1854 named_flag[v_sl_idx] = fl_sl_idx;
1855 if (!strcmp(fl,
"Unnamed"))
1856 unnamed_flag[v_sl_idx] = fl_sl_idx;
1857 } SMARTLIST_FOREACH_END(fl);
1858 n_voter_flags[v_sl_idx] = smartlist_len(v->known_flags);
1859 size[v_sl_idx] = smartlist_len(v->routerstatus_list);
1860 } SMARTLIST_FOREACH_END(v);
1866 if (named_flag[v_sl_idx]<0)
1868 nf = UINT64_C(1) << named_flag[v_sl_idx];
1872 if ((rs->flags & nf) != 0) {
1873 const char *d =
strmap_get_lc(name_to_id_map, rs->status.nickname);
1877 rs->status.identity_digest);
1878 }
else if (d != conflict &&
1881 strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
1886 } SMARTLIST_FOREACH_END(rs);
1887 } SMARTLIST_FOREACH_END(v);
1891 if (unnamed_flag[v_sl_idx]<0)
1893 uf = UINT64_C(1) << unnamed_flag[v_sl_idx];
1896 if ((rs->flags & uf) != 0) {
1897 const char *d =
strmap_get_lc(name_to_id_map, rs->status.nickname);
1898 if (d == conflict || d == unknown) {
1902 strmap_set_lc(name_to_id_map, rs->status.nickname, unknown);
1905 strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
1910 } SMARTLIST_FOREACH_END(rs);
1911 } SMARTLIST_FOREACH_END(v);
1915 n_authorities_measuring_bandwidth = 0;
1917 if (v->has_measured_bws) {
1918 ++n_authorities_measuring_bandwidth;
1926 } SMARTLIST_FOREACH_END(v);
1931 flag_counts = tor_calloc(smartlist_len(flags),
sizeof(
int));
1933 for (i = 0; i < num_routers; ++i) {
1939 const char *current_rsa_id = NULL;
1940 const char *chosen_version;
1941 const char *chosen_protocol_list;
1942 const char *chosen_name = NULL;
1943 int exitsummary_disagreement = 0;
1944 int is_named = 0, is_unnamed = 0, is_running = 0, is_valid = 0;
1945 int is_guard = 0, is_exit = 0, is_bad_exit = 0, is_middle_only = 0;
1946 int naming_conflict = 0;
1951 memset(flag_counts, 0,
sizeof(
int)*smartlist_len(flags));
1958 num_guardfraction_inputs = 0;
1959 int ed_consensus = 0;
1960 const uint8_t *ed_consensus_val = NULL;
1963 for (
int voter_idx = 0; voter_idx < smartlist_len(votes); ++voter_idx) {
1964 if (vrs_lst[voter_idx] == NULL)
1966 rs = vrs_lst[voter_idx];
1982 for (
int flag = 0; flag < n_voter_flags[voter_idx]; ++flag) {
1983 if (rs->
flags & (UINT64_C(1) << flag))
1984 ++flag_counts[flag_map[voter_idx][flag]];
1986 if (named_flag[voter_idx] >= 0 &&
1987 (rs->
flags & (UINT64_C(1) << named_flag[voter_idx]))) {
1989 log_notice(
LD_DIR,
"Conflict on naming for router: %s vs %s",
1991 naming_conflict = 1;
1998 measured_guardfraction[num_guardfraction_inputs++] =
2012 if (ed_consensus_val) {
2023 if (n_listing <= total_authorities/2)
2026 if (ed_consensus > 0) {
2027 if (ed_consensus <= total_authorities / 2) {
2028 log_warn(
LD_BUG,
"Not enough entries had ed_consensus set; how "
2029 "can we have a consensus of %d?", ed_consensus);
2039 memset(microdesc_digest, 0,
sizeof(microdesc_digest));
2041 microdesc_digest, &alt_orport);
2043 memset(&rs_out, 0,
sizeof(rs_out));
2068 flavor == FLAV_MICRODESC) {
2072 if (chosen_name && !naming_conflict) {
2081 is_named = is_unnamed = 0;
2083 is_named = 1; is_unnamed = 0;
2085 is_named = 0; is_unnamed = 1;
2091 if (!strcmp(fl,
"Named")) {
2094 }
else if (!strcmp(fl,
"Unnamed")) {
2097 }
else if (!strcmp(fl,
"NoEdConsensus")) {
2098 if (ed_consensus <= total_authorities/2)
2101 if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2) {
2103 if (!strcmp(fl,
"Exit"))
2105 else if (!strcmp(fl,
"Guard"))
2107 else if (!strcmp(fl,
"Running"))
2109 else if (!strcmp(fl,
"BadExit"))
2111 else if (!strcmp(fl,
"MiddleOnly"))
2113 else if (!strcmp(fl,
"Valid"))
2117 } SMARTLIST_FOREACH_END(fl);
2132 if (is_middle_only) {
2137 is_exit = is_guard = 0;
2138 if (! is_bad_exit && badexit_flag_is_listed) {
2146 if (smartlist_len(versions)) {
2150 chosen_version = NULL;
2154 if (smartlist_len(protocols)) {
2158 chosen_protocol_list = NULL;
2163 if (is_guard && num_guardfraction_inputs > 2) {
2166 num_guardfraction_inputs);
2175 rs_out.
bandwidth_kb = median_uint32(measured_bws_kb, num_mbws);
2176 }
else if (num_bandwidths > 0) {
2179 rs_out.
bandwidth_kb = median_uint32(bandwidths_kb, num_bandwidths);
2180 if (n_authorities_measuring_bandwidth > 2) {
2189 is_exit = is_exit && !is_bad_exit;
2195 &G, &M, &E, &D, &
T);
2215 const char *chosen_exitsummary = NULL;
2221 vsr->status.identity_digest,
2223 if (vsr->status.has_exitsummary &&
2225 vsr->status.descriptor_digest,
2229 if (!chosen_exitsummary) {
2230 chosen_exitsummary = vsr->status.exitsummary;
2231 }
else if (strcmp(chosen_exitsummary, vsr->status.exitsummary)) {
2234 exitsummary_disagreement = 1;
2237 } SMARTLIST_FOREACH_END(vsr);
2239 if (exitsummary_disagreement) {
2244 log_warn(
LD_DIR,
"The voters disagreed on the exit policy summary "
2245 " for router %s with descriptor %s. This really shouldn't"
2246 " have happened.",
id, dd);
2250 }
else if (!chosen_exitsummary) {
2255 log_warn(
LD_DIR,
"Not one of the voters that made us select"
2256 "descriptor %s for router %s had an exit policy"
2264 if (vsr->status.has_exitsummary)
2270 if (!chosen_exitsummary)
2271 log_warn(
LD_DIR,
"Wow, not one of the voters had an exit "
2272 "policy summary for %s. Wow.",
id);
2275 if (chosen_exitsummary) {
2282 if (flavor == FLAV_MICRODESC &&
2293 rs_format, NULL, published_on);
2298 if (flavor == FLAV_MICRODESC &&
2306 smartlist_len(chosen_flags)?
" ":
"");
2310 if (chosen_version) {
2315 if (chosen_protocol_list) {
2320 char *guardfraction_str = NULL;
2330 unmeasured?
" Unmeasured=1":
"",
2331 guardfraction_str ? guardfraction_str :
"");
2347 for (i = 0; i < smartlist_len(votes); ++i)
2353 strmap_free(name_to_id_map, NULL);
2354 smartlist_free(matching_descs);
2355 smartlist_free(chosen_flags);
2356 smartlist_free(versions);
2357 smartlist_free(protocols);
2358 smartlist_free(exitsummaries);
2368 int64_t weight_scale;
2371 if (weight_scale < 1)
2383 flavor == FLAV_NS ? DIGEST_SHA1 : DIGEST_SHA256;
2392 crypto_digest_smartlist(digest, digest_len, chunks,
"", digest_alg);
2399 if (flavor == FLAV_NS) {
2401 signing_key_fingerprint);
2404 algname, fingerprint,
2405 signing_key_fingerprint);
2410 log_warn(
LD_BUG,
"Couldn't sign consensus networkstatus.");
2420 signing_key_fingerprint, 0);
2421 if (flavor == FLAV_NS) {
2423 signing_key_fingerprint);
2426 algname, fingerprint,
2427 signing_key_fingerprint);
2432 log_warn(
LD_BUG,
"Couldn't sign consensus networkstatus.");
2445 NS_TYPE_CONSENSUS))) {
2446 log_err(
LD_BUG,
"Generated a networkstatus consensus we couldn't "
2452 if (added_weights) {
2455 networkstatus_vote_free(c);
2460 dircollator_free(collator);
2465 smartlist_free(flags);
2467 smartlist_free(chunks);
2469 smartlist_free(param_list);
2479 const int n_votes = smartlist_len(votes);
2485 strmap_t *package_status = strmap_new();
2488 if (! v->package_lines)
2495 const char *cp = strchr(line,
' ');
2498 cp = strchr(cp,
' ');
2501 char *key = tor_strndup(line, cp - line);
2503 const char **status = strmap_get(package_status, key);
2505 status = tor_calloc(n_votes,
sizeof(
const char *));
2506 strmap_set(package_status, key, status);
2508 status[v_sl_idx] = line;
2510 } SMARTLIST_FOREACH_END(line);
2511 } SMARTLIST_FOREACH_END(v);
2515 STRMAP_FOREACH(package_status, key,
const char **, values) {
2517 for (i = 0; i < n_votes; ++i) {
2522 int n_voting_for_entry = smartlist_len(entries);
2523 const char *most_frequent =
2526 if (n_voting_for_entry >= 3 && count > n_voting_for_entry / 2) {
2532 } STRMAP_FOREACH_END;
2539 smartlist_free(result_list);
2540 smartlist_free(entries);
2562 const char **msg_out)
2575 *msg_out =
"Valid-After times do not match "
2576 "when adding detached signatures to consensus";
2580 *msg_out =
"Fresh-until times do not match "
2581 "when adding detached signatures to consensus";
2585 *msg_out =
"Valid-until times do not match "
2586 "when adding detached signatures to consensus";
2589 siglist = strmap_get(sigs->
signatures, flavor);
2591 *msg_out =
"No signatures for given consensus flavor";
2601 *msg_out =
"No digests for given consensus flavor";
2610 *msg_out =
"Mismatched digest.";
2616 *msg_out =
"No recognized digests for given consensus flavor";
2626 const char *algorithm;
2633 log_info(
LD_DIR,
"Looking at signature from %s using %s", voter_identity,
2636 if (!target_voter) {
2637 log_info(
LD_DIR,
"We do not know any voter with ID %s", voter_identity);
2646 log_info(
LD_DIR,
"We already have a good signature from %s using %s",
2647 voter_identity, algorithm);
2652 if (!sig->good_signature && !sig->bad_signature) {
2654 sig->signing_key_digest);
2664 if (sig->good_signature || !old_sig || old_sig->
bad_signature) {
2665 log_info(
LD_DIR,
"Adding signature from %s with %s", voter_identity,
2667 tor_log(severity,
LD_DIR,
"Added a signature for %s from %s.",
2672 document_signature_free(old_sig);
2676 log_info(
LD_DIR,
"Not adding signature from %s", voter_identity);
2678 } SMARTLIST_FOREACH_END(sig);
2690 int for_detached_signatures)
2694 char *result = NULL;
2698 const char *keyword;
2700 if (for_detached_signatures && flavor != FLAV_NS)
2701 keyword =
"additional-signature";
2703 keyword =
"directory-signature";
2711 if (!sig->signature || sig->bad_signature)
2716 if (flavor == FLAV_NS) {
2718 "%s %s %s\n-----BEGIN SIGNATURE-----\n",
2721 const char *digest_name =
2724 "%s%s%s %s %s %s\n-----BEGIN SIGNATURE-----\n",
2726 for_detached_signatures ?
" " :
"",
2727 for_detached_signatures ? flavor_name :
"",
2728 digest_name,
id, sk);
2730 base64_encode(buf,
sizeof(buf), sig->signature, sig->signature_len,
2731 BASE64_ENCODE_MULTILINE);
2732 strlcat(buf,
"-----END SIGNATURE-----\n",
sizeof(buf));
2734 } SMARTLIST_FOREACH_END(sig);
2735 } SMARTLIST_FOREACH_END(v);
2739 smartlist_free(elements);
2753 char *result = NULL, *sigs = NULL;
2760 if (ns && ns->flavor == FLAV_NS)
2763 if (!consensus_ns) {
2764 log_warn(
LD_BUG,
"No NS consensus given.");
2771 char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
2772 vu_buf[ISO_TIME_LEN+1];
2782 "consensus-digest %s\n"
2785 "valid-until %s\n", d, va_buf, fu_buf, vu_buf);
2792 if (ns->flavor == FLAV_NS)
2799 const char *alg_name =
2805 flavor_name, alg_name, d);
2807 } SMARTLIST_FOREACH_END(ns);
2811 char *sigs_on_this_consensus;
2812 if (ns->flavor == FLAV_NS)
2815 if (!sigs_on_this_consensus) {
2816 log_warn(
LD_DIR,
"Couldn't format signatures");
2820 } SMARTLIST_FOREACH_END(ns);
2831 smartlist_free(elements);
2845 for (flav = 0; flav < n_flavors; ++flav) {
2846 if (pending[flav].consensus)
2862 if (!authdir_mode_v3(options))
2864 tor_assert_nonfatal(voting_schedule.voting_starts);
2870 if (voting_schedule.created_on_demand) {
2873 log_notice(
LD_DIR,
"Scheduling voting. Known authority IDs are %s. "
2880#define IF_TIME_FOR_NEXT_ACTION(when_field, done_field) \
2881 if (! voting_schedule.done_field) { \
2882 if (voting_schedule.when_field > now) { \
2883 return voting_schedule.when_field; \
2889 IF_TIME_FOR_NEXT_ACTION(voting_starts, have_voted) {
2890 log_notice(
LD_DIR,
"Time to vote.");
2892 voting_schedule.have_voted = 1;
2894 IF_TIME_FOR_NEXT_ACTION(fetch_missing_votes, have_fetched_missing_votes) {
2895 log_notice(
LD_DIR,
"Time to fetch any votes that we're missing.");
2897 voting_schedule.have_fetched_missing_votes = 1;
2899 IF_TIME_FOR_NEXT_ACTION(voting_ends, have_built_consensus) {
2900 log_notice(
LD_DIR,
"Time to compute a consensus.");
2904 voting_schedule.have_built_consensus = 1;
2906 IF_TIME_FOR_NEXT_ACTION(fetch_missing_signatures,
2907 have_fetched_missing_signatures) {
2908 log_notice(
LD_DIR,
"Time to fetch any signatures that we're missing.");
2910 voting_schedule.have_fetched_missing_signatures = 1;
2912 IF_TIME_FOR_NEXT_ACTION(interval_starts,
2913 have_published_consensus) {
2914 log_notice(
LD_DIR,
"Time to publish the consensus and discard old votes");
2917 voting_schedule.have_published_consensus = 1;
2924 return voting_schedule.voting_starts;
2931#undef IF_TIME_FOR_NEXT_ACTION
2970 time_t now = time(NULL);
2973 const char *msg =
"";
2975 if (!cert || !key) {
2976 log_warn(
LD_NET,
"Didn't find key/certificate to generate v3 vote");
2978 }
else if (cert->
expires < now) {
2979 log_warn(
LD_NET,
"Can't generate v3 vote with expired certificate");
2986 networkstatus_vote_free(ns);
2992 if (!pending_vote) {
2993 log_warn(
LD_DIR,
"Couldn't store my own vote! (I told myself, '%s'.)",
3001 pending_vote->vote_body->
dir,
3002 pending_vote->vote_body->
dir_len, 0);
3003 log_notice(
LD_DIR,
"Vote posted.");
3021 DGV_BY_ID|DGV_INCLUDE_PENDING)) {
3027 } SMARTLIST_FOREACH_END(ds);
3029 if (!smartlist_len(missing_fps)) {
3030 smartlist_free(missing_fps);
3035 log_notice(
LOG_NOTICE,
"We're missing votes from %d authorities (%s). "
3036 "Asking every other authority for a copy.",
3037 smartlist_len(missing_fps), tmp);
3045 smartlist_free(missing_fps);
3098 v->vote_body = NULL;
3099 networkstatus_vote_free(v->vote);
3108 v->vote_body = NULL;
3109 networkstatus_vote_free(v->vote);
3142 smartlist_free(known_v3_keys);
3151 int any_sig_good = 0;
3153 if (sig->good_signature)
3168 TRUSTED_DIRS_CERTS_SRC_FROM_VOTE, 1 ,
3172 log_warn(
LD_BUG,
"We added a cert, but still couldn't find it.");
3184 const char *where_from,
3185 const char **msg_out,
int *status_out)
3191 const char *end_of_vote = NULL;
3207 end_of_vote = vote_body + strlen(vote_body);
3209 log_warn(
LD_DIR,
"Couldn't parse vote: length was %d",
3210 (
int)strlen(vote_body));
3211 *msg_out =
"Unable to parse vote";
3216 assert_any_sig_good(vi);
3220 log_warn(
LD_DIR,
"Got a vote from an authority (nickname %s, address %s) "
3221 "with authority key ID %s. "
3222 "This key ID is not recognized. Known v3 key IDs are: %s",
3226 *msg_out =
"Vote not from a recognized v3 authority";
3229 add_new_cert_if_needed(vote->
cert);
3232 if (vote->
valid_after != voting_schedule.interval_starts) {
3233 char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1];
3236 log_warn(
LD_DIR,
"Rejecting vote from %s with valid-after time of %s; "
3237 "we were expecting %s", vi->
address, tbuf1, tbuf2);
3238 *msg_out =
"Bad valid-after time";
3243 log_notice(
LD_DIR,
"%s posted a vote to me from %s.",
3246 log_notice(
LD_DIR,
"Retrieved %s's vote from %s.",
3255 if (time_posted && time_posted > voting_schedule.fetch_missing_votes) {
3256 char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1];
3259 log_warn(
LD_DIR,
"Rejecting %s's posted vote from %s received at %s; "
3260 "our cutoff for received votes is %s. Check your clock, "
3261 "CPU load, and network load. Also check the authority that "
3263 *msg_out =
"Posted vote received too late, would be dangerous to count it";
3272 if (
fast_memeq(v->vote->cert->cache_info.identity_digest,
3278 log_notice(
LD_DIR,
"Discarding a vote we already have (from %s).",
3280 if (*status_out < 200)
3283 }
else if (v->vote->published < vote->
published) {
3284 log_notice(
LD_DIR,
"Replacing an older pending vote from this "
3285 "directory (%s)", vi->
address);
3287 networkstatus_vote_free(v->vote);
3289 end_of_vote-vote_body),
3293 !
strcmpstart(end_of_vote,
"network-status-version"))
3296 if (*status_out < 200)
3302 log_notice(
LD_DIR,
"Discarding vote from %s because we have "
3303 "a newer one already.", vi->
address);
3304 *msg_out =
"Already have a newer pending vote";
3308 } SMARTLIST_FOREACH_END(v);
3316 end_of_vote-vote_body),
3318 pending_vote->vote = vote;
3321 if (!
strcmpstart(end_of_vote,
"network-status-version ")) {
3322 vote_body = end_of_vote;
3331 *msg_out =
"Error adding vote";
3332 if (*status_out < 400)
3336 networkstatus_vote_free(vote);
3338 if (end_of_vote && !
strcmpstart(end_of_vote,
"network-status-version ")) {
3339 vote_body = end_of_vote;
3345 if (*status_out < 200)
3348 if (!any_failed && !pending_vote) {
3349 *msg_out =
"Duplicate discarded";
3355 return any_failed ? NULL : pending_vote;
3360write_v3_votes_to_disk(
const smartlist_t *pending_votes)
3363 char *votefile = NULL;
3368 c->bytes = v->vote_body->dir;
3369 c->len = v->vote_body->dir_len;
3373 votefile = get_datadir_fname(
"v3-status-votes");
3374 write_chunks_to_file(votefile, votestrings, 0, 0);
3375 log_debug(
LD_DIR,
"Wrote votes to disk (%s)!", votefile);
3379 smartlist_free(votestrings);
3390 int n_votes, n_voters, n_vote_running = 0;
3392 char *consensus_body = NULL, *signatures = NULL;
3398 memset(pending, 0,
sizeof(pending));
3416 if (n_votes <= n_voters/2) {
3417 log_warn(
LD_DIR,
"We don't have enough votes to generate a consensus: "
3418 "%d of %d", n_votes, n_voters/2+1);
3426 if (!n_vote_running) {
3428 log_warn(
LD_DIR,
"Nobody has voted on the Running flag. Generating "
3429 "and publishing a consensus without Running nodes "
3430 "would make many clients stop working. Not "
3431 "generating a consensus!");
3436 log_warn(
LD_DIR,
"Can't generate consensus without a certificate.");
3443 char *legacy_id_digest = NULL;
3444 int n_generated = 0;
3451 "Unable to compute digest of legacy v3 identity key");
3453 legacy_id_digest = legacy_dbuf;
3466 if (!consensus_body) {
3467 log_warn(
LD_DIR,
"Couldn't generate a %s consensus at all!",
3472 strlen(consensus_body),
3476 log_warn(
LD_DIR,
"Couldn't parse %s consensus we generated!",
3485 pending[flav].
body = consensus_body;
3492 tor_asprintf(&filename,
"my-consensus-%s", flavor_name);
3493 char *fpath = get_datadir_fname(filename);
3499 consensus_body = NULL;
3503 log_warn(
LD_DIR,
"Couldn't generate any consensus flavors at all.");
3512 log_warn(
LD_DIR,
"Couldn't extract signatures.");
3517 memcpy(pending_consensuses, pending,
sizeof(pending));
3527 const char *msg = NULL;
3534 "Could not add queued signature to new consensus: %s",
3537 } SMARTLIST_FOREACH_END(sig);
3539 log_notice(
LD_DIR,
"Added %d pending signatures while building "
3540 "consensus.", n_sigs);
3544 log_notice(
LD_DIR,
"Consensus computed; uploading signature(s)");
3551 log_notice(
LD_DIR,
"Signature(s) posted.");
3553 smartlist_free(votes);
3556 smartlist_free(votes);
3559 networkstatus_vote_free(consensus);
3573 const char **msg_out)
3575 const char *flavor_name;
3588 log_info(
LD_DIR,
"Have %d signatures for adding to %s consensus.",
3589 sig_list ? smartlist_len(sig_list) : 0, flavor_name);
3592 source, severity, msg_out);
3594 log_info(
LD_DIR,
"Added %d signatures to consensus.", r);
3597 "Unable to add signatures to consensus: %s",
3598 *msg_out ? *msg_out :
"(unknown)");
3602 char *new_signatures =
3604 char *dst, *dst_end;
3605 size_t new_consensus_len;
3606 if (!new_signatures) {
3607 *msg_out =
"No signatures to add";
3611 strlen(pc->
body) + strlen(new_signatures) + 1;
3612 pc->
body = tor_realloc(pc->
body, new_consensus_len);
3613 dst_end = pc->
body + new_consensus_len;
3616 strlcpy(dst, new_signatures, dst_end-dst);
3626 networkstatus_vote_free(v);
3628 *msg_out =
"Signatures added";
3630 }
else if (r == 0) {
3631 *msg_out =
"Signatures ignored";
3639 *msg_out =
"Unrecognized error while adding detached signatures.";
3654 const char *detached_signatures_body,
3656 const char **msg_out)
3658 int r=0, i, n_added = 0, errors = 0;
3665 detached_signatures_body, NULL))) {
3666 *msg_out =
"Couldn't parse detached signatures.";
3684 if (errors && !n_added) {
3689 if (n_added && pending_consensuses[FLAV_NS].consensus) {
3690 char *new_detached =
3703 *msg_out =
"Unrecognized error while adding detached signatures.";
3705 ns_detached_signatures_free(sigs);
3725 if (pending_consensuses[FLAV_NS].consensus) {
3726 log_notice(
LD_DIR,
"Got a signature from %s. "
3727 "Adding it to the pending consensus.", source);
3729 detached_signatures_body, source, msg);
3731 log_notice(
LD_DIR,
"Got a signature from %s. "
3732 "Queuing it for the next consensus.", source);
3736 detached_signatures_body);
3737 *msg =
"Signature queued";
3757 log_warn(
LD_DIR,
"Not enough info to publish pending %s consensus",
name);
3762 strlen(pending->
body),
3764 log_warn(
LD_DIR,
"Error publishing %s consensus",
name);
3766 log_notice(
LD_DIR,
"Published %s consensus",
name);
3801 return pending_consensuses[flav].
body;
3823 int by_id = flags & DGV_BY_ID;
3824 const int include_pending = flags & DGV_INCLUDE_PENDING;
3825 const int include_previous = flags & DGV_INCLUDE_PREVIOUS;
3841 return pv->vote_body);
3846 return pv->vote_body);
3852 return pv->vote_body);
3857 return pv->vote_body);
3869 (void) consensus_method;
3871 char *key = NULL, *summary = NULL, *family = NULL;
3874 char *output = NULL;
3903 if (summary && strcmp(summary,
"reject 1-65535"))
3911 if (p6 && strcmp(p6,
"reject 1-65535"))
3918 const char *keytype;
3921 keytype =
"ed25519";
3925 keytype =
"rsa1024";
3935 output+strlen(output), 0,
3937 if (smartlist_len(lst) != 1) {
3938 log_warn(
LD_DIR,
"We generated a microdescriptor we couldn't parse.");
3940 smartlist_free(lst);
3943 result = smartlist_get(lst, 0);
3944 smartlist_free(lst);
3948 crypto_pk_free(rsa_pubkey);
3955 smartlist_free(chunks);
3967 int consensus_method_low,
3968 int consensus_method_high)
3972 char *microdesc_consensus_methods =
3974 consensus_method_high,
3980 if (
tor_snprintf(out_buf, out_buf_len,
"m %s sha256=%s\n",
3981 microdesc_consensus_methods, d64)<0)
3984 ret = strlen(out_buf);
3987 tor_free(microdesc_consensus_methods);
3996} microdesc_consensus_methods[] = {
4023 for (cmr = microdesc_consensus_methods;
4024 cmr->low != -1 && cmr->high != -1;
4032 e->high = cmr->high;
4039 for (ep = entries; ep; ep = ep->next) {
4042 ep->low == ep->next->high + 1) {
4044 ep->low = next->low;
4045 microdesc_free(next->md);
4046 ep->next = next->next;
4052 while ((ep = entries)) {
4056 ep->low, ep->high) >= 0) {
4061 ep->md->last_listed = now;
4088 if (commits == NULL) {
4098 for (
int i = 0; i < tok->n_args; i++) {
4103 if (commit == NULL) {
4108 log_warn(
LD_DIR,
"SR: Unable to parse commit %s from vote of voter %s.",
4118 } SMARTLIST_FOREACH_END(tok);
4121 smartlist_free(chunks);
4122 smartlist_free(commits);
4150 smartlist_free(ns->
sr_info.commits);
4158dirvote_dirreq_get_status_vote(
const char *url,
smartlist_t *items,
4163 url += strlen(
"/tor/status-vote/");
4165 url = strchr(url,
'/');
4168 if (!strcmp(url,
"consensus")) {
4174 }
else if (!current && !strcmp(url,
"consensus-signatures")) {
4181 }
else if (!strcmp(url,
"authority")) {
4183 int flags = DGV_BY_ID |
4184 (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
4193 flags = DGV_INCLUDE_PENDING | DGV_INCLUDE_PREVIOUS;
4196 (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
4199 DSR_HEX|DSR_SORT_UNIQ);
4205 smartlist_free(fps);
4231 bw_kb = (uint32_t)mbw_kb;
4265 if (comparison == 0) {
4284 if (comparison == 0)
4300 int first_is_auth, second_is_auth;
4301 const node_t *node_first, *node_second;
4302 int first_is_running, second_is_running;
4303 uint32_t bw_kb_first, bw_kb_second;
4312 if (first_is_auth && !second_is_auth)
4314 else if (!first_is_auth && second_is_auth)
4319 first_is_running = node_first && node_first->
is_running;
4320 second_is_running = node_second && node_second->
is_running;
4321 if (first_is_running && !second_is_running)
4323 else if (!first_is_running && second_is_running)
4329 if (bw_kb_first > bw_kb_second)
4331 else if (bw_kb_first < bw_kb_second)
4350 digestmap_t *omit_as_sybil = digestmap_new();
4356 if (max_with_same_addr <= 0)
4357 max_with_same_addr = INT_MAX;
4360 if (family == AF_INET6)
4370 addrs_equal =
false;
4372 if (! addrs_equal) {
4375 }
else if (++addr_count > max_with_same_addr) {
4376 digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4378 } SMARTLIST_FOREACH_END(ri);
4379 smartlist_free(routers_by_ip);
4380 return omit_as_sybil;
4392 digestmap_t *omit_as_sybil_ipv4;
4393 digestmap_t *omit_as_sybil_ipv6;
4394 digestmap_t *omit_as_sybil = digestmap_new();
4405 } SMARTLIST_FOREACH_END(ri);
4411 digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4414 digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
4417 smartlist_free(routers_ipv4);
4418 smartlist_free(routers_ipv6);
4419 digestmap_free(omit_as_sybil_ipv4, NULL);
4420 digestmap_free(omit_as_sybil_ipv6, NULL);
4422 return omit_as_sybil;
4439 return tor_strndup(platform, eos-platform);
4456 for ( ; ln; ln = ln->next) {
4458 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4465 if (strchr(v,
' ')) {
4467 log_warn(
LD_DIRSERV,
"Unexpected space in versions list member %s. "
4468 "(These are supposed to be comma-separated; I'll pretend you "
4469 "used commas instead.)",
escaped(v));
4472 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4475 } SMARTLIST_FOREACH_END(v);
4477 smartlist_free(more_versions);
4484 log_warn(
LD_DIRSERV,
"Recommended version %s does not look valid. "
4485 " (I'll include it anyway, since you told me to.)",
4488 } SMARTLIST_FOREACH_END(v);
4494 smartlist_free(versions);
4505 digest256map_t *by_ed_key = digest256map_new();
4508 ri->omit_from_vote = 0;
4509 if (ri->cache_info.signing_key_cert == NULL)
4511 const uint8_t *pk = ri->cache_info.signing_key_cert->signing_key.pubkey;
4512 if ((ri2 = digest256map_get(by_ed_key, pk))) {
4515 const time_t ri_pub = ri->cache_info.published_on;
4517 if (ri2_pub < ri_pub ||
4518 (ri2_pub == ri_pub &&
4519 fast_memcmp(ri->cache_info.signed_descriptor_digest,
4521 digest256map_set(by_ed_key, pk, ri);
4524 ri->omit_from_vote = 1;
4528 digest256map_set(by_ed_key, pk, ri);
4530 } SMARTLIST_FOREACH_END(ri);
4532 digest256map_free(by_ed_key, NULL);
4536 if (ri->omit_from_vote) {
4539 } SMARTLIST_FOREACH_END(ri);
4594 char *hostname = NULL, *client_versions = NULL, *server_versions = NULL;
4595 const char *contact;
4602 time_t now = time(NULL);
4615 log_err(
LD_BUG,
"Error computing signing key digest");
4619 log_err(
LD_BUG,
"Error computing identity key digest");
4623 log_warn(
LD_NET,
"Couldn't resolve my hostname");
4626 if (!hostname || !strchr(hostname,
'.')) {
4632 log_err(
LD_BUG,
"Failed to determine hostname AND duplicate address");
4667 dirserv_set_router_is_running(ri, now);
4691 if (ri->protocol_list &&
4695 if (ri->cache_info.published_on >= cutoff) {
4709 if (ri->cache_info.signing_key_cert) {
4711 ri->cache_info.signing_key_cert->signing_key.pubkey,
4714 if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
4717 if (!vote_on_reachability)
4721 if (ri->protocol_list) {
4722 vrs->
protocols = tor_strdup(ri->protocol_list);
4732 } SMARTLIST_FOREACH_END(ri);
4738 smartlist_free(added);
4739 smartlist_free(microdescriptors);
4742 smartlist_free(routers);
4743 digestmap_free(omit_as_sybil, NULL);
4756 routerstatuses, bw_file_headers,
4770 v3_out->
type = NS_TYPE_VOTE;
4774 char tbuf[ISO_TIME_LEN+1];
4777 long last_consensus_interval;
4778 if (current_consensus)
4779 last_consensus_interval = current_consensus->
fresh_until -
4785 (
int)last_consensus_interval,
4788 log_notice(
LD_DIR,
"Choosing valid-after time in vote as %s: "
4789 "consensus_set=%d, last_interval=%d",
4790 tbuf, current_consensus?1:0, (
int)last_consensus_interval);
4802 v3_out->server_versions = server_versions;
4806 v3_out->recommended_client_protocols =
4808 v3_out->required_client_protocols =
4810 v3_out->required_relay_protocols =
4821 v3_out->recommended_client_protocols, NULL));
4826 0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4827 if (vote_on_reachability)
4831 if (list_middle_only)
4838 for ( ; paramline; paramline = paramline->next) {
4840 paramline->value, NULL, 0, 0);
4863 voter->
contact = tor_strdup(contact);
4868 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)
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_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.
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, time_t declared_publish_time)
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.
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.
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)
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