hs: Decode flow-control line
[tor.git] / src / test / test_protover.c
blob7ad02cb9c15e30ef3847e9e0f1c1917d3d0b72cd
1 /* Copyright (c) 2016-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 #define PROTOVER_PRIVATE
5 #define DIRVOTE_PRIVATE
7 #include "orconfig.h"
8 #include "test/test.h"
10 #include "lib/tls/tortls.h"
12 #include "core/or/or.h"
14 #include "core/or/connection_or.h"
15 #include "core/or/protover.h"
16 #include "core/or/versions.h"
18 #include "feature/dirauth/dirvote.h"
20 #include "feature/relay/relay_handshake.h"
22 static void
23 test_protover_parse(void *arg)
25 (void) arg;
26 char *re_encoded = NULL;
28 const char *orig = "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16";
29 smartlist_t *elts = parse_protocol_list(orig);
31 tt_assert(elts);
32 tt_int_op(smartlist_len(elts), OP_EQ, 4);
34 const proto_entry_t *e;
35 e = smartlist_get(elts, 0);
36 tt_str_op(e->name, OP_EQ, "Foo");
37 tt_int_op(e->bitmask, OP_EQ, 0x0a);
39 e = smartlist_get(elts, 1);
40 tt_str_op(e->name, OP_EQ, "Bar");
41 tt_int_op(e->bitmask, OP_EQ, 0x08);
43 e = smartlist_get(elts, 2);
44 tt_str_op(e->name, OP_EQ, "Baz");
45 tt_int_op(e->bitmask, OP_EQ, 0x00);
47 e = smartlist_get(elts, 3);
48 tt_str_op(e->name, OP_EQ, "Quux");
49 tt_int_op(e->bitmask, OP_EQ, 0x1de00);
51 re_encoded = encode_protocol_list(elts);
52 tt_assert(re_encoded);
53 tt_str_op(re_encoded, OP_EQ, "Foo=1,3 Bar=3 Baz= Quux=9-12,14-16");
55 done:
56 if (elts)
57 SMARTLIST_FOREACH(elts, proto_entry_t *, ent, proto_entry_free(ent));
58 smartlist_free(elts);
59 tor_free(re_encoded);
62 static void
63 test_protover_parse_fail(void *arg)
65 (void)arg;
66 smartlist_t *elts;
68 /* random junk */
69 elts = parse_protocol_list("!!3@*");
70 tt_ptr_op(elts, OP_EQ, NULL);
72 /* Missing equals sign in an entry */
73 elts = parse_protocol_list("Link=4 Haprauxymatyve Desc=9");
74 tt_ptr_op(elts, OP_EQ, NULL);
76 /* Missing word. */
77 elts = parse_protocol_list("Link=4 =3 Desc=9");
78 tt_ptr_op(elts, OP_EQ, NULL);
80 /* Broken numbers */
81 elts = parse_protocol_list("Link=fred");
82 tt_ptr_op(elts, OP_EQ, NULL);
83 elts = parse_protocol_list("Link=1,fred");
84 tt_ptr_op(elts, OP_EQ, NULL);
85 elts = parse_protocol_list("Link=1,fred,3");
86 tt_ptr_op(elts, OP_EQ, NULL);
88 /* Broken range */
89 elts = parse_protocol_list("Link=1,9-8,3");
90 tt_ptr_op(elts, OP_EQ, NULL);
92 /* Protocol name too long */
93 elts = parse_protocol_list("DoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
94 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
95 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
96 tt_ptr_op(elts, OP_EQ, NULL);
98 done:
102 static void
103 test_protover_vote(void *arg)
105 (void) arg;
107 smartlist_t *lst = smartlist_new();
108 char *result = protover_compute_vote(lst, 1);
110 tt_str_op(result, OP_EQ, "");
111 tor_free(result);
113 smartlist_add(lst, (void*) "Foo=1-10,63 Bar=1,3-7,8");
114 result = protover_compute_vote(lst, 1);
115 tt_str_op(result, OP_EQ, "Bar=1,3-8 Foo=1-10,63");
116 tor_free(result);
118 smartlist_add(lst, (void*) "Quux=12-45 Bar=2-6,8 Foo=9");
119 result = protover_compute_vote(lst, 1);
120 tt_str_op(result, OP_EQ, "Bar=1-8 Foo=1-10,63 Quux=12-45");
121 tor_free(result);
123 result = protover_compute_vote(lst, 2);
124 tt_str_op(result, OP_EQ, "Bar=3-6,8 Foo=9");
125 tor_free(result);
127 /* High threshold */
128 result = protover_compute_vote(lst, 3);
129 tt_str_op(result, OP_EQ, "");
130 tor_free(result);
132 /* Don't count double-voting. */
133 smartlist_clear(lst);
134 smartlist_add(lst, (void*) "Foo=1 Foo=1");
135 smartlist_add(lst, (void*) "Bar=1-2,2-3");
136 result = protover_compute_vote(lst, 2);
137 tt_str_op(result, OP_EQ, "");
138 tor_free(result);
140 /* Bad votes: the result must be empty */
141 smartlist_clear(lst);
142 smartlist_add(lst, (void*) "Faux=10-5");
143 result = protover_compute_vote(lst, 1);
144 tt_str_op(result, OP_EQ, "");
145 tor_free(result);
147 /* This fails, since "-0" is not valid. */
148 smartlist_clear(lst);
149 smartlist_add(lst, (void*) "Faux=-0");
150 result = protover_compute_vote(lst, 1);
151 tt_str_op(result, OP_EQ, "");
152 tor_free(result);
154 /* Vote large protover lists that are just below the threshold */
156 /* Just below the threshold: Rust */
157 smartlist_clear(lst);
158 smartlist_add(lst, (void*) "Sleen=1-50");
159 result = protover_compute_vote(lst, 1);
160 tt_str_op(result, OP_EQ, "Sleen=1-50");
161 tor_free(result);
163 /* Just below the threshold: C */
164 smartlist_clear(lst);
165 smartlist_add(lst, (void*) "Sleen=1-63");
166 result = protover_compute_vote(lst, 1);
167 tt_str_op(result, OP_EQ, "Sleen=1-63");
168 tor_free(result);
170 /* Protocol name too long */
171 smartlist_clear(lst);
172 smartlist_add(lst, (void*) "DoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
173 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
174 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
175 result = protover_compute_vote(lst, 1);
176 tt_str_op(result, OP_EQ, "");
177 tor_free(result);
179 done:
180 tor_free(result);
181 smartlist_free(lst);
184 static void
185 test_protover_all_supported(void *arg)
187 (void)arg;
188 char *msg = NULL;
190 tt_assert(protover_all_supported(NULL, &msg));
191 tt_ptr_op(msg, OP_EQ, NULL);
193 tt_assert(protover_all_supported("", &msg));
194 tt_ptr_op(msg, OP_EQ, NULL);
196 // Some things that we do support
197 tt_assert(protover_all_supported("Link=3-4", &msg));
198 tt_ptr_op(msg, OP_EQ, NULL);
199 tt_assert(protover_all_supported("Link=3-4 Desc=2", &msg));
200 tt_ptr_op(msg, OP_EQ, NULL);
202 // Some things we don't support
203 tt_assert(! protover_all_supported("Wombat=9", NULL));
204 tt_assert(! protover_all_supported("Wombat=9", &msg));
205 tt_str_op(msg, OP_EQ, "Wombat=9");
206 tor_free(msg);
207 tt_assert(! protover_all_supported("Link=60", &msg));
208 tt_str_op(msg, OP_EQ, "Link=60");
209 tor_free(msg);
211 // Mix of things we support and things we don't
212 tt_assert(! protover_all_supported("Link=3-4 Wombat=9", &msg));
213 tt_str_op(msg, OP_EQ, "Wombat=9");
214 tor_free(msg);
216 /* Mix of things we support and don't support within a single protocol
217 * which we do support */
218 tt_assert(! protover_all_supported("Link=3-60", &msg));
219 tt_str_op(msg, OP_EQ, "Link=6-60");
220 tor_free(msg);
221 tt_assert(! protover_all_supported("Link=1-3,50-63", &msg));
222 tt_str_op(msg, OP_EQ, "Link=50-63");
223 tor_free(msg);
224 tt_assert(! protover_all_supported("Link=1-3,5-12", &msg));
225 tt_str_op(msg, OP_EQ, "Link=6-12");
226 tor_free(msg);
228 /* Mix of protocols we do support and some we don't, where the protocols
229 * we do support have some versions we don't support. */
230 tt_assert(! protover_all_supported("Link=1-3,5-12 Quokka=40-41", &msg));
231 tt_str_op(msg, OP_EQ, "Link=6-12 Quokka=40-41");
232 tor_free(msg);
234 /* If we get a (barely) valid (but unsupported list, we say "yes, that's
235 * supported." */
236 tt_assert(protover_all_supported("Fribble=", &msg));
237 tt_ptr_op(msg, OP_EQ, NULL);
239 #ifndef ALL_BUGS_ARE_FATAL
240 /* If we get a completely unparseable list, protover_all_supported should
241 * hit a fatal assertion for BUG(entries == NULL). */
242 tor_capture_bugs_(1);
243 tt_assert(protover_all_supported("Fribble", &msg));
244 tor_end_capture_bugs_();
246 /* If we get a completely unparseable list, protover_all_supported should
247 * hit a fatal assertion for BUG(entries == NULL). */
248 tor_capture_bugs_(1);
249 tt_assert(protover_all_supported("Sleen=1-4294967295", &msg));
250 tor_end_capture_bugs_();
251 #endif /* !defined(ALL_BUGS_ARE_FATAL) */
253 /* Protocol name too long */
254 #if !defined(ALL_BUGS_ARE_FATAL)
255 tor_capture_bugs_(1);
256 tt_assert(protover_all_supported(
257 "DoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
258 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
259 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
260 "aaaaaaaaaaaa=1-65536", &msg));
261 tor_end_capture_bugs_();
262 #endif /* !defined(ALL_BUGS_ARE_FATAL) */
264 done:
265 tor_end_capture_bugs_();
266 tor_free(msg);
269 static void
270 test_protover_list_supports_protocol_returns_true(void *arg)
272 (void)arg;
274 const char *protocols = "Link=1";
275 int is_supported = protocol_list_supports_protocol(protocols, PRT_LINK, 1);
276 tt_int_op(is_supported, OP_EQ, 1);
278 done:
282 static void
283 test_protover_list_supports_protocol_for_unsupported_returns_false(void *arg)
285 (void)arg;
287 const char *protocols = "Link=1";
288 int is_supported = protocol_list_supports_protocol(protocols, PRT_LINK, 10);
289 tt_int_op(is_supported, OP_EQ, 0);
291 done:
295 static void
296 test_protover_supports_version(void *arg)
298 (void)arg;
300 tt_assert(protocol_list_supports_protocol("Link=3-6", PRT_LINK, 3));
301 tt_assert(protocol_list_supports_protocol("Link=3-6", PRT_LINK, 6));
302 tt_assert(!protocol_list_supports_protocol("Link=3-6", PRT_LINK, 7));
303 tt_assert(!protocol_list_supports_protocol("Link=3-6", PRT_LINKAUTH, 3));
305 tt_assert(!protocol_list_supports_protocol("Link=4-6 LinkAuth=3",
306 PRT_LINKAUTH, 2));
307 tt_assert(protocol_list_supports_protocol("Link=4-6 LinkAuth=3",
308 PRT_LINKAUTH, 3));
309 tt_assert(!protocol_list_supports_protocol("Link=4-6 LinkAuth=3",
310 PRT_LINKAUTH, 4));
311 tt_assert(!protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3",
312 PRT_LINKAUTH, 4));
313 tt_assert(protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3",
314 PRT_LINKAUTH, 3));
315 tt_assert(protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3",
316 PRT_LINKAUTH, 2));
318 tt_assert(!protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3",
319 PRT_DESC, 2));
320 done:
324 /* This could be MAX_PROTOCOLS_TO_EXPAND, but that's not exposed by protover */
325 #define MAX_PROTOCOLS_TO_TEST 1024
327 /* LinkAuth and Relay protocol versions.
328 * Hard-coded here, because they are not in the code, or not exposed in the
329 * headers. */
330 #define PROTOVER_LINKAUTH_V1 1
331 #define PROTOVER_LINKAUTH_V2 2
332 #define PROTOVER_RELAY_V1 1
334 /* Deprecated HSIntro versions */
335 #define PROTOVER_HS_INTRO_DEPRECATED_1 1
336 #define PROTOVER_HS_INTRO_DEPRECATED_2 2
338 /* HSv2 Rend and HSDir protocol versions. */
339 #define PROTOVER_HS_RENDEZVOUS_POINT_V2 1
340 #define PROTOVER_HSDIR_V2 2
342 /* DirCache, Desc, Microdesc, and Cons protocol versions. */
343 #define PROTOVER_DIRCACHE_V1 1
344 #define PROTOVER_DIRCACHE_V2 2
346 #define PROTOVER_DESC_V1 1
347 #define PROTOVER_DESC_V2 2
349 #define PROTOVER_MICRODESC_V1 1
350 #define PROTOVER_MICRODESC_V2 2
352 #define PROTOVER_CONS_V1 1
353 #define PROTOVER_CONS_V2 2
355 #define PROTOVER_PADDING_V1 1
357 #define PROTOVER_FLOWCTRL_V1 1
358 #define PROTOVER_FLOWCTRL_V2 2
360 #define PROTOVER_RELAY_NTOR_V3 4
362 /* Make sure we haven't forgotten any supported protocols */
363 static void
364 test_protover_supported_protocols(void *arg)
366 (void)arg;
368 const char *supported_protocols = protover_get_supported_protocols();
370 /* Test for new Link in the code, that hasn't been added to supported
371 * protocols */
372 tt_assert(protocol_list_supports_protocol(supported_protocols,
373 PRT_LINK,
374 MAX_LINK_PROTO));
375 for (uint16_t i = 0; i < MAX_PROTOCOLS_TO_TEST; i++) {
376 tt_int_op(protocol_list_supports_protocol(supported_protocols,
377 PRT_LINK,
379 OP_EQ,
380 is_or_protocol_version_known(i));
383 /* Legacy LinkAuth is only supported on OpenSSL and similar. */
384 tt_int_op(protocol_list_supports_protocol(supported_protocols,
385 PRT_LINKAUTH,
386 PROTOVER_LINKAUTH_V1),
387 OP_EQ,
388 authchallenge_type_is_supported(AUTHTYPE_RSA_SHA256_TLSSECRET));
389 /* LinkAuth=2 is unused */
390 tt_assert(!protocol_list_supports_protocol(supported_protocols,
391 PRT_LINKAUTH,
392 PROTOVER_LINKAUTH_V2));
393 tt_assert(
394 protocol_list_supports_protocol(supported_protocols,
395 PRT_LINKAUTH,
396 PROTOVER_LINKAUTH_ED25519_HANDSHAKE));
398 /* Relay protovers do not appear anywhere in the code. */
399 tt_assert(protocol_list_supports_protocol(supported_protocols,
400 PRT_RELAY,
401 PROTOVER_RELAY_V1));
402 tt_assert(protocol_list_supports_protocol(supported_protocols,
403 PRT_RELAY,
404 PROTOVER_RELAY_EXTEND2));
405 tt_assert(protocol_list_supports_protocol(supported_protocols,
406 PRT_RELAY,
407 PROTOVER_RELAY_ACCEPT_IPV6));
408 tt_assert(protocol_list_supports_protocol(supported_protocols,
409 PRT_RELAY,
410 PROTOVER_RELAY_EXTEND_IPV6));
411 tt_assert(protocol_list_supports_protocol(supported_protocols,
412 PRT_RELAY,
413 PROTOVER_RELAY_CANONICAL_IPV6));
415 /* These HSIntro versions are deprecated */
416 tt_assert(!protocol_list_supports_protocol(supported_protocols,
417 PRT_HSINTRO,
418 PROTOVER_HS_INTRO_DEPRECATED_1));
419 tt_assert(!protocol_list_supports_protocol(supported_protocols,
420 PRT_HSINTRO,
421 PROTOVER_HS_INTRO_DEPRECATED_2));
422 /* Test for HSv3 HSIntro */
423 tt_assert(protocol_list_supports_protocol(supported_protocols,
424 PRT_HSINTRO,
425 PROTOVER_HS_INTRO_V3));
426 /* Test for HSIntro DoS */
427 tt_assert(protocol_list_supports_protocol(supported_protocols,
428 PRT_HSINTRO,
429 PROTOVER_HS_INTRO_DOS));
431 /* Legacy HSRend does not appear anywhere in the code. */
432 tt_assert(protocol_list_supports_protocol(supported_protocols,
433 PRT_HSREND,
434 PROTOVER_HS_RENDEZVOUS_POINT_V2));
435 /* Test for HSv3 HSRend */
436 tt_assert(protocol_list_supports_protocol(supported_protocols,
437 PRT_HSREND,
438 PROTOVER_HS_RENDEZVOUS_POINT_V3));
440 /* Legacy HSDir does not appear anywhere in the code. */
441 tt_assert(protocol_list_supports_protocol(supported_protocols,
442 PRT_HSDIR,
443 PROTOVER_HSDIR_V2));
444 /* Test for HSv3 HSDir */
445 tt_assert(protocol_list_supports_protocol(supported_protocols,
446 PRT_HSDIR,
447 PROTOVER_HSDIR_V3));
449 /* No DirCache versions appear anywhere in the code. */
450 tt_assert(protocol_list_supports_protocol(supported_protocols,
451 PRT_DIRCACHE,
452 PROTOVER_DIRCACHE_V2));
454 /* No Desc versions appear anywhere in the code. */
455 tt_assert(protocol_list_supports_protocol(supported_protocols,
456 PRT_DESC,
457 PROTOVER_DESC_V1));
458 tt_assert(protocol_list_supports_protocol(supported_protocols,
459 PRT_DESC,
460 PROTOVER_DESC_V2));
461 /* Is there any way to test for new Desc? */
463 /* No Microdesc versions appear anywhere in the code. */
464 tt_assert(protocol_list_supports_protocol(supported_protocols,
465 PRT_MICRODESC,
466 PROTOVER_MICRODESC_V1));
467 tt_assert(protocol_list_supports_protocol(supported_protocols,
468 PRT_MICRODESC,
469 PROTOVER_MICRODESC_V2));
471 /* No Cons versions appear anywhere in the code. */
472 tt_assert(protocol_list_supports_protocol(supported_protocols,
473 PRT_CONS,
474 PROTOVER_CONS_V1));
475 tt_assert(protocol_list_supports_protocol(supported_protocols,
476 PRT_CONS,
477 PROTOVER_CONS_V2));
479 /* Padding=1 is deprecated. */
480 tt_assert(!protocol_list_supports_protocol(supported_protocols,
481 PRT_PADDING,
482 PROTOVER_PADDING_V1));
483 tt_assert(protocol_list_supports_protocol(supported_protocols,
484 PRT_PADDING,
485 PROTOVER_HS_SETUP_PADDING));
487 /* FlowCtrl */
488 tt_assert(protocol_list_supports_protocol(supported_protocols,
489 PRT_FLOWCTRL,
490 PROTOVER_FLOWCTRL_V1));
492 done:
496 static void
497 test_protover_vote_roundtrip(void *args)
499 (void) args;
500 static const struct {
501 const char *input;
502 const char *expected_output;
503 } examples[] = {
504 { "Risqu\u00e9=1", NULL },
505 { ",,,=1", NULL },
506 { "\xc1=1", NULL },
507 { "Foo_Bar=1", NULL },
508 { "Fkrkljdsf", NULL },
509 { "Zn=4294967295", NULL },
510 { "Zn=4294967295-1", NULL },
511 { "Zn=4294967293-4294967295", NULL },
512 /* Will fail because of 4294967295. */
513 { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900 Zn=1,4294967295",
514 NULL },
515 { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,50 Zn=1,42",
516 "Bar=3 Foo=1,3 Quux=9-12,14-16,50 Zn=1,42" },
517 { "Zu16=1,63", "Zu16=1,63" },
518 { "N-1=1,2", "N-1=1-2" },
519 { "-1=4294967295", NULL },
520 { "-1=3", "-1=3" },
521 { "Foo=,", NULL },
522 { "Foo=,1", NULL },
523 { "Foo=1,,3", NULL },
524 { "Foo=1,3,", NULL },
525 /* junk. */
526 { "!!3@*", NULL },
527 /* Missing equals sign */
528 { "Link=4 Haprauxymatyve Desc=9", NULL },
529 { "Link=4 Haprauxymatyve=7 Desc=9",
530 "Desc=9 Haprauxymatyve=7 Link=4" },
531 { "=10-11", NULL },
532 { "X=10-11", "X=10-11" },
533 { "Link=4 =3 Desc=9", NULL },
534 { "Link=4 Z=3 Desc=9", "Desc=9 Link=4 Z=3" },
535 { "Link=fred", NULL },
536 { "Link=1,fred", NULL },
537 { "Link=1,fred,3", NULL },
538 { "Link=1,9-8,3", NULL },
539 { "Faux=-0", NULL },
540 { "Faux=0--0", NULL },
541 { "Faux=-1", NULL },
542 { "Faux=-1-3", NULL },
543 { "Faux=1--1", NULL },
544 { "Link=1-2-", NULL },
545 { "Link=1-2-3", NULL },
546 { "Faux=1-2-", NULL },
547 { "Faux=1-2-3", NULL },
548 { "Link=\t1,3", NULL },
549 { "Link=1\n,3", NULL },
550 { "Faux=1,\r3", NULL },
551 { "Faux=1,3\f", NULL },
552 /* Large integers */
553 { "Link=4294967296", NULL },
554 /* Large range */
555 { "Sleen=1-63", "Sleen=1-63" },
556 { "Sleen=1-65537", NULL },
558 unsigned u;
559 smartlist_t *votes = smartlist_new();
560 char *result = NULL;
562 for (u = 0; u < ARRAY_LENGTH(examples); ++u) {
563 const char *input = examples[u].input;
564 const char *expected_output = examples[u].expected_output;
566 smartlist_add(votes, (void*)input);
567 result = protover_compute_vote(votes, 1);
568 if (expected_output != NULL) {
569 tt_str_op(result, OP_EQ, expected_output);
570 } else {
571 tt_str_op(result, OP_EQ, "");
574 smartlist_clear(votes);
575 tor_free(result);
578 done:
579 smartlist_free(votes);
580 tor_free(result);
583 static void
584 test_protover_vote_roundtrip_ours(void *args)
586 (void) args;
587 const char *examples[] = {
588 protover_get_supported_protocols(),
589 protover_get_recommended_client_protocols(),
590 protover_get_recommended_relay_protocols(),
591 protover_get_required_client_protocols(),
592 protover_get_required_relay_protocols(),
594 unsigned u;
595 smartlist_t *votes = smartlist_new();
596 char *result = NULL;
598 for (u = 0; u < ARRAY_LENGTH(examples); ++u) {
599 tt_assert(examples[u]);
600 const char *input = examples[u];
601 const char *expected_output = examples[u];
603 smartlist_add(votes, (void*)input);
604 result = protover_compute_vote(votes, 1);
605 if (expected_output != NULL) {
606 tt_str_op(result, OP_EQ, expected_output);
607 } else {
608 tt_str_op(result, OP_EQ, "");
611 smartlist_clear(votes);
612 tor_free(result);
615 done:
616 smartlist_free(votes);
617 tor_free(result);
620 /* Stringifies its argument.
621 * 4 -> "4" */
622 #define STR(x) #x
624 #ifdef COCCI
625 #define PROTOVER(proto_string, version_macro)
626 #else
627 /* Generate a protocol version string using proto_string and version_macro.
628 * PROTOVER("HSIntro", PROTOVER_HS_INTRO_DOS) -> "HSIntro" "=" "5"
629 * Uses two levels of macros to turn PROTOVER_HS_INTRO_DOS into "5".
631 #define PROTOVER(proto_string, version_macro) \
632 (proto_string "=" STR(version_macro))
633 #endif /* defined(COCCI) */
635 #define DEBUG_PROTOVER(flags) \
636 STMT_BEGIN \
637 log_debug(LD_GENERAL, \
638 "protovers:\n" \
639 "protocols_known: %d,\n" \
640 "supports_extend2_cells: %d,\n" \
641 "supports_accepting_ipv6_extends: %d,\n" \
642 "supports_initiating_ipv6_extends: %d,\n" \
643 "supports_canonical_ipv6_conns: %d,\n" \
644 "supports_ed25519_link_handshake_compat: %d,\n" \
645 "supports_ed25519_link_handshake_any: %d,\n" \
646 "supports_ed25519_hs_intro: %d,\n" \
647 "supports_establish_intro_dos_extension: %d,\n" \
648 "supports_v3_hsdir: %d,\n" \
649 "supports_v3_rendezvous_point: %d,\n" \
650 "supports_hs_setup_padding: %d,\n" \
651 "supports_congestion_control: %d.", \
652 (flags).protocols_known, \
653 (flags).supports_extend2_cells, \
654 (flags).supports_accepting_ipv6_extends, \
655 (flags).supports_initiating_ipv6_extends, \
656 (flags).supports_canonical_ipv6_conns, \
657 (flags).supports_ed25519_link_handshake_compat, \
658 (flags).supports_ed25519_link_handshake_any, \
659 (flags).supports_ed25519_hs_intro, \
660 (flags).supports_establish_intro_dos_extension, \
661 (flags).supports_v3_hsdir, \
662 (flags).supports_v3_rendezvous_point, \
663 (flags).supports_hs_setup_padding, \
664 (flags).supports_congestion_control); \
665 STMT_END
667 /* Test that the proto_string version version_macro sets summary_flag. */
668 #define TEST_PROTOVER(proto_string, version_macro, summary_flag) \
669 STMT_BEGIN \
670 memset(&flags, 0, sizeof(flags)); \
671 summarize_protover_flags(&flags, \
672 PROTOVER(proto_string, version_macro), \
673 NULL); \
674 DEBUG_PROTOVER(flags); \
675 tt_int_op(flags.protocols_known, OP_EQ, 1); \
676 tt_int_op(flags.summary_flag, OP_EQ, 1); \
677 flags.protocols_known = 0; \
678 flags.summary_flag = 0; \
679 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); \
680 STMT_END
682 static void
683 test_protover_summarize_flags(void *args)
685 (void) args;
686 char pv[30];
687 memset(&pv, 0, sizeof(pv));
689 protover_summary_cache_free_all();
691 protover_summary_flags_t zero_flags;
692 memset(&zero_flags, 0, sizeof(zero_flags));
693 protover_summary_flags_t flags;
695 memset(&flags, 0, sizeof(flags));
696 summarize_protover_flags(&flags, NULL, NULL);
697 DEBUG_PROTOVER(flags);
698 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags));
700 memset(&flags, 0, sizeof(flags));
701 summarize_protover_flags(&flags, "", "");
702 DEBUG_PROTOVER(flags);
703 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags));
705 /* Now check version exceptions */
707 /* Congestion control. */
708 memset(&flags, 0, sizeof(flags));
709 summarize_protover_flags(&flags,
710 PROTOVER("FlowCtrl", PROTOVER_FLOWCTRL_V2),
711 NULL);
712 summarize_protover_flags(&flags,
713 PROTOVER("Relay", PROTOVER_RELAY_NTOR_V3),
714 NULL);
715 DEBUG_PROTOVER(flags);
716 tt_int_op(flags.protocols_known, OP_EQ, 1);
717 tt_int_op(flags.supports_congestion_control, OP_EQ, 1);
718 /* Now clear those flags, and check the rest are zero */
719 flags.protocols_known = 0;
720 flags.supports_congestion_control = 0;
721 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags));
723 /* EXTEND2 cell support */
724 memset(&flags, 0, sizeof(flags));
725 summarize_protover_flags(&flags, NULL, "Tor 0.2.4.8-alpha");
726 DEBUG_PROTOVER(flags);
727 tt_int_op(flags.protocols_known, OP_EQ, 1);
728 tt_int_op(flags.supports_extend2_cells, OP_EQ, 1);
729 /* Now clear those flags, and check the rest are zero */
730 flags.protocols_known = 0;
731 flags.supports_extend2_cells = 0;
732 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags));
734 /* disabling HSDir v3 support for buggy versions */
735 memset(&flags, 0, sizeof(flags));
736 summarize_protover_flags(&flags,
737 PROTOVER("HSDir", PROTOVER_HSDIR_V3),
738 NULL);
739 DEBUG_PROTOVER(flags);
740 tt_int_op(flags.protocols_known, OP_EQ, 1);
741 tt_int_op(flags.supports_v3_hsdir, OP_EQ, 1);
742 /* Now clear those flags, and check the rest are zero */
743 flags.protocols_known = 0;
744 flags.supports_v3_hsdir = 0;
745 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags));
747 memset(&flags, 0, sizeof(flags));
748 summarize_protover_flags(&flags,
749 PROTOVER("HSDir", PROTOVER_HSDIR_V3),
750 "Tor 0.3.0.7");
751 DEBUG_PROTOVER(flags);
752 tt_int_op(flags.protocols_known, OP_EQ, 1);
753 /* Now clear that flag, and check the rest are zero */
754 flags.protocols_known = 0;
755 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags));
757 /* Now check standard summaries */
759 /* LinkAuth */
760 memset(&flags, 0, sizeof(flags));
761 summarize_protover_flags(&flags,
762 PROTOVER("LinkAuth",
763 PROTOVER_LINKAUTH_ED25519_HANDSHAKE),
764 NULL);
765 DEBUG_PROTOVER(flags);
766 tt_int_op(flags.protocols_known, OP_EQ, 1);
767 tt_int_op(flags.supports_ed25519_link_handshake_compat, OP_EQ, 1);
768 tt_int_op(flags.supports_ed25519_link_handshake_any, OP_EQ, 1);
769 /* Now clear those flags, and check the rest are zero */
770 flags.protocols_known = 0;
771 flags.supports_ed25519_link_handshake_compat = 0;
772 flags.supports_ed25519_link_handshake_any = 0;
773 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags));
775 /* Test one greater */
776 memset(&flags, 0, sizeof(flags));
777 snprintf(pv, sizeof(pv),
778 "%s=%d", "LinkAuth", PROTOVER_LINKAUTH_ED25519_HANDSHAKE + 1);
779 summarize_protover_flags(&flags, pv, NULL);
780 DEBUG_PROTOVER(flags);
781 tt_int_op(flags.protocols_known, OP_EQ, 1);
782 tt_int_op(flags.supports_ed25519_link_handshake_compat, OP_EQ, 0);
783 tt_int_op(flags.supports_ed25519_link_handshake_any, OP_EQ, 1);
784 /* Now clear those flags, and check the rest are zero */
785 flags.protocols_known = 0;
786 flags.supports_ed25519_link_handshake_compat = 0;
787 flags.supports_ed25519_link_handshake_any = 0;
788 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags));
790 /* Test one less */
791 memset(&flags, 0, sizeof(flags));
792 snprintf(pv, sizeof(pv),
793 "%s=%d", "LinkAuth", PROTOVER_LINKAUTH_ED25519_HANDSHAKE - 1);
794 summarize_protover_flags(&flags, pv, NULL);
795 DEBUG_PROTOVER(flags);
796 tt_int_op(flags.protocols_known, OP_EQ, 1);
797 tt_int_op(flags.supports_ed25519_link_handshake_compat, OP_EQ, 0);
798 tt_int_op(flags.supports_ed25519_link_handshake_any, OP_EQ, 0);
799 /* Now clear those flags, and check the rest are zero */
800 flags.protocols_known = 0;
801 flags.supports_ed25519_link_handshake_compat = 0;
802 flags.supports_ed25519_link_handshake_any = 0;
803 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags));
805 /* We don't test "one more" and "one less" for each protocol version.
806 * But that could be a useful thing to add. */
808 /* Relay */
809 memset(&flags, 0, sizeof(flags));
810 /* This test relies on these versions being equal */
811 tt_int_op(PROTOVER_RELAY_EXTEND2, OP_EQ, PROTOVER_RELAY_ACCEPT_IPV6);
812 summarize_protover_flags(&flags,
813 PROTOVER("Relay", PROTOVER_RELAY_EXTEND2), NULL);
814 DEBUG_PROTOVER(flags);
815 tt_int_op(flags.protocols_known, OP_EQ, 1);
816 tt_int_op(flags.supports_extend2_cells, OP_EQ, 1);
817 tt_int_op(flags.supports_accepting_ipv6_extends, OP_EQ, 1);
818 /* Now clear those flags, and check the rest are zero */
819 flags.protocols_known = 0;
820 flags.supports_extend2_cells = 0;
821 flags.supports_accepting_ipv6_extends = 0;
822 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags));
824 memset(&flags, 0, sizeof(flags));
825 /* This test relies on these versions being equal */
826 tt_int_op(PROTOVER_RELAY_EXTEND_IPV6, OP_EQ, PROTOVER_RELAY_CANONICAL_IPV6);
827 summarize_protover_flags(&flags,
828 PROTOVER("Relay", PROTOVER_RELAY_EXTEND_IPV6),
829 NULL);
830 DEBUG_PROTOVER(flags);
831 tt_int_op(flags.protocols_known, OP_EQ, 1);
832 tt_int_op(flags.supports_accepting_ipv6_extends, OP_EQ, 1);
833 tt_int_op(flags.supports_initiating_ipv6_extends, OP_EQ, 1);
834 tt_int_op(flags.supports_canonical_ipv6_conns, OP_EQ, 1);
835 /* Now clear those flags, and check the rest are zero */
836 flags.protocols_known = 0;
837 flags.supports_accepting_ipv6_extends = 0;
838 flags.supports_initiating_ipv6_extends = 0;
839 flags.supports_canonical_ipv6_conns = 0;
840 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags));
842 TEST_PROTOVER("HSIntro", PROTOVER_HS_INTRO_V3,
843 supports_ed25519_hs_intro);
844 TEST_PROTOVER("HSIntro", PROTOVER_HS_INTRO_DOS,
845 supports_establish_intro_dos_extension);
847 TEST_PROTOVER("HSRend", PROTOVER_HS_RENDEZVOUS_POINT_V3,
848 supports_v3_rendezvous_point);
850 TEST_PROTOVER("HSDir", PROTOVER_HSDIR_V3,
851 supports_v3_hsdir);
853 TEST_PROTOVER("Padding", PROTOVER_HS_SETUP_PADDING,
854 supports_hs_setup_padding);
856 done:
860 #define PV_TEST(name, flags) \
861 { #name, test_protover_ ##name, (flags), NULL, NULL }
863 struct testcase_t protover_tests[] = {
864 PV_TEST(parse, 0),
865 PV_TEST(parse_fail, 0),
866 PV_TEST(vote, 0),
867 PV_TEST(all_supported, 0),
868 PV_TEST(list_supports_protocol_for_unsupported_returns_false, 0),
869 PV_TEST(list_supports_protocol_returns_true, 0),
870 PV_TEST(supports_version, 0),
871 PV_TEST(supported_protocols, 0),
872 PV_TEST(vote_roundtrip, 0),
873 PV_TEST(vote_roundtrip_ours, 0),
874 /* fork, because we memoize flags internally */
875 PV_TEST(summarize_flags, TT_FORK),
876 END_OF_TESTCASES