12 #define NS_PARSE_PRIVATE
66 T1_START(
"network-status-version", K_NETWORK_STATUS_VERSION,
68 T1(
"vote-status", K_VOTE_STATUS,
GE(1),
NO_OBJ ),
73 T1(
"voting-delay", K_VOTING_DELAY,
GE(2),
NO_OBJ ),
79 T0N(
"shared-rand-commit", K_COMMIT,
GE(3),
NO_OBJ ),
80 T01(
"shared-rand-previous-value", K_PREVIOUS_SRV,
EQ(2),
NO_OBJ ),
81 T01(
"shared-rand-current-value", K_CURRENT_SRV,
EQ(2),
NO_OBJ ),
83 T01(
"recommended-client-protocols", K_RECOMMENDED_CLIENT_PROTOCOLS,
85 T01(
"recommended-relay-protocols", K_RECOMMENDED_RELAY_PROTOCOLS,
87 T01(
"required-client-protocols", K_REQUIRED_CLIENT_PROTOCOLS,
89 T01(
"required-relay-protocols", K_REQUIRED_RELAY_PROTOCOLS,
96 T1(
"dir-source", K_DIR_SOURCE,
GE(6),
NO_OBJ ),
97 T01(
"legacy-dir-key", K_LEGACY_DIR_KEY,
GE(1),
NO_OBJ ),
101 T1(
"consensus-methods", K_CONSENSUS_METHODS,
GE(1),
NO_OBJ ),
109 static token_rule_t networkstatus_consensus_token_table[] = {
110 T1_START(
"network-status-version", K_NETWORK_STATUS_VERSION,
112 T1(
"vote-status", K_VOTE_STATUS,
GE(1),
NO_OBJ ),
116 T1(
"voting-delay", K_VOTING_DELAY,
GE(2),
NO_OBJ ),
128 T01(
"consensus-method", K_CONSENSUS_METHOD,
EQ(1),
NO_OBJ),
131 T01(
"shared-rand-previous-value", K_PREVIOUS_SRV,
EQ(2),
NO_OBJ ),
132 T01(
"shared-rand-current-value", K_CURRENT_SRV,
EQ(2),
NO_OBJ ),
134 T01(
"recommended-client-protocols", K_RECOMMENDED_CLIENT_PROTOCOLS,
136 T01(
"recommended-relay-protocols", K_RECOMMENDED_RELAY_PROTOCOLS,
138 T01(
"required-client-protocols", K_REQUIRED_CLIENT_PROTOCOLS,
140 T01(
"required-relay-protocols", K_REQUIRED_RELAY_PROTOCOLS,
149 static token_rule_t networkstatus_vote_footer_token_table[] = {
152 T(
"directory-signature", K_DIRECTORY_SIGNATURE,
GE(2),
NEED_OBJ ),
165 const char **start_out,
166 const char **end_out)
169 "network-status-version",
170 "\ndirectory-signature",
180 const char *s,
size_t len)
182 const char *start, *end;
201 "network-status-version",
202 "\ndirectory-signature",
210 static inline const char *
211 find_start_of_next_routerstatus(
const char *s,
const char *s_eos)
213 const char *eos, *footer, *sig;
214 if ((eos = tor_memstr(s, s_eos - s,
"\nr ")))
219 footer = tor_memstr(s, eos-s,
"\ndirectory-footer");
220 sig = tor_memstr(s, eos-s,
"\ndirectory-signature");
223 return MIN(footer, sig) + 1;
238 routerstatus_parse_guardfraction(
const char *guardfraction_str,
244 const char *end_of_header = NULL;
245 int is_consensus = !vote_rs;
246 uint32_t guardfraction;
256 end_of_header = strchr(guardfraction_str,
'=');
257 if (!end_of_header) {
262 10, 0, 100, &ok, NULL);
264 log_warn(
LD_DIR,
"Invalid GuardFraction %s",
escaped(guardfraction_str));
268 log_debug(
LD_GENERAL,
"[*] Parsed %s guardfraction '%s' for '%s'.",
269 is_consensus ?
"consensus" :
"vote",
281 log_warn(
LD_BUG,
"Got GuardFraction for non-guard %s. "
282 "This is not supposed to happen. Not applying. ", rs->
nickname);
304 routerstatus_parse_entry_from_string(
memarea_t *area,
305 const char **s,
const char *s_eos,
309 int consensus_method,
312 const char *eos, *s_dup = *s;
315 char timebuf[ISO_TIME_LEN+1];
321 if (!consensus_method)
323 tor_assert(flav == FLAV_NS || flav == FLAV_MICRODESC);
325 eos = find_start_of_next_routerstatus(*s, s_eos);
328 log_warn(
LD_DIR,
"Error tokenizing router status");
331 if (smartlist_len(tokens) < 1) {
332 log_warn(
LD_DIR,
"Impossibly short router status");
335 tok = find_by_keyword(tokens, K_R);
337 if (flav == FLAV_NS) {
339 log_warn(
LD_DIR,
"Too few arguments to r");
342 }
else if (flav == FLAV_MICRODESC) {
354 "Invalid nickname %s in router status; skipping.",
361 log_warn(
LD_DIR,
"Error decoding identity digest %s",
366 if (flav == FLAV_NS) {
368 log_warn(
LD_DIR,
"Error decoding descriptor digest %s",
375 tok->
args[3+offset], tok->
args[4+offset]) < 0 ||
377 log_warn(
LD_DIR,
"Error parsing time '%s %s' [%d %d]",
378 tok->
args[3+offset], tok->
args[4+offset],
384 log_warn(
LD_DIR,
"Error parsing router address in network-status %s",
391 10,0,65535,NULL,NULL);
393 10,0,65535,NULL,NULL);
399 smartlist_free(a_lines);
407 for (i=0; i < tok->
n_args; ++i) {
410 vote_rs->
flags |= (UINT64_C(1)<<p);
412 log_warn(
LD_DIR,
"Flags line had a flag %s not listed in known_flags.",
420 for (i=0; i < tok->
n_args; ++i) {
421 if (!strcmp(tok->
args[i],
"Exit"))
423 else if (!strcmp(tok->
args[i],
"Stable"))
425 else if (!strcmp(tok->
args[i],
"Fast"))
427 else if (!strcmp(tok->
args[i],
"Running"))
429 else if (!strcmp(tok->
args[i],
"Named"))
431 else if (!strcmp(tok->
args[i],
"Valid"))
433 else if (!strcmp(tok->
args[i],
"Guard"))
435 else if (!strcmp(tok->
args[i],
"BadExit"))
437 else if (!strcmp(tok->
args[i],
"Authority"))
439 else if (!strcmp(tok->
args[i],
"Unnamed") &&
440 consensus_method >= 2) {
443 }
else if (!strcmp(tok->
args[i],
"HSDir")) {
445 }
else if (!strcmp(tok->
args[i],
"V2Dir")) {
447 }
else if (!strcmp(tok->
args[i],
"StaleDesc")) {
457 const char *protocols = NULL, *version = NULL;
460 protocols = tok->
args[0];
464 version = tok->
args[0];
480 for (i=0; i < tok->
n_args; ++i) {
496 10, 0, UINT32_MAX, &ok, NULL);
498 log_warn(
LD_DIR,
"Invalid Measured Bandwidth %s",
507 if (routerstatus_parse_guardfraction(tok->
args[i],
508 vote, vote_rs, rs) < 0) {
520 log_warn(
LD_DIR,
"Unknown exit policy summary type %s.",
534 if (t->tp == K_M && t->n_args) {
543 if (!strcmp(t->args[0],
"ed25519")) {
545 if (strcmp(t->args[1],
"none") &&
548 log_warn(
LD_DIR,
"Bogus ed25519 key in networkstatus vote");
553 if (t->tp == K_PROTO) {
555 vote_rs->
protocols = tor_strdup(t->args[0]);
557 } SMARTLIST_FOREACH_END(t);
558 }
else if (flav == FLAV_MICRODESC) {
563 log_warn(
LD_DIR,
"Error decoding microdescriptor digest %s",
568 log_info(
LD_BUG,
"Found an entry in networkstatus with no "
569 "microdescriptor digest. (Router %s ($%s) at %s:%d.)",
582 routerstatus_free(rs);
588 DUMP_AREA(area,
"routerstatus entry");
597 compare_vote_routerstatus_entries(
const void **_a,
const void **_b)
608 int64_t G=0, M=0, E=0, D=0,
T=0;
609 double Wgg, Wgm, Wgd, Wmg, Wmm, Wme, Wmd, Weg, Wem, Wee, Wed;
610 double Gtotal=0, Mtotal=0, Etotal=0;
611 const char *casename = NULL;
613 (void) consensus_method;
629 if (Wgg<0 || Wgm<0 || Wgd<0 || Wmg<0 || Wmm<0 || Wme<0 || Wmd<0 || Weg<0
630 || Wem<0 || Wee<0 || Wed<0) {
631 log_warn(
LD_BUG,
"No bandwidth weights produced in consensus!");
638 if (fabs(Wmm - weight_scale) > 1) {
639 log_warn(
LD_BUG,
"Wmm=%f != %"PRId64,
640 Wmm, (weight_scale));
644 if (fabs(Wem - Wee) > 1) {
645 log_warn(
LD_BUG,
"Wem=%f != Wee=%f", Wem, Wee);
649 if (fabs(Wgm - Wgg) > 1) {
650 log_warn(
LD_BUG,
"Wgm=%f != Wgg=%f", Wgm, Wgg);
654 if (fabs(Weg - Wed) > 1) {
655 log_warn(
LD_BUG,
"Wed=%f != Weg=%f", Wed, Weg);
659 if (fabs(Wgg + Wmg - weight_scale) > 0.001*weight_scale) {
660 log_warn(
LD_BUG,
"Wgg=%f != %"PRId64
" - Wmg=%f", Wgg,
661 (weight_scale), Wmg);
665 if (fabs(Wee + Wme - weight_scale) > 0.001*weight_scale) {
666 log_warn(
LD_BUG,
"Wee=%f != %"PRId64
" - Wme=%f", Wee,
667 (weight_scale), Wme);
671 if (fabs(Wgd + Wmd + Wed - weight_scale) > 0.001*weight_scale) {
672 log_warn(
LD_BUG,
"Wgd=%f + Wmd=%f + Wed=%f != %"PRId64,
673 Wgd, Wmd, Wed, (weight_scale));
678 Wgm /= weight_scale; (void) Wgm;
686 Weg /= weight_scale; (void) Weg;
687 Wem /= weight_scale; (void) Wem;
703 }
else if (is_exit) {
716 log_warn(
LD_BUG,
"Missing consensus bandwidth for router %s",
719 } SMARTLIST_FOREACH_END(rs);
725 if (3*E >=
T && 3*G >=
T) {
728 if (fabs(Etotal-Mtotal) > 0.01*
MAX(Etotal,Mtotal)) {
730 "Bw Weight Failure for %s: Etotal %f != Mtotal %f. "
731 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
733 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
734 casename, Etotal, Mtotal,
737 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
740 if (fabs(Etotal-Gtotal) > 0.01*
MAX(Etotal,Gtotal)) {
742 "Bw Weight Failure for %s: Etotal %f != Gtotal %f. "
743 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
745 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
746 casename, Etotal, Gtotal,
749 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
752 if (fabs(Gtotal-Mtotal) > 0.01*
MAX(Gtotal,Mtotal)) {
754 "Bw Weight Failure for %s: Mtotal %f != Gtotal %f. "
755 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
757 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
758 casename, Mtotal, Gtotal,
761 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
764 }
else if (3*E <
T && 3*G <
T) {
765 int64_t R = MIN(E, G);
766 int64_t S =
MAX(E, G);
774 double Rtotal, Stotal;
782 casename =
"Case 2a";
784 if (Rtotal > Stotal) {
786 "Bw Weight Failure for %s: Rtotal %f > Stotal %f. "
787 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
789 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
790 casename, Rtotal, Stotal,
793 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
799 "Bw Weight Failure for %s: 3*Rtotal %f > T "
800 "%"PRId64
". G=%"PRId64
" M=%"PRId64
" E=%"PRId64
801 " D=%"PRId64
" T=%"PRId64
". "
802 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
803 casename, Rtotal*3, (
T),
806 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
812 "Bw Weight Failure for %s: 3*Stotal %f > T "
813 "%"PRId64
". G=%"PRId64
" M=%"PRId64
" E=%"PRId64
814 " D=%"PRId64
" T=%"PRId64
". "
815 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
816 casename, Stotal*3, (
T),
819 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
825 "Bw Weight Failure for %s: 3*Mtotal %f < T "
827 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
829 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
830 casename, Mtotal*3, (
T),
833 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
837 casename =
"Case 2b";
840 if (D != 0 && 3*M <
T) {
841 casename =
"Case 2b (balanced)";
842 if (fabs(Etotal-Mtotal) > 0.01*
MAX(Etotal,Mtotal)) {
844 "Bw Weight Failure for %s: Etotal %f != Mtotal %f. "
845 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
847 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
848 casename, Etotal, Mtotal,
851 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
854 if (fabs(Etotal-Gtotal) > 0.01*
MAX(Etotal,Gtotal)) {
856 "Bw Weight Failure for %s: Etotal %f != Gtotal %f. "
857 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
859 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
860 casename, Etotal, Gtotal,
863 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
866 if (fabs(Gtotal-Mtotal) > 0.01*
MAX(Gtotal,Mtotal)) {
868 "Bw Weight Failure for %s: Mtotal %f != Gtotal %f. "
869 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
871 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
872 casename, Mtotal, Gtotal,
875 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
879 if (fabs(Etotal-Gtotal) > 0.01*
MAX(Etotal,Gtotal)) {
881 "Bw Weight Failure for %s: Etotal %f != Gtotal %f. "
882 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
884 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
885 casename, Etotal, Gtotal,
888 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
894 int64_t S = MIN(E, G);
895 int64_t NS =
MAX(E, G);
900 casename =
"Case 3a (G scarce)";
904 casename =
"Case 3a (E scarce)";
911 "Bw Weight Failure for %s: 3*Stotal %f > T "
912 "%"PRId64
". G=%"PRId64
" M=%"PRId64
" E=%"PRId64
913 " D=%"PRId64
" T=%"PRId64
". "
914 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
915 casename, Stotal*3, (
T),
918 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
922 if (fabs(NStotal-Mtotal) > 0.01*
MAX(NStotal,Mtotal)) {
924 "Bw Weight Failure for %s: NStotal %f != Mtotal %f. "
925 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
927 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
928 casename, NStotal, Mtotal,
931 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
938 "Bw Weight Failure for %s: 3*NStotal %f < T "
939 "%"PRId64
". G=%"PRId64
" M=%"PRId64
940 " E=%"PRId64
" D=%"PRId64
" T=%"PRId64
". "
941 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
942 casename, NStotal*3, (
T),
945 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
950 casename =
"Case 3b";
951 if (fabs(Etotal-Mtotal) > 0.01*
MAX(Etotal,Mtotal)) {
953 "Bw Weight Failure for %s: Etotal %f != Mtotal %f. "
954 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
956 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
957 casename, Etotal, Mtotal,
960 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
963 if (fabs(Etotal-Gtotal) > 0.01*
MAX(Etotal,Gtotal)) {
965 "Bw Weight Failure for %s: Etotal %f != Gtotal %f. "
966 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
968 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
969 casename, Etotal, Gtotal,
972 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
975 if (fabs(Gtotal-Mtotal) > 0.01*
MAX(Gtotal,Mtotal)) {
977 "Bw Weight Failure for %s: Mtotal %f != Gtotal %f. "
978 "G=%"PRId64
" M=%"PRId64
" E=%"PRId64
" D=%"PRId64
980 "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f",
981 casename, Mtotal, Gtotal,
984 Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
991 log_notice(
LD_DIR,
"Bandwidth-weight %s is verified and valid.",
1019 for (
int i = 0; i < tok->
n_args; i++) {
1031 smartlist_free(chunks);
1040 const char *voter_identity;
1048 if (ns->
type == NS_TYPE_VOTE) {
1049 voter = smartlist_get(ns->
voters, 0);
1055 voter_identity =
"consensus";
1060 if (extract_one_srv(tokens, K_PREVIOUS_SRV, &ns->
sr_info.previous_srv) < 0) {
1061 log_warn(
LD_DIR,
"SR: Unable to parse previous SRV from %s",
1065 if (extract_one_srv(tokens, K_CURRENT_SRV, &ns->
sr_info.current_srv) < 0) {
1066 log_warn(
LD_DIR,
"SR: Unable to parse current SRV from %s",
1081 return tor_strdup(tok->
args[0]);
1089 const char **eos_out,
1093 smartlist_t *rs_tokens = NULL, *footer_tokens = NULL;
1098 const char *cert, *end_of_header, *end_of_footer, *s_dup = s;
1101 int i, inorder, n_signatures = 0;
1102 memarea_t *area = NULL, *rs_area = NULL;
1104 char *last_kwd=NULL;
1105 const char *eos = s + s_len;
1115 log_warn(
LD_DIR,
"Unable to compute digest of network-status");
1120 end_of_header = find_start_of_next_routerstatus(s, eos);
1122 (ns_type == NS_TYPE_CONSENSUS) ?
1123 networkstatus_consensus_token_table :
1124 networkstatus_token_table, 0)) {
1125 log_warn(
LD_DIR,
"Error tokenizing network-status header");
1130 memcpy(&ns->
digests, &ns_digests,
sizeof(ns_digests));
1133 tok = find_by_keyword(tokens, K_NETWORK_STATUS_VERSION);
1138 log_warn(
LD_DIR,
"Can't parse document with unknown flavor %s",
1142 ns->
flavor = flav = flavor;
1144 if (flav != FLAV_NS && ns_type != NS_TYPE_CONSENSUS) {
1145 log_warn(
LD_DIR,
"Flavor found on non-consensus networkstatus.");
1149 if (ns_type != NS_TYPE_CONSENSUS) {
1150 const char *end_of_cert = NULL;
1151 if (!(cert = tor_memstr(s, end_of_header - s,
1152 "\ndir-key-certificate-version")))
1157 if (!ns->
cert || !end_of_cert || end_of_cert > end_of_header)
1161 tok = find_by_keyword(tokens, K_VOTE_STATUS);
1163 if (!strcmp(tok->
args[0],
"vote")) {
1164 ns->
type = NS_TYPE_VOTE;
1165 }
else if (!strcmp(tok->
args[0],
"consensus")) {
1166 ns->
type = NS_TYPE_CONSENSUS;
1167 }
else if (!strcmp(tok->
args[0],
"opinion")) {
1168 ns->
type = NS_TYPE_OPINION;
1170 log_warn(
LD_DIR,
"Unrecognized vote status %s in network-status",
1174 if (ns_type != ns->
type) {
1175 log_warn(
LD_DIR,
"Got the wrong kind of v3 networkstatus.");
1179 if (ns->
type == NS_TYPE_VOTE || ns->
type == NS_TYPE_OPINION) {
1180 tok = find_by_keyword(tokens, K_PUBLISHED);
1187 for (i=0; i < tok->
n_args; ++i)
1206 bool unparseable =
false;
1207 ns->recommended_client_protocols = dup_protocols_string(tokens, &unparseable,
1208 K_RECOMMENDED_CLIENT_PROTOCOLS);
1210 K_RECOMMENDED_RELAY_PROTOCOLS);
1211 ns->required_client_protocols = dup_protocols_string(tokens, &unparseable,
1212 K_REQUIRED_CLIENT_PROTOCOLS);
1213 ns->required_relay_protocols = dup_protocols_string(tokens, &unparseable,
1214 K_REQUIRED_RELAY_PROTOCOLS);
1218 tok = find_by_keyword(tokens, K_VALID_AFTER);
1222 tok = find_by_keyword(tokens, K_FRESH_UNTIL);
1226 tok = find_by_keyword(tokens, K_VALID_UNTIL);
1230 tok = find_by_keyword(tokens, K_VOTING_DELAY);
1246 log_warn(
LD_DIR,
"Vote/consensus freshness interval is too short");
1252 log_warn(
LD_DIR,
"Vote/consensus liveness interval is too short");
1256 log_warn(
LD_DIR,
"Vote seconds is too short");
1260 log_warn(
LD_DIR,
"Dist seconds is too short");
1268 ns->server_versions = tor_strdup(tok->
args[0]);
1278 smartlist_free(package_lst);
1281 tok = find_by_keyword(tokens, K_KNOWN_FLAGS);
1284 for (i = 0; i < tok->
n_args; ++i) {
1286 if (i>0 && strcmp(tok->
args[i-1], tok->
args[i])>= 0) {
1292 log_warn(
LD_DIR,
"known-flags not in order");
1295 if (ns->
type != NS_TYPE_CONSENSUS &&
1302 log_warn(
LD_DIR,
"Too many known-flags in consensus vote or opinion");
1311 for (i = 0; i < tok->
n_args; ++i) {
1313 char *eq = strchr(tok->
args[i],
'=');
1319 eq_pos = eq-tok->
args[i];
1325 if (i > 0 && strcmp(tok->
args[i-1], tok->
args[i]) >= 0) {
1329 if (last_kwd && eq_pos == strlen(last_kwd) &&
1331 log_warn(
LD_DIR,
"Duplicate value for %s parameter",
1336 last_kwd = tor_strndup(tok->
args[i], eq_pos);
1340 log_warn(
LD_DIR,
"params not in order");
1344 log_warn(
LD_DIR,
"Duplicate in parameters");
1353 if (tok->
tp == K_DIR_SOURCE) {
1360 if (ns->
type != NS_TYPE_CONSENSUS)
1368 log_warn(
LD_DIR,
"Error decoding identity digest %s in "
1369 "network-status document.",
escaped(tok->
args[1]));
1372 if (ns->
type != NS_TYPE_CONSENSUS &&
1375 log_warn(
LD_DIR,
"Mismatch between identities in certificate and vote");
1378 if (ns->
type != NS_TYPE_CONSENSUS) {
1380 log_warn(
LD_DIR,
"Rejecting vote signature made with denylisted "
1388 log_warn(
LD_DIR,
"Error decoding IP address %s in network-status.",
1402 }
else if (tok->
tp == K_CONTACT) {
1403 if (!voter || voter->
contact) {
1404 log_warn(
LD_DIR,
"contact element is out of place.");
1408 }
else if (tok->
tp == K_VOTE_DIGEST) {
1412 log_warn(
LD_DIR,
"vote-digest element is out of place.");
1419 log_warn(
LD_DIR,
"Error decoding vote digest %s in "
1420 "network-status consensus.",
escaped(tok->
args[0]));
1424 } SMARTLIST_FOREACH_END(_tok);
1429 if (smartlist_len(ns->
voters) == 0) {
1430 log_warn(
LD_DIR,
"Missing dir-source elements in a networkstatus.");
1432 }
else if (ns->
type != NS_TYPE_CONSENSUS && smartlist_len(ns->
voters) != 1) {
1433 log_warn(
LD_DIR,
"Too many dir-source elements in a vote networkstatus.");
1437 if (ns->
type != NS_TYPE_CONSENSUS &&
1449 log_warn(
LD_DIR,
"Invalid legacy key digest %s on vote.",
1456 if (ns->
type == NS_TYPE_VOTE) {
1457 dirvote_parse_sr_commits(ns, tokens);
1460 if (ns->
type == NS_TYPE_VOTE || ns->
type == NS_TYPE_CONSENSUS) {
1461 extract_shared_random_srvs(ns, tokens);
1470 while (eos - s >= 2 &&
fast_memeq(s,
"r ", 2)) {
1471 if (ns->
type != NS_TYPE_CONSENSUS) {
1473 if (routerstatus_parse_entry_from_string(rs_area, &s, eos, rs_tokens, ns,
1477 vote_routerstatus_free(rs);
1482 if ((rs = routerstatus_parse_entry_from_string(rs_area, &s, eos,
1496 if (ns->
type != NS_TYPE_CONSENSUS) {
1506 log_warn(
LD_DIR,
"Networkstatus entries not sorted by identity digest");
1510 if (ns_type != NS_TYPE_CONSENSUS) {
1511 digest256map_t *ed_id_map = digest256map_new();
1514 if (! vrs->has_ed25519_listing ||
1517 if (digest256map_get(ed_id_map, vrs->ed25519_id) != NULL) {
1518 log_warn(
LD_DIR,
"Vote networkstatus ed25519 identities were not "
1520 digest256map_free(ed_id_map, NULL);
1523 digest256map_set(ed_id_map, vrs->ed25519_id, (
void*)1);
1524 } SMARTLIST_FOREACH_END(vrs);
1525 digest256map_free(ed_id_map, NULL);
1530 if ((end_of_footer = tor_memstr(s, eos-s,
"\nnetwork-status-version ")))
1533 end_of_footer = eos;
1535 networkstatus_vote_footer_token_table, 0)) {
1536 log_warn(
LD_DIR,
"Error tokenizing network-status vote footer.");
1544 if (tok->
tp == K_DIRECTORY_SIGNATURE)
1546 else if (found_sig) {
1547 log_warn(
LD_DIR,
"Extraneous token after first directory-signature");
1550 } SMARTLIST_FOREACH_END(_tok);
1554 if (tok != smartlist_get(footer_tokens, 0)) {
1555 log_warn(
LD_DIR,
"Misplaced directory-footer token");
1563 for (i = 0; i < tok->
n_args; ++i) {
1565 char *eq = strchr(tok->
args[i],
'=');
1567 log_warn(
LD_DIR,
"Bad element '%s' in weight params",
1584 const char *id_hexdigest = NULL;
1585 const char *sk_hexdigest = NULL;
1588 if (tok->
tp != K_DIRECTORY_SIGNATURE)
1592 id_hexdigest = tok->
args[0];
1593 sk_hexdigest = tok->
args[1];
1595 const char *algname = tok->
args[0];
1597 id_hexdigest = tok->
args[1];
1598 sk_hexdigest = tok->
args[2];
1601 log_warn(
LD_DIR,
"Unknown digest algorithm %s; skipping",
1611 log_warn(
LD_DIR,
"Bad object type or length on directory-signature");
1618 !=
sizeof(declared_identity)) {
1619 log_warn(
LD_DIR,
"Error decoding declared identity %s in "
1620 "network-status document.",
escaped(id_hexdigest));
1624 log_warn(
LD_DIR,
"ID on signature on network-status document does "
1625 "not match any declared directory source.");
1635 log_warn(
LD_DIR,
"Error decoding declared signing key digest %s in "
1636 "network-status document.",
escaped(sk_hexdigest));
1641 if (ns->
type != NS_TYPE_CONSENSUS) {
1644 log_warn(
LD_DIR,
"Digest mismatch between declared and actual on "
1645 "network-status vote.");
1654 log_fn(LOG_PROTOCOL_WARN,
LD_DIR,
"We received a networkstatus "
1655 "that contains two signatures from the same voter with the same "
1656 "algorithm. Ignoring the second signature.");
1661 if (ns->
type != NS_TYPE_CONSENSUS) {
1664 "network-status document")) {
1680 } SMARTLIST_FOREACH_END(_tok);
1682 if (! n_signatures) {
1683 log_warn(
LD_DIR,
"No signatures on networkstatus document.");
1685 }
else if (ns->
type == NS_TYPE_VOTE && n_signatures != 1) {
1686 log_warn(
LD_DIR,
"Received more than one signature on a "
1687 "network-status vote.");
1692 *eos_out = end_of_footer;
1697 networkstatus_vote_free(ns);
1702 smartlist_free(tokens);
1707 document_signature_free(sig));
1708 smartlist_free(voter->
sigs);
1717 smartlist_free(rs_tokens);
1719 if (footer_tokens) {
1721 smartlist_free(footer_tokens);
1724 DUMP_AREA(area,
"v3 networkstatus");