dirvote: Handling adding vote and signature if module is disabled
[tor.git] / src / test / test_dir.c
blob74153c671a97de55c56ac201a22e79992e258fab
1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2017, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 #include "orconfig.h"
7 #include <math.h>
9 #define CONFIG_PRIVATE
10 #define CONTROL_PRIVATE
11 #define DIRSERV_PRIVATE
12 #define DIRVOTE_PRIVATE
13 #define ROUTER_PRIVATE
14 #define ROUTERLIST_PRIVATE
15 #define ROUTERPARSE_PRIVATE
16 #define HIBERNATE_PRIVATE
17 #define NETWORKSTATUS_PRIVATE
18 #define RELAY_PRIVATE
20 #include "or.h"
21 #include "bridges.h"
22 #include "confparse.h"
23 #include "config.h"
24 #include "control.h"
25 #include "crypto_ed25519.h"
26 #include "directory.h"
27 #include "dirserv.h"
28 #include "dirauth/dirvote.h"
29 #include "entrynodes.h"
30 #include "hibernate.h"
31 #include "memarea.h"
32 #include "networkstatus.h"
33 #include "router.h"
34 #include "routerkeys.h"
35 #include "routerlist.h"
36 #include "routerparse.h"
37 #include "routerset.h"
38 #include "dirauth/shared_random_state.h"
39 #include "test.h"
40 #include "test_dir_common.h"
41 #include "torcert.h"
42 #include "relay.h"
43 #include "log_test_helpers.h"
45 #define NS_MODULE dir
47 static void
48 test_dir_nicknames(void *arg)
50 (void)arg;
51 tt_assert( is_legal_nickname("a"));
52 tt_assert(!is_legal_nickname(""));
53 tt_assert(!is_legal_nickname("abcdefghijklmnopqrst")); /* 20 chars */
54 tt_assert(!is_legal_nickname("hyphen-")); /* bad char */
55 tt_assert( is_legal_nickname("abcdefghijklmnopqrs")); /* 19 chars */
56 tt_assert(!is_legal_nickname("$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
57 /* valid */
58 tt_assert( is_legal_nickname_or_hexdigest(
59 "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
60 tt_assert( is_legal_nickname_or_hexdigest(
61 "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
62 tt_assert( is_legal_nickname_or_hexdigest(
63 "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA~fred"));
64 /* too short */
65 tt_assert(!is_legal_nickname_or_hexdigest(
66 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
67 /* illegal char */
68 tt_assert(!is_legal_nickname_or_hexdigest(
69 "$AAAAAAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
70 /* hex part too long */
71 tt_assert(!is_legal_nickname_or_hexdigest(
72 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
73 tt_assert(!is_legal_nickname_or_hexdigest(
74 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
75 /* Bad nickname */
76 tt_assert(!is_legal_nickname_or_hexdigest(
77 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="));
78 tt_assert(!is_legal_nickname_or_hexdigest(
79 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"));
80 tt_assert(!is_legal_nickname_or_hexdigest(
81 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~hyphen-"));
82 tt_assert(!is_legal_nickname_or_hexdigest(
83 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"
84 "abcdefghijklmnoppqrst"));
85 /* Bad extra char. */
86 tt_assert(!is_legal_nickname_or_hexdigest(
87 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!"));
88 tt_assert(is_legal_nickname_or_hexdigest("xyzzy"));
89 tt_assert(is_legal_nickname_or_hexdigest("abcdefghijklmnopqrs"));
90 tt_assert(!is_legal_nickname_or_hexdigest("abcdefghijklmnopqrst"));
91 done:
95 static smartlist_t *mocked_configured_ports = NULL;
97 /** Returns mocked_configured_ports */
98 static const smartlist_t *
99 mock_get_configured_ports(void)
101 return mocked_configured_ports;
104 /** Run unit tests for router descriptor generation logic. */
105 static void
106 test_dir_formats(void *arg)
108 char *buf = NULL;
109 char buf2[8192];
110 char platform[256];
111 char fingerprint[FINGERPRINT_LEN+1];
112 char *pk1_str = NULL, *pk2_str = NULL, *cp;
113 size_t pk1_str_len, pk2_str_len;
114 routerinfo_t *r1=NULL, *r2=NULL;
115 crypto_pk_t *pk1 = NULL, *pk2 = NULL;
116 routerinfo_t *rp1 = NULL, *rp2 = NULL;
117 addr_policy_t *ex1, *ex2;
118 routerlist_t *dir1 = NULL, *dir2 = NULL;
119 uint8_t *rsa_cc = NULL;
120 or_options_t *options = get_options_mutable();
121 const addr_policy_t *p;
122 time_t now = time(NULL);
123 port_cfg_t orport, dirport;
124 char cert_buf[256];
126 (void)arg;
127 pk1 = pk_generate(0);
128 pk2 = pk_generate(1);
130 tt_assert(pk1 && pk2);
132 hibernate_set_state_for_testing_(HIBERNATE_STATE_LIVE);
134 get_platform_str(platform, sizeof(platform));
135 r1 = tor_malloc_zero(sizeof(routerinfo_t));
136 r1->addr = 0xc0a80001u; /* 192.168.0.1 */
137 r1->cache_info.published_on = 0;
138 r1->or_port = 9000;
139 r1->dir_port = 9003;
140 r1->supports_tunnelled_dir_requests = 1;
141 tor_addr_parse(&r1->ipv6_addr, "1:2:3:4::");
142 r1->ipv6_orport = 9999;
143 r1->onion_pkey = crypto_pk_dup_key(pk1);
144 /* Fake just enough of an ntor key to get by */
145 curve25519_keypair_t r1_onion_keypair;
146 curve25519_keypair_generate(&r1_onion_keypair, 0);
147 r1->onion_curve25519_pkey = tor_memdup(&r1_onion_keypair.pubkey,
148 sizeof(curve25519_public_key_t));
149 r1->identity_pkey = crypto_pk_dup_key(pk2);
150 r1->bandwidthrate = 1000;
151 r1->bandwidthburst = 5000;
152 r1->bandwidthcapacity = 10000;
153 r1->exit_policy = NULL;
154 r1->nickname = tor_strdup("Magri");
155 r1->platform = tor_strdup(platform);
157 ex1 = tor_malloc_zero(sizeof(addr_policy_t));
158 ex2 = tor_malloc_zero(sizeof(addr_policy_t));
159 ex1->policy_type = ADDR_POLICY_ACCEPT;
160 tor_addr_from_ipv4h(&ex1->addr, 0);
161 ex1->maskbits = 0;
162 ex1->prt_min = ex1->prt_max = 80;
163 ex2->policy_type = ADDR_POLICY_REJECT;
164 tor_addr_from_ipv4h(&ex2->addr, 18<<24);
165 ex2->maskbits = 8;
166 ex2->prt_min = ex2->prt_max = 24;
167 r2 = tor_malloc_zero(sizeof(routerinfo_t));
168 r2->addr = 0x0a030201u; /* 10.3.2.1 */
169 ed25519_keypair_t kp1, kp2;
170 ed25519_secret_key_from_seed(&kp1.seckey,
171 (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
172 ed25519_public_key_generate(&kp1.pubkey, &kp1.seckey);
173 ed25519_secret_key_from_seed(&kp2.seckey,
174 (const uint8_t*)"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
175 ed25519_public_key_generate(&kp2.pubkey, &kp2.seckey);
176 r2->cache_info.signing_key_cert = tor_cert_create(&kp1,
177 CERT_TYPE_ID_SIGNING,
178 &kp2.pubkey,
179 now, 86400,
180 CERT_FLAG_INCLUDE_SIGNING_KEY);
181 r2->platform = tor_strdup(platform);
182 r2->cache_info.published_on = 5;
183 r2->or_port = 9005;
184 r2->dir_port = 0;
185 r2->supports_tunnelled_dir_requests = 1;
186 r2->onion_pkey = crypto_pk_dup_key(pk2);
187 curve25519_keypair_t r2_onion_keypair;
188 curve25519_keypair_generate(&r2_onion_keypair, 0);
189 r2->onion_curve25519_pkey = tor_memdup(&r2_onion_keypair.pubkey,
190 sizeof(curve25519_public_key_t));
191 r2->identity_pkey = crypto_pk_dup_key(pk1);
192 r2->bandwidthrate = r2->bandwidthburst = r2->bandwidthcapacity = 3000;
193 r2->exit_policy = smartlist_new();
194 smartlist_add(r2->exit_policy, ex1);
195 smartlist_add(r2->exit_policy, ex2);
196 r2->nickname = tor_strdup("Fred");
198 tt_assert(!crypto_pk_write_public_key_to_string(pk1, &pk1_str,
199 &pk1_str_len));
200 tt_assert(!crypto_pk_write_public_key_to_string(pk2 , &pk2_str,
201 &pk2_str_len));
203 /* XXXX+++ router_dump_to_string should really take this from ri.*/
204 options->ContactInfo = tor_strdup("Magri White "
205 "<magri@elsewhere.example.com>");
206 /* Skip reachability checks for DirPort and tunnelled-dir-server */
207 options->AssumeReachable = 1;
209 /* Fake just enough of an ORPort and DirPort to get by */
210 MOCK(get_configured_ports, mock_get_configured_ports);
211 mocked_configured_ports = smartlist_new();
213 memset(&orport, 0, sizeof(orport));
214 orport.type = CONN_TYPE_OR_LISTENER;
215 orport.addr.family = AF_INET;
216 orport.port = 9000;
217 smartlist_add(mocked_configured_ports, &orport);
219 memset(&dirport, 0, sizeof(dirport));
220 dirport.type = CONN_TYPE_DIR_LISTENER;
221 dirport.addr.family = AF_INET;
222 dirport.port = 9003;
223 smartlist_add(mocked_configured_ports, &dirport);
225 buf = router_dump_router_to_string(r1, pk2, NULL, NULL, NULL);
227 UNMOCK(get_configured_ports);
228 smartlist_free(mocked_configured_ports);
229 mocked_configured_ports = NULL;
231 tor_free(options->ContactInfo);
232 tt_assert(buf);
234 strlcpy(buf2, "router Magri 192.168.0.1 9000 0 9003\n"
235 "or-address [1:2:3:4::]:9999\n"
236 "platform Tor "VERSION" on ", sizeof(buf2));
237 strlcat(buf2, get_uname(), sizeof(buf2));
238 strlcat(buf2, "\n"
239 "published 1970-01-01 00:00:00\n"
240 "fingerprint ", sizeof(buf2));
241 tt_assert(!crypto_pk_get_fingerprint(pk2, fingerprint, 1));
242 strlcat(buf2, fingerprint, sizeof(buf2));
243 strlcat(buf2, "\nuptime 0\n"
244 /* XXX the "0" above is hard-coded, but even if we made it reflect
245 * uptime, that still wouldn't make it right, because the two
246 * descriptors might be made on different seconds... hm. */
247 "bandwidth 1000 5000 10000\n"
248 "onion-key\n", sizeof(buf2));
249 strlcat(buf2, pk1_str, sizeof(buf2));
250 strlcat(buf2, "signing-key\n", sizeof(buf2));
251 strlcat(buf2, pk2_str, sizeof(buf2));
252 strlcat(buf2, "hidden-service-dir\n", sizeof(buf2));
253 strlcat(buf2, "contact Magri White <magri@elsewhere.example.com>\n",
254 sizeof(buf2));
255 strlcat(buf2, "ntor-onion-key ", sizeof(buf2));
256 base64_encode(cert_buf, sizeof(cert_buf),
257 (const char*)r1_onion_keypair.pubkey.public_key, 32,
258 BASE64_ENCODE_MULTILINE);
259 strlcat(buf2, cert_buf, sizeof(buf2));
260 strlcat(buf2, "reject *:*\n", sizeof(buf2));
261 strlcat(buf2, "tunnelled-dir-server\nrouter-signature\n", sizeof(buf2));
262 buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same
263 * twice */
265 tt_str_op(buf,OP_EQ, buf2);
266 tor_free(buf);
268 buf = router_dump_router_to_string(r1, pk2, NULL, NULL, NULL);
269 tt_assert(buf);
270 cp = buf;
271 rp1 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL);
272 tt_assert(rp1);
273 tt_int_op(rp1->addr,OP_EQ, r1->addr);
274 tt_int_op(rp1->or_port,OP_EQ, r1->or_port);
275 tt_int_op(rp1->dir_port,OP_EQ, r1->dir_port);
276 tt_int_op(rp1->bandwidthrate,OP_EQ, r1->bandwidthrate);
277 tt_int_op(rp1->bandwidthburst,OP_EQ, r1->bandwidthburst);
278 tt_int_op(rp1->bandwidthcapacity,OP_EQ, r1->bandwidthcapacity);
279 tt_int_op(crypto_pk_cmp_keys(rp1->onion_pkey, pk1), OP_EQ, 0);
280 tt_int_op(crypto_pk_cmp_keys(rp1->identity_pkey, pk2), OP_EQ, 0);
281 tt_assert(rp1->supports_tunnelled_dir_requests);
282 //tt_assert(rp1->exit_policy == NULL);
283 tor_free(buf);
285 strlcpy(buf2,
286 "router Fred 10.3.2.1 9005 0 0\n"
287 "identity-ed25519\n"
288 "-----BEGIN ED25519 CERT-----\n", sizeof(buf2));
289 base64_encode(cert_buf, sizeof(cert_buf),
290 (const char*)r2->cache_info.signing_key_cert->encoded,
291 r2->cache_info.signing_key_cert->encoded_len,
292 BASE64_ENCODE_MULTILINE);
293 strlcat(buf2, cert_buf, sizeof(buf2));
294 strlcat(buf2, "-----END ED25519 CERT-----\n", sizeof(buf2));
295 strlcat(buf2, "master-key-ed25519 ", sizeof(buf2));
297 char k[ED25519_BASE64_LEN+1];
298 tt_int_op(ed25519_public_to_base64(k,
299 &r2->cache_info.signing_key_cert->signing_key),
300 OP_GE, 0);
301 strlcat(buf2, k, sizeof(buf2));
302 strlcat(buf2, "\n", sizeof(buf2));
304 strlcat(buf2, "platform Tor "VERSION" on ", sizeof(buf2));
305 strlcat(buf2, get_uname(), sizeof(buf2));
306 strlcat(buf2, "\n"
307 "published 1970-01-01 00:00:05\n"
308 "fingerprint ", sizeof(buf2));
309 tt_assert(!crypto_pk_get_fingerprint(pk1, fingerprint, 1));
310 strlcat(buf2, fingerprint, sizeof(buf2));
311 strlcat(buf2, "\nuptime 0\n"
312 "bandwidth 3000 3000 3000\n", sizeof(buf2));
313 strlcat(buf2, "onion-key\n", sizeof(buf2));
314 strlcat(buf2, pk2_str, sizeof(buf2));
315 strlcat(buf2, "signing-key\n", sizeof(buf2));
316 strlcat(buf2, pk1_str, sizeof(buf2));
317 int rsa_cc_len;
318 rsa_cc = make_tap_onion_key_crosscert(pk2,
319 &kp1.pubkey,
320 pk1,
321 &rsa_cc_len);
322 tt_assert(rsa_cc);
323 base64_encode(cert_buf, sizeof(cert_buf), (char*)rsa_cc, rsa_cc_len,
324 BASE64_ENCODE_MULTILINE);
325 strlcat(buf2, "onion-key-crosscert\n"
326 "-----BEGIN CROSSCERT-----\n", sizeof(buf2));
327 strlcat(buf2, cert_buf, sizeof(buf2));
328 strlcat(buf2, "-----END CROSSCERT-----\n", sizeof(buf2));
329 int ntor_cc_sign;
331 tor_cert_t *ntor_cc = NULL;
332 ntor_cc = make_ntor_onion_key_crosscert(&r2_onion_keypair,
333 &kp1.pubkey,
334 r2->cache_info.published_on,
335 get_onion_key_lifetime(),
336 &ntor_cc_sign);
337 tt_assert(ntor_cc);
338 base64_encode(cert_buf, sizeof(cert_buf),
339 (char*)ntor_cc->encoded, ntor_cc->encoded_len,
340 BASE64_ENCODE_MULTILINE);
341 tor_cert_free(ntor_cc);
343 tor_snprintf(buf2+strlen(buf2), sizeof(buf2)-strlen(buf2),
344 "ntor-onion-key-crosscert %d\n"
345 "-----BEGIN ED25519 CERT-----\n"
346 "%s"
347 "-----END ED25519 CERT-----\n", ntor_cc_sign, cert_buf);
349 strlcat(buf2, "hidden-service-dir\n", sizeof(buf2));
350 strlcat(buf2, "ntor-onion-key ", sizeof(buf2));
351 base64_encode(cert_buf, sizeof(cert_buf),
352 (const char*)r2_onion_keypair.pubkey.public_key, 32,
353 BASE64_ENCODE_MULTILINE);
354 strlcat(buf2, cert_buf, sizeof(buf2));
355 strlcat(buf2, "accept *:80\nreject 18.0.0.0/8:24\n", sizeof(buf2));
356 strlcat(buf2, "tunnelled-dir-server\n", sizeof(buf2));
357 strlcat(buf2, "router-sig-ed25519 ", sizeof(buf2));
359 /* Fake just enough of an ORPort to get by */
360 MOCK(get_configured_ports, mock_get_configured_ports);
361 mocked_configured_ports = smartlist_new();
363 memset(&orport, 0, sizeof(orport));
364 orport.type = CONN_TYPE_OR_LISTENER;
365 orport.addr.family = AF_INET;
366 orport.port = 9005;
367 smartlist_add(mocked_configured_ports, &orport);
369 buf = router_dump_router_to_string(r2, pk1, pk2, &r2_onion_keypair, &kp2);
370 tt_assert(buf);
371 buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same
372 * twice */
374 tt_str_op(buf, OP_EQ, buf2);
375 tor_free(buf);
377 buf = router_dump_router_to_string(r2, pk1, NULL, NULL, NULL);
379 UNMOCK(get_configured_ports);
380 smartlist_free(mocked_configured_ports);
381 mocked_configured_ports = NULL;
383 /* Reset for later */
384 cp = buf;
385 rp2 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL);
386 tt_assert(rp2);
387 tt_int_op(rp2->addr,OP_EQ, r2->addr);
388 tt_int_op(rp2->or_port,OP_EQ, r2->or_port);
389 tt_int_op(rp2->dir_port,OP_EQ, r2->dir_port);
390 tt_int_op(rp2->bandwidthrate,OP_EQ, r2->bandwidthrate);
391 tt_int_op(rp2->bandwidthburst,OP_EQ, r2->bandwidthburst);
392 tt_int_op(rp2->bandwidthcapacity,OP_EQ, r2->bandwidthcapacity);
393 tt_mem_op(rp2->onion_curve25519_pkey->public_key,OP_EQ,
394 r2->onion_curve25519_pkey->public_key,
395 CURVE25519_PUBKEY_LEN);
396 tt_int_op(crypto_pk_cmp_keys(rp2->onion_pkey, pk2), OP_EQ, 0);
397 tt_int_op(crypto_pk_cmp_keys(rp2->identity_pkey, pk1), OP_EQ, 0);
398 tt_assert(rp2->supports_tunnelled_dir_requests);
400 tt_int_op(smartlist_len(rp2->exit_policy),OP_EQ, 2);
402 p = smartlist_get(rp2->exit_policy, 0);
403 tt_int_op(p->policy_type,OP_EQ, ADDR_POLICY_ACCEPT);
404 tt_assert(tor_addr_is_null(&p->addr));
405 tt_int_op(p->maskbits,OP_EQ, 0);
406 tt_int_op(p->prt_min,OP_EQ, 80);
407 tt_int_op(p->prt_max,OP_EQ, 80);
409 p = smartlist_get(rp2->exit_policy, 1);
410 tt_int_op(p->policy_type,OP_EQ, ADDR_POLICY_REJECT);
411 tt_assert(tor_addr_eq(&p->addr, &ex2->addr));
412 tt_int_op(p->maskbits,OP_EQ, 8);
413 tt_int_op(p->prt_min,OP_EQ, 24);
414 tt_int_op(p->prt_max,OP_EQ, 24);
416 #if 0
417 /* Okay, now for the directories. */
419 fingerprint_list = smartlist_new();
420 crypto_pk_get_fingerprint(pk2, buf, 1);
421 add_fingerprint_to_dir(buf, fingerprint_list, 0);
422 crypto_pk_get_fingerprint(pk1, buf, 1);
423 add_fingerprint_to_dir(buf, fingerprint_list, 0);
426 #endif /* 0 */
427 dirserv_free_fingerprint_list();
429 done:
430 if (r1)
431 routerinfo_free(r1);
432 if (r2)
433 routerinfo_free(r2);
434 if (rp2)
435 routerinfo_free(rp2);
437 tor_free(rsa_cc);
438 tor_free(buf);
439 tor_free(pk1_str);
440 tor_free(pk2_str);
441 if (pk1) crypto_pk_free(pk1);
442 if (pk2) crypto_pk_free(pk2);
443 if (rp1) routerinfo_free(rp1);
444 tor_free(dir1); /* XXXX And more !*/
445 tor_free(dir2); /* And more !*/
448 #include "failing_routerdescs.inc"
450 static void
451 test_dir_routerinfo_parsing(void *arg)
453 (void) arg;
455 int again;
456 routerinfo_t *ri = NULL;
458 #define CHECK_OK(s) \
459 do { \
460 routerinfo_free(ri); \
461 ri = router_parse_entry_from_string((s), NULL, 0, 0, NULL, NULL); \
462 tt_assert(ri); \
463 } while (0)
464 #define CHECK_FAIL(s, againval) \
465 do { \
466 routerinfo_free(ri); \
467 again = 999; \
468 ri = router_parse_entry_from_string((s), NULL, 0, 0, NULL, &again); \
469 tt_assert(ri == NULL); \
470 tt_int_op(again, OP_EQ, (againval)); \
471 } while (0)
473 CHECK_OK(EX_RI_MINIMAL);
474 CHECK_OK(EX_RI_MAXIMAL);
476 CHECK_OK(EX_RI_MINIMAL_ED);
478 /* good annotations prepended */
479 routerinfo_free(ri);
480 ri = router_parse_entry_from_string(EX_RI_MINIMAL, NULL, 0, 0,
481 "@purpose bridge\n", NULL);
482 tt_ptr_op(ri, OP_NE, NULL);
483 tt_assert(ri->purpose == ROUTER_PURPOSE_BRIDGE);
484 routerinfo_free(ri);
486 /* bad annotations prepended. */
487 ri = router_parse_entry_from_string(EX_RI_MINIMAL,
488 NULL, 0, 0, "@purpose\n", NULL);
489 tt_ptr_op(ri, OP_EQ, NULL);
491 /* bad annotations on router. */
492 ri = router_parse_entry_from_string("@purpose\nrouter x\n", NULL, 0, 1,
493 NULL, NULL);
494 tt_ptr_op(ri, OP_EQ, NULL);
496 /* unwanted annotations on router. */
497 ri = router_parse_entry_from_string("@purpose foo\nrouter x\n", NULL, 0, 0,
498 NULL, NULL);
499 tt_ptr_op(ri, OP_EQ, NULL);
501 /* No signature. */
502 ri = router_parse_entry_from_string("router x\n", NULL, 0, 0,
503 NULL, NULL);
504 tt_ptr_op(ri, OP_EQ, NULL);
506 /* Not a router */
507 routerinfo_free(ri);
508 ri = router_parse_entry_from_string("hello\n", NULL, 0, 0, NULL, NULL);
509 tt_ptr_op(ri, OP_EQ, NULL);
511 CHECK_FAIL(EX_RI_BAD_SIG1, 1);
512 CHECK_FAIL(EX_RI_BAD_SIG2, 1);
513 CHECK_FAIL(EX_RI_BAD_TOKENS, 0);
514 CHECK_FAIL(EX_RI_BAD_PUBLISHED, 0);
515 CHECK_FAIL(EX_RI_NEG_BANDWIDTH, 0);
516 CHECK_FAIL(EX_RI_BAD_BANDWIDTH, 0);
517 CHECK_FAIL(EX_RI_BAD_BANDWIDTH2, 0);
518 CHECK_FAIL(EX_RI_BAD_ONIONKEY1, 0);
519 CHECK_FAIL(EX_RI_BAD_ONIONKEY2, 0);
520 CHECK_FAIL(EX_RI_BAD_PORTS, 0);
521 CHECK_FAIL(EX_RI_BAD_IP, 0);
522 CHECK_FAIL(EX_RI_BAD_DIRPORT, 0);
523 CHECK_FAIL(EX_RI_BAD_NAME2, 0);
524 CHECK_FAIL(EX_RI_BAD_UPTIME, 0);
526 CHECK_FAIL(EX_RI_BAD_BANDWIDTH3, 0);
527 CHECK_FAIL(EX_RI_BAD_NTOR_KEY, 0);
528 CHECK_FAIL(EX_RI_BAD_FINGERPRINT, 0);
529 CHECK_FAIL(EX_RI_MISMATCHED_FINGERPRINT, 0);
530 CHECK_FAIL(EX_RI_BAD_HAS_ACCEPT6, 0);
531 CHECK_FAIL(EX_RI_BAD_NO_EXIT_POLICY, 0);
532 CHECK_FAIL(EX_RI_BAD_IPV6_EXIT_POLICY, 0);
533 CHECK_FAIL(EX_RI_BAD_FAMILY, 0);
534 CHECK_FAIL(EX_RI_ZERO_ORPORT, 0);
536 CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT, 0);
537 CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT2, 0);
538 CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT_SIGN, 0);
539 CHECK_FAIL(EX_RI_ED_BAD_SIG1, 0);
540 CHECK_FAIL(EX_RI_ED_BAD_SIG2, 0);
541 CHECK_FAIL(EX_RI_ED_BAD_SIG3, 0);
542 CHECK_FAIL(EX_RI_ED_BAD_SIG4, 0);
543 CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT1, 0);
544 CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT3, 0);
545 CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT4, 0);
546 CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT5, 0);
547 CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT6, 0);
548 CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT7, 0);
549 CHECK_FAIL(EX_RI_ED_MISPLACED1, 0);
550 CHECK_FAIL(EX_RI_ED_MISPLACED2, 0);
551 CHECK_FAIL(EX_RI_ED_BAD_CERT1, 0);
552 CHECK_FAIL(EX_RI_ED_BAD_CERT2, 0);
553 CHECK_FAIL(EX_RI_ED_BAD_CERT3, 0);
555 /* This is allowed; we just ignore it. */
556 CHECK_OK(EX_RI_BAD_EI_DIGEST);
557 CHECK_OK(EX_RI_BAD_EI_DIGEST2);
559 #undef CHECK_FAIL
560 #undef CHECK_OK
561 done:
562 routerinfo_free(ri);
565 #include "example_extrainfo.inc"
567 static void
568 routerinfo_free_wrapper_(void *arg)
570 routerinfo_free_(arg);
573 static void
574 test_dir_extrainfo_parsing(void *arg)
576 (void) arg;
578 #define CHECK_OK(s) \
579 do { \
580 extrainfo_free(ei); \
581 ei = extrainfo_parse_entry_from_string((s), NULL, 0, map, NULL); \
582 tt_assert(ei); \
583 } while (0)
584 #define CHECK_FAIL(s, againval) \
585 do { \
586 extrainfo_free(ei); \
587 again = 999; \
588 ei = extrainfo_parse_entry_from_string((s), NULL, 0, map, &again); \
589 tt_assert(ei == NULL); \
590 tt_int_op(again, OP_EQ, (againval)); \
591 } while (0)
592 #define ADD(name) \
593 do { \
594 ri = tor_malloc_zero(sizeof(routerinfo_t)); \
595 crypto_pk_t *pk = ri->identity_pkey = crypto_pk_new(); \
596 tt_assert(! crypto_pk_read_public_key_from_string(pk, \
597 name##_KEY, strlen(name##_KEY))); \
598 tt_int_op(20,OP_EQ,base16_decode(d, 20, name##_FP, strlen(name##_FP))); \
599 digestmap_set((digestmap_t*)map, d, ri); \
600 ri = NULL; \
601 } while (0)
603 routerinfo_t *ri = NULL;
604 char d[20];
605 struct digest_ri_map_t *map = NULL;
606 extrainfo_t *ei = NULL;
607 int again;
609 CHECK_OK(EX_EI_MINIMAL);
610 tt_assert(ei->pending_sig);
611 CHECK_OK(EX_EI_MAXIMAL);
612 tt_assert(ei->pending_sig);
613 CHECK_OK(EX_EI_GOOD_ED_EI);
614 tt_assert(ei->pending_sig);
616 map = (struct digest_ri_map_t *)digestmap_new();
617 ADD(EX_EI_MINIMAL);
618 ADD(EX_EI_MAXIMAL);
619 ADD(EX_EI_GOOD_ED_EI);
620 ADD(EX_EI_BAD_FP);
621 ADD(EX_EI_BAD_NICKNAME);
622 ADD(EX_EI_BAD_TOKENS);
623 ADD(EX_EI_BAD_START);
624 ADD(EX_EI_BAD_PUBLISHED);
626 ADD(EX_EI_ED_MISSING_SIG);
627 ADD(EX_EI_ED_MISSING_CERT);
628 ADD(EX_EI_ED_BAD_CERT1);
629 ADD(EX_EI_ED_BAD_CERT2);
630 ADD(EX_EI_ED_BAD_SIG1);
631 ADD(EX_EI_ED_BAD_SIG2);
632 ADD(EX_EI_ED_MISPLACED_CERT);
633 ADD(EX_EI_ED_MISPLACED_SIG);
635 CHECK_OK(EX_EI_MINIMAL);
636 tt_ptr_op(ei->pending_sig, OP_EQ, NULL);
637 CHECK_OK(EX_EI_MAXIMAL);
638 tt_ptr_op(ei->pending_sig, OP_EQ, NULL);
639 CHECK_OK(EX_EI_GOOD_ED_EI);
640 tt_ptr_op(ei->pending_sig, OP_EQ, NULL);
642 CHECK_FAIL(EX_EI_BAD_SIG1,1);
643 CHECK_FAIL(EX_EI_BAD_SIG2,1);
644 CHECK_FAIL(EX_EI_BAD_SIG3,1);
645 CHECK_FAIL(EX_EI_BAD_FP,0);
646 CHECK_FAIL(EX_EI_BAD_NICKNAME,0);
647 CHECK_FAIL(EX_EI_BAD_TOKENS,0);
648 CHECK_FAIL(EX_EI_BAD_START,0);
649 CHECK_FAIL(EX_EI_BAD_PUBLISHED,0);
651 CHECK_FAIL(EX_EI_ED_MISSING_SIG,0);
652 CHECK_FAIL(EX_EI_ED_MISSING_CERT,0);
653 CHECK_FAIL(EX_EI_ED_BAD_CERT1,0);
654 CHECK_FAIL(EX_EI_ED_BAD_CERT2,0);
655 CHECK_FAIL(EX_EI_ED_BAD_SIG1,0);
656 CHECK_FAIL(EX_EI_ED_BAD_SIG2,0);
657 CHECK_FAIL(EX_EI_ED_MISPLACED_CERT,0);
658 CHECK_FAIL(EX_EI_ED_MISPLACED_SIG,0);
660 #undef CHECK_OK
661 #undef CHECK_FAIL
663 done:
664 escaped(NULL);
665 extrainfo_free(ei);
666 routerinfo_free(ri);
667 digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_);
670 static void
671 test_dir_parse_router_list(void *arg)
673 (void) arg;
674 smartlist_t *invalid = smartlist_new();
675 smartlist_t *dest = smartlist_new();
676 smartlist_t *chunks = smartlist_new();
677 int dest_has_ri = 1;
678 char *list = NULL;
679 const char *cp;
680 digestmap_t *map = NULL;
681 char *mem_op_hex_tmp = NULL;
682 routerinfo_t *ri = NULL;
683 char d[DIGEST_LEN];
685 smartlist_add_strdup(chunks, EX_RI_MINIMAL); // ri 0
686 smartlist_add_strdup(chunks, EX_RI_BAD_PORTS); // bad ri 0
687 smartlist_add_strdup(chunks, EX_EI_MAXIMAL); // ei 0
688 smartlist_add_strdup(chunks, EX_EI_BAD_SIG2); // bad ei --
689 smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME);// bad ei 0
690 smartlist_add_strdup(chunks, EX_RI_BAD_SIG1); // bad ri --
691 smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED); // bad ei 1
692 smartlist_add_strdup(chunks, EX_RI_MAXIMAL); // ri 1
693 smartlist_add_strdup(chunks, EX_RI_BAD_FAMILY); // bad ri 1
694 smartlist_add_strdup(chunks, EX_EI_MINIMAL); // ei 1
696 list = smartlist_join_strings(chunks, "", 0, NULL);
698 /* First, parse the routers. */
699 cp = list;
700 tt_int_op(0,OP_EQ,
701 router_parse_list_from_string(&cp, NULL, dest, SAVED_NOWHERE,
702 0, 0, NULL, invalid));
703 tt_int_op(2, OP_EQ, smartlist_len(dest));
704 tt_ptr_op(cp, OP_EQ, list + strlen(list));
706 routerinfo_t *r = smartlist_get(dest, 0);
707 tt_mem_op(r->cache_info.signed_descriptor_body, OP_EQ,
708 EX_RI_MINIMAL, strlen(EX_RI_MINIMAL));
709 r = smartlist_get(dest, 1);
710 tt_mem_op(r->cache_info.signed_descriptor_body, OP_EQ,
711 EX_RI_MAXIMAL, strlen(EX_RI_MAXIMAL));
713 tt_int_op(2, OP_EQ, smartlist_len(invalid));
714 test_memeq_hex(smartlist_get(invalid, 0),
715 "ab9eeaa95e7d45740185b4e519c76ead756277a9");
716 test_memeq_hex(smartlist_get(invalid, 1),
717 "9a651ee03b64325959e8f1b46f2b689b30750b4c");
719 /* Now tidy up */
720 SMARTLIST_FOREACH(dest, routerinfo_t *, rinfo, routerinfo_free(rinfo));
721 SMARTLIST_FOREACH(invalid, uint8_t *, dig, tor_free(dig));
722 smartlist_clear(dest);
723 smartlist_clear(invalid);
725 /* And check extrainfos. */
726 dest_has_ri = 0;
727 map = (digestmap_t*)router_get_routerlist()->identity_map;
728 ADD(EX_EI_MINIMAL);
729 ADD(EX_EI_MAXIMAL);
730 ADD(EX_EI_BAD_NICKNAME);
731 ADD(EX_EI_BAD_PUBLISHED);
732 cp = list;
733 tt_int_op(0,OP_EQ,
734 router_parse_list_from_string(&cp, NULL, dest, SAVED_NOWHERE,
735 1, 0, NULL, invalid));
736 tt_int_op(2, OP_EQ, smartlist_len(dest));
737 extrainfo_t *e = smartlist_get(dest, 0);
738 tt_mem_op(e->cache_info.signed_descriptor_body, OP_EQ,
739 EX_EI_MAXIMAL, strlen(EX_EI_MAXIMAL));
740 e = smartlist_get(dest, 1);
741 tt_mem_op(e->cache_info.signed_descriptor_body, OP_EQ,
742 EX_EI_MINIMAL, strlen(EX_EI_MINIMAL));
744 tt_int_op(2, OP_EQ, smartlist_len(invalid));
745 test_memeq_hex(smartlist_get(invalid, 0),
746 "d5df4aa62ee9ffc9543d41150c9864908e0390af");
747 test_memeq_hex(smartlist_get(invalid, 1),
748 "f61efd2a7f4531f3687a9043e0de90a862ec64ba");
750 done:
751 tor_free(list);
752 if (dest_has_ri)
753 SMARTLIST_FOREACH(dest, routerinfo_t *, rt, routerinfo_free(rt));
754 else
755 SMARTLIST_FOREACH(dest, extrainfo_t *, ei, extrainfo_free(ei));
756 smartlist_free(dest);
757 SMARTLIST_FOREACH(invalid, uint8_t *, dig, tor_free(dig));
758 smartlist_free(invalid);
759 SMARTLIST_FOREACH(chunks, char *, chunk, tor_free(chunk));
760 smartlist_free(chunks);
761 routerinfo_free(ri);
762 if (map) {
763 digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_);
764 router_get_routerlist()->identity_map =
765 (struct digest_ri_map_t*)digestmap_new();
767 tor_free(mem_op_hex_tmp);
769 #undef ADD
772 static download_status_t dls_minimal;
773 static download_status_t dls_maximal;
774 static download_status_t dls_bad_fingerprint;
775 static download_status_t dls_bad_sig2;
776 static download_status_t dls_bad_ports;
777 static download_status_t dls_bad_tokens;
779 static int mock_router_get_dl_status_unrecognized = 0;
780 static int mock_router_get_dl_status_calls = 0;
782 static download_status_t *
783 mock_router_get_dl_status(const char *d)
785 ++mock_router_get_dl_status_calls;
786 char hex[HEX_DIGEST_LEN+1];
787 base16_encode(hex, sizeof(hex), d, DIGEST_LEN);
788 if (!strcmp(hex, "3E31D19A69EB719C00B02EC60D13356E3F7A3452")) {
789 return &dls_minimal;
790 } else if (!strcmp(hex, "581D8A368A0FA854ECDBFAB841D88B3F1B004038")) {
791 return &dls_maximal;
792 } else if (!strcmp(hex, "2578AE227C6116CDE29B3F0E95709B9872DEE5F1")) {
793 return &dls_bad_fingerprint;
794 } else if (!strcmp(hex, "16D387D3A58F7DB3CF46638F8D0B90C45C7D769C")) {
795 return &dls_bad_sig2;
796 } else if (!strcmp(hex, "AB9EEAA95E7D45740185B4E519C76EAD756277A9")) {
797 return &dls_bad_ports;
798 } else if (!strcmp(hex, "A0CC2CEFAD59DBF19F468BFEE60E0868C804B422")) {
799 return &dls_bad_tokens;
800 } else {
801 ++mock_router_get_dl_status_unrecognized;
802 return NULL;
806 static void
807 test_dir_load_routers(void *arg)
809 (void) arg;
810 smartlist_t *chunks = smartlist_new();
811 smartlist_t *wanted = smartlist_new();
812 char buf[DIGEST_LEN];
813 char *mem_op_hex_tmp = NULL;
814 char *list = NULL;
816 #define ADD(str) \
817 do { \
818 tt_int_op(0,OP_EQ,router_get_router_hash(str, strlen(str), buf)); \
819 smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN)); \
820 } while (0)
822 MOCK(router_get_dl_status_by_descriptor_digest, mock_router_get_dl_status);
824 update_approx_time(1412510400);
826 smartlist_add_strdup(chunks, EX_RI_MINIMAL);
827 smartlist_add_strdup(chunks, EX_RI_BAD_FINGERPRINT);
828 smartlist_add_strdup(chunks, EX_RI_BAD_SIG2);
829 smartlist_add_strdup(chunks, EX_RI_MAXIMAL);
830 smartlist_add_strdup(chunks, EX_RI_BAD_PORTS);
831 smartlist_add_strdup(chunks, EX_RI_BAD_TOKENS);
833 /* not ADDing MINIMIAL */
834 ADD(EX_RI_MAXIMAL);
835 ADD(EX_RI_BAD_FINGERPRINT);
836 ADD(EX_RI_BAD_SIG2);
837 /* Not ADDing BAD_PORTS */
838 ADD(EX_RI_BAD_TOKENS);
840 list = smartlist_join_strings(chunks, "", 0, NULL);
841 tt_int_op(1, OP_EQ,
842 router_load_routers_from_string(list, NULL, SAVED_IN_JOURNAL,
843 wanted, 1, NULL));
845 /* The "maximal" router was added. */
846 /* "minimal" was not. */
847 tt_int_op(smartlist_len(router_get_routerlist()->routers),OP_EQ,1);
848 routerinfo_t *r = smartlist_get(router_get_routerlist()->routers, 0);
849 test_memeq_hex(r->cache_info.signed_descriptor_digest,
850 "581D8A368A0FA854ECDBFAB841D88B3F1B004038");
851 tt_int_op(dls_minimal.n_download_failures, OP_EQ, 0);
852 tt_int_op(dls_maximal.n_download_failures, OP_EQ, 0);
854 /* "Bad fingerprint" and "Bad tokens" should have gotten marked
855 * non-retriable. */
856 tt_want_int_op(mock_router_get_dl_status_calls, OP_EQ, 2);
857 tt_want_int_op(mock_router_get_dl_status_unrecognized, OP_EQ, 0);
858 tt_int_op(dls_bad_fingerprint.n_download_failures, OP_EQ, 255);
859 tt_int_op(dls_bad_tokens.n_download_failures, OP_EQ, 255);
861 /* bad_sig2 and bad ports" are retriable -- one since only the signature
862 * was bad, and one because we didn't ask for it. */
863 tt_int_op(dls_bad_sig2.n_download_failures, OP_EQ, 0);
864 tt_int_op(dls_bad_ports.n_download_failures, OP_EQ, 0);
866 /* Wanted still contains "BAD_SIG2" */
867 tt_int_op(smartlist_len(wanted), OP_EQ, 1);
868 tt_str_op(smartlist_get(wanted, 0), OP_EQ,
869 "E0A3753CEFD54128EAB239F294954121DB23D2EF");
871 #undef ADD
873 done:
874 tor_free(mem_op_hex_tmp);
875 UNMOCK(router_get_dl_status_by_descriptor_digest);
876 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
877 smartlist_free(chunks);
878 SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
879 smartlist_free(wanted);
880 tor_free(list);
883 static int mock_get_by_ei_dd_calls = 0;
884 static int mock_get_by_ei_dd_unrecognized = 0;
886 static signed_descriptor_t sd_ei_minimal;
887 static signed_descriptor_t sd_ei_bad_nickname;
888 static signed_descriptor_t sd_ei_maximal;
889 static signed_descriptor_t sd_ei_bad_tokens;
890 static signed_descriptor_t sd_ei_bad_sig2;
892 static signed_descriptor_t *
893 mock_get_by_ei_desc_digest(const char *d)
896 ++mock_get_by_ei_dd_calls;
897 char hex[HEX_DIGEST_LEN+1];
898 base16_encode(hex, sizeof(hex), d, DIGEST_LEN);
900 if (!strcmp(hex, "11E0EDF526950739F7769810FCACAB8C882FAEEE")) {
901 return &sd_ei_minimal;
902 } else if (!strcmp(hex, "47803B02A0E70E9E8BDA226CB1D74DE354D67DFF")) {
903 return &sd_ei_maximal;
904 } else if (!strcmp(hex, "D5DF4AA62EE9FFC9543D41150C9864908E0390AF")) {
905 return &sd_ei_bad_nickname;
906 } else if (!strcmp(hex, "16D387D3A58F7DB3CF46638F8D0B90C45C7D769C")) {
907 return &sd_ei_bad_sig2;
908 } else if (!strcmp(hex, "9D90F8C42955BBC57D54FB05E54A3F083AF42E8B")) {
909 return &sd_ei_bad_tokens;
910 } else {
911 ++mock_get_by_ei_dd_unrecognized;
912 return NULL;
916 static signed_descriptor_t *
917 mock_ei_get_by_ei_digest(const char *d)
919 char hex[HEX_DIGEST_LEN+1];
920 base16_encode(hex, sizeof(hex), d, DIGEST_LEN);
921 signed_descriptor_t *sd = &sd_ei_minimal;
923 if (!strcmp(hex, "11E0EDF526950739F7769810FCACAB8C882FAEEE")) {
924 sd->signed_descriptor_body = (char *)EX_EI_MINIMAL;
925 sd->signed_descriptor_len = sizeof(EX_EI_MINIMAL);
926 sd->annotations_len = 0;
927 sd->saved_location = SAVED_NOWHERE;
928 return sd;
930 return NULL;
933 static smartlist_t *mock_ei_insert_list = NULL;
934 static was_router_added_t
935 mock_ei_insert(routerlist_t *rl, extrainfo_t *ei, int warn_if_incompatible)
937 (void) rl;
938 (void) warn_if_incompatible;
939 smartlist_add(mock_ei_insert_list, ei);
940 return ROUTER_ADDED_SUCCESSFULLY;
943 static void
944 test_dir_load_extrainfo(void *arg)
946 (void) arg;
947 smartlist_t *chunks = smartlist_new();
948 smartlist_t *wanted = smartlist_new();
949 char buf[DIGEST_LEN];
950 char *mem_op_hex_tmp = NULL;
951 char *list = NULL;
953 #define ADD(str) \
954 do { \
955 tt_int_op(0,OP_EQ,router_get_extrainfo_hash(str, strlen(str), buf)); \
956 smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN)); \
957 } while (0)
959 mock_ei_insert_list = smartlist_new();
960 MOCK(router_get_by_extrainfo_digest, mock_get_by_ei_desc_digest);
961 MOCK(extrainfo_insert, mock_ei_insert);
963 smartlist_add_strdup(chunks, EX_EI_MINIMAL);
964 smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME);
965 smartlist_add_strdup(chunks, EX_EI_MAXIMAL);
966 smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED);
967 smartlist_add_strdup(chunks, EX_EI_BAD_TOKENS);
969 /* not ADDing MINIMIAL */
970 ADD(EX_EI_MAXIMAL);
971 ADD(EX_EI_BAD_NICKNAME);
972 /* Not ADDing BAD_PUBLISHED */
973 ADD(EX_EI_BAD_TOKENS);
974 ADD(EX_EI_BAD_SIG2);
976 list = smartlist_join_strings(chunks, "", 0, NULL);
977 router_load_extrainfo_from_string(list, NULL, SAVED_IN_JOURNAL, wanted, 1);
979 /* The "maximal" router was added. */
980 /* "minimal" was also added, even though we didn't ask for it, since
981 * that's what we do with extrainfos. */
982 tt_int_op(smartlist_len(mock_ei_insert_list),OP_EQ,2);
984 extrainfo_t *e = smartlist_get(mock_ei_insert_list, 0);
985 test_memeq_hex(e->cache_info.signed_descriptor_digest,
986 "11E0EDF526950739F7769810FCACAB8C882FAEEE");
988 e = smartlist_get(mock_ei_insert_list, 1);
989 test_memeq_hex(e->cache_info.signed_descriptor_digest,
990 "47803B02A0E70E9E8BDA226CB1D74DE354D67DFF");
991 tt_int_op(dls_minimal.n_download_failures, OP_EQ, 0);
992 tt_int_op(dls_maximal.n_download_failures, OP_EQ, 0);
994 /* "Bad nickname" and "Bad tokens" should have gotten marked
995 * non-retriable. */
996 tt_want_int_op(mock_get_by_ei_dd_calls, OP_EQ, 2);
997 tt_want_int_op(mock_get_by_ei_dd_unrecognized, OP_EQ, 0);
998 tt_int_op(sd_ei_bad_nickname.ei_dl_status.n_download_failures, OP_EQ, 255);
999 tt_int_op(sd_ei_bad_tokens.ei_dl_status.n_download_failures, OP_EQ, 255);
1001 /* bad_ports is retriable -- because we didn't ask for it. */
1002 tt_int_op(dls_bad_ports.n_download_failures, OP_EQ, 0);
1004 /* Wanted still contains "BAD_SIG2" */
1005 tt_int_op(smartlist_len(wanted), OP_EQ, 1);
1006 tt_str_op(smartlist_get(wanted, 0), OP_EQ,
1007 "16D387D3A58F7DB3CF46638F8D0B90C45C7D769C");
1009 #undef ADD
1011 done:
1012 tor_free(mem_op_hex_tmp);
1013 UNMOCK(router_get_by_extrainfo_digest);
1014 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
1015 smartlist_free(chunks);
1016 SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
1017 smartlist_free(wanted);
1018 tor_free(list);
1021 static void
1022 test_dir_getinfo_extra(void *arg)
1024 int r;
1025 char *answer = NULL;
1026 const char *errmsg = NULL;
1028 (void)arg;
1029 MOCK(extrainfo_get_by_descriptor_digest, mock_ei_get_by_ei_digest);
1030 r = getinfo_helper_dir(NULL, "extra-info/digest/"
1031 "11E0EDF526950739F7769810FCACAB8C882FAEEE", &answer,
1032 &errmsg);
1033 tt_int_op(0, OP_EQ, r);
1034 tt_ptr_op(NULL, OP_EQ, errmsg);
1035 tt_str_op(answer, OP_EQ, EX_EI_MINIMAL);
1036 tor_free(answer);
1038 answer = NULL;
1039 r = getinfo_helper_dir(NULL, "extra-info/digest/"
1040 "NOTAVALIDHEXSTRINGNOTAVALIDHEXSTRINGNOTA", &answer,
1041 &errmsg);
1042 tt_int_op(0, OP_EQ, r);
1043 /* getinfo_helper_dir() should maybe return an error here but doesn't */
1044 tt_ptr_op(NULL, OP_EQ, errmsg);
1045 /* In any case, there should be no answer for an invalid hex string. */
1046 tt_ptr_op(NULL, OP_EQ, answer);
1048 done:
1049 UNMOCK(extrainfo_get_by_descriptor_digest);
1052 static void
1053 test_dir_versions(void *arg)
1055 tor_version_t ver1;
1057 /* Try out version parsing functionality */
1058 (void)arg;
1059 tt_int_op(0,OP_EQ, tor_version_parse("0.3.4pre2-cvs", &ver1));
1060 tt_int_op(0,OP_EQ, ver1.major);
1061 tt_int_op(3,OP_EQ, ver1.minor);
1062 tt_int_op(4,OP_EQ, ver1.micro);
1063 tt_int_op(VER_PRE,OP_EQ, ver1.status);
1064 tt_int_op(2,OP_EQ, ver1.patchlevel);
1065 tt_int_op(0,OP_EQ, tor_version_parse("0.3.4rc1", &ver1));
1066 tt_int_op(0,OP_EQ, ver1.major);
1067 tt_int_op(3,OP_EQ, ver1.minor);
1068 tt_int_op(4,OP_EQ, ver1.micro);
1069 tt_int_op(VER_RC,OP_EQ, ver1.status);
1070 tt_int_op(1,OP_EQ, ver1.patchlevel);
1071 tt_int_op(0,OP_EQ, tor_version_parse("1.3.4", &ver1));
1072 tt_int_op(1,OP_EQ, ver1.major);
1073 tt_int_op(3,OP_EQ, ver1.minor);
1074 tt_int_op(4,OP_EQ, ver1.micro);
1075 tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1076 tt_int_op(0,OP_EQ, ver1.patchlevel);
1077 tt_int_op(0,OP_EQ, tor_version_parse("1.3.4.999", &ver1));
1078 tt_int_op(1,OP_EQ, ver1.major);
1079 tt_int_op(3,OP_EQ, ver1.minor);
1080 tt_int_op(4,OP_EQ, ver1.micro);
1081 tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1082 tt_int_op(999,OP_EQ, ver1.patchlevel);
1083 tt_int_op(0,OP_EQ, tor_version_parse("0.1.2.4-alpha", &ver1));
1084 tt_int_op(0,OP_EQ, ver1.major);
1085 tt_int_op(1,OP_EQ, ver1.minor);
1086 tt_int_op(2,OP_EQ, ver1.micro);
1087 tt_int_op(4,OP_EQ, ver1.patchlevel);
1088 tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1089 tt_str_op("alpha",OP_EQ, ver1.status_tag);
1090 tt_int_op(0,OP_EQ, tor_version_parse("0.1.2.4", &ver1));
1091 tt_int_op(0,OP_EQ, ver1.major);
1092 tt_int_op(1,OP_EQ, ver1.minor);
1093 tt_int_op(2,OP_EQ, ver1.micro);
1094 tt_int_op(4,OP_EQ, ver1.patchlevel);
1095 tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1096 tt_str_op("",OP_EQ, ver1.status_tag);
1098 tt_int_op(0, OP_EQ, tor_version_parse("10.1", &ver1));
1099 tt_int_op(10, OP_EQ, ver1.major);
1100 tt_int_op(1, OP_EQ, ver1.minor);
1101 tt_int_op(0, OP_EQ, ver1.micro);
1102 tt_int_op(0, OP_EQ, ver1.patchlevel);
1103 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1104 tt_str_op("", OP_EQ, ver1.status_tag);
1105 tt_int_op(0, OP_EQ, tor_version_parse("5.99.999", &ver1));
1106 tt_int_op(5, OP_EQ, ver1.major);
1107 tt_int_op(99, OP_EQ, ver1.minor);
1108 tt_int_op(999, OP_EQ, ver1.micro);
1109 tt_int_op(0, OP_EQ, ver1.patchlevel);
1110 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1111 tt_str_op("", OP_EQ, ver1.status_tag);
1112 tt_int_op(0, OP_EQ, tor_version_parse("10.1-alpha", &ver1));
1113 tt_int_op(10, OP_EQ, ver1.major);
1114 tt_int_op(1, OP_EQ, ver1.minor);
1115 tt_int_op(0, OP_EQ, ver1.micro);
1116 tt_int_op(0, OP_EQ, ver1.patchlevel);
1117 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1118 tt_str_op("alpha", OP_EQ, ver1.status_tag);
1119 /* Go through the full set of status tags */
1120 tt_int_op(0, OP_EQ, tor_version_parse("2.1.700-alpha", &ver1));
1121 tt_int_op(2, OP_EQ, ver1.major);
1122 tt_int_op(1, OP_EQ, ver1.minor);
1123 tt_int_op(700, OP_EQ, ver1.micro);
1124 tt_int_op(0, OP_EQ, ver1.patchlevel);
1125 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1126 tt_str_op("alpha", OP_EQ, ver1.status_tag);
1127 tt_int_op(0, OP_EQ, tor_version_parse("1.6.8-alpha-dev", &ver1));
1128 tt_int_op(1, OP_EQ, ver1.major);
1129 tt_int_op(6, OP_EQ, ver1.minor);
1130 tt_int_op(8, OP_EQ, ver1.micro);
1131 tt_int_op(0, OP_EQ, ver1.patchlevel);
1132 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1133 tt_str_op("alpha-dev", OP_EQ, ver1.status_tag);
1134 tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.5-rc", &ver1));
1135 tt_int_op(0, OP_EQ, ver1.major);
1136 tt_int_op(2, OP_EQ, ver1.minor);
1137 tt_int_op(9, OP_EQ, ver1.micro);
1138 tt_int_op(5, OP_EQ, ver1.patchlevel);
1139 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1140 tt_str_op("rc", OP_EQ, ver1.status_tag);
1141 tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.6-rc-dev", &ver1));
1142 tt_int_op(0, OP_EQ, ver1.major);
1143 tt_int_op(2, OP_EQ, ver1.minor);
1144 tt_int_op(9, OP_EQ, ver1.micro);
1145 tt_int_op(6, OP_EQ, ver1.patchlevel);
1146 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1147 tt_str_op("rc-dev", OP_EQ, ver1.status_tag);
1148 tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.8", &ver1));
1149 tt_int_op(0, OP_EQ, ver1.major);
1150 tt_int_op(2, OP_EQ, ver1.minor);
1151 tt_int_op(9, OP_EQ, ver1.micro);
1152 tt_int_op(8, OP_EQ, ver1.patchlevel);
1153 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1154 tt_str_op("", OP_EQ, ver1.status_tag);
1155 tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.9-dev", &ver1));
1156 tt_int_op(0, OP_EQ, ver1.major);
1157 tt_int_op(2, OP_EQ, ver1.minor);
1158 tt_int_op(9, OP_EQ, ver1.micro);
1159 tt_int_op(9, OP_EQ, ver1.patchlevel);
1160 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1161 tt_str_op("dev", OP_EQ, ver1.status_tag);
1162 /* In #21450, we fixed an inconsistency in parsing versions > INT32_MAX
1163 * between i386 and x86_64, as we used tor_parse_long, and then cast to int
1165 tt_int_op(0, OP_EQ, tor_version_parse("0.2147483647.0", &ver1));
1166 tt_int_op(0, OP_EQ, ver1.major);
1167 tt_int_op(2147483647, OP_EQ, ver1.minor);
1168 tt_int_op(0, OP_EQ, ver1.micro);
1169 tt_int_op(0, OP_EQ, ver1.patchlevel);
1170 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1171 tt_str_op("", OP_EQ, ver1.status_tag);
1172 tt_int_op(-1, OP_EQ, tor_version_parse("0.2147483648.0", &ver1));
1173 tt_int_op(-1, OP_EQ, tor_version_parse("0.4294967295.0", &ver1));
1174 /* In #21278, we reject negative version components */
1175 tt_int_op(-1, OP_EQ, tor_version_parse("0.-1.0", &ver1));
1176 tt_int_op(-1, OP_EQ, tor_version_parse("0.-2147483648.0", &ver1));
1177 tt_int_op(-1, OP_EQ, tor_version_parse("0.-4294967295.0", &ver1));
1178 /* In #21507, we reject version components with non-numeric prefixes */
1179 tt_int_op(-1, OP_EQ, tor_version_parse("0.-0.0", &ver1));
1180 tt_int_op(-1, OP_EQ, tor_version_parse("+1.0.0", &ver1));
1181 /* use the list in isspace() */
1182 tt_int_op(-1, OP_EQ, tor_version_parse("0.\t0.0", &ver1));
1183 tt_int_op(-1, OP_EQ, tor_version_parse("0.\n0.0", &ver1));
1184 tt_int_op(-1, OP_EQ, tor_version_parse("0.\v0.0", &ver1));
1185 tt_int_op(-1, OP_EQ, tor_version_parse("0.\f0.0", &ver1));
1186 tt_int_op(-1, OP_EQ, tor_version_parse("0.\r0.0", &ver1));
1187 tt_int_op(-1, OP_EQ, tor_version_parse("0. 0.0", &ver1));
1189 #define tt_versionstatus_op(vs1, op, vs2) \
1190 tt_assert_test_type(vs1,vs2,#vs1" "#op" "#vs2,version_status_t, \
1191 (val1_ op val2_),"%d",TT_EXIT_TEST_FUNCTION)
1192 #define test_v_i_o(val, ver, lst) \
1193 tt_versionstatus_op(val, OP_EQ, tor_version_is_obsolete(ver, lst))
1195 /* make sure tor_version_is_obsolete() works */
1196 test_v_i_o(VS_OLD, "0.0.1", "Tor 0.0.2");
1197 test_v_i_o(VS_OLD, "0.0.1", "0.0.2, Tor 0.0.3");
1198 test_v_i_o(VS_OLD, "0.0.1", "0.0.2,Tor 0.0.3");
1199 test_v_i_o(VS_OLD, "0.0.1","0.0.3,BetterTor 0.0.1");
1200 test_v_i_o(VS_RECOMMENDED, "0.0.2", "Tor 0.0.2,Tor 0.0.3");
1201 test_v_i_o(VS_NEW_IN_SERIES, "0.0.2", "Tor 0.0.2pre1,Tor 0.0.3");
1202 test_v_i_o(VS_OLD, "0.0.2", "Tor 0.0.2.1,Tor 0.0.3");
1203 test_v_i_o(VS_NEW, "0.1.0", "Tor 0.0.2,Tor 0.0.3");
1204 test_v_i_o(VS_RECOMMENDED, "0.0.7rc2", "0.0.7,Tor 0.0.7rc2,Tor 0.0.8");
1205 test_v_i_o(VS_OLD, "0.0.5.0", "0.0.5.1-cvs");
1206 test_v_i_o(VS_NEW_IN_SERIES, "0.0.5.1-cvs", "0.0.5, 0.0.6");
1207 test_v_i_o(VS_NEW, "0.2.9.9-dev", "0.2.9.9");
1208 /* Not on list, but newer than any in same series. */
1209 test_v_i_o(VS_NEW_IN_SERIES, "0.1.0.3",
1210 "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1211 /* Series newer than any on list. */
1212 test_v_i_o(VS_NEW, "0.1.2.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1213 /* Series older than any on list. */
1214 test_v_i_o(VS_OLD, "0.0.1.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1215 /* Not on list, not newer than any on same series. */
1216 test_v_i_o(VS_UNRECOMMENDED, "0.1.0.1",
1217 "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1218 /* On list, not newer than any on same series. */
1219 test_v_i_o(VS_UNRECOMMENDED,
1220 "0.1.0.1", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1221 tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.0.5", "0.0.9pre1-cvs"));
1222 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1223 "Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
1224 "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh",
1225 "0.0.8rc2"));
1226 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1227 "Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
1228 "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh", "0.0.8.2"));
1230 /* Now try svn revisions. */
1231 tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
1232 "Tor 0.2.1.0-dev (r99)"));
1233 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1234 "Tor 0.2.1.0-dev (r100) on Banana Jr",
1235 "Tor 0.2.1.0-dev (r99) on Hal 9000"));
1236 tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
1237 "Tor 0.2.1.0-dev on Colossus"));
1238 tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r99)",
1239 "Tor 0.2.1.0-dev (r100)"));
1240 tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r99) on MCP",
1241 "Tor 0.2.1.0-dev (r100) on AM"));
1242 tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev",
1243 "Tor 0.2.1.0-dev (r99)"));
1244 tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.1",
1245 "Tor 0.2.1.0-dev (r99)"));
1246 /* And git revisions */
1247 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1248 "Tor 0.2.9.9 (git-56788a2489127072)",
1249 "Tor 0.2.9.9 (git-56788a2489127072)"));
1250 /* a git revision is newer than no git revision */
1251 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1252 "Tor 0.2.9.9 (git-56788a2489127072)",
1253 "Tor 0.2.9.9"));
1254 /* a longer git revision is newer than a shorter git revision
1255 * this should be true if they prefix-match, but if they don't, they are
1256 * incomparable, because hashes aren't ordered (but we compare their bytes
1257 * anyway) */
1258 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1259 "Tor 0.2.9.9 (git-56788a2489127072d513cf4baf35a8ff475f3c7b)",
1260 "Tor 0.2.9.9 (git-56788a2489127072)"));
1261 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1262 "Tor 0.2.9.9 (git-0102)",
1263 "Tor 0.2.9.9 (git-03)"));
1264 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1265 "Tor 0.2.9.9 (git-0102)",
1266 "Tor 0.2.9.9 (git-00)"));
1267 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1268 "Tor 0.2.9.9 (git-01)",
1269 "Tor 0.2.9.9 (git-00)"));
1270 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1271 "Tor 0.2.9.9 (git-00)",
1272 "Tor 0.2.9.9 (git-01)"));
1273 /* In #21278, we compare without integer overflows.
1274 * But since #21450 limits version components to [0, INT32_MAX], it is no
1275 * longer possible to cause an integer overflow in tor_version_compare() */
1276 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1277 "Tor 0.0.0.0",
1278 "Tor 2147483647.0.0.0"));
1279 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1280 "Tor 2147483647.0.0.0",
1281 "Tor 0.0.0.0"));
1282 /* These versions used to cause an overflow, now they don't parse
1283 * (and authorities reject their descriptors), and log a BUG message */
1284 setup_full_capture_of_logs(LOG_WARN);
1285 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1286 "Tor 0.0.0.0",
1287 "Tor 0.-2147483648.0.0"));
1288 expect_single_log_msg_containing("unparseable");
1289 mock_clean_saved_logs();
1290 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1291 "Tor 0.2147483647.0.0",
1292 "Tor 0.-1.0.0"));
1293 expect_single_log_msg_containing("unparseable");
1294 mock_clean_saved_logs();
1295 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1296 "Tor 0.2147483647.0.0",
1297 "Tor 0.-2147483648.0.0"));
1298 expect_single_log_msg_containing("unparseable");
1299 mock_clean_saved_logs();
1300 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1301 "Tor 4294967295.0.0.0",
1302 "Tor 0.0.0.0"));
1303 expect_no_log_entry();
1304 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1305 "Tor 0.4294967295.0.0",
1306 "Tor 0.-4294967295.0.0"));
1307 expect_single_log_msg_containing("unparseable");
1308 mock_clean_saved_logs();
1309 teardown_capture_of_logs();
1311 /* Now try git revisions */
1312 tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00ff)", &ver1));
1313 tt_int_op(0,OP_EQ, ver1.major);
1314 tt_int_op(5,OP_EQ, ver1.minor);
1315 tt_int_op(6,OP_EQ, ver1.micro);
1316 tt_int_op(7,OP_EQ, ver1.patchlevel);
1317 tt_int_op(3,OP_EQ, ver1.git_tag_len);
1318 tt_mem_op(ver1.git_tag,OP_EQ, "\xff\x00\xff", 3);
1319 /* reject bad hex digits */
1320 tt_int_op(-1,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00xx)", &ver1));
1321 /* reject odd hex digit count */
1322 tt_int_op(-1,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00fff)", &ver1));
1323 /* ignore "git " */
1324 tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git ff00fff)", &ver1));
1325 /* standard length is 16 hex digits */
1326 tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git-0010203040506070)",
1327 &ver1));
1328 /* length limit is 40 hex digits */
1329 tt_int_op(0,OP_EQ, tor_version_parse(
1330 "0.5.6.7 (git-000102030405060708090a0b0c0d0e0f10111213)",
1331 &ver1));
1332 tt_int_op(-1,OP_EQ, tor_version_parse(
1333 "0.5.6.7 (git-000102030405060708090a0b0c0d0e0f1011121314)",
1334 &ver1));
1335 done:
1336 teardown_capture_of_logs();
1339 /** Run unit tests for directory fp_pair functions. */
1340 static void
1341 test_dir_fp_pairs(void *arg)
1343 smartlist_t *sl = smartlist_new();
1344 fp_pair_t *pair;
1346 (void)arg;
1347 dir_split_resource_into_fingerprint_pairs(
1348 /* Two pairs, out of order, with one duplicate. */
1349 "73656372657420646174612E0000000000FFFFFF-"
1350 "557365204145532d32353620696e73746561642e+"
1351 "73656372657420646174612E0000000000FFFFFF-"
1352 "557365204145532d32353620696e73746561642e+"
1353 "48657861646563696d616c2069736e277420736f-"
1354 "676f6f6420666f7220686964696e6720796f7572.z", sl);
1356 tt_int_op(smartlist_len(sl),OP_EQ, 2);
1357 pair = smartlist_get(sl, 0);
1358 tt_mem_op(pair->first,OP_EQ, "Hexadecimal isn't so", DIGEST_LEN);
1359 tt_mem_op(pair->second,OP_EQ, "good for hiding your", DIGEST_LEN);
1360 pair = smartlist_get(sl, 1);
1361 tt_mem_op(pair->first,OP_EQ, "secret data.\0\0\0\0\0\xff\xff\xff",
1362 DIGEST_LEN);
1363 tt_mem_op(pair->second,OP_EQ, "Use AES-256 instead.", DIGEST_LEN);
1365 done:
1366 SMARTLIST_FOREACH(sl, fp_pair_t *, pair_to_free, tor_free(pair_to_free));
1367 smartlist_free(sl);
1370 static void
1371 test_dir_split_fps(void *testdata)
1373 smartlist_t *sl = smartlist_new();
1374 char *mem_op_hex_tmp = NULL;
1375 (void)testdata;
1377 /* Some example hex fingerprints and their base64 equivalents */
1378 #define HEX1 "Fe0daff89127389bc67558691231234551193EEE"
1379 #define HEX2 "Deadbeef99999991111119999911111111f00ba4"
1380 #define HEX3 "b33ff00db33ff00db33ff00db33ff00db33ff00d"
1381 #define HEX256_1 \
1382 "f3f3f3f3fbbbbf3f3f3f3fbbbf3f3f3f3fbbbbf3f3f3f3fbbbf3f3f3f3fbbbbf"
1383 #define HEX256_2 \
1384 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccCCc"
1385 #define HEX256_3 \
1386 "0123456789ABCdef0123456789ABCdef0123456789ABCdef0123456789ABCdef"
1387 #define B64_1 "/g2v+JEnOJvGdVhpEjEjRVEZPu4"
1388 #define B64_2 "3q2+75mZmZERERmZmRERERHwC6Q"
1389 #define B64_256_1 "8/Pz8/u7vz8/Pz+7vz8/Pz+7u/Pz8/P7u/Pz8/P7u78"
1390 #define B64_256_2 "zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMw"
1392 /* no flags set */
1393 dir_split_resource_into_fingerprints("A+C+B", sl, NULL, 0);
1394 tt_int_op(smartlist_len(sl), OP_EQ, 3);
1395 tt_str_op(smartlist_get(sl, 0), OP_EQ, "A");
1396 tt_str_op(smartlist_get(sl, 1), OP_EQ, "C");
1397 tt_str_op(smartlist_get(sl, 2), OP_EQ, "B");
1398 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1399 smartlist_clear(sl);
1401 /* uniq strings. */
1402 dir_split_resource_into_fingerprints("A+C+B+A+B+B", sl, NULL, DSR_SORT_UNIQ);
1403 tt_int_op(smartlist_len(sl), OP_EQ, 3);
1404 tt_str_op(smartlist_get(sl, 0), OP_EQ, "A");
1405 tt_str_op(smartlist_get(sl, 1), OP_EQ, "B");
1406 tt_str_op(smartlist_get(sl, 2), OP_EQ, "C");
1407 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1408 smartlist_clear(sl);
1410 /* Decode hex. */
1411 dir_split_resource_into_fingerprints(HEX1"+"HEX2, sl, NULL, DSR_HEX);
1412 tt_int_op(smartlist_len(sl), OP_EQ, 2);
1413 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX1);
1414 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
1415 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1416 smartlist_clear(sl);
1418 /* decode hex and drop weirdness. */
1419 dir_split_resource_into_fingerprints(HEX1"+bogus+"HEX2"+"HEX256_1,
1420 sl, NULL, DSR_HEX);
1421 tt_int_op(smartlist_len(sl), OP_EQ, 2);
1422 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX1);
1423 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
1424 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1425 smartlist_clear(sl);
1427 /* Decode long hex */
1428 dir_split_resource_into_fingerprints(HEX256_1"+"HEX256_2"+"HEX2"+"HEX256_3,
1429 sl, NULL, DSR_HEX|DSR_DIGEST256);
1430 tt_int_op(smartlist_len(sl), OP_EQ, 3);
1431 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_1);
1432 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX256_2);
1433 test_mem_op_hex(smartlist_get(sl, 2), OP_EQ, HEX256_3);
1434 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1435 smartlist_clear(sl);
1437 /* Decode hex and sort. */
1438 dir_split_resource_into_fingerprints(HEX1"+"HEX2"+"HEX3"+"HEX2,
1439 sl, NULL, DSR_HEX|DSR_SORT_UNIQ);
1440 tt_int_op(smartlist_len(sl), OP_EQ, 3);
1441 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX3);
1442 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
1443 test_mem_op_hex(smartlist_get(sl, 2), OP_EQ, HEX1);
1444 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1445 smartlist_clear(sl);
1447 /* Decode long hex and sort */
1448 dir_split_resource_into_fingerprints(HEX256_1"+"HEX256_2"+"HEX256_3
1449 "+"HEX256_1,
1450 sl, NULL,
1451 DSR_HEX|DSR_DIGEST256|DSR_SORT_UNIQ);
1452 tt_int_op(smartlist_len(sl), OP_EQ, 3);
1453 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_3);
1454 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX256_2);
1455 test_mem_op_hex(smartlist_get(sl, 2), OP_EQ, HEX256_1);
1456 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1457 smartlist_clear(sl);
1459 /* Decode base64 */
1460 dir_split_resource_into_fingerprints(B64_1"-"B64_2, sl, NULL, DSR_BASE64);
1461 tt_int_op(smartlist_len(sl), OP_EQ, 2);
1462 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX1);
1463 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
1464 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1465 smartlist_clear(sl);
1467 /* Decode long base64 */
1468 dir_split_resource_into_fingerprints(B64_256_1"-"B64_256_2,
1469 sl, NULL, DSR_BASE64|DSR_DIGEST256);
1470 tt_int_op(smartlist_len(sl), OP_EQ, 2);
1471 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_1);
1472 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX256_2);
1473 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1474 smartlist_clear(sl);
1476 dir_split_resource_into_fingerprints(B64_256_1,
1477 sl, NULL, DSR_BASE64|DSR_DIGEST256);
1478 tt_int_op(smartlist_len(sl), OP_EQ, 1);
1479 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_1);
1480 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1481 smartlist_clear(sl);
1483 done:
1484 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1485 smartlist_free(sl);
1486 tor_free(mem_op_hex_tmp);
1489 static void
1490 test_dir_measured_bw_kb(void *arg)
1492 measured_bw_line_t mbwl;
1493 int i;
1494 const char *lines_pass[] = {
1495 "node_id=$557365204145532d32353620696e73746561642e bw=1024\n",
1496 "node_id=$557365204145532d32353620696e73746561642e\t bw=1024 \n",
1497 " node_id=$557365204145532d32353620696e73746561642e bw=1024\n",
1498 "\tnoise\tnode_id=$557365204145532d32353620696e73746561642e "
1499 "bw=1024 junk=007\n",
1500 "misc=junk node_id=$557365204145532d32353620696e73746561642e "
1501 "bw=1024 junk=007\n",
1502 "end"
1504 const char *lines_fail[] = {
1505 /* Test possible python stupidity on input */
1506 "node_id=None bw=1024\n",
1507 "node_id=$None bw=1024\n",
1508 "node_id=$557365204145532d32353620696e73746561642e bw=None\n",
1509 "node_id=$557365204145532d32353620696e73746561642e bw=1024.0\n",
1510 "node_id=$557365204145532d32353620696e73746561642e bw=.1024\n",
1511 "node_id=$557365204145532d32353620696e73746561642e bw=1.024\n",
1512 "node_id=$557365204145532d32353620696e73746561642e bw=1024 bw=0\n",
1513 "node_id=$557365204145532d32353620696e73746561642e bw=1024 bw=None\n",
1514 "node_id=$557365204145532d32353620696e73746561642e bw=-1024\n",
1515 /* Test incomplete writes due to race conditions, partial copies, etc */
1516 "node_i",
1517 "node_i\n",
1518 "node_id=",
1519 "node_id=\n",
1520 "node_id=$557365204145532d32353620696e73746561642e bw=",
1521 "node_id=$557365204145532d32353620696e73746561642e bw=1024",
1522 "node_id=$557365204145532d32353620696e73746561642e bw=\n",
1523 "node_id=$557365204145532d32353620696e7374",
1524 "node_id=$557365204145532d32353620696e7374\n",
1526 "\n",
1527 " \n ",
1528 " \n\n",
1529 /* Test assorted noise */
1530 " node_id= ",
1531 "node_id==$557365204145532d32353620696e73746561642e bw==1024\n",
1532 "node_id=$55736520414552d32353620696e73746561642e bw=1024\n",
1533 "node_id=557365204145532d32353620696e73746561642e bw=1024\n",
1534 "node_id= $557365204145532d32353620696e73746561642e bw=0.23\n",
1535 "end"
1538 (void)arg;
1539 for (i = 0; strcmp(lines_fail[i], "end"); i++) {
1540 //fprintf(stderr, "Testing: %s\n", lines_fail[i]);
1541 tt_int_op(measured_bw_line_parse(&mbwl, lines_fail[i]), OP_EQ, -1);
1544 for (i = 0; strcmp(lines_pass[i], "end"); i++) {
1545 //fprintf(stderr, "Testing: %s %d\n", lines_pass[i], TOR_ISSPACE('\n'));
1546 tt_int_op(measured_bw_line_parse(&mbwl, lines_pass[i]), OP_EQ, 0);
1547 tt_assert(mbwl.bw_kb == 1024);
1548 tt_assert(strcmp(mbwl.node_hex,
1549 "557365204145532d32353620696e73746561642e") == 0);
1552 done:
1553 return;
1556 #define MBWC_INIT_TIME 1000
1558 /** Do the measured bandwidth cache unit test */
1559 static void
1560 test_dir_measured_bw_kb_cache(void *arg)
1562 /* Initial fake time_t for testing */
1563 time_t curr = MBWC_INIT_TIME;
1564 /* Some measured_bw_line_ts */
1565 measured_bw_line_t mbwl[3];
1566 /* For receiving output on cache queries */
1567 long bw;
1568 time_t as_of;
1570 /* First, clear the cache and assert that it's empty */
1571 (void)arg;
1572 dirserv_clear_measured_bw_cache();
1573 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 0);
1575 * Set up test mbwls; none of the dirserv_cache_*() functions care about
1576 * the node_hex field.
1578 memset(mbwl[0].node_id, 0x01, DIGEST_LEN);
1579 mbwl[0].bw_kb = 20;
1580 memset(mbwl[1].node_id, 0x02, DIGEST_LEN);
1581 mbwl[1].bw_kb = 40;
1582 memset(mbwl[2].node_id, 0x03, DIGEST_LEN);
1583 mbwl[2].bw_kb = 80;
1584 /* Try caching something */
1585 dirserv_cache_measured_bw(&(mbwl[0]), curr);
1586 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 1);
1587 /* Okay, let's see if we can retrieve it */
1588 tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, &as_of));
1589 tt_int_op(bw,OP_EQ, 20);
1590 tt_int_op(as_of,OP_EQ, MBWC_INIT_TIME);
1591 /* Try retrieving it without some outputs */
1592 tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL, NULL));
1593 tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, NULL));
1594 tt_int_op(bw,OP_EQ, 20);
1595 tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL,&as_of));
1596 tt_int_op(as_of,OP_EQ, MBWC_INIT_TIME);
1597 /* Now expire it */
1598 curr += MAX_MEASUREMENT_AGE + 1;
1599 dirserv_expire_measured_bw_cache(curr);
1600 /* Check that the cache is empty */
1601 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 0);
1602 /* Check that we can't retrieve it */
1603 tt_assert(!dirserv_query_measured_bw_cache_kb(mbwl[0].node_id, NULL,NULL));
1604 /* Try caching a few things now */
1605 dirserv_cache_measured_bw(&(mbwl[0]), curr);
1606 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 1);
1607 curr += MAX_MEASUREMENT_AGE / 4;
1608 dirserv_cache_measured_bw(&(mbwl[1]), curr);
1609 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 2);
1610 curr += MAX_MEASUREMENT_AGE / 4;
1611 dirserv_cache_measured_bw(&(mbwl[2]), curr);
1612 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 3);
1613 curr += MAX_MEASUREMENT_AGE / 4 + 1;
1614 /* Do an expire that's too soon to get any of them */
1615 dirserv_expire_measured_bw_cache(curr);
1616 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 3);
1617 /* Push the oldest one off the cliff */
1618 curr += MAX_MEASUREMENT_AGE / 4;
1619 dirserv_expire_measured_bw_cache(curr);
1620 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 2);
1621 /* And another... */
1622 curr += MAX_MEASUREMENT_AGE / 4;
1623 dirserv_expire_measured_bw_cache(curr);
1624 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 1);
1625 /* This should empty it out again */
1626 curr += MAX_MEASUREMENT_AGE / 4;
1627 dirserv_expire_measured_bw_cache(curr);
1628 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 0);
1630 done:
1631 return;
1634 static char *
1635 my_dirvote_compute_params(smartlist_t *votes, int method,
1636 int total_authorities)
1638 smartlist_t *s = dirvote_compute_params(votes, method, total_authorities);
1639 tor_assert(s);
1640 char *res = smartlist_join_strings(s, " ", 0, NULL);
1641 SMARTLIST_FOREACH(s, char *, cp, tor_free(cp));
1642 smartlist_free(s);
1643 return res;
1646 #define dirvote_compute_params my_dirvote_compute_params
1648 static void
1649 test_dir_param_voting(void *arg)
1651 networkstatus_t vote1, vote2, vote3, vote4;
1652 smartlist_t *votes = smartlist_new();
1653 char *res = NULL;
1655 /* dirvote_compute_params only looks at the net_params field of the votes,
1656 so that's all we need to set.
1658 (void)arg;
1659 memset(&vote1, 0, sizeof(vote1));
1660 memset(&vote2, 0, sizeof(vote2));
1661 memset(&vote3, 0, sizeof(vote3));
1662 memset(&vote4, 0, sizeof(vote4));
1663 vote1.net_params = smartlist_new();
1664 vote2.net_params = smartlist_new();
1665 vote3.net_params = smartlist_new();
1666 vote4.net_params = smartlist_new();
1667 smartlist_split_string(vote1.net_params,
1668 "ab=90 abcd=20 cw=50 x-yz=-99", NULL, 0, 0);
1669 smartlist_split_string(vote2.net_params,
1670 "ab=27 cw=5 x-yz=88", NULL, 0, 0);
1671 smartlist_split_string(vote3.net_params,
1672 "abcd=20 c=60 cw=500 x-yz=-9 zzzzz=101", NULL, 0, 0);
1673 smartlist_split_string(vote4.net_params,
1674 "ab=900 abcd=200 c=1 cw=51 x-yz=100", NULL, 0, 0);
1675 tt_int_op(100,OP_EQ, networkstatus_get_param(&vote4, "x-yz", 50, 0, 300));
1676 tt_int_op(222,OP_EQ, networkstatus_get_param(&vote4, "foobar", 222, 0, 300));
1677 tt_int_op(80,OP_EQ, networkstatus_get_param(&vote4, "ab", 12, 0, 80));
1678 tt_int_op(-8,OP_EQ, networkstatus_get_param(&vote4, "ab", -12, -100, -8));
1679 tt_int_op(0,OP_EQ, networkstatus_get_param(&vote4, "foobar", 0, -100, 8));
1681 tt_int_op(100,OP_EQ, networkstatus_get_overridable_param(
1682 &vote4, -1, "x-yz", 50, 0, 300));
1683 tt_int_op(30,OP_EQ, networkstatus_get_overridable_param(
1684 &vote4, 30, "x-yz", 50, 0, 300));
1685 tt_int_op(0,OP_EQ, networkstatus_get_overridable_param(
1686 &vote4, -101, "foobar", 0, -100, 8));
1687 tt_int_op(-99,OP_EQ, networkstatus_get_overridable_param(
1688 &vote4, -99, "foobar", 0, -100, 8));
1690 smartlist_add(votes, &vote1);
1692 /* Do the first tests without adding all the other votes, for
1693 * networks without many dirauths. */
1695 res = dirvote_compute_params(votes, 12, 2);
1696 tt_str_op(res,OP_EQ, "");
1697 tor_free(res);
1699 res = dirvote_compute_params(votes, 12, 1);
1700 tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-99");
1701 tor_free(res);
1703 smartlist_add(votes, &vote2);
1705 res = dirvote_compute_params(votes, 12, 2);
1706 tt_str_op(res,OP_EQ, "ab=27 cw=5 x-yz=-99");
1707 tor_free(res);
1709 res = dirvote_compute_params(votes, 12, 3);
1710 tt_str_op(res,OP_EQ, "ab=27 cw=5 x-yz=-99");
1711 tor_free(res);
1713 res = dirvote_compute_params(votes, 12, 6);
1714 tt_str_op(res,OP_EQ, "");
1715 tor_free(res);
1717 smartlist_add(votes, &vote3);
1719 res = dirvote_compute_params(votes, 12, 3);
1720 tt_str_op(res,OP_EQ, "ab=27 abcd=20 cw=50 x-yz=-9");
1721 tor_free(res);
1723 res = dirvote_compute_params(votes, 12, 5);
1724 tt_str_op(res,OP_EQ, "cw=50 x-yz=-9");
1725 tor_free(res);
1727 res = dirvote_compute_params(votes, 12, 9);
1728 tt_str_op(res,OP_EQ, "cw=50 x-yz=-9");
1729 tor_free(res);
1731 smartlist_add(votes, &vote4);
1733 res = dirvote_compute_params(votes, 12, 4);
1734 tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
1735 tor_free(res);
1737 res = dirvote_compute_params(votes, 12, 5);
1738 tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
1739 tor_free(res);
1741 /* Test that the special-cased "at least three dirauths voted for
1742 * this param" logic works as expected. */
1743 res = dirvote_compute_params(votes, 12, 6);
1744 tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
1745 tor_free(res);
1747 res = dirvote_compute_params(votes, 12, 10);
1748 tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
1749 tor_free(res);
1751 done:
1752 tor_free(res);
1753 SMARTLIST_FOREACH(vote1.net_params, char *, cp, tor_free(cp));
1754 SMARTLIST_FOREACH(vote2.net_params, char *, cp, tor_free(cp));
1755 SMARTLIST_FOREACH(vote3.net_params, char *, cp, tor_free(cp));
1756 SMARTLIST_FOREACH(vote4.net_params, char *, cp, tor_free(cp));
1757 smartlist_free(vote1.net_params);
1758 smartlist_free(vote2.net_params);
1759 smartlist_free(vote3.net_params);
1760 smartlist_free(vote4.net_params);
1761 smartlist_free(votes);
1763 return;
1766 static void
1767 test_dir_param_voting_lookup(void *arg)
1769 (void)arg;
1770 smartlist_t *lst = smartlist_new();
1772 smartlist_split_string(lst,
1773 "moomin=9 moomin=10 moomintroll=5 fred "
1774 "jack= electricity=sdk opa=6z abc=9 abcd=99",
1775 NULL, 0, 0);
1777 tt_int_op(1000,
1778 OP_EQ, dirvote_get_intermediate_param_value(lst, "ab", 1000));
1779 tt_int_op(9, OP_EQ, dirvote_get_intermediate_param_value(lst, "abc", 1000));
1780 tt_int_op(99, OP_EQ,
1781 dirvote_get_intermediate_param_value(lst, "abcd", 1000));
1783 /* moomin appears twice. That's a bug. */
1784 tor_capture_bugs_(1);
1785 tt_int_op(-100, OP_EQ,
1786 dirvote_get_intermediate_param_value(lst, "moomin", -100));
1787 tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
1788 tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
1789 "n_found == 0");
1790 tor_end_capture_bugs_();
1791 /* There is no 'fred=', so that is treated as not existing. */
1792 tt_int_op(-100, OP_EQ,
1793 dirvote_get_intermediate_param_value(lst, "fred", -100));
1794 /* jack is truncated */
1795 tor_capture_bugs_(1);
1796 tt_int_op(-100, OP_EQ,
1797 dirvote_get_intermediate_param_value(lst, "jack", -100));
1798 tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
1799 tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
1800 "!(! ok)");
1801 tor_end_capture_bugs_();
1802 /* electricity and opa aren't integers. */
1803 tor_capture_bugs_(1);
1804 tt_int_op(-100, OP_EQ,
1805 dirvote_get_intermediate_param_value(lst, "electricity", -100));
1806 tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
1807 tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
1808 "!(! ok)");
1809 tor_end_capture_bugs_();
1811 tor_capture_bugs_(1);
1812 tt_int_op(-100, OP_EQ,
1813 dirvote_get_intermediate_param_value(lst, "opa", -100));
1814 tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
1815 tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
1816 "!(! ok)");
1817 tor_end_capture_bugs_();
1819 done:
1820 SMARTLIST_FOREACH(lst, char *, cp, tor_free(cp));
1821 smartlist_free(lst);
1822 tor_end_capture_bugs_();
1825 #undef dirvote_compute_params
1827 /** Helper: Test that two networkstatus_voter_info_t do in fact represent the
1828 * same voting authority, and that they do in fact have all the same
1829 * information. */
1830 static void
1831 test_same_voter(networkstatus_voter_info_t *v1,
1832 networkstatus_voter_info_t *v2)
1834 tt_str_op(v1->nickname,OP_EQ, v2->nickname);
1835 tt_mem_op(v1->identity_digest,OP_EQ, v2->identity_digest, DIGEST_LEN);
1836 tt_str_op(v1->address,OP_EQ, v2->address);
1837 tt_int_op(v1->addr,OP_EQ, v2->addr);
1838 tt_int_op(v1->dir_port,OP_EQ, v2->dir_port);
1839 tt_int_op(v1->or_port,OP_EQ, v2->or_port);
1840 tt_str_op(v1->contact,OP_EQ, v2->contact);
1841 tt_mem_op(v1->vote_digest,OP_EQ, v2->vote_digest, DIGEST_LEN);
1842 done:
1846 /** Helper: get a detached signatures document for one or two
1847 * consensuses. */
1848 static char *
1849 get_detached_sigs(networkstatus_t *ns, networkstatus_t *ns2)
1851 char *r;
1852 smartlist_t *sl;
1853 tor_assert(ns && ns->flavor == FLAV_NS);
1854 sl = smartlist_new();
1855 smartlist_add(sl,ns);
1856 if (ns2)
1857 smartlist_add(sl,ns2);
1858 r = networkstatus_get_detached_signatures(sl);
1859 smartlist_free(sl);
1860 return r;
1863 /** Apply tweaks to the vote list for each voter */
1864 static int
1865 vote_tweaks_for_v3ns(networkstatus_t *v, int voter, time_t now)
1867 vote_routerstatus_t *vrs;
1868 const char *msg = NULL;
1870 tt_assert(v);
1871 (void)now;
1873 if (voter == 1) {
1874 measured_bw_line_t mbw;
1875 memset(mbw.node_id, 33, sizeof(mbw.node_id));
1876 mbw.bw_kb = 1024;
1877 tt_int_op(measured_bw_line_apply(&mbw, v->routerstatus_list), OP_EQ, 1);
1878 } else if (voter == 2 || voter == 3) {
1879 /* Monkey around with the list a bit */
1880 vrs = smartlist_get(v->routerstatus_list, 2);
1881 smartlist_del_keeporder(v->routerstatus_list, 2);
1882 vote_routerstatus_free(vrs);
1883 vrs = smartlist_get(v->routerstatus_list, 0);
1884 vrs->status.is_fast = 1;
1886 if (voter == 3) {
1887 vrs = smartlist_get(v->routerstatus_list, 0);
1888 smartlist_del_keeporder(v->routerstatus_list, 0);
1889 vote_routerstatus_free(vrs);
1890 vrs = smartlist_get(v->routerstatus_list, 0);
1891 memset(vrs->status.descriptor_digest, (int)'Z', DIGEST_LEN);
1892 tt_assert(router_add_to_routerlist(
1893 dir_common_generate_ri_from_rs(vrs), &msg,0,0) >= 0);
1897 done:
1898 return 0;
1902 * Test a parsed vote_routerstatus_t for v3_networkstatus test
1904 static void
1905 test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
1907 routerstatus_t *rs;
1908 tor_addr_t addr_ipv6;
1910 tt_assert(vrs);
1911 rs = &(vrs->status);
1912 tt_assert(rs);
1914 /* Split out by digests to test */
1915 if (tor_memeq(rs->identity_digest,
1916 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
1917 "\x3\x3\x3\x3",
1918 DIGEST_LEN) &&
1919 (voter == 1)) {
1920 /* Check the first routerstatus. */
1921 tt_str_op(vrs->version,OP_EQ, "0.1.2.14");
1922 tt_int_op(rs->published_on,OP_EQ, now-1500);
1923 tt_str_op(rs->nickname,OP_EQ, "router2");
1924 tt_mem_op(rs->identity_digest,OP_EQ,
1925 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
1926 "\x3\x3\x3\x3",
1927 DIGEST_LEN);
1928 tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
1929 tt_int_op(rs->addr,OP_EQ, 0x99008801);
1930 tt_int_op(rs->or_port,OP_EQ, 443);
1931 tt_int_op(rs->dir_port,OP_EQ, 8000);
1932 /* no flags except "running" (16) and "v2dir" (64) and "valid" (128) */
1933 tt_u64_op(vrs->flags, OP_EQ, U64_LITERAL(0xd0));
1934 } else if (tor_memeq(rs->identity_digest,
1935 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
1936 "\x5\x5\x5\x5",
1937 DIGEST_LEN) &&
1938 (voter == 1 || voter == 2)) {
1939 tt_mem_op(rs->identity_digest,OP_EQ,
1940 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
1941 "\x5\x5\x5\x5",
1942 DIGEST_LEN);
1944 if (voter == 1) {
1945 /* Check the second routerstatus. */
1946 tt_str_op(vrs->version,OP_EQ, "0.2.0.5");
1947 tt_int_op(rs->published_on,OP_EQ, now-1000);
1948 tt_str_op(rs->nickname,OP_EQ, "router1");
1950 tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
1951 tt_int_op(rs->addr,OP_EQ, 0x99009901);
1952 tt_int_op(rs->or_port,OP_EQ, 443);
1953 tt_int_op(rs->dir_port,OP_EQ, 0);
1954 tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
1955 tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
1956 tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
1957 if (voter == 1) {
1958 /* all except "authority" (1) */
1959 tt_u64_op(vrs->flags, OP_EQ, U64_LITERAL(254));
1960 } else {
1961 /* 1023 - authority(1) - madeofcheese(16) - madeoftin(32) */
1962 tt_u64_op(vrs->flags, OP_EQ, U64_LITERAL(974));
1964 } else if (tor_memeq(rs->identity_digest,
1965 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
1966 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
1967 DIGEST_LEN) &&
1968 (voter == 1 || voter == 2)) {
1969 /* Check the measured bandwidth bits */
1970 tt_assert(vrs->has_measured_bw &&
1971 vrs->measured_bw_kb == 1024);
1972 } else {
1974 * Didn't expect this, but the old unit test only checked some of them,
1975 * so don't assert.
1977 /* tt_assert(0); */
1980 done:
1981 return;
1985 * Test a consensus for v3_networkstatus_test
1987 static void
1988 test_consensus_for_v3ns(networkstatus_t *con, time_t now)
1990 (void)now;
1992 tt_assert(con);
1993 tt_ptr_op(con->cert, OP_EQ, NULL);
1994 tt_int_op(2,OP_EQ, smartlist_len(con->routerstatus_list));
1995 /* There should be two listed routers: one with identity 3, one with
1996 * identity 5. */
1998 done:
1999 return;
2003 * Test a router list entry for v3_networkstatus test
2005 static void
2006 test_routerstatus_for_v3ns(routerstatus_t *rs, time_t now)
2008 tor_addr_t addr_ipv6;
2010 tt_assert(rs);
2012 /* There should be two listed routers: one with identity 3, one with
2013 * identity 5. */
2014 /* This one showed up in 2 digests. */
2015 if (tor_memeq(rs->identity_digest,
2016 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
2017 "\x3\x3",
2018 DIGEST_LEN)) {
2019 tt_mem_op(rs->identity_digest,OP_EQ,
2020 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
2021 DIGEST_LEN);
2022 tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
2023 tt_assert(!rs->is_authority);
2024 tt_assert(!rs->is_exit);
2025 tt_assert(!rs->is_fast);
2026 tt_assert(!rs->is_possible_guard);
2027 tt_assert(!rs->is_stable);
2028 /* (If it wasn't running it wouldn't be here) */
2029 tt_assert(rs->is_flagged_running);
2030 tt_assert(rs->is_valid);
2031 tt_assert(!rs->is_named);
2032 tt_assert(rs->is_v2_dir);
2033 /* XXXX check version */
2034 } else if (tor_memeq(rs->identity_digest,
2035 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
2036 "\x5\x5\x5\x5",
2037 DIGEST_LEN)) {
2038 /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */
2039 tt_mem_op(rs->identity_digest,OP_EQ,
2040 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
2041 DIGEST_LEN);
2042 tt_str_op(rs->nickname,OP_EQ, "router1");
2043 tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
2044 tt_int_op(rs->published_on,OP_EQ, now-1000);
2045 tt_int_op(rs->addr,OP_EQ, 0x99009901);
2046 tt_int_op(rs->or_port,OP_EQ, 443);
2047 tt_int_op(rs->dir_port,OP_EQ, 0);
2048 tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
2049 tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
2050 tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
2051 tt_assert(!rs->is_authority);
2052 tt_assert(rs->is_exit);
2053 tt_assert(rs->is_fast);
2054 tt_assert(rs->is_possible_guard);
2055 tt_assert(rs->is_stable);
2056 tt_assert(rs->is_flagged_running);
2057 tt_assert(rs->is_valid);
2058 tt_assert(rs->is_v2_dir);
2059 tt_assert(!rs->is_named);
2060 /* XXXX check version */
2061 } else {
2062 /* Weren't expecting this... */
2063 tt_abort();
2066 done:
2067 return;
2070 static void
2071 test_dir_networkstatus_compute_bw_weights_v10(void *arg)
2073 (void) arg;
2074 smartlist_t *chunks = smartlist_new();
2075 int64_t G, M, E, D, T, weight_scale;
2076 int ret;
2077 weight_scale = 10000;
2079 /* no case. one or more of the values is 0 */
2080 G = M = E = D = 0;
2081 T = G + M + E + D;
2082 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
2083 weight_scale);
2084 tt_int_op(ret, OP_EQ, 0);
2085 tt_int_op(smartlist_len(chunks), OP_EQ, 0);
2087 /* case 1 */
2088 /* XXX dir-spec not followed? See #20272. If it isn't closed, then this is
2089 * testing current behavior, not spec. */
2090 G = E = 10;
2091 M = D = 1;
2092 T = G + M + E + D;
2093 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
2094 weight_scale);
2095 tt_int_op(ret, OP_EQ, 1);
2096 tt_int_op(smartlist_len(chunks), OP_EQ, 1);
2097 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=3333 "
2098 "Wbe=3000 Wbg=3000 Wbm=10000 Wdb=10000 Web=10000 Wed=3333 Wee=7000 "
2099 "Weg=3333 Wem=7000 Wgb=10000 Wgd=3333 Wgg=7000 Wgm=7000 Wmb=10000 "
2100 "Wmd=3333 Wme=3000 Wmg=3000 Wmm=10000\n");
2101 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2102 smartlist_clear(chunks);
2104 /* case 2a E scarce */
2105 M = 100;
2106 G = 20;
2107 E = D = 5;
2108 T = G + M + E + D;
2109 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
2110 weight_scale);
2111 tt_int_op(ret, OP_EQ, 1);
2112 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
2113 "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
2114 "Wem=10000 Wgb=10000 Wgd=0 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 Wme=0 "
2115 "Wmg=0 Wmm=10000\n");
2116 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2117 smartlist_clear(chunks);
2119 /* case 2a G scarce */
2120 M = 100;
2121 E = 20;
2122 G = D = 5;
2123 T = G + M + E + D;
2124 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
2125 weight_scale);
2126 tt_int_op(ret, OP_EQ, 1);
2127 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
2128 "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=10000 Weg=0 Wem=10000 "
2129 "Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 Wme=0 Wmg=0 "
2130 "Wmm=10000\n");
2131 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2132 smartlist_clear(chunks);
2134 /* case 2b1 (Wgg=1, Wmd=Wgd) */
2135 M = 10;
2136 E = 30;
2137 G = 10;
2138 D = 100;
2139 T = G + M + E + D;
2140 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
2141 weight_scale);
2142 tt_int_op(ret, OP_EQ, 1);
2143 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=4000 "
2144 "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=2000 Wee=10000 Weg=2000 "
2145 "Wem=10000 Wgb=10000 Wgd=4000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=4000 "
2146 "Wme=0 Wmg=0 Wmm=10000\n");
2147 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2148 smartlist_clear(chunks);
2150 /* case 2b2 */
2151 M = 60;
2152 E = 30;
2153 G = 10;
2154 D = 100;
2155 T = G + M + E + D;
2156 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
2157 weight_scale);
2158 tt_int_op(ret, OP_EQ, 1);
2159 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=666 Wbe=0 "
2160 "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=3666 Wee=10000 Weg=3666 "
2161 "Wem=10000 Wgb=10000 Wgd=5668 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=666 "
2162 "Wme=0 Wmg=0 Wmm=10000\n");
2163 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2164 smartlist_clear(chunks);
2166 /* case 2b3 */
2167 /* XXX I can't get a combination of values that hits this case without error,
2168 * so this just tests that it fails. See #20285. Also see #20284 as 2b3 does
2169 * not follow dir-spec. */
2170 /* (E < T/3 && G < T/3) && (E+D>=G || G+D>=E) && (M > T/3) */
2171 M = 80;
2172 E = 30;
2173 G = 30;
2174 D = 30;
2175 T = G + M + E + D;
2176 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
2177 weight_scale);
2178 tt_int_op(ret, OP_EQ, 0);
2179 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2180 smartlist_clear(chunks);
2182 /* case 3a G scarce */
2183 M = 10;
2184 E = 30;
2185 G = 10;
2186 D = 5;
2187 T = G + M + E + D;
2188 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
2189 weight_scale);
2190 tt_int_op(ret, OP_EQ, 1);
2191 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 "
2192 "Wbe=3333 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=6667 Weg=0 "
2193 "Wem=6667 Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 "
2194 "Wme=3333 Wmg=0 Wmm=10000\n");
2195 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2196 smartlist_clear(chunks);
2198 /* case 3a E scarce */
2199 M = 10;
2200 E = 10;
2201 G = 30;
2202 D = 5;
2203 T = G + M + E + D;
2204 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
2205 weight_scale);
2206 tt_int_op(ret, OP_EQ, 1);
2207 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
2208 "Wbg=3333 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
2209 "Wem=10000 Wgb=10000 Wgd=0 Wgg=6667 Wgm=6667 Wmb=10000 Wmd=0 Wme=0 "
2210 "Wmg=3333 Wmm=10000\n");
2211 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2212 smartlist_clear(chunks);
2214 /* case 3bg */
2215 M = 10;
2216 E = 30;
2217 G = 10;
2218 D = 10;
2219 T = G + M + E + D;
2220 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
2221 weight_scale);
2222 tt_int_op(ret, OP_EQ, 1);
2223 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 "
2224 "Wbe=3334 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=6666 Weg=0 "
2225 "Wem=6666 Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 "
2226 "Wme=3334 Wmg=0 Wmm=10000\n");
2227 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2228 smartlist_clear(chunks);
2230 /* case 3be */
2231 M = 10;
2232 E = 10;
2233 G = 30;
2234 D = 10;
2235 T = G + M + E + D;
2236 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
2237 weight_scale);
2238 tt_int_op(ret, OP_EQ, 1);
2239 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
2240 "Wbg=3334 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
2241 "Wem=10000 Wgb=10000 Wgd=0 Wgg=6666 Wgm=6666 Wmb=10000 Wmd=0 Wme=0 "
2242 "Wmg=3334 Wmm=10000\n");
2243 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2244 smartlist_clear(chunks);
2246 /* case from 21 Jul 2013 (3be) */
2247 G = 5483409;
2248 M = 1455379;
2249 E = 980834;
2250 D = 3385803;
2251 T = 11305425;
2252 tt_i64_op(G+M+E+D, OP_EQ, T);
2253 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
2254 weight_scale);
2255 tt_assert(ret);
2256 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=883 Wbe=0 "
2257 "Wbg=3673 Wbm=10000 Wdb=10000 Web=10000 Wed=8233 Wee=10000 Weg=8233 "
2258 "Wem=10000 Wgb=10000 Wgd=883 Wgg=6327 Wgm=6327 Wmb=10000 Wmd=883 Wme=0 "
2259 "Wmg=3673 Wmm=10000\n");
2260 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2261 smartlist_clear(chunks);
2263 /* case from 04 Oct 2016 (3a E scarce) */
2264 G=29322240;
2265 M=4721546;
2266 E=1522058;
2267 D=9273571;
2268 T=44839415;
2269 tt_i64_op(G+M+E+D, OP_EQ, T);
2270 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
2271 weight_scale);
2272 tt_assert(ret);
2273 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
2274 "Wbg=4194 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
2275 "Wem=10000 Wgb=10000 Wgd=0 Wgg=5806 Wgm=5806 Wmb=10000 Wmd=0 Wme=0 "
2276 "Wmg=4194 Wmm=10000\n");
2277 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2278 smartlist_clear(chunks);
2280 /* case from 04 Sep 2013 (2b1) */
2281 G=3091352;
2282 M=1838837;
2283 E=2109300;
2284 D=2469369;
2285 T=9508858;
2286 tt_i64_op(G+M+E+D, OP_EQ, T);
2287 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
2288 weight_scale);
2289 tt_assert(ret);
2290 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=317 "
2291 "Wbe=5938 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=9366 Wee=4061 "
2292 "Weg=9366 Wem=4061 Wgb=10000 Wgd=317 Wgg=10000 Wgm=10000 Wmb=10000 "
2293 "Wmd=317 Wme=5938 Wmg=0 Wmm=10000\n");
2294 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2295 smartlist_clear(chunks);
2297 /* explicitly test initializing weights to 1*/
2298 G=1;
2299 M=1;
2300 E=1;
2301 D=1;
2302 T=4;
2303 tt_i64_op(G+M+E+D, OP_EQ, T);
2304 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
2305 weight_scale);
2306 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=3333 "
2307 "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=3333 Wee=10000 Weg=3333 "
2308 "Wem=10000 Wgb=10000 Wgd=3333 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=3333 "
2309 "Wme=0 Wmg=0 Wmm=10000\n");
2310 tt_assert(ret);
2312 done:
2313 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
2314 smartlist_free(chunks);
2317 static authority_cert_t *mock_cert;
2319 static authority_cert_t *
2320 get_my_v3_authority_cert_m(void)
2322 tor_assert(mock_cert);
2323 return mock_cert;
2326 /** Run a unit tests for generating and parsing networkstatuses, with
2327 * the supply test fns. */
2328 static void
2329 test_a_networkstatus(
2330 vote_routerstatus_t * (*vrs_gen)(int idx, time_t now),
2331 int (*vote_tweaks)(networkstatus_t *v, int voter, time_t now),
2332 void (*vrs_test)(vote_routerstatus_t *vrs, int voter, time_t now),
2333 void (*consensus_test)(networkstatus_t *con, time_t now),
2334 void (*rs_test)(routerstatus_t *rs, time_t now))
2336 authority_cert_t *cert1=NULL, *cert2=NULL, *cert3=NULL;
2337 crypto_pk_t *sign_skey_1=NULL, *sign_skey_2=NULL, *sign_skey_3=NULL;
2338 crypto_pk_t *sign_skey_leg1=NULL;
2340 * Sum the non-zero returns from vote_tweaks() we've seen; if vote_tweaks()
2341 * returns non-zero, it changed net_params and we should skip the tests for
2342 * that later as they will fail.
2344 int params_tweaked = 0;
2346 time_t now = time(NULL);
2347 networkstatus_voter_info_t *voter;
2348 document_signature_t *sig;
2349 networkstatus_t *vote=NULL, *v1=NULL, *v2=NULL, *v3=NULL, *con=NULL,
2350 *con_md=NULL;
2351 vote_routerstatus_t *vrs;
2352 routerstatus_t *rs;
2353 int idx, n_rs, n_vrs;
2354 char *consensus_text=NULL, *cp=NULL;
2355 smartlist_t *votes = smartlist_new();
2357 /* For generating the two other consensuses. */
2358 char *detached_text1=NULL, *detached_text2=NULL;
2359 char *consensus_text2=NULL, *consensus_text3=NULL;
2360 char *consensus_text_md2=NULL, *consensus_text_md3=NULL;
2361 char *consensus_text_md=NULL;
2362 networkstatus_t *con2=NULL, *con_md2=NULL, *con3=NULL, *con_md3=NULL;
2363 ns_detached_signatures_t *dsig1=NULL, *dsig2=NULL;
2365 tt_assert(vrs_gen);
2366 tt_assert(rs_test);
2367 tt_assert(vrs_test);
2369 MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
2371 /* Parse certificates and keys. */
2372 cert1 = mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1, NULL);
2373 tt_assert(cert1);
2374 cert2 = authority_cert_parse_from_string(AUTHORITY_CERT_2, NULL);
2375 tt_assert(cert2);
2376 cert3 = authority_cert_parse_from_string(AUTHORITY_CERT_3, NULL);
2377 tt_assert(cert3);
2378 sign_skey_1 = crypto_pk_new();
2379 sign_skey_2 = crypto_pk_new();
2380 sign_skey_3 = crypto_pk_new();
2381 sign_skey_leg1 = pk_generate(4);
2382 dirvote_recalculate_timing(get_options(), now);
2383 sr_state_init(0, 0);
2385 tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_1,
2386 AUTHORITY_SIGNKEY_1, -1));
2387 tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_2,
2388 AUTHORITY_SIGNKEY_2, -1));
2389 tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_3,
2390 AUTHORITY_SIGNKEY_3, -1));
2392 tt_assert(!crypto_pk_cmp_keys(sign_skey_1, cert1->signing_key));
2393 tt_assert(!crypto_pk_cmp_keys(sign_skey_2, cert2->signing_key));
2395 tt_assert(!dir_common_construct_vote_1(&vote, cert1, sign_skey_1, vrs_gen,
2396 &v1, &n_vrs, now, 1));
2397 tt_assert(v1);
2399 /* Make sure the parsed thing was right. */
2400 tt_int_op(v1->type,OP_EQ, NS_TYPE_VOTE);
2401 tt_int_op(v1->published,OP_EQ, vote->published);
2402 tt_int_op(v1->valid_after,OP_EQ, vote->valid_after);
2403 tt_int_op(v1->fresh_until,OP_EQ, vote->fresh_until);
2404 tt_int_op(v1->valid_until,OP_EQ, vote->valid_until);
2405 tt_int_op(v1->vote_seconds,OP_EQ, vote->vote_seconds);
2406 tt_int_op(v1->dist_seconds,OP_EQ, vote->dist_seconds);
2407 tt_str_op(v1->client_versions,OP_EQ, vote->client_versions);
2408 tt_str_op(v1->server_versions,OP_EQ, vote->server_versions);
2409 tt_assert(v1->voters && smartlist_len(v1->voters));
2410 voter = smartlist_get(v1->voters, 0);
2411 tt_str_op(voter->nickname,OP_EQ, "Voter1");
2412 tt_str_op(voter->address,OP_EQ, "1.2.3.4");
2413 tt_int_op(voter->addr,OP_EQ, 0x01020304);
2414 tt_int_op(voter->dir_port,OP_EQ, 80);
2415 tt_int_op(voter->or_port,OP_EQ, 9000);
2416 tt_str_op(voter->contact,OP_EQ, "voter@example.com");
2417 tt_assert(v1->cert);
2418 tt_assert(!crypto_pk_cmp_keys(sign_skey_1, v1->cert->signing_key));
2419 cp = smartlist_join_strings(v1->known_flags, ":", 0, NULL);
2420 tt_str_op(cp,OP_EQ, "Authority:Exit:Fast:Guard:Running:Stable:V2Dir:Valid");
2421 tor_free(cp);
2422 tt_int_op(smartlist_len(v1->routerstatus_list),OP_EQ, n_vrs);
2423 networkstatus_vote_free(vote);
2424 vote = NULL;
2426 if (vote_tweaks) params_tweaked += vote_tweaks(v1, 1, now);
2428 /* Check the routerstatuses. */
2429 for (idx = 0; idx < n_vrs; ++idx) {
2430 vrs = smartlist_get(v1->routerstatus_list, idx);
2431 tt_assert(vrs);
2432 vrs_test(vrs, 1, now);
2435 /* Generate second vote. It disagrees on some of the times,
2436 * and doesn't list versions, and knows some crazy flags.
2437 * Generate and parse v2. */
2438 tt_assert(!dir_common_construct_vote_2(&vote, cert2, sign_skey_2, vrs_gen,
2439 &v2, &n_vrs, now, 1));
2440 tt_assert(v2);
2442 if (vote_tweaks) params_tweaked += vote_tweaks(v2, 2, now);
2444 /* Check that flags come out right.*/
2445 cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
2446 tt_str_op(cp,OP_EQ, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
2447 "Running:Stable:V2Dir:Valid");
2448 tor_free(cp);
2450 /* Check the routerstatuses. */
2451 n_vrs = smartlist_len(v2->routerstatus_list);
2452 for (idx = 0; idx < n_vrs; ++idx) {
2453 vrs = smartlist_get(v2->routerstatus_list, idx);
2454 tt_assert(vrs);
2455 vrs_test(vrs, 2, now);
2457 networkstatus_vote_free(vote);
2458 vote = NULL;
2460 /* Generate the third vote with a legacy id. */
2461 tt_assert(!dir_common_construct_vote_3(&vote, cert3, sign_skey_3, vrs_gen,
2462 &v3, &n_vrs, now, 1));
2463 tt_assert(v3);
2465 if (vote_tweaks) params_tweaked += vote_tweaks(v3, 3, now);
2467 /* Compute a consensus as voter 3. */
2468 smartlist_add(votes, v3);
2469 smartlist_add(votes, v1);
2470 smartlist_add(votes, v2);
2471 consensus_text = networkstatus_compute_consensus(votes, 3,
2472 cert3->identity_key,
2473 sign_skey_3,
2474 "AAAAAAAAAAAAAAAAAAAA",
2475 sign_skey_leg1,
2476 FLAV_NS);
2477 tt_assert(consensus_text);
2478 con = networkstatus_parse_vote_from_string(consensus_text, NULL,
2479 NS_TYPE_CONSENSUS);
2480 tt_assert(con);
2481 //log_notice(LD_GENERAL, "<<%s>>\n<<%s>>\n<<%s>>\n",
2482 // v1_text, v2_text, v3_text);
2483 consensus_text_md = networkstatus_compute_consensus(votes, 3,
2484 cert3->identity_key,
2485 sign_skey_3,
2486 "AAAAAAAAAAAAAAAAAAAA",
2487 sign_skey_leg1,
2488 FLAV_MICRODESC);
2489 tt_assert(consensus_text_md);
2490 con_md = networkstatus_parse_vote_from_string(consensus_text_md, NULL,
2491 NS_TYPE_CONSENSUS);
2492 tt_assert(con_md);
2493 tt_int_op(con_md->flavor,OP_EQ, FLAV_MICRODESC);
2495 /* Check consensus contents. */
2496 tt_assert(con->type == NS_TYPE_CONSENSUS);
2497 tt_int_op(con->published,OP_EQ, 0); /* this field only appears in votes. */
2498 tt_int_op(con->valid_after,OP_EQ, now+1000);
2499 tt_int_op(con->fresh_until,OP_EQ, now+2003); /* median */
2500 tt_int_op(con->valid_until,OP_EQ, now+3000);
2501 tt_int_op(con->vote_seconds,OP_EQ, 100);
2502 tt_int_op(con->dist_seconds,OP_EQ, 250); /* median */
2503 tt_str_op(con->client_versions,OP_EQ, "0.1.2.14");
2504 tt_str_op(con->server_versions,OP_EQ, "0.1.2.15,0.1.2.16");
2505 cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
2506 tt_str_op(cp,OP_EQ, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
2507 "Running:Stable:V2Dir:Valid");
2508 tor_free(cp);
2509 if (!params_tweaked) {
2510 /* Skip this one if vote_tweaks() messed with the param lists */
2511 cp = smartlist_join_strings(con->net_params, ":", 0, NULL);
2512 tt_str_op(cp,OP_EQ, "circuitwindow=80:foo=660");
2513 tor_free(cp);
2516 tt_int_op(4,OP_EQ, smartlist_len(con->voters)); /*3 voters, 1 legacy key.*/
2517 /* The voter id digests should be in this order. */
2518 tt_assert(fast_memcmp(cert2->cache_info.identity_digest,
2519 cert1->cache_info.identity_digest,DIGEST_LEN)<0);
2520 tt_assert(fast_memcmp(cert1->cache_info.identity_digest,
2521 cert3->cache_info.identity_digest,DIGEST_LEN)<0);
2522 test_same_voter(smartlist_get(con->voters, 1),
2523 smartlist_get(v2->voters, 0));
2524 test_same_voter(smartlist_get(con->voters, 2),
2525 smartlist_get(v1->voters, 0));
2526 test_same_voter(smartlist_get(con->voters, 3),
2527 smartlist_get(v3->voters, 0));
2529 consensus_test(con, now);
2531 /* Check the routerstatuses. */
2532 n_rs = smartlist_len(con->routerstatus_list);
2533 tt_assert(n_rs);
2534 for (idx = 0; idx < n_rs; ++idx) {
2535 rs = smartlist_get(con->routerstatus_list, idx);
2536 tt_assert(rs);
2537 rs_test(rs, now);
2540 n_rs = smartlist_len(con_md->routerstatus_list);
2541 tt_assert(n_rs);
2542 for (idx = 0; idx < n_rs; ++idx) {
2543 rs = smartlist_get(con_md->routerstatus_list, idx);
2544 tt_assert(rs);
2547 /* Check signatures. the first voter is a pseudo-entry with a legacy key.
2548 * The second one hasn't signed. The fourth one has signed: validate it. */
2549 voter = smartlist_get(con->voters, 1);
2550 tt_int_op(smartlist_len(voter->sigs),OP_EQ, 0);
2552 voter = smartlist_get(con->voters, 3);
2553 tt_int_op(smartlist_len(voter->sigs),OP_EQ, 1);
2554 sig = smartlist_get(voter->sigs, 0);
2555 tt_assert(sig->signature);
2556 tt_assert(!sig->good_signature);
2557 tt_assert(!sig->bad_signature);
2559 tt_assert(!networkstatus_check_document_signature(con, sig, cert3));
2560 tt_assert(sig->signature);
2561 tt_assert(sig->good_signature);
2562 tt_assert(!sig->bad_signature);
2565 const char *msg=NULL;
2566 /* Compute the other two signed consensuses. */
2567 smartlist_shuffle(votes);
2568 consensus_text2 = networkstatus_compute_consensus(votes, 3,
2569 cert2->identity_key,
2570 sign_skey_2, NULL,NULL,
2571 FLAV_NS);
2572 consensus_text_md2 = networkstatus_compute_consensus(votes, 3,
2573 cert2->identity_key,
2574 sign_skey_2, NULL,NULL,
2575 FLAV_MICRODESC);
2576 smartlist_shuffle(votes);
2577 consensus_text3 = networkstatus_compute_consensus(votes, 3,
2578 cert1->identity_key,
2579 sign_skey_1, NULL,NULL,
2580 FLAV_NS);
2581 consensus_text_md3 = networkstatus_compute_consensus(votes, 3,
2582 cert1->identity_key,
2583 sign_skey_1, NULL,NULL,
2584 FLAV_MICRODESC);
2585 tt_assert(consensus_text2);
2586 tt_assert(consensus_text3);
2587 tt_assert(consensus_text_md2);
2588 tt_assert(consensus_text_md3);
2589 con2 = networkstatus_parse_vote_from_string(consensus_text2, NULL,
2590 NS_TYPE_CONSENSUS);
2591 con3 = networkstatus_parse_vote_from_string(consensus_text3, NULL,
2592 NS_TYPE_CONSENSUS);
2593 con_md2 = networkstatus_parse_vote_from_string(consensus_text_md2, NULL,
2594 NS_TYPE_CONSENSUS);
2595 con_md3 = networkstatus_parse_vote_from_string(consensus_text_md3, NULL,
2596 NS_TYPE_CONSENSUS);
2597 tt_assert(con2);
2598 tt_assert(con3);
2599 tt_assert(con_md2);
2600 tt_assert(con_md3);
2602 /* All three should have the same digest. */
2603 tt_mem_op(&con->digests,OP_EQ, &con2->digests, sizeof(common_digests_t));
2604 tt_mem_op(&con->digests,OP_EQ, &con3->digests, sizeof(common_digests_t));
2606 tt_mem_op(&con_md->digests,OP_EQ, &con_md2->digests,
2607 sizeof(common_digests_t));
2608 tt_mem_op(&con_md->digests,OP_EQ, &con_md3->digests,
2609 sizeof(common_digests_t));
2611 /* Extract a detached signature from con3. */
2612 detached_text1 = get_detached_sigs(con3, con_md3);
2613 tt_assert(detached_text1);
2614 /* Try to parse it. */
2615 dsig1 = networkstatus_parse_detached_signatures(detached_text1, NULL);
2616 tt_assert(dsig1);
2618 /* Are parsed values as expected? */
2619 tt_int_op(dsig1->valid_after,OP_EQ, con3->valid_after);
2620 tt_int_op(dsig1->fresh_until,OP_EQ, con3->fresh_until);
2621 tt_int_op(dsig1->valid_until,OP_EQ, con3->valid_until);
2623 common_digests_t *dsig_digests = strmap_get(dsig1->digests, "ns");
2624 tt_assert(dsig_digests);
2625 tt_mem_op(dsig_digests->d[DIGEST_SHA1], OP_EQ,
2626 con3->digests.d[DIGEST_SHA1], DIGEST_LEN);
2627 dsig_digests = strmap_get(dsig1->digests, "microdesc");
2628 tt_assert(dsig_digests);
2629 tt_mem_op(dsig_digests->d[DIGEST_SHA256],OP_EQ,
2630 con_md3->digests.d[DIGEST_SHA256],
2631 DIGEST256_LEN);
2634 smartlist_t *dsig_signatures = strmap_get(dsig1->signatures, "ns");
2635 tt_assert(dsig_signatures);
2636 tt_int_op(1,OP_EQ, smartlist_len(dsig_signatures));
2637 sig = smartlist_get(dsig_signatures, 0);
2638 tt_mem_op(sig->identity_digest,OP_EQ, cert1->cache_info.identity_digest,
2639 DIGEST_LEN);
2640 tt_int_op(sig->alg,OP_EQ, DIGEST_SHA1);
2642 dsig_signatures = strmap_get(dsig1->signatures, "microdesc");
2643 tt_assert(dsig_signatures);
2644 tt_int_op(1,OP_EQ, smartlist_len(dsig_signatures));
2645 sig = smartlist_get(dsig_signatures, 0);
2646 tt_mem_op(sig->identity_digest,OP_EQ, cert1->cache_info.identity_digest,
2647 DIGEST_LEN);
2648 tt_int_op(sig->alg,OP_EQ, DIGEST_SHA256);
2651 /* Try adding it to con2. */
2652 detached_text2 = get_detached_sigs(con2,con_md2);
2653 tt_int_op(1,OP_EQ, networkstatus_add_detached_signatures(con2, dsig1,
2654 "test", LOG_INFO, &msg));
2655 tor_free(detached_text2);
2656 tt_int_op(1,OP_EQ,
2657 networkstatus_add_detached_signatures(con_md2, dsig1, "test",
2658 LOG_INFO, &msg));
2659 tor_free(detached_text2);
2660 detached_text2 = get_detached_sigs(con2,con_md2);
2661 //printf("\n<%s>\n", detached_text2);
2662 dsig2 = networkstatus_parse_detached_signatures(detached_text2, NULL);
2663 tt_assert(dsig2);
2665 printf("\n");
2666 SMARTLIST_FOREACH(dsig2->signatures, networkstatus_voter_info_t *, vi, {
2667 char hd[64];
2668 base16_encode(hd, sizeof(hd), vi->identity_digest, DIGEST_LEN);
2669 printf("%s\n", hd);
2672 tt_int_op(2,OP_EQ,
2673 smartlist_len((smartlist_t*)strmap_get(dsig2->signatures, "ns")));
2674 tt_int_op(2,OP_EQ,
2675 smartlist_len((smartlist_t*)strmap_get(dsig2->signatures,
2676 "microdesc")));
2678 /* Try adding to con2 twice; verify that nothing changes. */
2679 tt_int_op(0,OP_EQ, networkstatus_add_detached_signatures(con2, dsig1,
2680 "test", LOG_INFO, &msg));
2682 /* Add to con. */
2683 tt_int_op(2,OP_EQ, networkstatus_add_detached_signatures(con, dsig2,
2684 "test", LOG_INFO, &msg));
2685 /* Check signatures */
2686 voter = smartlist_get(con->voters, 1);
2687 sig = smartlist_get(voter->sigs, 0);
2688 tt_assert(sig);
2689 tt_assert(!networkstatus_check_document_signature(con, sig, cert2));
2690 voter = smartlist_get(con->voters, 2);
2691 sig = smartlist_get(voter->sigs, 0);
2692 tt_assert(sig);
2693 tt_assert(!networkstatus_check_document_signature(con, sig, cert1));
2696 done:
2697 tor_free(cp);
2698 smartlist_free(votes);
2699 tor_free(consensus_text);
2700 tor_free(consensus_text_md);
2702 networkstatus_vote_free(vote);
2703 networkstatus_vote_free(v1);
2704 networkstatus_vote_free(v2);
2705 networkstatus_vote_free(v3);
2706 networkstatus_vote_free(con);
2707 networkstatus_vote_free(con_md);
2708 crypto_pk_free(sign_skey_1);
2709 crypto_pk_free(sign_skey_2);
2710 crypto_pk_free(sign_skey_3);
2711 crypto_pk_free(sign_skey_leg1);
2712 authority_cert_free(cert1);
2713 authority_cert_free(cert2);
2714 authority_cert_free(cert3);
2716 tor_free(consensus_text2);
2717 tor_free(consensus_text3);
2718 tor_free(consensus_text_md2);
2719 tor_free(consensus_text_md3);
2720 tor_free(detached_text1);
2721 tor_free(detached_text2);
2723 networkstatus_vote_free(con2);
2724 networkstatus_vote_free(con3);
2725 networkstatus_vote_free(con_md2);
2726 networkstatus_vote_free(con_md3);
2727 ns_detached_signatures_free(dsig1);
2728 ns_detached_signatures_free(dsig2);
2731 /** Run unit tests for generating and parsing V3 consensus networkstatus
2732 * documents. */
2733 static void
2734 test_dir_v3_networkstatus(void *arg)
2736 (void)arg;
2737 test_a_networkstatus(dir_common_gen_routerstatus_for_v3ns,
2738 vote_tweaks_for_v3ns,
2739 test_vrs_for_v3ns,
2740 test_consensus_for_v3ns,
2741 test_routerstatus_for_v3ns);
2744 static void
2745 test_dir_scale_bw(void *testdata)
2747 double v[8] = { 2.0/3,
2748 7.0,
2749 1.0,
2750 3.0,
2751 1.0/5,
2752 1.0/7,
2753 12.0,
2754 24.0 };
2755 double vals_dbl[8];
2756 uint64_t vals_u64[8];
2757 uint64_t total;
2758 int i;
2760 (void) testdata;
2762 for (i=0; i<8; ++i)
2763 vals_dbl[i] = v[i];
2765 scale_array_elements_to_u64(vals_u64, vals_dbl, 8, &total);
2767 tt_int_op((int)total, OP_EQ, 48);
2768 total = 0;
2769 for (i=0; i<8; ++i) {
2770 total += vals_u64[i];
2772 tt_assert(total >= (U64_LITERAL(1)<<60));
2773 tt_assert(total <= (U64_LITERAL(1)<<62));
2775 for (i=0; i<8; ++i) {
2776 /* vals[2].u64 is the scaled value of 1.0 */
2777 double ratio = ((double)vals_u64[i]) / vals_u64[2];
2778 tt_double_op(fabs(ratio - v[i]), OP_LT, .00001);
2781 /* test handling of no entries */
2782 total = 1;
2783 scale_array_elements_to_u64(vals_u64, vals_dbl, 0, &total);
2784 tt_assert(total == 0);
2786 /* make sure we don't read the array when we have no entries
2787 * may require compiler flags to catch NULL dereferences */
2788 total = 1;
2789 scale_array_elements_to_u64(NULL, NULL, 0, &total);
2790 tt_assert(total == 0);
2792 scale_array_elements_to_u64(NULL, NULL, 0, NULL);
2794 /* test handling of zero totals */
2795 total = 1;
2796 vals_dbl[0] = 0.0;
2797 scale_array_elements_to_u64(vals_u64, vals_dbl, 1, &total);
2798 tt_assert(total == 0);
2799 tt_assert(vals_u64[0] == 0);
2801 vals_dbl[0] = 0.0;
2802 vals_dbl[1] = 0.0;
2803 scale_array_elements_to_u64(vals_u64, vals_dbl, 2, NULL);
2804 tt_assert(vals_u64[0] == 0);
2805 tt_assert(vals_u64[1] == 0);
2807 done:
2811 static void
2812 test_dir_random_weighted(void *testdata)
2814 int histogram[10];
2815 uint64_t vals[10] = {3,1,2,4,6,0,7,5,8,9}, total=0;
2816 uint64_t inp_u64[10];
2817 int i, choice;
2818 const int n = 50000;
2819 double max_sq_error;
2820 (void) testdata;
2822 /* Try a ten-element array with values from 0 through 10. The values are
2823 * in a scrambled order to make sure we don't depend on order. */
2824 memset(histogram,0,sizeof(histogram));
2825 for (i=0; i<10; ++i) {
2826 inp_u64[i] = vals[i];
2827 total += vals[i];
2829 tt_u64_op(total, OP_EQ, 45);
2830 for (i=0; i<n; ++i) {
2831 choice = choose_array_element_by_weight(inp_u64, 10);
2832 tt_int_op(choice, OP_GE, 0);
2833 tt_int_op(choice, OP_LT, 10);
2834 histogram[choice]++;
2837 /* Now see if we chose things about frequently enough. */
2838 max_sq_error = 0;
2839 for (i=0; i<10; ++i) {
2840 int expected = (int)(n*vals[i]/total);
2841 double frac_diff = 0, sq;
2842 TT_BLATHER((" %d : %5d vs %5d\n", (int)vals[i], histogram[i], expected));
2843 if (expected)
2844 frac_diff = (histogram[i] - expected) / ((double)expected);
2845 else
2846 tt_int_op(histogram[i], OP_EQ, 0);
2848 sq = frac_diff * frac_diff;
2849 if (sq > max_sq_error)
2850 max_sq_error = sq;
2852 /* It should almost always be much much less than this. If you want to
2853 * figure out the odds, please feel free. */
2854 tt_double_op(max_sq_error, OP_LT, .05);
2856 /* Now try a singleton; do we choose it? */
2857 for (i = 0; i < 100; ++i) {
2858 choice = choose_array_element_by_weight(inp_u64, 1);
2859 tt_int_op(choice, OP_EQ, 0);
2862 /* Now try an array of zeros. We should choose randomly. */
2863 memset(histogram,0,sizeof(histogram));
2864 for (i = 0; i < 5; ++i)
2865 inp_u64[i] = 0;
2866 for (i = 0; i < n; ++i) {
2867 choice = choose_array_element_by_weight(inp_u64, 5);
2868 tt_int_op(choice, OP_GE, 0);
2869 tt_int_op(choice, OP_LT, 5);
2870 histogram[choice]++;
2872 /* Now see if we chose things about frequently enough. */
2873 max_sq_error = 0;
2874 for (i=0; i<5; ++i) {
2875 int expected = n/5;
2876 double frac_diff = 0, sq;
2877 TT_BLATHER((" %d : %5d vs %5d\n", (int)vals[i], histogram[i], expected));
2878 frac_diff = (histogram[i] - expected) / ((double)expected);
2879 sq = frac_diff * frac_diff;
2880 if (sq > max_sq_error)
2881 max_sq_error = sq;
2883 /* It should almost always be much much less than this. If you want to
2884 * figure out the odds, please feel free. */
2885 tt_double_op(max_sq_error, OP_LT, .05);
2886 done:
2890 /* Function pointers for test_dir_clip_unmeasured_bw_kb() */
2892 static uint32_t alternate_clip_bw = 0;
2895 * Generate a routerstatus for clip_unmeasured_bw_kb test; based on the
2896 * v3_networkstatus ones.
2898 static vote_routerstatus_t *
2899 gen_routerstatus_for_umbw(int idx, time_t now)
2901 vote_routerstatus_t *vrs = NULL;
2902 routerstatus_t *rs;
2903 tor_addr_t addr_ipv6;
2904 uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
2905 alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
2907 switch (idx) {
2908 case 0:
2909 /* Generate the first routerstatus. */
2910 vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
2911 rs = &vrs->status;
2912 vrs->version = tor_strdup("0.1.2.14");
2913 rs->published_on = now-1500;
2914 strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
2915 memset(rs->identity_digest, 3, DIGEST_LEN);
2916 memset(rs->descriptor_digest, 78, DIGEST_LEN);
2917 rs->addr = 0x99008801;
2918 rs->or_port = 443;
2919 rs->dir_port = 8000;
2920 /* all flags but running and valid cleared */
2921 rs->is_flagged_running = 1;
2922 rs->is_valid = 1;
2924 * This one has measured bandwidth below the clip cutoff, and
2925 * so shouldn't be clipped; we'll have to test that it isn't
2926 * later.
2928 vrs->has_measured_bw = 1;
2929 rs->has_bandwidth = 1;
2930 vrs->measured_bw_kb = rs->bandwidth_kb = max_unmeasured_bw_kb / 2;
2931 break;
2932 case 1:
2933 /* Generate the second routerstatus. */
2934 vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
2935 rs = &vrs->status;
2936 vrs->version = tor_strdup("0.2.0.5");
2937 rs->published_on = now-1000;
2938 strlcpy(rs->nickname, "router1", sizeof(rs->nickname));
2939 memset(rs->identity_digest, 5, DIGEST_LEN);
2940 memset(rs->descriptor_digest, 77, DIGEST_LEN);
2941 rs->addr = 0x99009901;
2942 rs->or_port = 443;
2943 rs->dir_port = 0;
2944 tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
2945 tor_addr_copy(&rs->ipv6_addr, &addr_ipv6);
2946 rs->ipv6_orport = 4711;
2947 rs->is_exit = rs->is_stable = rs->is_fast = rs->is_flagged_running =
2948 rs->is_valid = rs->is_possible_guard = 1;
2950 * This one has measured bandwidth above the clip cutoff, and
2951 * so shouldn't be clipped; we'll have to test that it isn't
2952 * later.
2954 vrs->has_measured_bw = 1;
2955 rs->has_bandwidth = 1;
2956 vrs->measured_bw_kb = rs->bandwidth_kb = 2 * max_unmeasured_bw_kb;
2957 break;
2958 case 2:
2959 /* Generate the third routerstatus. */
2960 vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
2961 rs = &vrs->status;
2962 vrs->version = tor_strdup("0.1.0.3");
2963 rs->published_on = now-1000;
2964 strlcpy(rs->nickname, "router3", sizeof(rs->nickname));
2965 memset(rs->identity_digest, 0x33, DIGEST_LEN);
2966 memset(rs->descriptor_digest, 79, DIGEST_LEN);
2967 rs->addr = 0xAA009901;
2968 rs->or_port = 400;
2969 rs->dir_port = 9999;
2970 rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
2971 rs->is_flagged_running = rs->is_valid =
2972 rs->is_possible_guard = 1;
2974 * This one has unmeasured bandwidth above the clip cutoff, and
2975 * so should be clipped; we'll have to test that it isn't
2976 * later.
2978 vrs->has_measured_bw = 0;
2979 rs->has_bandwidth = 1;
2980 vrs->measured_bw_kb = 0;
2981 rs->bandwidth_kb = 2 * max_unmeasured_bw_kb;
2982 break;
2983 case 3:
2984 /* Generate a fourth routerstatus that is not running. */
2985 vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
2986 rs = &vrs->status;
2987 vrs->version = tor_strdup("0.1.6.3");
2988 rs->published_on = now-1000;
2989 strlcpy(rs->nickname, "router4", sizeof(rs->nickname));
2990 memset(rs->identity_digest, 0x34, DIGEST_LEN);
2991 memset(rs->descriptor_digest, 47, DIGEST_LEN);
2992 rs->addr = 0xC0000203;
2993 rs->or_port = 500;
2994 rs->dir_port = 1999;
2995 /* all flags but running and valid cleared */
2996 rs->is_flagged_running = 1;
2997 rs->is_valid = 1;
2999 * This one has unmeasured bandwidth below the clip cutoff, and
3000 * so shouldn't be clipped; we'll have to test that it isn't
3001 * later.
3003 vrs->has_measured_bw = 0;
3004 rs->has_bandwidth = 1;
3005 vrs->measured_bw_kb = 0;
3006 rs->bandwidth_kb = max_unmeasured_bw_kb / 2;
3007 break;
3008 case 4:
3009 /* No more for this test; return NULL */
3010 vrs = NULL;
3011 break;
3012 default:
3013 /* Shouldn't happen */
3014 tt_abort();
3016 if (vrs) {
3017 vrs->microdesc = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
3018 tor_asprintf(&vrs->microdesc->microdesc_hash_line,
3019 "m 25,26,27,28 "
3020 "sha256=xyzajkldsdsajdadlsdjaslsdksdjlsdjsdaskdaaa%d\n",
3021 idx);
3024 done:
3025 return vrs;
3028 /** Apply tweaks to the vote list for each voter; for the umbw test this is
3029 * just adding the right consensus methods to let clipping happen */
3030 static int
3031 vote_tweaks_for_umbw(networkstatus_t *v, int voter, time_t now)
3033 char *maxbw_param = NULL;
3034 int rv = 0;
3036 tt_assert(v);
3037 (void)voter;
3038 (void)now;
3040 tt_assert(v->supported_methods);
3041 SMARTLIST_FOREACH(v->supported_methods, char *, c, tor_free(c));
3042 smartlist_clear(v->supported_methods);
3043 /* Method 17 is MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB */
3044 smartlist_split_string(v->supported_methods,
3045 "25 26 27 28",
3046 NULL, 0, -1);
3047 /* If we're using a non-default clip bandwidth, add it to net_params */
3048 if (alternate_clip_bw > 0) {
3049 tor_asprintf(&maxbw_param, "maxunmeasuredbw=%u", alternate_clip_bw);
3050 tt_assert(maxbw_param);
3051 if (maxbw_param) {
3052 smartlist_add(v->net_params, maxbw_param);
3053 rv = 1;
3057 done:
3058 return rv;
3062 * Test a parsed vote_routerstatus_t for umbw test.
3064 static void
3065 test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now)
3067 routerstatus_t *rs;
3068 tor_addr_t addr_ipv6;
3069 uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
3070 alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
3072 (void)voter;
3073 tt_assert(vrs);
3074 rs = &(vrs->status);
3075 tt_assert(rs);
3077 /* Split out by digests to test */
3078 if (tor_memeq(rs->identity_digest,
3079 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
3080 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
3081 DIGEST_LEN)) {
3083 * Check the first routerstatus - measured bandwidth below the clip
3084 * cutoff.
3086 tt_str_op(vrs->version,OP_EQ, "0.1.2.14");
3087 tt_int_op(rs->published_on,OP_EQ, now-1500);
3088 tt_str_op(rs->nickname,OP_EQ, "router2");
3089 tt_mem_op(rs->identity_digest,OP_EQ,
3090 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
3091 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
3092 DIGEST_LEN);
3093 tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
3094 tt_int_op(rs->addr,OP_EQ, 0x99008801);
3095 tt_int_op(rs->or_port,OP_EQ, 443);
3096 tt_int_op(rs->dir_port,OP_EQ, 8000);
3097 tt_assert(rs->has_bandwidth);
3098 tt_assert(vrs->has_measured_bw);
3099 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
3100 tt_int_op(vrs->measured_bw_kb,OP_EQ, max_unmeasured_bw_kb / 2);
3101 } else if (tor_memeq(rs->identity_digest,
3102 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
3103 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
3104 DIGEST_LEN)) {
3107 * Check the second routerstatus - measured bandwidth above the clip
3108 * cutoff.
3110 tt_str_op(vrs->version,OP_EQ, "0.2.0.5");
3111 tt_int_op(rs->published_on,OP_EQ, now-1000);
3112 tt_str_op(rs->nickname,OP_EQ, "router1");
3113 tt_mem_op(rs->identity_digest,OP_EQ,
3114 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
3115 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
3116 DIGEST_LEN);
3117 tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
3118 tt_int_op(rs->addr,OP_EQ, 0x99009901);
3119 tt_int_op(rs->or_port,OP_EQ, 443);
3120 tt_int_op(rs->dir_port,OP_EQ, 0);
3121 tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
3122 tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
3123 tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
3124 tt_assert(rs->has_bandwidth);
3125 tt_assert(vrs->has_measured_bw);
3126 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb * 2);
3127 tt_int_op(vrs->measured_bw_kb,OP_EQ, max_unmeasured_bw_kb * 2);
3128 } else if (tor_memeq(rs->identity_digest,
3129 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
3130 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
3131 DIGEST_LEN)) {
3133 * Check the third routerstatus - unmeasured bandwidth above the clip
3134 * cutoff; this one should be clipped later on in the consensus, but
3135 * appears unclipped in the vote.
3137 tt_assert(rs->has_bandwidth);
3138 tt_assert(!(vrs->has_measured_bw));
3139 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb * 2);
3140 tt_int_op(vrs->measured_bw_kb,OP_EQ, 0);
3141 } else if (tor_memeq(rs->identity_digest,
3142 "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34"
3143 "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34",
3144 DIGEST_LEN)) {
3146 * Check the fourth routerstatus - unmeasured bandwidth below the clip
3147 * cutoff; this one should not be clipped.
3149 tt_assert(rs->has_bandwidth);
3150 tt_assert(!(vrs->has_measured_bw));
3151 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
3152 tt_int_op(vrs->measured_bw_kb,OP_EQ, 0);
3153 } else {
3154 tt_abort();
3157 done:
3158 return;
3162 * Test a consensus for v3_networkstatus_test
3164 static void
3165 test_consensus_for_umbw(networkstatus_t *con, time_t now)
3167 (void)now;
3169 tt_assert(con);
3170 tt_ptr_op(con->cert, OP_EQ, NULL);
3171 // tt_assert(con->consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB);
3172 tt_int_op(con->consensus_method, OP_GE, 16);
3173 tt_int_op(4,OP_EQ, smartlist_len(con->routerstatus_list));
3174 /* There should be four listed routers; all voters saw the same in this */
3176 done:
3177 return;
3181 * Test a router list entry for umbw test
3183 static void
3184 test_routerstatus_for_umbw(routerstatus_t *rs, time_t now)
3186 tor_addr_t addr_ipv6;
3187 uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
3188 alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
3190 tt_assert(rs);
3192 /* There should be four listed routers, as constructed above */
3193 if (tor_memeq(rs->identity_digest,
3194 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
3195 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
3196 DIGEST_LEN)) {
3197 tt_mem_op(rs->identity_digest,OP_EQ,
3198 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
3199 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
3200 DIGEST_LEN);
3201 tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
3202 tt_assert(!rs->is_authority);
3203 tt_assert(!rs->is_exit);
3204 tt_assert(!rs->is_fast);
3205 tt_assert(!rs->is_possible_guard);
3206 tt_assert(!rs->is_stable);
3207 /* (If it wasn't running and valid it wouldn't be here) */
3208 tt_assert(rs->is_flagged_running);
3209 tt_assert(rs->is_valid);
3210 tt_assert(!rs->is_named);
3211 /* This one should have measured bandwidth below the clip cutoff */
3212 tt_assert(rs->has_bandwidth);
3213 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
3214 tt_assert(!(rs->bw_is_unmeasured));
3215 } else if (tor_memeq(rs->identity_digest,
3216 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
3217 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
3218 DIGEST_LEN)) {
3219 /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */
3220 tt_mem_op(rs->identity_digest,OP_EQ,
3221 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
3222 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
3223 DIGEST_LEN);
3224 tt_str_op(rs->nickname,OP_EQ, "router1");
3225 tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
3226 tt_int_op(rs->published_on,OP_EQ, now-1000);
3227 tt_int_op(rs->addr,OP_EQ, 0x99009901);
3228 tt_int_op(rs->or_port,OP_EQ, 443);
3229 tt_int_op(rs->dir_port,OP_EQ, 0);
3230 tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
3231 tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
3232 tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
3233 tt_assert(!rs->is_authority);
3234 tt_assert(rs->is_exit);
3235 tt_assert(rs->is_fast);
3236 tt_assert(rs->is_possible_guard);
3237 tt_assert(rs->is_stable);
3238 tt_assert(rs->is_flagged_running);
3239 tt_assert(rs->is_valid);
3240 tt_assert(!rs->is_named);
3241 /* This one should have measured bandwidth above the clip cutoff */
3242 tt_assert(rs->has_bandwidth);
3243 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb * 2);
3244 tt_assert(!(rs->bw_is_unmeasured));
3245 } else if (tor_memeq(rs->identity_digest,
3246 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
3247 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
3248 DIGEST_LEN)) {
3250 * This one should have unmeasured bandwidth above the clip cutoff,
3251 * and so should be clipped
3253 tt_assert(rs->has_bandwidth);
3254 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb);
3255 tt_assert(rs->bw_is_unmeasured);
3256 } else if (tor_memeq(rs->identity_digest,
3257 "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34"
3258 "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34",
3259 DIGEST_LEN)) {
3261 * This one should have unmeasured bandwidth below the clip cutoff,
3262 * and so should not be clipped
3264 tt_assert(rs->has_bandwidth);
3265 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
3266 tt_assert(rs->bw_is_unmeasured);
3267 } else {
3268 /* Weren't expecting this... */
3269 tt_abort();
3272 done:
3273 return;
3277 * Compute a consensus involving clipping unmeasured bandwidth with consensus
3278 * method 17; this uses the same test_a_networkstatus() function that the
3279 * v3_networkstatus test uses.
3282 static void
3283 test_dir_clip_unmeasured_bw_kb(void *arg)
3285 /* Run the test with the default clip bandwidth */
3286 (void)arg;
3287 alternate_clip_bw = 0;
3288 test_a_networkstatus(gen_routerstatus_for_umbw,
3289 vote_tweaks_for_umbw,
3290 test_vrs_for_umbw,
3291 test_consensus_for_umbw,
3292 test_routerstatus_for_umbw);
3296 * This version of test_dir_clip_unmeasured_bw_kb() uses a non-default choice
3297 * of clip bandwidth.
3300 static void
3301 test_dir_clip_unmeasured_bw_kb_alt(void *arg)
3304 * Try a different one; this value is chosen so that the below-the-cutoff
3305 * unmeasured nodes the test uses, at alternate_clip_bw / 2, will be above
3306 * DEFAULT_MAX_UNMEASURED_BW_KB and if the consensus incorrectly uses that
3307 * cutoff it will fail the test.
3309 (void)arg;
3310 alternate_clip_bw = 3 * DEFAULT_MAX_UNMEASURED_BW_KB;
3311 test_a_networkstatus(gen_routerstatus_for_umbw,
3312 vote_tweaks_for_umbw,
3313 test_vrs_for_umbw,
3314 test_consensus_for_umbw,
3315 test_routerstatus_for_umbw);
3318 static void
3319 test_dir_fmt_control_ns(void *arg)
3321 char *s = NULL;
3322 routerstatus_t rs;
3323 (void)arg;
3325 memset(&rs, 0, sizeof(rs));
3326 rs.published_on = 1364925198;
3327 strlcpy(rs.nickname, "TetsuoMilk", sizeof(rs.nickname));
3328 memcpy(rs.identity_digest, "Stately, plump Buck ", DIGEST_LEN);
3329 memcpy(rs.descriptor_digest, "Mulligan came up fro", DIGEST_LEN);
3330 rs.addr = 0x20304050;
3331 rs.or_port = 9001;
3332 rs.dir_port = 9002;
3333 rs.is_exit = 1;
3334 rs.is_fast = 1;
3335 rs.is_flagged_running = 1;
3336 rs.has_bandwidth = 1;
3337 rs.is_v2_dir = 1;
3338 rs.bandwidth_kb = 1000;
3340 s = networkstatus_getinfo_helper_single(&rs);
3341 tt_assert(s);
3342 tt_str_op(s, OP_EQ,
3343 "r TetsuoMilk U3RhdGVseSwgcGx1bXAgQnVjayA "
3344 "TXVsbGlnYW4gY2FtZSB1cCBmcm8 2013-04-02 17:53:18 "
3345 "32.48.64.80 9001 9002\n"
3346 "s Exit Fast Running V2Dir\n"
3347 "w Bandwidth=1000\n");
3349 done:
3350 tor_free(s);
3353 static int mock_get_options_calls = 0;
3354 static or_options_t *mock_options = NULL;
3356 static void
3357 reset_options(or_options_t *options, int *get_options_calls)
3359 memset(options, 0, sizeof(or_options_t));
3360 options->TestingTorNetwork = 1;
3362 *get_options_calls = 0;
3365 static const or_options_t *
3366 mock_get_options(void)
3368 ++mock_get_options_calls;
3369 tor_assert(mock_options);
3370 return mock_options;
3373 static void
3374 reset_routerstatus(routerstatus_t *rs,
3375 const char *hex_identity_digest,
3376 uint32_t ipv4_addr)
3378 memset(rs, 0, sizeof(routerstatus_t));
3379 base16_decode(rs->identity_digest, sizeof(rs->identity_digest),
3380 hex_identity_digest, HEX_DIGEST_LEN);
3381 /* A zero address matches everything, so the address needs to be set.
3382 * But the specific value is irrelevant. */
3383 rs->addr = ipv4_addr;
3386 #define ROUTER_A_ID_STR "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3387 #define ROUTER_A_IPV4 0xAA008801
3388 #define ROUTER_B_ID_STR "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
3389 #define ROUTER_B_IPV4 0xBB008801
3391 #define ROUTERSET_ALL_STR "*"
3392 #define ROUTERSET_A_STR ROUTER_A_ID_STR
3393 #define ROUTERSET_NONE_STR ""
3396 * Test that dirserv_set_routerstatus_testing sets router flags correctly
3397 * Using "*" sets flags on A and B
3398 * Using "A" sets flags on A
3399 * Using "" sets flags on Neither
3400 * If the router is not included:
3401 * - if *Strict is set, the flag is set to 0,
3402 * - otherwise, the flag is not modified. */
3403 static void
3404 test_dir_dirserv_set_routerstatus_testing(void *arg)
3406 (void)arg;
3408 /* Init options */
3409 mock_options = tor_malloc(sizeof(or_options_t));
3410 reset_options(mock_options, &mock_get_options_calls);
3412 MOCK(get_options, mock_get_options);
3414 /* Init routersets */
3415 routerset_t *routerset_all = routerset_new();
3416 routerset_parse(routerset_all, ROUTERSET_ALL_STR, "All routers");
3418 routerset_t *routerset_a = routerset_new();
3419 routerset_parse(routerset_a, ROUTERSET_A_STR, "Router A only");
3421 routerset_t *routerset_none = routerset_new();
3422 /* Routersets are empty when provided by routerset_new(),
3423 * so this is not strictly necessary */
3424 routerset_parse(routerset_none, ROUTERSET_NONE_STR, "No routers");
3426 /* Init routerstatuses */
3427 routerstatus_t *rs_a = tor_malloc(sizeof(routerstatus_t));
3428 reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
3430 routerstatus_t *rs_b = tor_malloc(sizeof(routerstatus_t));
3431 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
3433 /* Sanity check that routersets correspond to routerstatuses.
3434 * Return values are {2, 3, 4} */
3436 /* We want 3 ("*" means match all addresses) */
3437 tt_int_op(routerset_contains_routerstatus(routerset_all, rs_a, 0), OP_EQ, 3);
3438 tt_int_op(routerset_contains_routerstatus(routerset_all, rs_b, 0), OP_EQ, 3);
3440 /* We want 4 (match id_digest [or nickname]) */
3441 tt_int_op(routerset_contains_routerstatus(routerset_a, rs_a, 0), OP_EQ, 4);
3442 tt_int_op(routerset_contains_routerstatus(routerset_a, rs_b, 0), OP_EQ, 0);
3444 tt_int_op(routerset_contains_routerstatus(routerset_none, rs_a, 0), OP_EQ,
3446 tt_int_op(routerset_contains_routerstatus(routerset_none, rs_b, 0), OP_EQ,
3449 /* Check that "*" sets flags on all routers: Exit
3450 * Check the flags aren't being confused with each other */
3451 reset_options(mock_options, &mock_get_options_calls);
3452 reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
3453 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
3455 mock_options->TestingDirAuthVoteExit = routerset_all;
3456 mock_options->TestingDirAuthVoteExitIsStrict = 0;
3458 dirserv_set_routerstatus_testing(rs_a);
3459 tt_int_op(mock_get_options_calls, OP_EQ, 1);
3460 dirserv_set_routerstatus_testing(rs_b);
3461 tt_int_op(mock_get_options_calls, OP_EQ, 2);
3463 tt_uint_op(rs_a->is_exit, OP_EQ, 1);
3464 tt_uint_op(rs_b->is_exit, OP_EQ, 1);
3465 /* Be paranoid - check no other flags are set */
3466 tt_uint_op(rs_a->is_possible_guard, OP_EQ, 0);
3467 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
3468 tt_uint_op(rs_a->is_hs_dir, OP_EQ, 0);
3469 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
3471 /* Check that "*" sets flags on all routers: Guard & HSDir
3472 * Cover the remaining flags in one test */
3473 reset_options(mock_options, &mock_get_options_calls);
3474 reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
3475 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
3477 mock_options->TestingDirAuthVoteGuard = routerset_all;
3478 mock_options->TestingDirAuthVoteGuardIsStrict = 0;
3479 mock_options->TestingDirAuthVoteHSDir = routerset_all;
3480 mock_options->TestingDirAuthVoteHSDirIsStrict = 0;
3482 dirserv_set_routerstatus_testing(rs_a);
3483 tt_int_op(mock_get_options_calls, OP_EQ, 1);
3484 dirserv_set_routerstatus_testing(rs_b);
3485 tt_int_op(mock_get_options_calls, OP_EQ, 2);
3487 tt_uint_op(rs_a->is_possible_guard, OP_EQ, 1);
3488 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1);
3489 tt_uint_op(rs_a->is_hs_dir, OP_EQ, 1);
3490 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1);
3491 /* Be paranoid - check exit isn't set */
3492 tt_uint_op(rs_a->is_exit, OP_EQ, 0);
3493 tt_uint_op(rs_b->is_exit, OP_EQ, 0);
3495 /* Check routerset A sets all flags on router A,
3496 * but leaves router B unmodified */
3497 reset_options(mock_options, &mock_get_options_calls);
3498 reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
3499 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
3501 mock_options->TestingDirAuthVoteExit = routerset_a;
3502 mock_options->TestingDirAuthVoteExitIsStrict = 0;
3503 mock_options->TestingDirAuthVoteGuard = routerset_a;
3504 mock_options->TestingDirAuthVoteGuardIsStrict = 0;
3505 mock_options->TestingDirAuthVoteHSDir = routerset_a;
3506 mock_options->TestingDirAuthVoteHSDirIsStrict = 0;
3508 dirserv_set_routerstatus_testing(rs_a);
3509 tt_int_op(mock_get_options_calls, OP_EQ, 1);
3510 dirserv_set_routerstatus_testing(rs_b);
3511 tt_int_op(mock_get_options_calls, OP_EQ, 2);
3513 tt_uint_op(rs_a->is_exit, OP_EQ, 1);
3514 tt_uint_op(rs_b->is_exit, OP_EQ, 0);
3515 tt_uint_op(rs_a->is_possible_guard, OP_EQ, 1);
3516 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
3517 tt_uint_op(rs_a->is_hs_dir, OP_EQ, 1);
3518 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
3520 /* Check routerset A unsets all flags on router B when Strict is set */
3521 reset_options(mock_options, &mock_get_options_calls);
3522 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
3524 mock_options->TestingDirAuthVoteExit = routerset_a;
3525 mock_options->TestingDirAuthVoteExitIsStrict = 1;
3526 mock_options->TestingDirAuthVoteGuard = routerset_a;
3527 mock_options->TestingDirAuthVoteGuardIsStrict = 1;
3528 mock_options->TestingDirAuthVoteHSDir = routerset_a;
3529 mock_options->TestingDirAuthVoteHSDirIsStrict = 1;
3531 rs_b->is_exit = 1;
3532 rs_b->is_possible_guard = 1;
3533 rs_b->is_hs_dir = 1;
3535 dirserv_set_routerstatus_testing(rs_b);
3536 tt_int_op(mock_get_options_calls, OP_EQ, 1);
3538 tt_uint_op(rs_b->is_exit, OP_EQ, 0);
3539 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
3540 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
3542 /* Check routerset A doesn't modify flags on router B without Strict set */
3543 reset_options(mock_options, &mock_get_options_calls);
3544 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
3546 mock_options->TestingDirAuthVoteExit = routerset_a;
3547 mock_options->TestingDirAuthVoteExitIsStrict = 0;
3548 mock_options->TestingDirAuthVoteGuard = routerset_a;
3549 mock_options->TestingDirAuthVoteGuardIsStrict = 0;
3550 mock_options->TestingDirAuthVoteHSDir = routerset_a;
3551 mock_options->TestingDirAuthVoteHSDirIsStrict = 0;
3553 rs_b->is_exit = 1;
3554 rs_b->is_possible_guard = 1;
3555 rs_b->is_hs_dir = 1;
3557 dirserv_set_routerstatus_testing(rs_b);
3558 tt_int_op(mock_get_options_calls, OP_EQ, 1);
3560 tt_uint_op(rs_b->is_exit, OP_EQ, 1);
3561 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1);
3562 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1);
3564 /* Check the empty routerset zeroes all flags
3565 * on routers A & B with Strict set */
3566 reset_options(mock_options, &mock_get_options_calls);
3567 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
3569 mock_options->TestingDirAuthVoteExit = routerset_none;
3570 mock_options->TestingDirAuthVoteExitIsStrict = 1;
3571 mock_options->TestingDirAuthVoteGuard = routerset_none;
3572 mock_options->TestingDirAuthVoteGuardIsStrict = 1;
3573 mock_options->TestingDirAuthVoteHSDir = routerset_none;
3574 mock_options->TestingDirAuthVoteHSDirIsStrict = 1;
3576 rs_b->is_exit = 1;
3577 rs_b->is_possible_guard = 1;
3578 rs_b->is_hs_dir = 1;
3580 dirserv_set_routerstatus_testing(rs_b);
3581 tt_int_op(mock_get_options_calls, OP_EQ, 1);
3583 tt_uint_op(rs_b->is_exit, OP_EQ, 0);
3584 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
3585 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
3587 /* Check the empty routerset doesn't modify any flags
3588 * on A or B without Strict set */
3589 reset_options(mock_options, &mock_get_options_calls);
3590 reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
3591 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
3593 mock_options->TestingDirAuthVoteExit = routerset_none;
3594 mock_options->TestingDirAuthVoteExitIsStrict = 0;
3595 mock_options->TestingDirAuthVoteGuard = routerset_none;
3596 mock_options->TestingDirAuthVoteGuardIsStrict = 0;
3597 mock_options->TestingDirAuthVoteHSDir = routerset_none;
3598 mock_options->TestingDirAuthVoteHSDirIsStrict = 0;
3600 rs_b->is_exit = 1;
3601 rs_b->is_possible_guard = 1;
3602 rs_b->is_hs_dir = 1;
3604 dirserv_set_routerstatus_testing(rs_a);
3605 tt_int_op(mock_get_options_calls, OP_EQ, 1);
3606 dirserv_set_routerstatus_testing(rs_b);
3607 tt_int_op(mock_get_options_calls, OP_EQ, 2);
3609 tt_uint_op(rs_a->is_exit, OP_EQ, 0);
3610 tt_uint_op(rs_a->is_possible_guard, OP_EQ, 0);
3611 tt_uint_op(rs_a->is_hs_dir, OP_EQ, 0);
3612 tt_uint_op(rs_b->is_exit, OP_EQ, 1);
3613 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1);
3614 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1);
3616 done:
3617 tor_free(mock_options);
3618 mock_options = NULL;
3620 UNMOCK(get_options);
3622 routerset_free(routerset_all);
3623 routerset_free(routerset_a);
3624 routerset_free(routerset_none);
3626 tor_free(rs_a);
3627 tor_free(rs_b);
3630 static void
3631 test_dir_http_handling(void *args)
3633 char *url = NULL;
3634 (void)args;
3636 /* Parse http url tests: */
3637 /* Good headers */
3638 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1\r\n"
3639 "Host: example.com\r\n"
3640 "User-Agent: Mozilla/5.0 (Windows;"
3641 " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
3642 &url),OP_EQ, 0);
3643 tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
3644 tor_free(url);
3646 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.0\r\n", &url),OP_EQ, 0);
3647 tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
3648 tor_free(url);
3650 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.600\r\n", &url),
3651 OP_EQ, 0);
3652 tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
3653 tor_free(url);
3655 /* Should prepend '/tor/' to url if required */
3656 tt_int_op(parse_http_url("GET /a/b/c.txt HTTP/1.1\r\n"
3657 "Host: example.com\r\n"
3658 "User-Agent: Mozilla/5.0 (Windows;"
3659 " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
3660 &url),OP_EQ, 0);
3661 tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
3662 tor_free(url);
3664 /* Bad headers -- no HTTP/1.x*/
3665 tt_int_op(parse_http_url("GET /a/b/c.txt\r\n"
3666 "Host: example.com\r\n"
3667 "User-Agent: Mozilla/5.0 (Windows;"
3668 " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
3669 &url),OP_EQ, -1);
3670 tt_ptr_op(url, OP_EQ, NULL);
3672 /* Bad headers */
3673 tt_int_op(parse_http_url("GET /a/b/c.txt\r\n"
3674 "Host: example.com\r\n"
3675 "User-Agent: Mozilla/5.0 (Windows;"
3676 " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
3677 &url),OP_EQ, -1);
3678 tt_ptr_op(url, OP_EQ, NULL);
3680 tt_int_op(parse_http_url("GET /tor/a/b/c.txt", &url),OP_EQ, -1);
3681 tt_ptr_op(url, OP_EQ, NULL);
3683 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1", &url),OP_EQ, -1);
3684 tt_ptr_op(url, OP_EQ, NULL);
3686 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1x\r\n", &url),
3687 OP_EQ, -1);
3688 tt_ptr_op(url, OP_EQ, NULL);
3690 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.", &url),OP_EQ, -1);
3691 tt_ptr_op(url, OP_EQ, NULL);
3693 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.\r", &url),OP_EQ, -1);
3694 tt_ptr_op(url, OP_EQ, NULL);
3696 done:
3697 tor_free(url);
3700 static void
3701 test_dir_purpose_needs_anonymity_returns_true_by_default(void *arg)
3703 (void)arg;
3705 tor_capture_bugs_(1);
3706 setup_full_capture_of_logs(LOG_WARN);
3707 tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, 0, NULL));
3708 tt_int_op(1, OP_EQ, smartlist_len(tor_get_captured_bug_log_()));
3709 expect_single_log_msg_containing("Called with dir_purpose=0");
3711 tor_end_capture_bugs_();
3712 done:
3713 tor_end_capture_bugs_();
3714 teardown_capture_of_logs();
3717 static void
3718 test_dir_purpose_needs_anonymity_returns_true_for_bridges(void *arg)
3720 (void)arg;
3722 tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE, NULL));
3723 tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE,
3724 "foobar"));
3725 tt_int_op(1, OP_EQ,
3726 purpose_needs_anonymity(DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2,
3727 ROUTER_PURPOSE_BRIDGE, NULL));
3728 done: ;
3731 static void
3732 test_dir_purpose_needs_anonymity_returns_false_for_own_bridge_desc(void *arg)
3734 (void)arg;
3735 tt_int_op(0, OP_EQ, purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC,
3736 ROUTER_PURPOSE_BRIDGE,
3737 "authority.z"));
3738 done: ;
3741 static void
3742 test_dir_purpose_needs_anonymity_returns_true_for_sensitive_purpose(void *arg)
3744 (void)arg;
3746 tt_int_op(1, OP_EQ, purpose_needs_anonymity(
3747 DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2,
3748 ROUTER_PURPOSE_GENERAL, NULL));
3749 tt_int_op(1, OP_EQ, purpose_needs_anonymity(
3750 DIR_PURPOSE_UPLOAD_RENDDESC_V2, 0, NULL));
3751 tt_int_op(1, OP_EQ, purpose_needs_anonymity(
3752 DIR_PURPOSE_FETCH_RENDDESC_V2, 0, NULL));
3753 done: ;
3756 static void
3757 test_dir_purpose_needs_anonymity_ret_false_for_non_sensitive_conn(void *arg)
3759 (void)arg;
3761 tt_int_op(0, OP_EQ, purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_DIR,
3762 ROUTER_PURPOSE_GENERAL, NULL));
3763 tt_int_op(0, OP_EQ,
3764 purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_VOTE, 0, NULL));
3765 tt_int_op(0, OP_EQ,
3766 purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_SIGNATURES, 0, NULL));
3767 tt_int_op(0, OP_EQ,
3768 purpose_needs_anonymity(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL));
3769 tt_int_op(0, OP_EQ, purpose_needs_anonymity(
3770 DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0, NULL));
3771 tt_int_op(0, OP_EQ,
3772 purpose_needs_anonymity(DIR_PURPOSE_FETCH_CONSENSUS, 0, NULL));
3773 tt_int_op(0, OP_EQ,
3774 purpose_needs_anonymity(DIR_PURPOSE_FETCH_CERTIFICATE, 0, NULL));
3775 tt_int_op(0, OP_EQ,
3776 purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC, 0, NULL));
3777 tt_int_op(0, OP_EQ,
3778 purpose_needs_anonymity(DIR_PURPOSE_FETCH_EXTRAINFO, 0, NULL));
3779 tt_int_op(0, OP_EQ,
3780 purpose_needs_anonymity(DIR_PURPOSE_FETCH_MICRODESC, 0, NULL));
3781 done: ;
3784 static void
3785 test_dir_fetch_type(void *arg)
3787 (void)arg;
3789 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_BRIDGE,
3790 NULL), OP_EQ, EXTRAINFO_DIRINFO | BRIDGE_DIRINFO);
3791 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_GENERAL,
3792 NULL), OP_EQ, EXTRAINFO_DIRINFO | V3_DIRINFO);
3794 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_SERVERDESC, ROUTER_PURPOSE_BRIDGE,
3795 NULL), OP_EQ, BRIDGE_DIRINFO);
3796 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_SERVERDESC,
3797 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
3799 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_STATUS_VOTE,
3800 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
3801 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
3802 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
3803 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CERTIFICATE,
3804 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
3806 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CONSENSUS, ROUTER_PURPOSE_GENERAL,
3807 "microdesc"), OP_EQ, V3_DIRINFO|MICRODESC_DIRINFO);
3808 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CONSENSUS, ROUTER_PURPOSE_GENERAL,
3809 NULL), OP_EQ, V3_DIRINFO);
3811 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_MICRODESC, ROUTER_PURPOSE_GENERAL,
3812 NULL), OP_EQ, MICRODESC_DIRINFO);
3814 /* This will give a warning, because this function isn't supposed to be
3815 * used for HS descriptors. */
3816 setup_full_capture_of_logs(LOG_WARN);
3817 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_RENDDESC_V2,
3818 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, NO_DIRINFO);
3819 expect_single_log_msg_containing("Unexpected purpose");
3820 done:
3821 teardown_capture_of_logs();
3824 static void
3825 test_dir_packages(void *arg)
3827 smartlist_t *votes = smartlist_new();
3828 char *res = NULL;
3829 (void)arg;
3831 #define BAD(s) \
3832 tt_int_op(0, OP_EQ, validate_recommended_package_line(s));
3833 #define GOOD(s) \
3834 tt_int_op(1, OP_EQ, validate_recommended_package_line(s));
3835 GOOD("tor 0.2.6.3-alpha "
3836 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
3837 "sha256=sssdlkfjdsklfjdskfljasdklfj");
3838 GOOD("tor 0.2.6.3-alpha "
3839 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
3840 "sha256=sssdlkfjdsklfjdskfljasdklfj blake2b=fred");
3841 BAD("tor 0.2.6.3-alpha "
3842 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
3843 "sha256=sssdlkfjdsklfjdskfljasdklfj=");
3844 BAD("tor 0.2.6.3-alpha "
3845 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
3846 "sha256=sssdlkfjdsklfjdskfljasdklfj blake2b");
3847 BAD("tor 0.2.6.3-alpha "
3848 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz ");
3849 BAD("tor 0.2.6.3-alpha "
3850 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz");
3851 BAD("tor 0.2.6.3-alpha ");
3852 BAD("tor 0.2.6.3-alpha");
3853 BAD("tor ");
3854 BAD("tor");
3855 BAD("");
3856 BAD("=foobar sha256="
3857 "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
3858 BAD("= = sha256="
3859 "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
3861 BAD("sha512= sha256="
3862 "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
3864 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
3865 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
3866 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
3867 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
3868 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
3869 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
3870 SMARTLIST_FOREACH(votes, networkstatus_t *, ns,
3871 ns->package_lines = smartlist_new());
3873 #define ADD(i, s) \
3874 smartlist_add(((networkstatus_t*)smartlist_get(votes, (i)))->package_lines, \
3875 (void*)(s));
3877 /* Only one vote for this one. */
3878 ADD(4, "cisco 99z http://foobar.example.com/ sha256=blahblah");
3880 /* Only two matching entries for this one, but 3 voters */
3881 ADD(1, "mystic 99y http://barfoo.example.com/ sha256=blahblah");
3882 ADD(3, "mystic 99y http://foobar.example.com/ sha256=blahblah");
3883 ADD(4, "mystic 99y http://foobar.example.com/ sha256=blahblah");
3885 /* Only two matching entries for this one, but at least 4 voters */
3886 ADD(1, "mystic 99p http://barfoo.example.com/ sha256=ggggggg");
3887 ADD(3, "mystic 99p http://foobar.example.com/ sha256=blahblah");
3888 ADD(4, "mystic 99p http://foobar.example.com/ sha256=blahblah");
3889 ADD(5, "mystic 99p http://foobar.example.com/ sha256=ggggggg");
3891 /* This one has only invalid votes. */
3892 ADD(0, "haffenreffer 1.2 http://foobar.example.com/ sha256");
3893 ADD(1, "haffenreffer 1.2 http://foobar.example.com/ ");
3894 ADD(2, "haffenreffer 1.2 ");
3895 ADD(3, "haffenreffer ");
3896 ADD(4, "haffenreffer");
3898 /* Three matching votes for this; it should actually go in! */
3899 ADD(2, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
3900 ADD(3, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
3901 ADD(4, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
3902 ADD(1, "element 0.66.1 http://quum.example.com/ sha256=abcdef");
3903 ADD(0, "element 0.66.1 http://quux.example.com/ sha256=abcde");
3905 /* Three votes for A, three votes for B */
3906 ADD(0, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
3907 ADD(1, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
3908 ADD(2, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
3909 ADD(3, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
3910 ADD(4, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
3911 ADD(5, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
3913 /* Three votes for A, two votes for B */
3914 ADD(1, "clownshoes 22alpha3 http://quumble.example.com/ blake2=foob");
3915 ADD(2, "clownshoes 22alpha3 http://quumble.example.com/ blake2=foob");
3916 ADD(3, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
3917 ADD(4, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
3918 ADD(5, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
3920 /* Four votes for A, two for B. */
3921 ADD(0, "clownshoes 22alpha4 http://quumble.example.com/ blake2=foob");
3922 ADD(1, "clownshoes 22alpha4 http://quumble.example.com/ blake2=foob");
3923 ADD(2, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
3924 ADD(3, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
3925 ADD(4, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
3926 ADD(5, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
3928 /* Five votes for A ... all from the same authority. Three for B. */
3929 ADD(0, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
3930 ADD(1, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
3931 ADD(3, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
3932 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
3933 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
3934 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
3935 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
3936 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
3938 /* As above but new replaces old: no two match. */
3939 ADD(0, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
3940 ADD(1, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
3941 ADD(1, "cbc 99.1.11.1.2 http://example.com/cbc/x cubehash=ahooy sha512=m");
3942 ADD(2, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
3943 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
3944 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
3945 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
3946 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
3947 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
3949 res = compute_consensus_package_lines(votes);
3950 tt_assert(res);
3951 tt_str_op(res, OP_EQ,
3952 "package cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m\n"
3953 "package clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz\n"
3954 "package clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa\n"
3955 "package element 0.66.1 http://quux.example.com/ sha256=abcdef\n"
3956 "package mystic 99y http://foobar.example.com/ sha256=blahblah\n"
3959 #undef ADD
3960 #undef BAD
3961 #undef GOOD
3962 done:
3963 SMARTLIST_FOREACH(votes, networkstatus_t *, ns,
3964 { smartlist_free(ns->package_lines); tor_free(ns); });
3965 smartlist_free(votes);
3966 tor_free(res);
3969 static void
3970 download_status_random_backoff_helper(int min_delay)
3972 download_status_t dls_random =
3973 { 0, 0, 0, DL_SCHED_GENERIC, DL_WANT_AUTHORITY,
3974 DL_SCHED_INCREMENT_FAILURE, 0, 0 };
3975 int increment = -1;
3976 int old_increment = -1;
3977 time_t current_time = time(NULL);
3979 /* Check the random backoff cases */
3980 int n_attempts = 0;
3981 do {
3982 increment = download_status_schedule_get_delay(&dls_random,
3983 min_delay,
3984 current_time);
3986 log_debug(LD_DIR, "Min: %d, Inc: %d, Old Inc: %d",
3987 min_delay, increment, old_increment);
3989 /* Regression test for 20534 and friends
3990 * increment must always increase after the first */
3991 if (dls_random.last_backoff_position > 0) {
3992 /* Always increment the exponential backoff */
3993 tt_int_op(increment, OP_GE, 1);
3996 /* Test */
3997 tt_int_op(increment, OP_GE, min_delay);
3999 /* Advance */
4000 if (dls_random.n_download_attempts < IMPOSSIBLE_TO_DOWNLOAD - 1) {
4001 ++(dls_random.n_download_attempts);
4002 ++(dls_random.n_download_failures);
4005 /* Try another maybe */
4006 old_increment = increment;
4007 } while (++n_attempts < 1000);
4009 done:
4010 return;
4013 static void
4014 test_dir_download_status_random_backoff(void *arg)
4016 (void)arg;
4018 /* Do a standard test */
4019 download_status_random_backoff_helper(0);
4020 /* regression tests for 17750: initial delay */
4021 download_status_random_backoff_helper(10);
4022 download_status_random_backoff_helper(20);
4024 /* Pathological cases */
4025 download_status_random_backoff_helper(INT_MAX/2);
4028 static void
4029 test_dir_download_status_random_backoff_ranges(void *arg)
4031 (void)arg;
4032 int lo, hi;
4033 next_random_exponential_delay_range(&lo, &hi, 0, 10);
4034 tt_int_op(lo, OP_EQ, 10);
4035 tt_int_op(hi, OP_EQ, 11);
4037 next_random_exponential_delay_range(&lo, &hi, 6, 10);
4038 tt_int_op(lo, OP_EQ, 10);
4039 tt_int_op(hi, OP_EQ, 6*3);
4041 next_random_exponential_delay_range(&lo, &hi, 13, 10);
4042 tt_int_op(lo, OP_EQ, 10);
4043 tt_int_op(hi, OP_EQ, 13 * 3);
4045 next_random_exponential_delay_range(&lo, &hi, 37, 10);
4046 tt_int_op(lo, OP_EQ, 10);
4047 tt_int_op(hi, OP_EQ, 111);
4049 next_random_exponential_delay_range(&lo, &hi, 123, 10);
4050 tt_int_op(lo, OP_EQ, 10);
4051 tt_int_op(hi, OP_EQ, 369);
4053 next_random_exponential_delay_range(&lo, &hi, INT_MAX-5, 10);
4054 tt_int_op(lo, OP_EQ, 10);
4055 tt_int_op(hi, OP_EQ, INT_MAX);
4056 done:
4060 static void
4061 test_dir_download_status_increment(void *arg)
4063 (void)arg;
4064 download_status_t dls_exp = { 0, 0, 0, DL_SCHED_GENERIC,
4065 DL_WANT_ANY_DIRSERVER,
4066 DL_SCHED_INCREMENT_ATTEMPT,
4067 0, 0 };
4068 int no_delay = 0;
4069 int delay0 = -1;
4070 int delay1 = -1;
4071 int delay2 = -1;
4072 smartlist_t *schedule = smartlist_new();
4073 smartlist_t *schedule_no_initial_delay = smartlist_new();
4074 or_options_t test_options;
4075 time_t current_time = time(NULL);
4077 /* Provide some values for the schedules */
4078 delay0 = 10;
4079 delay1 = 99;
4080 delay2 = 20;
4082 /* Make the schedules */
4083 smartlist_add(schedule, (void *)&delay0);
4084 smartlist_add(schedule, (void *)&delay1);
4085 smartlist_add(schedule, (void *)&delay2);
4087 smartlist_add(schedule_no_initial_delay, (void *)&no_delay);
4088 smartlist_add(schedule_no_initial_delay, (void *)&delay1);
4089 smartlist_add(schedule_no_initial_delay, (void *)&delay2);
4091 /* Put it in the options */
4092 mock_options = &test_options;
4093 reset_options(mock_options, &mock_get_options_calls);
4094 mock_options->TestingBridgeBootstrapDownloadSchedule = schedule;
4095 mock_options->TestingClientDownloadSchedule = schedule;
4097 MOCK(get_options, mock_get_options);
4099 /* Check that the initial value of the schedule is the first value used,
4100 * whether or not it was reset before being used */
4102 /* regression test for 17750: no initial delay */
4103 mock_options->TestingClientDownloadSchedule = schedule_no_initial_delay;
4104 mock_get_options_calls = 0;
4105 /* we really want to test that it's equal to time(NULL) + delay0, but that's
4106 * an unrealiable test, because time(NULL) might change. */
4108 /* regression test for 17750: exponential, no initial delay */
4109 mock_options->TestingClientDownloadSchedule = schedule_no_initial_delay;
4110 mock_get_options_calls = 0;
4111 /* we really want to test that it's equal to time(NULL) + delay0, but that's
4112 * an unrealiable test, because time(NULL) might change. */
4113 tt_assert(download_status_get_next_attempt_at(&dls_exp)
4114 >= current_time + no_delay);
4115 tt_assert(download_status_get_next_attempt_at(&dls_exp)
4116 != TIME_MAX);
4117 tt_int_op(download_status_get_n_failures(&dls_exp), OP_EQ, 0);
4118 tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0);
4119 tt_int_op(mock_get_options_calls, OP_GE, 1);
4121 /* regression test for 17750: exponential, initial delay */
4122 mock_options->TestingClientDownloadSchedule = schedule;
4123 mock_get_options_calls = 0;
4124 /* we really want to test that it's equal to time(NULL) + delay0, but that's
4125 * an unrealiable test, because time(NULL) might change. */
4126 tt_assert(download_status_get_next_attempt_at(&dls_exp)
4127 >= current_time + delay0);
4128 tt_assert(download_status_get_next_attempt_at(&dls_exp)
4129 != TIME_MAX);
4130 tt_int_op(download_status_get_n_failures(&dls_exp), OP_EQ, 0);
4131 tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0);
4132 tt_int_op(mock_get_options_calls, OP_GE, 1);
4134 done:
4135 /* the pointers in schedule are allocated on the stack */
4136 smartlist_free(schedule);
4137 smartlist_free(schedule_no_initial_delay);
4138 UNMOCK(get_options);
4139 mock_options = NULL;
4140 mock_get_options_calls = 0;
4141 teardown_capture_of_logs();
4144 static void
4145 test_dir_authdir_type_to_string(void *data)
4147 (void)data;
4148 char *res;
4150 tt_str_op(res = authdir_type_to_string(NO_DIRINFO), OP_EQ,
4151 "[Not an authority]");
4152 tor_free(res);
4154 tt_str_op(res = authdir_type_to_string(EXTRAINFO_DIRINFO), OP_EQ,
4155 "[Not an authority]");
4156 tor_free(res);
4158 tt_str_op(res = authdir_type_to_string(MICRODESC_DIRINFO), OP_EQ,
4159 "[Not an authority]");
4160 tor_free(res);
4162 tt_str_op(res = authdir_type_to_string(V3_DIRINFO), OP_EQ, "V3");
4163 tor_free(res);
4165 tt_str_op(res = authdir_type_to_string(BRIDGE_DIRINFO), OP_EQ, "Bridge");
4166 tor_free(res);
4168 tt_str_op(res = authdir_type_to_string(
4169 V3_DIRINFO | BRIDGE_DIRINFO | EXTRAINFO_DIRINFO), OP_EQ,
4170 "V3, Bridge");
4171 done:
4172 tor_free(res);
4175 static void
4176 test_dir_conn_purpose_to_string(void *data)
4178 (void)data;
4180 #define EXPECT_CONN_PURPOSE(purpose, expected) \
4181 tt_str_op(dir_conn_purpose_to_string(purpose), OP_EQ, expected);
4183 EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_DIR, "server descriptor upload");
4184 EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_VOTE, "server vote upload");
4185 EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_SIGNATURES,
4186 "consensus signature upload");
4187 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_SERVERDESC, "server descriptor fetch");
4188 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_EXTRAINFO, "extra-info fetch");
4189 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_CONSENSUS,
4190 "consensus network-status fetch");
4191 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_CERTIFICATE, "authority cert fetch");
4192 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_STATUS_VOTE, "status vote fetch");
4193 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
4194 "consensus signature fetch");
4195 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_RENDDESC_V2,
4196 "hidden-service v2 descriptor fetch");
4197 EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_RENDDESC_V2,
4198 "hidden-service v2 descriptor upload");
4199 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_MICRODESC, "microdescriptor fetch");
4201 /* This will give a warning, because there is no purpose 1024. */
4202 setup_full_capture_of_logs(LOG_WARN);
4203 EXPECT_CONN_PURPOSE(1024, "(unknown)");
4204 expect_single_log_msg_containing("Called with unknown purpose 1024");
4206 done:
4207 teardown_capture_of_logs();
4210 NS_DECL(int,
4211 public_server_mode, (const or_options_t *options));
4213 static int
4214 NS(public_server_mode)(const or_options_t *options)
4216 (void)options;
4218 if (CALLED(public_server_mode)++ == 0) {
4219 return 1;
4222 return 0;
4225 static void
4226 test_dir_should_use_directory_guards(void *data)
4228 or_options_t *options;
4229 char *errmsg = NULL;
4230 (void)data;
4232 NS_MOCK(public_server_mode);
4234 options = options_new();
4235 options_init(options);
4237 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
4238 tt_int_op(CALLED(public_server_mode), OP_EQ, 1);
4240 options->UseEntryGuards = 1;
4241 options->DownloadExtraInfo = 0;
4242 options->FetchDirInfoEarly = 0;
4243 options->FetchDirInfoExtraEarly = 0;
4244 options->FetchUselessDescriptors = 0;
4245 tt_int_op(should_use_directory_guards(options), OP_EQ, 1);
4246 tt_int_op(CALLED(public_server_mode), OP_EQ, 2);
4248 options->UseEntryGuards = 0;
4249 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
4250 tt_int_op(CALLED(public_server_mode), OP_EQ, 3);
4251 options->UseEntryGuards = 1;
4253 options->DownloadExtraInfo = 1;
4254 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
4255 tt_int_op(CALLED(public_server_mode), OP_EQ, 4);
4256 options->DownloadExtraInfo = 0;
4258 options->FetchDirInfoEarly = 1;
4259 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
4260 tt_int_op(CALLED(public_server_mode), OP_EQ, 5);
4261 options->FetchDirInfoEarly = 0;
4263 options->FetchDirInfoExtraEarly = 1;
4264 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
4265 tt_int_op(CALLED(public_server_mode), OP_EQ, 6);
4266 options->FetchDirInfoExtraEarly = 0;
4268 options->FetchUselessDescriptors = 1;
4269 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
4270 tt_int_op(CALLED(public_server_mode), OP_EQ, 7);
4271 options->FetchUselessDescriptors = 0;
4273 done:
4274 NS_UNMOCK(public_server_mode);
4275 or_options_free(options);
4276 tor_free(errmsg);
4279 NS_DECL(void,
4280 directory_initiate_request, (directory_request_t *req));
4282 static void
4283 test_dir_should_not_init_request_to_ourselves(void *data)
4285 char digest[DIGEST_LEN];
4286 dir_server_t *ourself = NULL;
4287 crypto_pk_t *key = pk_generate(2);
4288 (void) data;
4290 NS_MOCK(directory_initiate_request);
4292 clear_dir_servers();
4293 routerlist_free_all();
4295 set_server_identity_key(key);
4296 crypto_pk_get_digest(key, (char*) &digest);
4297 ourself = trusted_dir_server_new("ourself", "127.0.0.1", 9059, 9060,
4298 NULL, digest,
4299 NULL, V3_DIRINFO, 1.0);
4301 tt_assert(ourself);
4302 dir_server_add(ourself);
4304 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
4305 tt_int_op(CALLED(directory_initiate_request), OP_EQ, 0);
4307 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
4308 NULL);
4310 tt_int_op(CALLED(directory_initiate_request), OP_EQ, 0);
4312 done:
4313 NS_UNMOCK(directory_initiate_request);
4314 clear_dir_servers();
4315 routerlist_free_all();
4316 crypto_pk_free(key);
4319 static void
4320 test_dir_should_not_init_request_to_dir_auths_without_v3_info(void *data)
4322 dir_server_t *ds = NULL;
4323 dirinfo_type_t dirinfo_type = BRIDGE_DIRINFO | EXTRAINFO_DIRINFO \
4324 | MICRODESC_DIRINFO;
4325 (void) data;
4327 NS_MOCK(directory_initiate_request);
4329 clear_dir_servers();
4330 routerlist_free_all();
4332 ds = trusted_dir_server_new("ds", "10.0.0.1", 9059, 9060, NULL,
4333 "12345678901234567890", NULL, dirinfo_type, 1.0);
4334 tt_assert(ds);
4335 dir_server_add(ds);
4337 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
4338 tt_int_op(CALLED(directory_initiate_request), OP_EQ, 0);
4340 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
4341 NULL);
4342 tt_int_op(CALLED(directory_initiate_request), OP_EQ, 0);
4344 done:
4345 NS_UNMOCK(directory_initiate_request);
4346 clear_dir_servers();
4347 routerlist_free_all();
4350 static void
4351 test_dir_should_init_request_to_dir_auths(void *data)
4353 dir_server_t *ds = NULL;
4354 (void) data;
4356 NS_MOCK(directory_initiate_request);
4358 clear_dir_servers();
4359 routerlist_free_all();
4361 ds = trusted_dir_server_new("ds", "10.0.0.1", 9059, 9060, NULL,
4362 "12345678901234567890", NULL, V3_DIRINFO, 1.0);
4363 tt_assert(ds);
4364 dir_server_add(ds);
4366 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
4367 tt_int_op(CALLED(directory_initiate_request), OP_EQ, 1);
4369 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
4370 NULL);
4371 tt_int_op(CALLED(directory_initiate_request), OP_EQ, 2);
4373 done:
4374 NS_UNMOCK(directory_initiate_request);
4375 clear_dir_servers();
4376 routerlist_free_all();
4379 void
4380 NS(directory_initiate_request)(directory_request_t *req)
4382 (void)req;
4383 CALLED(directory_initiate_request)++;
4386 static void
4387 test_dir_choose_compression_level(void* data)
4389 (void)data;
4391 /* It starts under_memory_pressure */
4392 tt_int_op(have_been_under_memory_pressure(), OP_EQ, 1);
4394 tt_assert(HIGH_COMPRESSION == choose_compression_level(-1));
4395 tt_assert(LOW_COMPRESSION == choose_compression_level(1024-1));
4396 tt_assert(MEDIUM_COMPRESSION == choose_compression_level(2048-1));
4397 tt_assert(HIGH_COMPRESSION == choose_compression_level(2048));
4399 /* Reset under_memory_pressure timer */
4400 cell_queues_check_size();
4401 tt_int_op(have_been_under_memory_pressure(), OP_EQ, 0);
4403 tt_assert(HIGH_COMPRESSION == choose_compression_level(-1));
4404 tt_assert(HIGH_COMPRESSION == choose_compression_level(1024-1));
4405 tt_assert(HIGH_COMPRESSION == choose_compression_level(2048-1));
4406 tt_assert(HIGH_COMPRESSION == choose_compression_level(2048));
4408 done: ;
4412 * Mock check_private_dir(), and always succeed - no need to actually
4413 * look at or create anything on the filesystem.
4416 static int
4417 mock_check_private_dir(const char *dirname, cpd_check_t check,
4418 const char *effective_user)
4420 (void)dirname;
4421 (void)check;
4422 (void)effective_user;
4424 return 0;
4428 * This really mocks options_get_datadir_fname2_suffix(), but for testing
4429 * dump_desc(), we only care about get_datadir_fname(sub1), which is defined
4430 * in config.h as:
4432 * options_get_datadir_fname2_suffix(get_options(), sub1, NULL, NULL)
4435 static char *
4436 mock_get_datadir_fname(const or_options_t *options,
4437 directory_root_t roottype,
4438 const char *sub1, const char *sub2,
4439 const char *suffix)
4441 (void) roottype;
4442 char *rv = NULL;
4445 * Assert we were called like get_datadir_fname2() or get_datadir_fname(),
4446 * since that's all we implement here.
4448 tt_ptr_op(options, OP_NE, NULL);
4449 tt_ptr_op(sub1, OP_NE, NULL);
4451 * No particular assertions about sub2, since we could be in the
4452 * get_datadir_fname() or get_datadir_fname2() case.
4454 tt_ptr_op(suffix, OP_EQ, NULL);
4456 /* Just duplicate the basename and return it for this mock */
4457 if (sub2) {
4458 /* If we have sub2, it's the basename, otherwise sub1 */
4459 rv = tor_strdup(sub2);
4460 } else {
4461 rv = tor_strdup(sub1);
4464 done:
4465 return rv;
4468 static char *last_unlinked_path = NULL;
4469 static int unlinked_count = 0;
4471 static void
4472 mock_unlink_reset(void)
4474 tor_free(last_unlinked_path);
4475 unlinked_count = 0;
4478 static int
4479 mock_unlink(const char *path)
4481 tt_ptr_op(path, OP_NE, NULL);
4483 tor_free(last_unlinked_path);
4484 last_unlinked_path = tor_strdup(path);
4485 ++unlinked_count;
4487 done:
4488 return 0;
4491 static char *last_write_str_path = NULL;
4492 static uint8_t last_write_str_hash[DIGEST256_LEN];
4493 static int write_str_count = 0;
4495 static void
4496 mock_write_str_to_file_reset(void)
4498 tor_free(last_write_str_path);
4499 write_str_count = 0;
4502 static int
4503 mock_write_str_to_file(const char *path, const char *str, int bin)
4505 size_t len;
4506 uint8_t hash[DIGEST256_LEN];
4508 (void)bin;
4510 tt_ptr_op(path, OP_NE, NULL);
4511 tt_ptr_op(str, OP_NE, NULL);
4513 len = strlen(str);
4514 crypto_digest256((char *)hash, str, len, DIGEST_SHA256);
4516 tor_free(last_write_str_path);
4517 last_write_str_path = tor_strdup(path);
4518 memcpy(last_write_str_hash, hash, sizeof(last_write_str_hash));
4519 ++write_str_count;
4521 done:
4522 return 0;
4525 static void
4526 test_dir_dump_unparseable_descriptors(void *data)
4529 * These bogus descriptors look nothing at all like real bogus descriptors
4530 * we might see, but we're only testing dump_desc() here, not the parser.
4532 const char *test_desc_type = "squamous";
4533 /* strlen(test_desc_1) = 583 bytes */
4534 const char *test_desc_1 =
4535 "The most merciful thing in the world, I think, is the inability of the "
4536 "human mind to correlate all its contents. We live on a placid island of"
4537 " ignorance in the midst of black seas of infinity, and it was not meant"
4538 " that we should voyage far. The sciences, each straining in its own dir"
4539 "ection, have hitherto harmed us little; but some day the piecing togeth"
4540 "er of dissociated knowledge will open up such terrifying vistas of real"
4541 "ity, and of our frightful position therein, that we shall either go mad"
4542 "from the revelation or flee from the light into the peace and safety of"
4543 "a new dark age.";
4544 uint8_t test_desc_1_hash[DIGEST256_LEN];
4545 char test_desc_1_hash_str[HEX_DIGEST256_LEN+1];
4546 /* strlen(test_desc_2) = 650 bytes */
4547 const char *test_desc_2 =
4548 "I think their predominant colour was a greyish-green, though they had w"
4549 "hite bellies. They were mostly shiny and slippery, but the ridges of th"
4550 "eir backs were scaly. Their forms vaguely suggested the anthropoid, whi"
4551 "le their heads were the heads of fish, with prodigious bulging eyes tha"
4552 "t never closed. At the sides of their necks were palpitating gills, and"
4553 "their long paws were webbed. They hopped irregularly, sometimes on two "
4554 "legs and sometimes on four. I was somehow glad that they had no more th"
4555 "an four limbs. Their croaking, baying voices, clearly wed tar articulat"
4556 "e speech, held all the dark shades of expression which their staring fa"
4557 "ces lacked.";
4558 uint8_t test_desc_2_hash[DIGEST256_LEN];
4559 char test_desc_2_hash_str[HEX_DIGEST256_LEN+1];
4560 /* strlen(test_desc_3) = 700 bytes */
4561 const char *test_desc_3 =
4562 "Without knowing what futurism is like, Johansen achieved something very"
4563 "close to it when he spoke of the city; for instead of describing any de"
4564 "finite structure or building, he dwells only on broad impressions of va"
4565 "st angles and stone surfaces - surfaces too great to belong to anything"
4566 "right or proper for this earth, and impious with horrible images and hi"
4567 "eroglyphs. I mention his talk about angles because it suggests somethin"
4568 "g Wilcox had told me of his awful dreams. He said that the geometry of "
4569 "the dream-place he saw was abnormal, non-Euclidean, and loathsomely red"
4570 "olent of spheres and dimensions apart from ours. Now an unlettered seam"
4571 "an felt the same thing whilst gazing at the terrible reality.";
4572 uint8_t test_desc_3_hash[DIGEST256_LEN];
4573 char test_desc_3_hash_str[HEX_DIGEST256_LEN+1];
4574 /* strlen(test_desc_3) = 604 bytes */
4575 const char *test_desc_4 =
4576 "So we glanced back simultaneously, it would appear; though no doubt the"
4577 "incipient motion of one prompted the imitation of the other. As we did "
4578 "so we flashed both torches full strength at the momentarily thinned mis"
4579 "t; either from sheer primitive anxiety to see all we could, or in a les"
4580 "s primitive but equally unconscious effort to dazzle the entity before "
4581 "we dimmed our light and dodged among the penguins of the labyrinth cent"
4582 "er ahead. Unhappy act! Not Orpheus himself, or Lot's wife, paid much mo"
4583 "re dearly for a backward glance. And again came that shocking, wide-ran"
4584 "ged piping - \"Tekeli-li! Tekeli-li!\"";
4585 uint8_t test_desc_4_hash[DIGEST256_LEN];
4586 char test_desc_4_hash_str[HEX_DIGEST256_LEN+1];
4587 (void)data;
4590 * Set up options mock so we can force a tiny FIFO size and generate
4591 * cleanups.
4593 mock_options = tor_malloc(sizeof(or_options_t));
4594 reset_options(mock_options, &mock_get_options_calls);
4595 mock_options->MaxUnparseableDescSizeToLog = 1536;
4596 MOCK(get_options, mock_get_options);
4597 MOCK(check_private_dir, mock_check_private_dir);
4598 MOCK(options_get_dir_fname2_suffix,
4599 mock_get_datadir_fname);
4602 * Set up unlink and write mocks
4604 MOCK(tor_unlink, mock_unlink);
4605 mock_unlink_reset();
4606 MOCK(write_str_to_file, mock_write_str_to_file);
4607 mock_write_str_to_file_reset();
4610 * Compute hashes we'll need to recognize which descriptor is which
4612 crypto_digest256((char *)test_desc_1_hash, test_desc_1,
4613 strlen(test_desc_1), DIGEST_SHA256);
4614 base16_encode(test_desc_1_hash_str, sizeof(test_desc_1_hash_str),
4615 (const char *)test_desc_1_hash,
4616 sizeof(test_desc_1_hash));
4617 crypto_digest256((char *)test_desc_2_hash, test_desc_2,
4618 strlen(test_desc_2), DIGEST_SHA256);
4619 base16_encode(test_desc_2_hash_str, sizeof(test_desc_2_hash_str),
4620 (const char *)test_desc_2_hash,
4621 sizeof(test_desc_2_hash));
4622 crypto_digest256((char *)test_desc_3_hash, test_desc_3,
4623 strlen(test_desc_3), DIGEST_SHA256);
4624 base16_encode(test_desc_3_hash_str, sizeof(test_desc_3_hash_str),
4625 (const char *)test_desc_3_hash,
4626 sizeof(test_desc_3_hash));
4627 crypto_digest256((char *)test_desc_4_hash, test_desc_4,
4628 strlen(test_desc_4), DIGEST_SHA256);
4629 base16_encode(test_desc_4_hash_str, sizeof(test_desc_4_hash_str),
4630 (const char *)test_desc_4_hash,
4631 sizeof(test_desc_4_hash));
4634 * Reset the FIFO and check its state
4636 dump_desc_fifo_cleanup();
4637 tt_u64_op(len_descs_dumped, OP_EQ, 0);
4638 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
4641 * (1) Fire off dump_desc() once; these descriptors should all be safely
4642 * smaller than configured FIFO size.
4645 dump_desc(test_desc_1, test_desc_type);
4648 * Assert things about the FIFO state
4650 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_1));
4651 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
4654 * Assert things about the mocks
4656 tt_int_op(unlinked_count, OP_EQ, 0);
4657 tt_int_op(write_str_count, OP_EQ, 1);
4658 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
4661 * Reset the FIFO and check its state
4663 dump_desc_fifo_cleanup();
4664 tt_u64_op(len_descs_dumped, OP_EQ, 0);
4665 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
4668 * Reset the mocks and check their state
4670 mock_unlink_reset();
4671 mock_write_str_to_file_reset();
4672 tt_int_op(unlinked_count, OP_EQ, 0);
4673 tt_int_op(write_str_count, OP_EQ, 0);
4676 * (2) Fire off dump_desc() twice; this still should trigger no cleanup.
4679 /* First time */
4680 dump_desc(test_desc_2, test_desc_type);
4683 * Assert things about the FIFO state
4685 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_2));
4686 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
4689 * Assert things about the mocks
4691 tt_int_op(unlinked_count, OP_EQ, 0);
4692 tt_int_op(write_str_count, OP_EQ, 1);
4693 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
4695 /* Second time */
4696 dump_desc(test_desc_3, test_desc_type);
4699 * Assert things about the FIFO state
4701 tt_u64_op(len_descs_dumped, OP_EQ,
4702 strlen(test_desc_2) + strlen(test_desc_3));
4703 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
4706 * Assert things about the mocks
4708 tt_int_op(unlinked_count, OP_EQ, 0);
4709 tt_int_op(write_str_count, OP_EQ, 2);
4710 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
4713 * Reset the FIFO and check its state
4715 dump_desc_fifo_cleanup();
4716 tt_u64_op(len_descs_dumped, OP_EQ, 0);
4717 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
4720 * Reset the mocks and check their state
4722 mock_unlink_reset();
4723 mock_write_str_to_file_reset();
4724 tt_int_op(unlinked_count, OP_EQ, 0);
4725 tt_int_op(write_str_count, OP_EQ, 0);
4728 * (3) Three calls to dump_desc cause a FIFO cleanup
4731 /* First time */
4732 dump_desc(test_desc_4, test_desc_type);
4735 * Assert things about the FIFO state
4737 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_4));
4738 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
4741 * Assert things about the mocks
4743 tt_int_op(unlinked_count, OP_EQ, 0);
4744 tt_int_op(write_str_count, OP_EQ, 1);
4745 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
4747 /* Second time */
4748 dump_desc(test_desc_1, test_desc_type);
4751 * Assert things about the FIFO state
4753 tt_u64_op(len_descs_dumped, OP_EQ,
4754 strlen(test_desc_4) + strlen(test_desc_1));
4755 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
4758 * Assert things about the mocks
4760 tt_int_op(unlinked_count, OP_EQ, 0);
4761 tt_int_op(write_str_count, OP_EQ, 2);
4762 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
4764 /* Third time - we should unlink the dump of test_desc_4 here */
4765 dump_desc(test_desc_2, test_desc_type);
4768 * Assert things about the FIFO state
4770 tt_u64_op(len_descs_dumped, OP_EQ,
4771 strlen(test_desc_1) + strlen(test_desc_2));
4772 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
4775 * Assert things about the mocks
4777 tt_int_op(unlinked_count, OP_EQ, 1);
4778 tt_int_op(write_str_count, OP_EQ, 3);
4779 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
4782 * Reset the FIFO and check its state
4784 dump_desc_fifo_cleanup();
4785 tt_u64_op(len_descs_dumped, OP_EQ, 0);
4786 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
4789 * Reset the mocks and check their state
4791 mock_unlink_reset();
4792 mock_write_str_to_file_reset();
4793 tt_int_op(unlinked_count, OP_EQ, 0);
4794 tt_int_op(write_str_count, OP_EQ, 0);
4797 * (4) But repeating one (A B B) doesn't overflow and cleanup
4800 /* First time */
4801 dump_desc(test_desc_3, test_desc_type);
4804 * Assert things about the FIFO state
4806 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_3));
4807 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
4810 * Assert things about the mocks
4812 tt_int_op(unlinked_count, OP_EQ, 0);
4813 tt_int_op(write_str_count, OP_EQ, 1);
4814 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
4816 /* Second time */
4817 dump_desc(test_desc_4, test_desc_type);
4820 * Assert things about the FIFO state
4822 tt_u64_op(len_descs_dumped, OP_EQ,
4823 strlen(test_desc_3) + strlen(test_desc_4));
4824 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
4827 * Assert things about the mocks
4829 tt_int_op(unlinked_count, OP_EQ, 0);
4830 tt_int_op(write_str_count, OP_EQ, 2);
4831 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
4833 /* Third time */
4834 dump_desc(test_desc_4, test_desc_type);
4837 * Assert things about the FIFO state
4839 tt_u64_op(len_descs_dumped, OP_EQ,
4840 strlen(test_desc_3) + strlen(test_desc_4));
4841 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
4844 * Assert things about the mocks
4846 tt_int_op(unlinked_count, OP_EQ, 0);
4847 tt_int_op(write_str_count, OP_EQ, 2);
4848 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
4851 * Reset the FIFO and check its state
4853 dump_desc_fifo_cleanup();
4854 tt_u64_op(len_descs_dumped, OP_EQ, 0);
4855 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
4858 * Reset the mocks and check their state
4860 mock_unlink_reset();
4861 mock_write_str_to_file_reset();
4862 tt_int_op(unlinked_count, OP_EQ, 0);
4863 tt_int_op(write_str_count, OP_EQ, 0);
4866 * (5) Same for the (A B A) repetition
4869 /* First time */
4870 dump_desc(test_desc_1, test_desc_type);
4873 * Assert things about the FIFO state
4875 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_1));
4876 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
4879 * Assert things about the mocks
4881 tt_int_op(unlinked_count, OP_EQ, 0);
4882 tt_int_op(write_str_count, OP_EQ, 1);
4883 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
4885 /* Second time */
4886 dump_desc(test_desc_2, test_desc_type);
4889 * Assert things about the FIFO state
4891 tt_u64_op(len_descs_dumped, OP_EQ,
4892 strlen(test_desc_1) + strlen(test_desc_2));
4893 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
4896 * Assert things about the mocks
4898 tt_int_op(unlinked_count, OP_EQ, 0);
4899 tt_int_op(write_str_count, OP_EQ, 2);
4900 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
4902 /* Third time */
4903 dump_desc(test_desc_1, test_desc_type);
4906 * Assert things about the FIFO state
4908 tt_u64_op(len_descs_dumped, OP_EQ,
4909 strlen(test_desc_1) + strlen(test_desc_2));
4910 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
4913 * Assert things about the mocks
4915 tt_int_op(unlinked_count, OP_EQ, 0);
4916 tt_int_op(write_str_count, OP_EQ, 2);
4917 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
4920 * Reset the FIFO and check its state
4922 dump_desc_fifo_cleanup();
4923 tt_u64_op(len_descs_dumped, OP_EQ, 0);
4924 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
4927 * Reset the mocks and check their state
4929 mock_unlink_reset();
4930 mock_write_str_to_file_reset();
4931 tt_int_op(unlinked_count, OP_EQ, 0);
4932 tt_int_op(write_str_count, OP_EQ, 0);
4935 * (6) (A B B C) triggering overflow on C causes A, not B to be unlinked
4938 /* First time */
4939 dump_desc(test_desc_3, test_desc_type);
4942 * Assert things about the FIFO state
4944 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_3));
4945 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
4948 * Assert things about the mocks
4950 tt_int_op(unlinked_count, OP_EQ, 0);
4951 tt_int_op(write_str_count, OP_EQ, 1);
4952 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
4954 /* Second time */
4955 dump_desc(test_desc_4, test_desc_type);
4958 * Assert things about the FIFO state
4960 tt_u64_op(len_descs_dumped, OP_EQ,
4961 strlen(test_desc_3) + strlen(test_desc_4));
4962 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
4965 * Assert things about the mocks
4967 tt_int_op(unlinked_count, OP_EQ, 0);
4968 tt_int_op(write_str_count, OP_EQ, 2);
4969 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
4971 /* Third time */
4972 dump_desc(test_desc_4, test_desc_type);
4975 * Assert things about the FIFO state
4977 tt_u64_op(len_descs_dumped, OP_EQ,
4978 strlen(test_desc_3) + strlen(test_desc_4));
4979 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
4982 * Assert things about the mocks
4984 tt_int_op(unlinked_count, OP_EQ, 0);
4985 tt_int_op(write_str_count, OP_EQ, 2);
4986 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
4988 /* Fourth time - we should unlink the dump of test_desc_3 here */
4989 dump_desc(test_desc_1, test_desc_type);
4992 * Assert things about the FIFO state
4994 tt_u64_op(len_descs_dumped, OP_EQ,
4995 strlen(test_desc_4) + strlen(test_desc_1));
4996 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
4999 * Assert things about the mocks
5001 tt_int_op(unlinked_count, OP_EQ, 1);
5002 tt_int_op(write_str_count, OP_EQ, 3);
5003 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
5006 * Reset the FIFO and check its state
5008 dump_desc_fifo_cleanup();
5009 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5010 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5013 * Reset the mocks and check their state
5015 mock_unlink_reset();
5016 mock_write_str_to_file_reset();
5017 tt_int_op(unlinked_count, OP_EQ, 0);
5018 tt_int_op(write_str_count, OP_EQ, 0);
5021 * (7) (A B A C) triggering overflow on C causes B, not A to be unlinked
5024 /* First time */
5025 dump_desc(test_desc_2, test_desc_type);
5028 * Assert things about the FIFO state
5030 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_2));
5031 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5034 * Assert things about the mocks
5036 tt_int_op(unlinked_count, OP_EQ, 0);
5037 tt_int_op(write_str_count, OP_EQ, 1);
5038 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
5040 /* Second time */
5041 dump_desc(test_desc_3, test_desc_type);
5044 * Assert things about the FIFO state
5046 tt_u64_op(len_descs_dumped, OP_EQ,
5047 strlen(test_desc_2) + strlen(test_desc_3));
5048 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5051 * Assert things about the mocks
5053 tt_int_op(unlinked_count, OP_EQ, 0);
5054 tt_int_op(write_str_count, OP_EQ, 2);
5055 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
5057 /* Third time */
5058 dump_desc(test_desc_2, test_desc_type);
5061 * Assert things about the FIFO state
5063 tt_u64_op(len_descs_dumped, OP_EQ,
5064 strlen(test_desc_2) + strlen(test_desc_3));
5065 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5068 * Assert things about the mocks
5070 tt_int_op(unlinked_count, OP_EQ, 0);
5071 tt_int_op(write_str_count, OP_EQ, 2);
5072 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
5074 /* Fourth time - we should unlink the dump of test_desc_3 here */
5075 dump_desc(test_desc_4, test_desc_type);
5078 * Assert things about the FIFO state
5080 tt_u64_op(len_descs_dumped, OP_EQ,
5081 strlen(test_desc_2) + strlen(test_desc_4));
5082 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5085 * Assert things about the mocks
5087 tt_int_op(unlinked_count, OP_EQ, 1);
5088 tt_int_op(write_str_count, OP_EQ, 3);
5089 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
5092 * Reset the FIFO and check its state
5094 dump_desc_fifo_cleanup();
5095 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5096 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5099 * Reset the mocks and check their state
5101 mock_unlink_reset();
5102 mock_write_str_to_file_reset();
5103 tt_int_op(unlinked_count, OP_EQ, 0);
5104 tt_int_op(write_str_count, OP_EQ, 0);
5106 done:
5108 /* Clean up the fifo */
5109 dump_desc_fifo_cleanup();
5111 /* Remove mocks */
5112 UNMOCK(tor_unlink);
5113 mock_unlink_reset();
5114 UNMOCK(write_str_to_file);
5115 mock_write_str_to_file_reset();
5116 UNMOCK(options_get_dir_fname2_suffix);
5117 UNMOCK(check_private_dir);
5118 UNMOCK(get_options);
5119 tor_free(mock_options);
5120 mock_options = NULL;
5122 return;
5125 /* Variables for reset_read_file_to_str_mock() */
5127 static int enforce_expected_filename = 0;
5128 static char *expected_filename = NULL;
5129 static char *file_content = NULL;
5130 static size_t file_content_len = 0;
5131 static struct stat file_stat;
5132 static int read_count = 0, read_call_count = 0;
5134 static void
5135 reset_read_file_to_str_mock(void)
5137 tor_free(expected_filename);
5138 tor_free(file_content);
5139 file_content_len = 0;
5140 memset(&file_stat, 0, sizeof(file_stat));
5141 read_count = 0;
5142 read_call_count = 0;
5145 static char *
5146 read_file_to_str_mock(const char *filename, int flags,
5147 struct stat *stat_out) {
5148 char *result = NULL;
5150 /* Insist we got a filename */
5151 tt_ptr_op(filename, OP_NE, NULL);
5153 /* We ignore flags */
5154 (void)flags;
5156 /* Bump the call count */
5157 ++read_call_count;
5159 if (enforce_expected_filename) {
5160 tt_assert(expected_filename);
5161 tt_str_op(filename, OP_EQ, expected_filename);
5164 if (expected_filename != NULL &&
5165 file_content != NULL &&
5166 strcmp(filename, expected_filename) == 0) {
5167 /* You asked for it, you got it */
5170 * This is the same behavior as the real read_file_to_str();
5171 * if there's a NUL, the real size ends up in stat_out.
5173 result = tor_malloc(file_content_len + 1);
5174 if (file_content_len > 0) {
5175 memcpy(result, file_content, file_content_len);
5177 result[file_content_len] = '\0';
5179 /* Do we need to set up stat_out? */
5180 if (stat_out != NULL) {
5181 memcpy(stat_out, &file_stat, sizeof(file_stat));
5182 /* We always return the correct length here */
5183 stat_out->st_size = file_content_len;
5186 /* Wooo, we have a return value - bump the counter */
5187 ++read_count;
5189 /* else no match, return NULL */
5191 done:
5192 return result;
5195 /* This one tests dump_desc_populate_one_file() */
5196 static void
5197 test_dir_populate_dump_desc_fifo(void *data)
5199 const char *dirname = "foo";
5200 const char *fname = NULL;
5201 dumped_desc_t *ent;
5203 (void)data;
5206 * Set up unlink and read_file_to_str mocks
5208 MOCK(tor_unlink, mock_unlink);
5209 mock_unlink_reset();
5210 MOCK(read_file_to_str, read_file_to_str_mock);
5211 reset_read_file_to_str_mock();
5213 /* Check state of unlink mock */
5214 tt_int_op(unlinked_count, OP_EQ, 0);
5216 /* Some cases that should fail before trying to read the file */
5217 ent = dump_desc_populate_one_file(dirname, "bar");
5218 tt_ptr_op(ent, OP_EQ, NULL);
5219 tt_int_op(unlinked_count, OP_EQ, 1);
5220 tt_int_op(read_count, OP_EQ, 0);
5221 tt_int_op(read_call_count, OP_EQ, 0);
5223 ent = dump_desc_populate_one_file(dirname, "unparseable-desc");
5224 tt_ptr_op(ent, OP_EQ, NULL);
5225 tt_int_op(unlinked_count, OP_EQ, 2);
5226 tt_int_op(read_count, OP_EQ, 0);
5227 tt_int_op(read_call_count, OP_EQ, 0);
5229 ent = dump_desc_populate_one_file(dirname, "unparseable-desc.baz");
5230 tt_ptr_op(ent, OP_EQ, NULL);
5231 tt_int_op(unlinked_count, OP_EQ, 3);
5232 tt_int_op(read_count, OP_EQ, 0);
5233 tt_int_op(read_call_count, OP_EQ, 0);
5235 ent = dump_desc_populate_one_file(
5236 dirname,
5237 "unparseable-desc.08AE85E90461F59E");
5238 tt_ptr_op(ent, OP_EQ, NULL);
5239 tt_int_op(unlinked_count, OP_EQ, 4);
5240 tt_int_op(read_count, OP_EQ, 0);
5241 tt_int_op(read_call_count, OP_EQ, 0);
5243 ent = dump_desc_populate_one_file(
5244 dirname,
5245 "unparseable-desc.08AE85E90461F59EDF0981323F3A70D02B55AB54B44B04F"
5246 "287D72F7B72F242E85C8CB0EDA8854A99");
5247 tt_ptr_op(ent, OP_EQ, NULL);
5248 tt_int_op(unlinked_count, OP_EQ, 5);
5249 tt_int_op(read_count, OP_EQ, 0);
5250 tt_int_op(read_call_count, OP_EQ, 0);
5252 /* This is a correct-length digest but base16_decode() will fail */
5253 ent = dump_desc_populate_one_file(
5254 dirname,
5255 "unparseable-desc.68219B8BGE64B705A6FFC728C069DC596216D60A7D7520C"
5256 "D5ECE250D912E686B");
5257 tt_ptr_op(ent, OP_EQ, NULL);
5258 tt_int_op(unlinked_count, OP_EQ, 6);
5259 tt_int_op(read_count, OP_EQ, 0);
5260 tt_int_op(read_call_count, OP_EQ, 0);
5262 /* This one has a correctly formed filename and should try reading */
5264 /* Read fails */
5265 ent = dump_desc_populate_one_file(
5266 dirname,
5267 "unparseable-desc.DF0981323F3A70D02B55AB54B44B04F287D72F7B72F242E"
5268 "85C8CB0EDA8854A99");
5269 tt_ptr_op(ent, OP_EQ, NULL);
5270 tt_int_op(unlinked_count, OP_EQ, 7);
5271 tt_int_op(read_count, OP_EQ, 0);
5272 tt_int_op(read_call_count, OP_EQ, 1);
5274 /* This read will succeed but the digest won't match the file content */
5275 fname =
5276 "unparseable-desc."
5277 "DF0981323F3A70D02B55AB54B44B04F287D72F7B72F242E85C8CB0EDA8854A99";
5278 enforce_expected_filename = 1;
5279 tor_asprintf(&expected_filename, "%s%s%s", dirname, PATH_SEPARATOR, fname);
5280 file_content = tor_strdup("hanc culpam maiorem an illam dicam?");
5281 file_content_len = strlen(file_content);
5282 file_stat.st_mtime = 123456;
5283 ent = dump_desc_populate_one_file(dirname, fname);
5284 enforce_expected_filename = 0;
5285 tt_ptr_op(ent, OP_EQ, NULL);
5286 tt_int_op(unlinked_count, OP_EQ, 8);
5287 tt_int_op(read_count, OP_EQ, 1);
5288 tt_int_op(read_call_count, OP_EQ, 2);
5289 tor_free(expected_filename);
5290 tor_free(file_content);
5292 /* This one will match */
5293 fname =
5294 "unparseable-desc."
5295 "0786C7173447B7FB033FFCA2FC47C3CF71C30DD47CA8236D3FC7FF35853271C6";
5296 tor_asprintf(&expected_filename, "%s%s%s", dirname, PATH_SEPARATOR, fname);
5297 file_content = tor_strdup("hanc culpam maiorem an illam dicam?");
5298 file_content_len = strlen(file_content);
5299 file_stat.st_mtime = 789012;
5300 ent = dump_desc_populate_one_file(dirname, fname);
5301 tt_ptr_op(ent, OP_NE, NULL);
5302 tt_int_op(unlinked_count, OP_EQ, 8);
5303 tt_int_op(read_count, OP_EQ, 2);
5304 tt_int_op(read_call_count, OP_EQ, 3);
5305 tt_str_op(ent->filename, OP_EQ, expected_filename);
5306 tt_int_op(ent->len, OP_EQ, file_content_len);
5307 tt_int_op(ent->when, OP_EQ, file_stat.st_mtime);
5308 tor_free(ent->filename);
5309 tor_free(ent);
5310 tor_free(expected_filename);
5313 * Reset the mocks and check their state
5315 mock_unlink_reset();
5316 tt_int_op(unlinked_count, OP_EQ, 0);
5317 reset_read_file_to_str_mock();
5318 tt_int_op(read_count, OP_EQ, 0);
5320 done:
5322 UNMOCK(tor_unlink);
5323 mock_unlink_reset();
5324 UNMOCK(read_file_to_str);
5325 reset_read_file_to_str_mock();
5327 tor_free(file_content);
5329 return;
5332 static smartlist_t *
5333 listdir_mock(const char *dname)
5335 smartlist_t *l;
5337 /* Ignore the name, always return this list */
5338 (void)dname;
5340 l = smartlist_new();
5341 smartlist_add_strdup(l, "foo");
5342 smartlist_add_strdup(l, "bar");
5343 smartlist_add_strdup(l, "baz");
5345 return l;
5348 static dumped_desc_t *
5349 pop_one_mock(const char *dirname, const char *f)
5351 dumped_desc_t *ent = NULL;
5353 if (dirname != NULL && strcmp(dirname, "d") == 0) {
5354 if (f != NULL && strcmp(f, "foo") == 0) {
5355 ent = tor_malloc_zero(sizeof(*ent));
5356 ent->filename = tor_strdup("d/foo");
5357 ent->len = 123;
5358 ent->digest_sha256[0] = 1;
5359 ent->when = 1024;
5360 } else if (f != NULL && strcmp(f, "bar") == 0) {
5361 ent = tor_malloc_zero(sizeof(*ent));
5362 ent->filename = tor_strdup("d/bar");
5363 ent->len = 456;
5364 ent->digest_sha256[0] = 2;
5366 * Note that the timestamps are in a different order than
5367 * listdir_mock() returns; we're testing the sort order.
5369 ent->when = 512;
5370 } else if (f != NULL && strcmp(f, "baz") == 0) {
5371 ent = tor_malloc_zero(sizeof(*ent));
5372 ent->filename = tor_strdup("d/baz");
5373 ent->len = 789;
5374 ent->digest_sha256[0] = 3;
5375 ent->when = 768;
5379 return ent;
5382 /* This one tests dump_desc_populate_fifo_from_directory() */
5383 static void
5384 test_dir_populate_dump_desc_fifo_2(void *data)
5386 dumped_desc_t *ent = NULL;
5388 (void)data;
5390 /* Set up the mocks */
5391 MOCK(tor_listdir, listdir_mock);
5392 MOCK(dump_desc_populate_one_file, pop_one_mock);
5394 /* Run dump_desc_populate_fifo_from_directory() */
5395 descs_dumped = NULL;
5396 len_descs_dumped = 0;
5397 dump_desc_populate_fifo_from_directory("d");
5398 tt_assert(descs_dumped != NULL);
5399 tt_int_op(smartlist_len(descs_dumped), OP_EQ, 3);
5400 tt_u64_op(len_descs_dumped, OP_EQ, 1368);
5401 ent = smartlist_get(descs_dumped, 0);
5402 tt_str_op(ent->filename, OP_EQ, "d/bar");
5403 tt_int_op(ent->len, OP_EQ, 456);
5404 tt_int_op(ent->when, OP_EQ, 512);
5405 ent = smartlist_get(descs_dumped, 1);
5406 tt_str_op(ent->filename, OP_EQ, "d/baz");
5407 tt_int_op(ent->len, OP_EQ, 789);
5408 tt_int_op(ent->when, OP_EQ, 768);
5409 ent = smartlist_get(descs_dumped, 2);
5410 tt_str_op(ent->filename, OP_EQ, "d/foo");
5411 tt_int_op(ent->len, OP_EQ, 123);
5412 tt_int_op(ent->when, OP_EQ, 1024);
5414 done:
5415 dump_desc_fifo_cleanup();
5417 UNMOCK(dump_desc_populate_one_file);
5418 UNMOCK(tor_listdir);
5420 return;
5423 static int mock_networkstatus_consensus_is_bootstrapping_value = 0;
5424 static int
5425 mock_networkstatus_consensus_is_bootstrapping(time_t now)
5427 (void)now;
5428 return mock_networkstatus_consensus_is_bootstrapping_value;
5431 static int mock_networkstatus_consensus_can_use_extra_fallbacks_value = 0;
5432 static int
5433 mock_networkstatus_consensus_can_use_extra_fallbacks(
5434 const or_options_t *options)
5436 (void)options;
5437 return mock_networkstatus_consensus_can_use_extra_fallbacks_value;
5440 static int mock_num_bridges_usable_value = 0;
5441 static int
5442 mock_num_bridges_usable(int use_maybe_reachable)
5444 (void)use_maybe_reachable;
5445 return mock_num_bridges_usable_value;
5448 /* data is a 3 character nul-terminated string.
5449 * If data[0] is 'b', set bootstrapping, anything else means not bootstrapping
5450 * If data[1] is 'f', set extra fallbacks, anything else means no extra
5451 * If data[2] is 'f', set running bridges, anything else means no extra
5452 * fallbacks.
5454 static void
5455 test_dir_find_dl_schedule(void* data)
5457 const char *str = (const char *)data;
5459 tt_assert(strlen(data) == 3);
5461 if (str[0] == 'b') {
5462 mock_networkstatus_consensus_is_bootstrapping_value = 1;
5463 } else {
5464 mock_networkstatus_consensus_is_bootstrapping_value = 0;
5467 if (str[1] == 'f') {
5468 mock_networkstatus_consensus_can_use_extra_fallbacks_value = 1;
5469 } else {
5470 mock_networkstatus_consensus_can_use_extra_fallbacks_value = 0;
5473 if (str[2] == 'r') {
5474 /* Any positive, non-zero value should work */
5475 mock_num_bridges_usable_value = 2;
5476 } else {
5477 mock_num_bridges_usable_value = 0;
5480 MOCK(networkstatus_consensus_is_bootstrapping,
5481 mock_networkstatus_consensus_is_bootstrapping);
5482 MOCK(networkstatus_consensus_can_use_extra_fallbacks,
5483 mock_networkstatus_consensus_can_use_extra_fallbacks);
5484 MOCK(num_bridges_usable,
5485 mock_num_bridges_usable);
5487 download_status_t dls;
5488 smartlist_t server, client, server_cons, client_cons;
5489 smartlist_t client_boot_auth_only_cons, client_boot_auth_cons;
5490 smartlist_t client_boot_fallback_cons, bridge, bridge_bootstrap;
5492 mock_options = tor_malloc(sizeof(or_options_t));
5493 reset_options(mock_options, &mock_get_options_calls);
5494 MOCK(get_options, mock_get_options);
5496 mock_options->TestingServerDownloadSchedule = &server;
5497 mock_options->TestingClientDownloadSchedule = &client;
5498 mock_options->TestingServerConsensusDownloadSchedule = &server_cons;
5499 mock_options->TestingClientConsensusDownloadSchedule = &client_cons;
5500 mock_options->ClientBootstrapConsensusAuthorityOnlyDownloadSchedule =
5501 &client_boot_auth_only_cons;
5502 mock_options->ClientBootstrapConsensusAuthorityDownloadSchedule =
5503 &client_boot_auth_cons;
5504 mock_options->ClientBootstrapConsensusFallbackDownloadSchedule =
5505 &client_boot_fallback_cons;
5506 mock_options->TestingBridgeDownloadSchedule = &bridge;
5507 mock_options->TestingBridgeBootstrapDownloadSchedule = &bridge_bootstrap;
5509 dls.schedule = DL_SCHED_GENERIC;
5510 /* client */
5511 mock_options->ClientOnly = 1;
5512 tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &client);
5513 mock_options->ClientOnly = 0;
5515 /* dir mode */
5516 mock_options->DirPort_set = 1;
5517 mock_options->DirCache = 1;
5518 tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &server);
5519 mock_options->DirPort_set = 0;
5520 mock_options->DirCache = 0;
5522 dls.schedule = DL_SCHED_CONSENSUS;
5523 /* public server mode */
5524 mock_options->ORPort_set = 1;
5525 tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &server_cons);
5526 mock_options->ORPort_set = 0;
5528 /* client and bridge modes */
5529 if (networkstatus_consensus_is_bootstrapping(time(NULL))) {
5530 if (networkstatus_consensus_can_use_extra_fallbacks(mock_options)) {
5531 dls.want_authority = 1;
5532 /* client */
5533 mock_options->ClientOnly = 1;
5534 tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
5535 &client_boot_auth_cons);
5536 mock_options->ClientOnly = 0;
5538 /* bridge relay */
5539 mock_options->ORPort_set = 1;
5540 mock_options->BridgeRelay = 1;
5541 tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
5542 &client_boot_auth_cons);
5543 mock_options->ORPort_set = 0;
5544 mock_options->BridgeRelay = 0;
5546 dls.want_authority = 0;
5547 /* client */
5548 mock_options->ClientOnly = 1;
5549 tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
5550 &client_boot_fallback_cons);
5551 mock_options->ClientOnly = 0;
5553 /* bridge relay */
5554 mock_options->ORPort_set = 1;
5555 mock_options->BridgeRelay = 1;
5556 tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
5557 &client_boot_fallback_cons);
5558 mock_options->ORPort_set = 0;
5559 mock_options->BridgeRelay = 0;
5561 } else {
5562 /* dls.want_authority is ignored */
5563 /* client */
5564 mock_options->ClientOnly = 1;
5565 tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
5566 &client_boot_auth_only_cons);
5567 mock_options->ClientOnly = 0;
5569 /* bridge relay */
5570 mock_options->ORPort_set = 1;
5571 mock_options->BridgeRelay = 1;
5572 tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
5573 &client_boot_auth_only_cons);
5574 mock_options->ORPort_set = 0;
5575 mock_options->BridgeRelay = 0;
5577 } else {
5578 /* client */
5579 mock_options->ClientOnly = 1;
5580 tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
5581 &client_cons);
5582 mock_options->ClientOnly = 0;
5584 /* bridge relay */
5585 mock_options->ORPort_set = 1;
5586 mock_options->BridgeRelay = 1;
5587 tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
5588 &client_cons);
5589 mock_options->ORPort_set = 0;
5590 mock_options->BridgeRelay = 0;
5593 dls.schedule = DL_SCHED_BRIDGE;
5594 /* client */
5595 mock_options->ClientOnly = 1;
5596 mock_options->UseBridges = 1;
5597 if (num_bridges_usable(0) > 0) {
5598 tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &bridge);
5599 } else {
5600 tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &bridge_bootstrap);
5603 done:
5604 UNMOCK(networkstatus_consensus_is_bootstrapping);
5605 UNMOCK(networkstatus_consensus_can_use_extra_fallbacks);
5606 UNMOCK(num_bridges_usable);
5607 UNMOCK(get_options);
5608 tor_free(mock_options);
5609 mock_options = NULL;
5612 static void
5613 test_dir_assumed_flags(void *arg)
5615 (void)arg;
5616 smartlist_t *tokens = smartlist_new();
5617 memarea_t *area = memarea_new();
5618 routerstatus_t *rs = NULL;
5620 /* We can assume that consensus method is higher than 24, so Running and
5621 * Valid are always implicitly set */
5622 const char *str1 =
5623 "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 "
5624 "192.168.0.1 9001 0\n"
5625 "m thisoneislongerbecauseitisa256bitmddigest33\n"
5626 "s Fast Guard Stable\n";
5628 const char *cp = str1;
5629 rs = routerstatus_parse_entry_from_string(area, &cp, tokens, NULL, NULL,
5630 24, FLAV_MICRODESC);
5631 tt_assert(rs);
5632 tt_assert(rs->is_flagged_running);
5633 tt_assert(rs->is_valid);
5634 tt_assert(! rs->is_exit);
5635 tt_assert(rs->is_fast);
5637 done:
5638 smartlist_free(tokens);
5639 memarea_drop_all(area);
5640 routerstatus_free(rs);
5643 static void
5644 test_dir_post_parsing(void *arg)
5646 (void) arg;
5648 /* Test the version parsing from an HS descriptor publish request. */
5650 const char *end;
5651 const char *prefix = "/tor/hs/";
5652 int version = parse_hs_version_from_post("/tor/hs//publish", prefix, &end);
5653 tt_int_op(version, OP_EQ, -1);
5654 tt_ptr_op(end, OP_EQ, NULL);
5655 version = parse_hs_version_from_post("/tor/hs/a/publish", prefix, &end);
5656 tt_int_op(version, OP_EQ, -1);
5657 tt_ptr_op(end, OP_EQ, NULL);
5658 version = parse_hs_version_from_post("/tor/hs/3/publish", prefix, &end);
5659 tt_int_op(version, OP_EQ, 3);
5660 tt_str_op(end, OP_EQ, "/publish");
5661 version = parse_hs_version_from_post("/tor/hs/42/publish", prefix, &end);
5662 tt_int_op(version, OP_EQ, 42);
5663 tt_str_op(end, OP_EQ, "/publish");
5664 version = parse_hs_version_from_post("/tor/hs/18163/publish",prefix, &end);
5665 tt_int_op(version, OP_EQ, 18163);
5666 tt_str_op(end, OP_EQ, "/publish");
5667 version = parse_hs_version_from_post("JUNKJUNKJUNK", prefix, &end);
5668 tt_int_op(version, OP_EQ, -1);
5669 tt_ptr_op(end, OP_EQ, NULL);
5670 version = parse_hs_version_from_post("/tor/hs/3/publish", "blah", &end);
5671 tt_int_op(version, OP_EQ, -1);
5672 tt_ptr_op(end, OP_EQ, NULL);
5673 /* Missing the '/' at the end of the prefix. */
5674 version = parse_hs_version_from_post("/tor/hs/3/publish", "/tor/hs", &end);
5675 tt_int_op(version, OP_EQ, -1);
5676 tt_ptr_op(end, OP_EQ, NULL);
5677 version = parse_hs_version_from_post("/random/blah/tor/hs/3/publish",
5678 prefix, &end);
5679 tt_int_op(version, OP_EQ, -1);
5680 tt_ptr_op(end, OP_EQ, NULL);
5681 version = parse_hs_version_from_post("/tor/hs/3/publish/random/junk",
5682 prefix, &end);
5683 tt_int_op(version, OP_EQ, 3);
5684 tt_str_op(end, OP_EQ, "/publish/random/junk");
5685 version = parse_hs_version_from_post("/tor/hs/-1/publish", prefix, &end);
5686 tt_int_op(version, OP_EQ, -1);
5687 tt_ptr_op(end, OP_EQ, NULL);
5688 /* INT_MAX */
5689 version = parse_hs_version_from_post("/tor/hs/2147483647/publish",
5690 prefix, &end);
5691 tt_int_op(version, OP_EQ, INT_MAX);
5692 tt_str_op(end, OP_EQ, "/publish");
5693 /* INT_MAX + 1*/
5694 version = parse_hs_version_from_post("/tor/hs/2147483648/publish",
5695 prefix, &end);
5696 tt_int_op(version, OP_EQ, -1);
5697 tt_ptr_op(end, OP_EQ, NULL);
5700 done:
5704 static void
5705 test_dir_platform_str(void *arg)
5707 char platform[256];
5708 (void)arg;
5709 platform[0] = 0;
5710 get_platform_str(platform, sizeof(platform));
5711 tt_int_op((int)strlen(platform), OP_GT, 0);
5712 tt_assert(!strcmpstart(platform, "Tor "));
5714 tor_version_t ver;
5715 // make sure this is a tor version, a real actual tor version.
5716 tt_int_op(tor_version_parse_platform(platform, &ver, 1), OP_EQ, 1);
5718 TT_BLATHER(("%d.%d.%d.%d", ver.major, ver.minor, ver.micro, ver.patchlevel));
5720 // Handle an example version.
5721 tt_int_op(tor_version_parse_platform(
5722 "Tor 0.3.3.3 (foo) (git-xyzzy) on a potato", &ver, 1), OP_EQ, 1);
5723 done:
5727 static networkstatus_t *mock_networkstatus;
5729 static networkstatus_t *
5730 mock_networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
5732 (void)f;
5733 return mock_networkstatus;
5736 static void
5737 test_dir_networkstatus_consensus_has_ipv6(void *arg)
5739 (void)arg;
5741 int has_ipv6 = 0;
5743 /* Init options and networkstatus */
5744 or_options_t our_options;
5745 mock_options = &our_options;
5746 reset_options(mock_options, &mock_get_options_calls);
5747 MOCK(get_options, mock_get_options);
5749 networkstatus_t our_networkstatus;
5750 mock_networkstatus = &our_networkstatus;
5751 memset(mock_networkstatus, 0, sizeof(*mock_networkstatus));
5752 MOCK(networkstatus_get_latest_consensus_by_flavor,
5753 mock_networkstatus_get_latest_consensus_by_flavor);
5755 /* A live consensus */
5756 mock_networkstatus->valid_after = time(NULL) - 3600;
5757 mock_networkstatus->valid_until = time(NULL) + 3600;
5759 /* Test the bounds for A lines in the NS consensus */
5760 mock_options->UseMicrodescriptors = 0;
5762 mock_networkstatus->consensus_method = MIN_SUPPORTED_CONSENSUS_METHOD;
5763 has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
5764 tt_assert(has_ipv6);
5766 /* Test the bounds for A lines in the microdesc consensus */
5767 mock_options->UseMicrodescriptors = 1;
5769 mock_networkstatus->consensus_method =
5770 MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS;
5771 has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
5772 tt_assert(has_ipv6);
5774 mock_networkstatus->consensus_method = MAX_SUPPORTED_CONSENSUS_METHOD + 20;
5775 has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
5776 tt_assert(has_ipv6);
5778 mock_networkstatus->consensus_method =
5779 MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS + 1;
5780 has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
5781 tt_assert(has_ipv6);
5783 mock_networkstatus->consensus_method =
5784 MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS + 20;
5785 has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
5786 tt_assert(has_ipv6);
5788 mock_networkstatus->consensus_method =
5789 MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS - 1;
5790 has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
5791 tt_assert(!has_ipv6);
5793 /* Test the edge cases */
5794 mock_options->UseMicrodescriptors = 1;
5795 mock_networkstatus->consensus_method =
5796 MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS;
5798 /* Reasonably live */
5799 mock_networkstatus->valid_until = approx_time() - 60;
5800 has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
5801 tt_assert(has_ipv6);
5803 /* Not reasonably live */
5804 mock_networkstatus->valid_after = approx_time() - 24*60*60 - 3600;
5805 mock_networkstatus->valid_until = approx_time() - 24*60*60 - 60;
5806 has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
5807 tt_assert(!has_ipv6);
5809 /* NULL consensus */
5810 mock_networkstatus = NULL;
5811 has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
5812 tt_assert(!has_ipv6);
5814 done:
5815 UNMOCK(get_options);
5816 UNMOCK(networkstatus_get_latest_consensus_by_flavor);
5819 #define DIR_LEGACY(name) \
5820 { #name, test_dir_ ## name , TT_FORK, NULL, NULL }
5822 #define DIR(name,flags) \
5823 { #name, test_dir_##name, (flags), NULL, NULL }
5825 /* where arg is a string constant */
5826 #define DIR_ARG(name,flags,arg) \
5827 { #name "_" arg, test_dir_##name, (flags), &passthrough_setup, (void*) arg }
5829 struct testcase_t dir_tests[] = {
5830 DIR_LEGACY(nicknames),
5831 DIR_LEGACY(formats),
5832 DIR(routerinfo_parsing, 0),
5833 DIR(extrainfo_parsing, 0),
5834 DIR(parse_router_list, TT_FORK),
5835 DIR(load_routers, TT_FORK),
5836 DIR(load_extrainfo, TT_FORK),
5837 DIR(getinfo_extra, 0),
5838 DIR_LEGACY(versions),
5839 DIR_LEGACY(fp_pairs),
5840 DIR(split_fps, 0),
5841 DIR_LEGACY(measured_bw_kb),
5842 DIR_LEGACY(measured_bw_kb_cache),
5843 DIR_LEGACY(param_voting),
5844 DIR(param_voting_lookup, 0),
5845 DIR_LEGACY(v3_networkstatus),
5846 DIR(random_weighted, 0),
5847 DIR(scale_bw, 0),
5848 DIR_LEGACY(clip_unmeasured_bw_kb),
5849 DIR_LEGACY(clip_unmeasured_bw_kb_alt),
5850 DIR(fmt_control_ns, 0),
5851 DIR(dirserv_set_routerstatus_testing, 0),
5852 DIR(http_handling, 0),
5853 DIR(purpose_needs_anonymity_returns_true_for_bridges, 0),
5854 DIR(purpose_needs_anonymity_returns_false_for_own_bridge_desc, 0),
5855 DIR(purpose_needs_anonymity_returns_true_by_default, 0),
5856 DIR(purpose_needs_anonymity_returns_true_for_sensitive_purpose, 0),
5857 DIR(purpose_needs_anonymity_ret_false_for_non_sensitive_conn, 0),
5858 DIR(post_parsing, 0),
5859 DIR(fetch_type, 0),
5860 DIR(packages, 0),
5861 DIR(download_status_random_backoff, 0),
5862 DIR(download_status_random_backoff_ranges, 0),
5863 DIR(download_status_increment, TT_FORK),
5864 DIR(authdir_type_to_string, 0),
5865 DIR(conn_purpose_to_string, 0),
5866 DIR(should_use_directory_guards, 0),
5867 DIR(should_not_init_request_to_ourselves, TT_FORK),
5868 DIR(should_not_init_request_to_dir_auths_without_v3_info, 0),
5869 DIR(should_init_request_to_dir_auths, 0),
5870 DIR(choose_compression_level, 0),
5871 DIR(dump_unparseable_descriptors, 0),
5872 DIR(populate_dump_desc_fifo, 0),
5873 DIR(populate_dump_desc_fifo_2, 0),
5874 DIR_ARG(find_dl_schedule, TT_FORK, "bfd"),
5875 DIR_ARG(find_dl_schedule, TT_FORK, "bad"),
5876 DIR_ARG(find_dl_schedule, TT_FORK, "cfd"),
5877 DIR_ARG(find_dl_schedule, TT_FORK, "cad"),
5878 DIR_ARG(find_dl_schedule, TT_FORK, "bfr"),
5879 DIR_ARG(find_dl_schedule, TT_FORK, "bar"),
5880 DIR_ARG(find_dl_schedule, TT_FORK, "cfr"),
5881 DIR_ARG(find_dl_schedule, TT_FORK, "car"),
5882 DIR(assumed_flags, 0),
5883 DIR(networkstatus_compute_bw_weights_v10, 0),
5884 DIR(platform_str, 0),
5885 DIR(networkstatus_consensus_has_ipv6, TT_FORK),
5886 END_OF_TESTCASES