Merge branch 'tap-out-phase-1' into 'main'
[tor.git] / src / test / test_dir.c
blobb34711dcad210a9b3d2721c77bf466f778f43dc5
1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 #include "orconfig.h"
7 #include <math.h>
9 #define BWAUTH_PRIVATE
10 #define CONFIG_PRIVATE
11 #define CONTROL_GETINFO_PRIVATE
12 #define DIRAUTH_SYS_PRIVATE
13 #define DIRCACHE_PRIVATE
14 #define DIRCLIENT_PRIVATE
15 #define DIRVOTE_PRIVATE
16 #define DLSTATUS_PRIVATE
17 #define HIBERNATE_PRIVATE
18 #define NETWORKSTATUS_PRIVATE
19 #define NS_PARSE_PRIVATE
20 #define NODE_SELECT_PRIVATE
21 #define RELAY_PRIVATE
22 #define ROUTERLIST_PRIVATE
23 #define ROUTER_PRIVATE
24 #define UNPARSEABLE_PRIVATE
25 #define VOTEFLAGS_PRIVATE
27 #include "core/or/or.h"
28 #include "app/config/config.h"
29 #include "lib/confmgt/confmgt.h"
30 #include "core/mainloop/connection.h"
31 #include "core/or/relay.h"
32 #include "core/or/protover.h"
33 #include "core/or/versions.h"
34 #include "feature/client/bridges.h"
35 #include "feature/client/entrynodes.h"
36 #include "feature/control/control_getinfo.h"
37 #include "feature/dirauth/bwauth.h"
38 #include "feature/dirauth/dirauth_sys.h"
39 #include "feature/dirauth/dirvote.h"
40 #include "feature/dirauth/dsigs_parse.h"
41 #include "feature/dirauth/process_descs.h"
42 #include "feature/dirauth/recommend_pkg.h"
43 #include "feature/dirauth/shared_random_state.h"
44 #include "feature/dirauth/voteflags.h"
45 #include "feature/dircache/dircache.h"
46 #include "feature/dircache/dirserv.h"
47 #include "feature/dirclient/dirclient.h"
48 #include "feature/dirclient/dlstatus.h"
49 #include "feature/dircommon/directory.h"
50 #include "feature/dircommon/fp_pair.h"
51 #include "feature/dirauth/voting_schedule.h"
52 #include "feature/hibernate/hibernate.h"
53 #include "feature/nodelist/authcert.h"
54 #include "feature/nodelist/dirlist.h"
55 #include "feature/nodelist/microdesc.h"
56 #include "feature/nodelist/networkstatus.h"
57 #include "feature/nodelist/nickname.h"
58 #include "feature/nodelist/node_select.h"
59 #include "feature/nodelist/routerlist.h"
60 #include "feature/dirparse/authcert_parse.h"
61 #include "feature/dirparse/ns_parse.h"
62 #include "feature/dirparse/routerparse.h"
63 #include "feature/dirparse/unparseable.h"
64 #include "feature/nodelist/routerset.h"
65 #include "feature/nodelist/torcert.h"
66 #include "feature/relay/router.h"
67 #include "feature/relay/routerkeys.h"
68 #include "feature/relay/routermode.h"
69 #include "lib/compress/compress.h"
70 #include "lib/crypt_ops/crypto_ed25519.h"
71 #include "lib/crypt_ops/crypto_format.h"
72 #include "lib/crypt_ops/crypto_rand.h"
73 #include "lib/encoding/confline.h"
74 #include "lib/memarea/memarea.h"
75 #include "lib/osinfo/uname.h"
76 #include "test/log_test_helpers.h"
77 #include "test/opts_test_helpers.h"
78 #include "test/test.h"
79 #include "test/test_dir_common.h"
81 #include "core/or/addr_policy_st.h"
82 #include "feature/dirauth/dirauth_options_st.h"
83 #include "feature/nodelist/authority_cert_st.h"
84 #include "feature/nodelist/document_signature_st.h"
85 #include "feature/nodelist/extrainfo_st.h"
86 #include "feature/nodelist/microdesc_st.h"
87 #include "feature/nodelist/networkstatus_st.h"
88 #include "feature/nodelist/networkstatus_voter_info_st.h"
89 #include "feature/dirauth/ns_detached_signatures_st.h"
90 #include "core/or/port_cfg_st.h"
91 #include "feature/nodelist/routerinfo_st.h"
92 #include "feature/nodelist/routerlist_st.h"
93 #include "core/or/tor_version_st.h"
94 #include "feature/dirauth/vote_microdesc_hash_st.h"
95 #include "feature/nodelist/vote_routerstatus_st.h"
97 #ifdef HAVE_SYS_STAT_H
98 #include <sys/stat.h>
99 #endif
100 #ifdef HAVE_UNISTD_H
101 #include <unistd.h>
102 #endif
104 static void setup_ei_digests(void);
105 static uint8_t digest_ei_minimal[20];
106 static uint8_t digest_ei_bad_nickname[20];
107 static uint8_t digest_ei_maximal[20];
108 static uint8_t digest_ei_bad_tokens[20];
109 static uint8_t digest_ei_bad_sig2[20];
110 static uint8_t digest_ei_bad_published[20];
112 static networkstatus_t *
113 networkstatus_parse_vote_from_string_(const char *s,
114 const char **eos_out,
115 enum networkstatus_type_t ns_type)
117 size_t len = strlen(s);
118 // memdup so that it won't be nul-terminated.
119 char *tmp = tor_memdup(s, len);
120 networkstatus_t *result =
121 networkstatus_parse_vote_from_string(tmp, len, eos_out, ns_type);
122 if (eos_out && *eos_out) {
123 *eos_out = s + (*eos_out - tmp);
125 tor_free(tmp);
126 return result;
129 static void
130 test_dir_nicknames(void *arg)
132 (void)arg;
133 tt_assert( is_legal_nickname("a"));
134 tt_assert(!is_legal_nickname(""));
135 tt_assert(!is_legal_nickname("abcdefghijklmnopqrst")); /* 20 chars */
136 tt_assert(!is_legal_nickname("hyphen-")); /* bad char */
137 tt_assert( is_legal_nickname("abcdefghijklmnopqrs")); /* 19 chars */
138 tt_assert(!is_legal_nickname("$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
139 /* valid */
140 tt_assert( is_legal_nickname_or_hexdigest(
141 "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
142 tt_assert( is_legal_nickname_or_hexdigest(
143 "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
144 tt_assert( is_legal_nickname_or_hexdigest(
145 "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA~fred"));
146 /* too short */
147 tt_assert(!is_legal_nickname_or_hexdigest(
148 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
149 /* illegal char */
150 tt_assert(!is_legal_nickname_or_hexdigest(
151 "$AAAAAAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
152 /* hex part too long */
153 tt_assert(!is_legal_nickname_or_hexdigest(
154 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
155 tt_assert(!is_legal_nickname_or_hexdigest(
156 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
157 /* Bad nickname */
158 tt_assert(!is_legal_nickname_or_hexdigest(
159 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="));
160 tt_assert(!is_legal_nickname_or_hexdigest(
161 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"));
162 tt_assert(!is_legal_nickname_or_hexdigest(
163 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~hyphen-"));
164 tt_assert(!is_legal_nickname_or_hexdigest(
165 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"
166 "abcdefghijklmnoppqrst"));
167 /* Bad extra char. */
168 tt_assert(!is_legal_nickname_or_hexdigest(
169 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!"));
170 tt_assert(is_legal_nickname_or_hexdigest("xyzzy"));
171 tt_assert(is_legal_nickname_or_hexdigest("abcdefghijklmnopqrs"));
172 tt_assert(!is_legal_nickname_or_hexdigest("abcdefghijklmnopqrst"));
173 done:
177 /* Allocate and return a new routerinfo, with the fields set from the
178 * arguments to this function.
180 * Also sets:
181 * - random RSA identity and onion keys,
182 * - the platform field using get_platform_str(), and
183 * - supports_tunnelled_dir_requests to 1.
185 * If rsa_onion_keypair_out is not NULL, it is set to the onion keypair.
186 * The caller must free this keypair.
188 static routerinfo_t *
189 basic_routerinfo_new(const char *nickname, uint32_t ipv4_addr,
190 uint16_t or_port, uint16_t dir_port,
191 uint32_t bandwidthrate, uint32_t bandwidthburst,
192 uint32_t bandwidthcapacity,
193 time_t published_on,
194 crypto_pk_t **rsa_onion_keypair_out)
196 char platform[256];
198 tor_assert(nickname);
200 crypto_pk_t *pk1 = NULL, *pk2 = NULL;
201 /* These keys are random: idx is ignored. */
202 pk1 = pk_generate(0);
203 pk2 = pk_generate(1);
205 tor_assert(pk1);
206 tor_assert(pk2);
208 get_platform_str(platform, sizeof(platform));
210 routerinfo_t *r1 = tor_malloc_zero(sizeof(routerinfo_t));
212 r1->nickname = tor_strdup(nickname);
213 r1->platform = tor_strdup(platform);
215 tor_addr_from_ipv4h(&r1->ipv4_addr, ipv4_addr);
216 r1->ipv4_orport = or_port;
217 r1->ipv4_dirport = dir_port;
218 r1->supports_tunnelled_dir_requests = 1;
220 router_set_rsa_onion_pkey(pk1, &r1->tap_onion_pkey, &r1->tap_onion_pkey_len);
221 r1->identity_pkey = pk2;
223 r1->bandwidthrate = bandwidthrate;
224 r1->bandwidthburst = bandwidthburst;
225 r1->bandwidthcapacity = bandwidthcapacity;
227 r1->cache_info.published_on = published_on;
228 r1->protocol_list = tor_strdup(protover_get_supported_protocols());
230 if (rsa_onion_keypair_out) {
231 *rsa_onion_keypair_out = pk1;
232 } else {
233 crypto_pk_free(pk1);
236 return r1;
239 /* Allocate and return a new string containing a "router" line for r1. */
240 static char *
241 get_new_router_line(const routerinfo_t *r1)
243 char *line = NULL;
245 tor_assert(r1);
247 tor_asprintf(&line,
248 "router %s %s %d 0 %d\n",
249 r1->nickname, fmt_addr(&r1->ipv4_addr),
250 r1->ipv4_orport, r1->ipv4_dirport);
251 tor_assert(line);
253 return line;
256 /* Allocate and return a new string containing a "platform" line for the
257 * current Tor version and OS. */
258 static char *
259 get_new_platform_line(void)
261 char *line = NULL;
263 tor_asprintf(&line,
264 "platform Tor %s on %s\n",
265 VERSION, get_uname());
266 tor_assert(line);
268 return line;
271 /* Allocate and return a new string containing a "published" line for r1.
272 * r1->cache_info.published_on must be between 0 and 59 seconds. */
273 static char *
274 get_new_published_line(const routerinfo_t *r1)
276 char *line = NULL;
278 tor_assert(r1);
280 tor_assert(r1->cache_info.published_on >= 0);
281 tor_assert(r1->cache_info.published_on <= 59);
283 tor_asprintf(&line,
284 "published 1970-01-01 00:00:%02u\n",
285 (unsigned)r1->cache_info.published_on);
286 tor_assert(line);
288 return line;
291 /* Allocate and return a new string containing a "fingerprint" line for r1. */
292 static char *
293 get_new_fingerprint_line(const routerinfo_t *r1)
295 char *line = NULL;
296 char fingerprint[FINGERPRINT_LEN+1];
298 tor_assert(r1);
300 tor_assert(!crypto_pk_get_fingerprint(r1->identity_pkey, fingerprint, 1));
301 tor_assert(strlen(fingerprint) > 0);
303 tor_asprintf(&line,
304 "fingerprint %s\n",
305 fingerprint);
306 tor_assert(line);
308 return line;
311 /* Allocate and return a new string containing an "uptime" line with uptime t.
313 * You should pass a hard-coded value to this function, because even if we made
314 * it reflect uptime, that still wouldn't make it right, because the two
315 * descriptors might be made on different seconds.
317 static char *
318 get_new_uptime_line(time_t t)
320 char *line = NULL;
322 tor_asprintf(&line,
323 "uptime %u\n",
324 (unsigned)t);
325 tor_assert(line);
327 return line;
330 /* Allocate and return a new string containing an "bandwidth" line for r1.
332 static char *
333 get_new_bandwidth_line(const routerinfo_t *r1)
335 char *line = NULL;
337 tor_assert(r1);
339 tor_asprintf(&line,
340 "bandwidth %u %u %u\n",
341 r1->bandwidthrate,
342 r1->bandwidthburst,
343 r1->bandwidthcapacity);
344 tor_assert(line);
346 return line;
349 /* Allocate and return a new string containing a key_name block for the
350 * RSA key pk1.
352 static char *
353 get_new_rsa_key_block(const char *key_name, crypto_pk_t *pk1)
355 char *block = NULL;
356 char *pk1_str = NULL;
357 size_t pk1_str_len = 0;
359 tor_assert(key_name);
360 tor_assert(pk1);
362 tor_assert(!crypto_pk_write_public_key_to_string(pk1, &pk1_str,
363 &pk1_str_len));
364 tor_assert(pk1_str);
365 tor_assert(pk1_str_len);
367 tor_asprintf(&block,
368 "%s\n%s",
369 key_name,
370 pk1_str);
371 tor_free(pk1_str);
373 tor_assert(block);
374 return block;
377 /* Allocate and return a new string containing an "onion-key" block for the
378 * router r1.
380 static char *
381 get_new_onion_key_block(const routerinfo_t *r1)
383 char *block = NULL;
384 tor_assert(r1);
385 crypto_pk_t *pk_tmp = router_get_rsa_onion_pkey(r1->tap_onion_pkey,
386 r1->tap_onion_pkey_len);
387 block = get_new_rsa_key_block("onion-key", pk_tmp);
388 crypto_pk_free(pk_tmp);
389 return block;
392 /* Allocate and return a new string containing an "signing-key" block for the
393 * router r1.
395 static char *
396 get_new_signing_key_block(const routerinfo_t *r1)
398 tor_assert(r1);
399 return get_new_rsa_key_block("signing-key", r1->identity_pkey);
402 /* Allocate and return a new string containing an "ntor-onion-key" line for
403 * the curve25519 public key ntor_onion_pubkey.
405 static char *
406 get_new_ntor_onion_key_line(const curve25519_public_key_t *ntor_onion_pubkey)
408 char *line = NULL;
409 char cert_buf[256];
411 tor_assert(ntor_onion_pubkey);
413 curve25519_public_to_base64(cert_buf, ntor_onion_pubkey, false);
414 tor_assert(strlen(cert_buf) > 0);
416 tor_asprintf(&line,
417 "ntor-onion-key %s\n",
418 cert_buf);
419 tor_assert(line);
421 return line;
424 /* Allocate and return a new string containing a "bridge-distribution-request"
425 * line for options.
427 static char *
428 get_new_bridge_distribution_request_line(const or_options_t *options)
430 if (options->BridgeRelay) {
431 return tor_strdup("bridge-distribution-request any\n");
432 } else {
433 return tor_strdup("");
437 static smartlist_t *mocked_configured_ports = NULL;
439 /** Returns mocked_configured_ports */
440 static const smartlist_t *
441 mock_get_configured_ports(void)
443 return mocked_configured_ports;
446 static crypto_pk_t *mocked_server_identitykey = NULL;
448 /* Returns mocked_server_identitykey with no checks. */
449 static crypto_pk_t *
450 mock_get_server_identity_key(void)
452 return mocked_server_identitykey;
455 static crypto_pk_t *mocked_onionkey = NULL;
457 /* Returns mocked_onionkey with no checks. */
458 static crypto_pk_t *
459 mock_get_onion_key(void)
461 return mocked_onionkey;
464 static routerinfo_t *mocked_routerinfo = NULL;
466 /* Returns 0 and sets ri_out to mocked_routerinfo.
467 * ri_out must not be NULL. There are no other checks. */
468 static int
469 mock_router_build_fresh_unsigned_routerinfo(routerinfo_t **ri_out)
471 tor_assert(ri_out);
472 *ri_out = mocked_routerinfo;
473 return 0;
476 static ed25519_keypair_t *mocked_master_signing_key = NULL;
478 /* Returns mocked_master_signing_key with no checks. */
479 static const ed25519_keypair_t *
480 mock_get_master_signing_keypair(void)
482 return mocked_master_signing_key;
485 static struct tor_cert_st *mocked_signing_key_cert = NULL;
487 /* Returns mocked_signing_key_cert with no checks. */
488 static const struct tor_cert_st *
489 mock_get_master_signing_key_cert(void)
491 return mocked_signing_key_cert;
494 static curve25519_keypair_t *mocked_curve25519_onion_key = NULL;
496 /* Returns mocked_curve25519_onion_key with no checks. */
497 static const curve25519_keypair_t *
498 mock_get_current_curve25519_keypair(void)
500 return mocked_curve25519_onion_key;
503 /* Unmock get_configured_ports() and free mocked_configured_ports. */
504 static void
505 cleanup_mock_configured_ports(void)
507 UNMOCK(get_configured_ports);
509 if (mocked_configured_ports) {
510 SMARTLIST_FOREACH(mocked_configured_ports, port_cfg_t *, p, tor_free(p));
511 smartlist_free(mocked_configured_ports);
515 /* Mock get_configured_ports() with a list containing or_port and dir_port.
516 * If a port is 0, don't set it.
517 * Only sets the minimal data required for the tests to pass. */
518 static void
519 setup_mock_configured_ports(uint16_t or_port, uint16_t dir_port)
521 cleanup_mock_configured_ports();
523 /* Fake just enough of an ORPort and DirPort to get by */
524 MOCK(get_configured_ports, mock_get_configured_ports);
525 mocked_configured_ports = smartlist_new();
527 if (or_port) {
528 port_cfg_t *or_port_cfg = tor_malloc_zero(sizeof(*or_port_cfg));
529 or_port_cfg->type = CONN_TYPE_OR_LISTENER;
530 or_port_cfg->addr.family = AF_INET;
531 or_port_cfg->port = or_port;
532 smartlist_add(mocked_configured_ports, or_port_cfg);
535 if (dir_port) {
536 port_cfg_t *dir_port_cfg = tor_malloc_zero(sizeof(*dir_port_cfg));
537 dir_port_cfg->type = CONN_TYPE_DIR_LISTENER;
538 dir_port_cfg->addr.family = AF_INET;
539 dir_port_cfg->port = dir_port;
540 smartlist_add(mocked_configured_ports, dir_port_cfg);
544 /* Clean up the data structures and unmock the functions needed for generating
545 * a fresh descriptor. */
546 static void
547 cleanup_mocks_for_fresh_descriptor(void)
549 tor_free(get_options_mutable()->Nickname);
551 mocked_server_identitykey = NULL;
552 UNMOCK(get_server_identity_key);
554 crypto_pk_free(mocked_onionkey);
555 UNMOCK(get_onion_key);
558 /* Mock the data structures and functions needed for generating a fresh
559 * descriptor.
561 * Sets options->Nickname from r1->nickname.
562 * Mocks get_server_identity_key() with r1->identity_pkey.
564 * If rsa_onion_keypair is not NULL, it is used to mock get_onion_key().
565 * Otherwise, the public key in r1->onion_pkey is used to mock get_onion_key().
567 static void
568 setup_mocks_for_fresh_descriptor(const routerinfo_t *r1,
569 crypto_pk_t *rsa_onion_keypair)
571 cleanup_mocks_for_fresh_descriptor();
573 tor_assert(r1);
575 /* router_build_fresh_signed_extrainfo() requires options->Nickname */
576 get_options_mutable()->Nickname = tor_strdup(r1->nickname);
578 /* router_build_fresh_signed_extrainfo() requires get_server_identity_key().
579 * Use the same one as the call to router_dump_router_to_string() above.
581 mocked_server_identitykey = r1->identity_pkey;
582 MOCK(get_server_identity_key, mock_get_server_identity_key);
584 /* router_dump_and_sign_routerinfo_descriptor_body() requires
585 * get_onion_key(). Use the same one as r1.
587 if (rsa_onion_keypair) {
588 mocked_onionkey = crypto_pk_dup_key(rsa_onion_keypair);
589 } else {
590 mocked_onionkey = router_get_rsa_onion_pkey(r1->tap_onion_pkey,
591 r1->tap_onion_pkey_len);
593 MOCK(get_onion_key, mock_get_onion_key);
596 /* Set options based on arg.
598 * b: BridgeRelay 1
599 * e: ExtraInfoStatistics 1
600 * s: sets all the individual statistics options to 1
602 * Always sets AssumeReachable to 1.
604 * Does not set ServerTransportPlugin, because it's parsed before use.
606 * Does not set BridgeRecordUsageByCountry, because the tests don't have access
607 * to a GeoIPFile or GeoIPv6File. */
608 static void
609 setup_dir_formats_options(const char *arg, or_options_t *options)
611 /* Skip reachability checks for DirPort, ORPort, and tunnelled-dir-server */
612 options->AssumeReachable = 1;
614 if (strchr(arg, 'b')) {
615 options->BridgeRelay = 1;
618 if (strchr(arg, 'e')) {
619 options->ExtraInfoStatistics = 1;
622 if (strchr(arg, 's')) {
623 options->DirReqStatistics = 1;
624 options->HiddenServiceStatistics = 1;
625 options->EntryStatistics = 1;
626 options->CellStatistics = 1;
627 options->ExitPortStatistics = 1;
628 options->ConnDirectionStatistics = 1;
629 options->PaddingStatistics = 1;
633 /* Check that routerinfos r1 and rp1 are consistent.
634 * Only performs some basic checks.
636 #define CHECK_ROUTERINFO_CONSISTENCY(r1, rp1) \
637 STMT_BEGIN \
638 tt_assert(r1); \
639 tt_assert(rp1); \
640 tt_assert(tor_addr_eq(&rp1->ipv4_addr, &r1->ipv4_addr)); \
641 tt_int_op(rp1->ipv4_orport,OP_EQ, r1->ipv4_orport); \
642 tt_int_op(rp1->ipv4_dirport,OP_EQ, r1->ipv4_dirport); \
643 tt_int_op(rp1->bandwidthrate,OP_EQ, r1->bandwidthrate); \
644 tt_int_op(rp1->bandwidthburst,OP_EQ, r1->bandwidthburst); \
645 tt_int_op(rp1->bandwidthcapacity,OP_EQ, r1->bandwidthcapacity); \
646 crypto_pk_t *rp1_onion_pkey = router_get_rsa_onion_pkey( \
647 rp1->tap_onion_pkey, \
648 rp1->tap_onion_pkey_len); \
649 crypto_pk_t *r1_onion_pkey = router_get_rsa_onion_pkey( \
650 r1->tap_onion_pkey, \
651 r1->tap_onion_pkey_len); \
652 tt_int_op(crypto_pk_cmp_keys(rp1_onion_pkey, r1_onion_pkey), OP_EQ, 0); \
653 crypto_pk_free(rp1_onion_pkey); \
654 crypto_pk_free(r1_onion_pkey); \
655 tt_int_op(crypto_pk_cmp_keys(rp1->identity_pkey, r1->identity_pkey), \
656 OP_EQ, 0); \
657 tt_int_op(rp1->supports_tunnelled_dir_requests, OP_EQ, \
658 r1->supports_tunnelled_dir_requests); \
659 STMT_END
661 /* Check that routerinfo r1 and extrainfo e1 are consistent.
662 * Only performs some basic checks.
664 #define CHECK_EXTRAINFO_CONSISTENCY(r1, e1) \
665 STMT_BEGIN \
666 tt_assert(r1); \
667 tt_assert(e1); \
669 tt_str_op(e1->nickname, OP_EQ, r1->nickname); \
670 STMT_END
672 /* Check that the exit policy in rp2 is as expected. */
673 #define CHECK_PARSED_EXIT_POLICY(rp2) \
674 STMT_BEGIN \
675 tt_int_op(smartlist_len(rp2->exit_policy),OP_EQ, 2); \
677 p = smartlist_get(rp2->exit_policy, 0); \
678 tt_int_op(p->policy_type,OP_EQ, ADDR_POLICY_ACCEPT); \
679 tt_assert(tor_addr_is_null(&p->addr)); \
680 tt_int_op(p->maskbits,OP_EQ, 0); \
681 tt_int_op(p->prt_min,OP_EQ, 80); \
682 tt_int_op(p->prt_max,OP_EQ, 80); \
684 p = smartlist_get(rp2->exit_policy, 1); \
685 tt_int_op(p->policy_type,OP_EQ, ADDR_POLICY_REJECT); \
686 tt_assert(tor_addr_eq(&p->addr, &ex2->addr)); \
687 tt_int_op(p->maskbits,OP_EQ, 8); \
688 tt_int_op(p->prt_min,OP_EQ, 24); \
689 tt_int_op(p->prt_max,OP_EQ, 24); \
690 STMT_END
692 /** Run unit tests for router descriptor generation logic for a RSA + ed25519
693 * router.
695 static void
696 test_dir_formats_rsa_ed25519(void *arg)
698 char *buf = NULL;
699 char *buf2 = NULL;
700 char *cp = NULL;
702 crypto_pk_t *r2_onion_pkey = NULL;
703 char cert_buf[256];
704 uint8_t *rsa_cc = NULL;
705 time_t now = time(NULL);
707 routerinfo_t *r2 = NULL;
708 extrainfo_t *e2 = NULL;
709 routerinfo_t *r2_out = NULL;
710 routerinfo_t *rp2 = NULL;
711 extrainfo_t *ep2 = NULL;
712 addr_policy_t *ex1, *ex2;
713 const addr_policy_t *p;
715 smartlist_t *chunks = NULL;
716 int rv = -1;
718 or_options_t *options = get_options_mutable();
719 setup_dir_formats_options((const char *)arg, options);
721 hibernate_set_state_for_testing_(HIBERNATE_STATE_LIVE);
723 /* r2 is a RSA + ed25519 descriptor, with an exit policy, but no DirPort or
724 * IPv6 */
725 r2 = basic_routerinfo_new("Fred", 0x0a030201u /* 10.3.2.1 */,
726 9005, 0,
727 3000, 3000, 3000,
729 &r2_onion_pkey);
731 /* Fake just enough of an ntor key to get by */
732 curve25519_keypair_t r2_onion_keypair;
733 curve25519_keypair_generate(&r2_onion_keypair, 0);
734 r2->onion_curve25519_pkey = tor_memdup(&r2_onion_keypair.pubkey,
735 sizeof(curve25519_public_key_t));
737 /* Now add relay ed25519 keys
738 * We can't use init_mock_ed_keys() here, because the keys are seeded */
739 ed25519_keypair_t kp1, kp2;
740 ed25519_secret_key_from_seed(&kp1.seckey,
741 (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
742 ed25519_public_key_generate(&kp1.pubkey, &kp1.seckey);
743 ed25519_secret_key_from_seed(&kp2.seckey,
744 (const uint8_t*)"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
745 ed25519_public_key_generate(&kp2.pubkey, &kp2.seckey);
746 r2->cache_info.signing_key_cert = tor_cert_create_ed25519(&kp1,
747 CERT_TYPE_ID_SIGNING,
748 &kp2.pubkey,
749 now, 86400,
750 CERT_FLAG_INCLUDE_SIGNING_KEY);
752 /* Now add an exit policy */
753 ex1 = tor_malloc_zero(sizeof(addr_policy_t));
754 ex2 = tor_malloc_zero(sizeof(addr_policy_t));
755 ex1->policy_type = ADDR_POLICY_ACCEPT;
756 tor_addr_from_ipv4h(&ex1->addr, 0);
757 ex1->maskbits = 0;
758 ex1->prt_min = ex1->prt_max = 80;
759 ex2->policy_type = ADDR_POLICY_REJECT;
760 tor_addr_from_ipv4h(&ex2->addr, 18<<24);
761 ex2->maskbits = 8;
762 ex2->prt_min = ex2->prt_max = 24;
764 r2->exit_policy = smartlist_new();
765 smartlist_add(r2->exit_policy, ex1);
766 smartlist_add(r2->exit_policy, ex2);
768 /* Fake just enough of an ORPort to get by */
769 setup_mock_configured_ports(r2->ipv4_orport, 0);
771 buf = router_dump_router_to_string(r2,
772 r2->identity_pkey, r2_onion_pkey,
773 &r2_onion_keypair, &kp2);
774 tt_assert(buf);
776 cleanup_mock_configured_ports();
778 chunks = smartlist_new();
780 /* Synthesise a router descriptor, without the signatures */
781 smartlist_add(chunks, get_new_router_line(r2));
783 smartlist_add_strdup(chunks,
784 "identity-ed25519\n"
785 "-----BEGIN ED25519 CERT-----\n");
786 base64_encode(cert_buf, sizeof(cert_buf),
787 (const char*)r2->cache_info.signing_key_cert->encoded,
788 r2->cache_info.signing_key_cert->encoded_len,
789 BASE64_ENCODE_MULTILINE);
790 smartlist_add_strdup(chunks, cert_buf);
791 smartlist_add_strdup(chunks, "-----END ED25519 CERT-----\n");
793 smartlist_add_strdup(chunks, "master-key-ed25519 ");
795 char k[ED25519_BASE64_LEN+1];
796 ed25519_public_to_base64(k, &r2->cache_info.signing_key_cert->signing_key);
797 smartlist_add_strdup(chunks, k);
798 smartlist_add_strdup(chunks, "\n");
801 smartlist_add(chunks, get_new_platform_line());
802 smartlist_add_asprintf(chunks,
803 "proto %s\n", protover_get_supported_protocols());
804 smartlist_add(chunks, get_new_published_line(r2));
805 smartlist_add(chunks, get_new_fingerprint_line(r2));
807 smartlist_add(chunks, get_new_uptime_line(0));
808 smartlist_add(chunks, get_new_bandwidth_line(r2));
810 smartlist_add(chunks, get_new_onion_key_block(r2));
811 smartlist_add(chunks, get_new_signing_key_block(r2));
813 int rsa_cc_len;
814 rsa_cc = make_tap_onion_key_crosscert(r2_onion_pkey,
815 &kp1.pubkey,
816 r2->identity_pkey,
817 &rsa_cc_len);
818 tt_assert(rsa_cc);
819 base64_encode(cert_buf, sizeof(cert_buf), (char*)rsa_cc, rsa_cc_len,
820 BASE64_ENCODE_MULTILINE);
821 smartlist_add_strdup(chunks, "onion-key-crosscert\n"
822 "-----BEGIN CROSSCERT-----\n");
823 smartlist_add_strdup(chunks, cert_buf);
824 smartlist_add_strdup(chunks, "-----END CROSSCERT-----\n");
825 int ntor_cc_sign;
827 tor_cert_t *ntor_cc = NULL;
828 ntor_cc = make_ntor_onion_key_crosscert(&r2_onion_keypair,
829 &kp1.pubkey,
830 r2->cache_info.published_on,
831 get_onion_key_lifetime(),
832 &ntor_cc_sign);
833 tt_assert(ntor_cc);
834 base64_encode(cert_buf, sizeof(cert_buf),
835 (char*)ntor_cc->encoded, ntor_cc->encoded_len,
836 BASE64_ENCODE_MULTILINE);
837 tor_cert_free(ntor_cc);
839 smartlist_add_asprintf(chunks,
840 "ntor-onion-key-crosscert %d\n"
841 "-----BEGIN ED25519 CERT-----\n"
842 "%s"
843 "-----END ED25519 CERT-----\n", ntor_cc_sign, cert_buf);
845 smartlist_add_strdup(chunks, "hidden-service-dir\n");
847 smartlist_add(chunks, get_new_bridge_distribution_request_line(options));
848 smartlist_add(chunks, get_new_ntor_onion_key_line(&r2_onion_keypair.pubkey));
849 smartlist_add_strdup(chunks, "accept *:80\nreject 18.0.0.0/8:24\n");
850 smartlist_add_strdup(chunks, "tunnelled-dir-server\n");
852 smartlist_add_strdup(chunks, "router-sig-ed25519 ");
854 size_t len_out = 0;
855 buf2 = smartlist_join_strings(chunks, "", 0, &len_out);
856 SMARTLIST_FOREACH(chunks, char *, s, tor_free(s));
857 smartlist_free(chunks);
859 tt_assert(len_out > 0);
861 buf[strlen(buf2)] = '\0'; /* Don't compare either sig; they're never the same
862 * twice */
864 tt_str_op(buf, OP_EQ, buf2);
865 tor_free(buf);
867 setup_mock_configured_ports(r2->ipv4_orport, 0);
869 buf = router_dump_router_to_string(r2, r2->identity_pkey,
870 r2_onion_pkey,
871 &r2_onion_keypair, &kp2);
872 tt_assert(buf);
874 cleanup_mock_configured_ports();
876 /* Now, try to parse buf */
877 cp = buf;
878 rp2 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL);
880 CHECK_ROUTERINFO_CONSISTENCY(r2, rp2);
882 tt_mem_op(rp2->onion_curve25519_pkey->public_key,OP_EQ,
883 r2->onion_curve25519_pkey->public_key,
884 CURVE25519_PUBKEY_LEN);
886 CHECK_PARSED_EXIT_POLICY(rp2);
888 tor_free(buf);
889 routerinfo_free(rp2);
891 /* Test extrainfo creation. */
893 /* Set up standard mocks and data */
894 setup_mocks_for_fresh_descriptor(r2, r2_onion_pkey);
896 /* router_build_fresh_descriptor() requires
897 * router_build_fresh_unsigned_routerinfo(), but the implementation is
898 * too complex. Instead, we re-use r2.
900 mocked_routerinfo = r2;
901 MOCK(router_build_fresh_unsigned_routerinfo,
902 mock_router_build_fresh_unsigned_routerinfo);
904 /* r2 uses ed25519, so we need to mock the ed key functions */
905 mocked_master_signing_key = &kp2;
906 MOCK(get_master_signing_keypair, mock_get_master_signing_keypair);
908 mocked_signing_key_cert = r2->cache_info.signing_key_cert;
909 MOCK(get_master_signing_key_cert, mock_get_master_signing_key_cert);
911 mocked_curve25519_onion_key = &r2_onion_keypair;
912 MOCK(get_current_curve25519_keypair, mock_get_current_curve25519_keypair);
914 /* Fake just enough of an ORPort to get by */
915 setup_mock_configured_ports(r2->ipv4_orport, 0);
917 /* Test the high-level interface. */
918 rv = router_build_fresh_descriptor(&r2_out, &e2);
919 if (rv < 0) {
920 /* router_build_fresh_descriptor() frees r2 on failure. */
921 r2 = NULL;
922 /* Get rid of an alias to rp2 */
923 r2_out = NULL;
925 tt_assert(rv == 0);
926 tt_assert(r2_out);
927 tt_assert(e2);
928 /* Guaranteed by mock_router_build_fresh_unsigned_routerinfo() */
929 tt_ptr_op(r2_out, OP_EQ, r2);
930 /* Get rid of an alias to r2 */
931 r2_out = NULL;
933 /* Now cleanup */
934 cleanup_mocks_for_fresh_descriptor();
936 mocked_routerinfo = NULL;
937 UNMOCK(router_build_fresh_unsigned_routerinfo);
938 mocked_master_signing_key = NULL;
939 UNMOCK(get_master_signing_keypair);
940 mocked_signing_key_cert = NULL;
941 UNMOCK(get_master_signing_key_cert);
942 mocked_curve25519_onion_key = NULL;
943 UNMOCK(get_current_curve25519_keypair);
945 cleanup_mock_configured_ports();
947 CHECK_EXTRAINFO_CONSISTENCY(r2, e2);
949 /* Test that the signed ri is parseable */
950 tt_assert(r2->cache_info.signed_descriptor_body);
951 cp = r2->cache_info.signed_descriptor_body;
952 rp2 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL);
954 CHECK_ROUTERINFO_CONSISTENCY(r2, rp2);
956 tt_mem_op(rp2->onion_curve25519_pkey->public_key,OP_EQ,
957 r2->onion_curve25519_pkey->public_key,
958 CURVE25519_PUBKEY_LEN);
960 CHECK_PARSED_EXIT_POLICY(rp2);
962 routerinfo_free(rp2);
964 /* Test that the signed ei is parseable */
965 tt_assert(e2->cache_info.signed_descriptor_body);
966 cp = e2->cache_info.signed_descriptor_body;
967 ep2 = extrainfo_parse_entry_from_string((const char*)cp,NULL,1,NULL,NULL);
969 CHECK_EXTRAINFO_CONSISTENCY(r2, ep2);
971 /* In future tests, we could check the actual extrainfo statistics. */
973 extrainfo_free(ep2);
975 done:
976 dirserv_free_fingerprint_list();
978 tor_free(options->Nickname);
980 cleanup_mock_configured_ports();
981 cleanup_mocks_for_fresh_descriptor();
983 if (chunks) {
984 SMARTLIST_FOREACH(chunks, char *, s, tor_free(s));
985 smartlist_free(chunks);
988 routerinfo_free(r2);
989 routerinfo_free(r2_out);
990 routerinfo_free(rp2);
992 extrainfo_free(e2);
993 extrainfo_free(ep2);
995 tor_free(rsa_cc);
996 crypto_pk_free(r2_onion_pkey);
998 tor_free(buf);
999 tor_free(buf2);
1002 #include "failing_routerdescs.inc"
1004 static void
1005 test_dir_routerinfo_parsing(void *arg)
1007 (void) arg;
1009 int again;
1010 routerinfo_t *ri = NULL;
1012 #define CHECK_OK(s) \
1013 do { \
1014 routerinfo_free(ri); \
1015 ri = router_parse_entry_from_string((s), NULL, 0, 0, NULL, NULL); \
1016 tt_assert(ri); \
1017 } while (0)
1018 #define CHECK_FAIL(s, againval) \
1019 do { \
1020 routerinfo_free(ri); \
1021 again = 999; \
1022 ri = router_parse_entry_from_string((s), NULL, 0, 0, NULL, &again); \
1023 tt_assert(ri == NULL); \
1024 tt_int_op(again, OP_EQ, (againval)); \
1025 } while (0)
1027 CHECK_OK(EX_RI_MINIMAL);
1028 CHECK_OK(EX_RI_MAXIMAL);
1030 /* good annotations prepended */
1031 routerinfo_free(ri);
1032 ri = router_parse_entry_from_string(EX_RI_MINIMAL, NULL, 0, 0,
1033 "@purpose bridge\n", NULL);
1034 tt_ptr_op(ri, OP_NE, NULL);
1035 tt_assert(ri->purpose == ROUTER_PURPOSE_BRIDGE);
1036 routerinfo_free(ri);
1038 /* bad annotations prepended. */
1039 ri = router_parse_entry_from_string(EX_RI_MINIMAL,
1040 NULL, 0, 0, "@purpose\n", NULL);
1041 tt_ptr_op(ri, OP_EQ, NULL);
1043 /* bad annotations on router. */
1044 ri = router_parse_entry_from_string("@purpose\nrouter x\n", NULL, 0, 1,
1045 NULL, NULL);
1046 tt_ptr_op(ri, OP_EQ, NULL);
1048 /* unwanted annotations on router. */
1049 ri = router_parse_entry_from_string("@purpose foo\nrouter x\n", NULL, 0, 0,
1050 NULL, NULL);
1051 tt_ptr_op(ri, OP_EQ, NULL);
1053 /* No signature. */
1054 ri = router_parse_entry_from_string("router x\n", NULL, 0, 0,
1055 NULL, NULL);
1056 tt_ptr_op(ri, OP_EQ, NULL);
1058 /* Not a router */
1059 routerinfo_free(ri);
1060 ri = router_parse_entry_from_string("hello\n", NULL, 0, 0, NULL, NULL);
1061 tt_ptr_op(ri, OP_EQ, NULL);
1063 CHECK_FAIL(EX_RI_BAD_SIG1, 1);
1064 CHECK_FAIL(EX_RI_BAD_TOKENS, 0);
1065 CHECK_FAIL(EX_RI_BAD_PUBLISHED, 0);
1066 CHECK_FAIL(EX_RI_NEG_BANDWIDTH, 0);
1067 CHECK_FAIL(EX_RI_BAD_BANDWIDTH, 0);
1068 CHECK_FAIL(EX_RI_BAD_BANDWIDTH2, 0);
1069 CHECK_FAIL(EX_RI_BAD_BANDWIDTH3, 0);
1070 CHECK_FAIL(EX_RI_BAD_ONIONKEY, 0);
1071 CHECK_FAIL(EX_RI_BAD_PORTS, 0);
1072 CHECK_FAIL(EX_RI_BAD_IP, 0);
1073 CHECK_FAIL(EX_RI_BAD_DIRPORT, 0);
1074 CHECK_FAIL(EX_RI_BAD_NAME2, 0);
1075 CHECK_FAIL(EX_RI_BAD_UPTIME, 0);
1077 CHECK_FAIL(EX_RI_BAD_BANDWIDTH3, 0);
1078 CHECK_FAIL(EX_RI_BAD_NTOR_KEY, 0);
1079 CHECK_FAIL(EX_RI_BAD_FINGERPRINT, 0);
1080 CHECK_FAIL(EX_RI_MISMATCHED_FINGERPRINT, 0);
1081 CHECK_FAIL(EX_RI_BAD_HAS_ACCEPT6, 0);
1082 CHECK_FAIL(EX_RI_BAD_NO_EXIT_POLICY, 0);
1083 CHECK_FAIL(EX_RI_BAD_IPV6_EXIT_POLICY, 0);
1084 CHECK_FAIL(EX_RI_BAD_FAMILY, 0);
1085 CHECK_FAIL(EX_RI_ZERO_ORPORT, 0);
1087 CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT, 0);
1088 CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT2, 0);
1089 CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT_SIGN, 0);
1090 CHECK_FAIL(EX_RI_ED_BAD_SIG1, 0);
1091 CHECK_FAIL(EX_RI_ED_BAD_SIG2, 0);
1092 CHECK_FAIL(EX_RI_ED_BAD_SIG3, 0);
1093 CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT1, 0);
1094 CHECK_FAIL(EX_RI_ED_MISPLACED1, 0);
1095 CHECK_FAIL(EX_RI_ED_MISPLACED2, 0);
1096 CHECK_FAIL(EX_RI_ED_BAD_CERT1, 0);
1098 #undef CHECK_FAIL
1099 #undef CHECK_OK
1100 done:
1101 routerinfo_free(ri);
1104 #include "example_extrainfo.inc"
1106 static void
1107 routerinfo_free_wrapper_(void *arg)
1109 routerinfo_free_(arg);
1112 static void
1113 test_dir_extrainfo_parsing(void *arg)
1115 (void) arg;
1117 #define CHECK_OK(s) \
1118 do { \
1119 extrainfo_free(ei); \
1120 ei = extrainfo_parse_entry_from_string((s), NULL, 0, map, NULL); \
1121 tt_assert(ei); \
1122 } while (0)
1123 #define CHECK_FAIL(s, againval) \
1124 do { \
1125 extrainfo_free(ei); \
1126 again = 999; \
1127 ei = extrainfo_parse_entry_from_string((s), NULL, 0, map, &again); \
1128 tt_assert(ei == NULL); \
1129 tt_int_op(again, OP_EQ, (againval)); \
1130 } while (0)
1131 #define ADD(name) \
1132 do { \
1133 ri = tor_malloc_zero(sizeof(routerinfo_t)); \
1134 crypto_pk_t *pk = ri->identity_pkey = crypto_pk_new(); \
1135 tt_assert(! crypto_pk_read_public_key_from_string(pk, \
1136 name##_KEY, strlen(name##_KEY))); \
1137 tt_int_op(20,OP_EQ,base16_decode(d, 20, name##_FP, strlen(name##_FP))); \
1138 digestmap_set((digestmap_t*)map, d, ri); \
1139 ri = NULL; \
1140 } while (0)
1142 routerinfo_t *ri = NULL;
1143 char d[20];
1144 struct digest_ri_map_t *map = NULL;
1145 extrainfo_t *ei = NULL;
1146 int again;
1148 CHECK_OK(EX_EI_MINIMAL);
1149 tt_assert(ei->pending_sig);
1150 CHECK_OK(EX_EI_MAXIMAL);
1151 tt_assert(ei->pending_sig);
1153 map = (struct digest_ri_map_t *)digestmap_new();
1154 ADD(EX_EI_MINIMAL);
1155 ADD(EX_EI_MAXIMAL);
1156 ADD(EX_EI_BAD_NICKNAME);
1157 ADD(EX_EI_BAD_TOKENS);
1158 ADD(EX_EI_BAD_START);
1159 ADD(EX_EI_BAD_PUBLISHED);
1161 ADD(EX_EI_ED_MISSING_SIG);
1162 ADD(EX_EI_ED_MISSING_CERT);
1163 ADD(EX_EI_ED_BAD_CERT1);
1164 ADD(EX_EI_ED_BAD_CERT2);
1165 ADD(EX_EI_ED_MISPLACED_CERT);
1166 ADD(EX_EI_ED_MISPLACED_SIG);
1168 CHECK_OK(EX_EI_MINIMAL);
1169 tt_ptr_op(ei->pending_sig, OP_EQ, NULL);
1170 CHECK_OK(EX_EI_MAXIMAL);
1171 tt_ptr_op(ei->pending_sig, OP_EQ, NULL);
1173 CHECK_FAIL(EX_EI_BAD_SIG1,1);
1174 CHECK_FAIL(EX_EI_BAD_SIG2,0);
1175 CHECK_FAIL(EX_EI_BAD_NICKNAME,0);
1176 CHECK_FAIL(EX_EI_BAD_TOKENS,0);
1177 CHECK_FAIL(EX_EI_BAD_START,0);
1178 CHECK_FAIL(EX_EI_BAD_PUBLISHED,0);
1180 CHECK_FAIL(EX_EI_ED_MISSING_SIG,0);
1181 CHECK_FAIL(EX_EI_ED_MISSING_CERT,0);
1182 CHECK_FAIL(EX_EI_ED_BAD_CERT1,0);
1183 CHECK_FAIL(EX_EI_ED_BAD_CERT2,0);
1184 CHECK_FAIL(EX_EI_ED_MISPLACED_CERT,0);
1185 CHECK_FAIL(EX_EI_ED_MISPLACED_SIG,0);
1187 #undef CHECK_OK
1188 #undef CHECK_FAIL
1190 done:
1191 escaped(NULL);
1192 extrainfo_free(ei);
1193 routerinfo_free(ri);
1194 digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_);
1197 static void
1198 test_dir_parse_router_list(void *arg)
1200 (void) arg;
1201 smartlist_t *invalid = smartlist_new();
1202 smartlist_t *dest = smartlist_new();
1203 smartlist_t *chunks = smartlist_new();
1204 int dest_has_ri = 1;
1205 char *list = NULL;
1206 const char *cp;
1207 digestmap_t *map = NULL;
1208 char *mem_op_hex_tmp = NULL;
1209 routerinfo_t *ri = NULL;
1210 char d[DIGEST_LEN];
1212 smartlist_add_strdup(chunks, EX_RI_MINIMAL); // ri 0
1213 smartlist_add_strdup(chunks, EX_RI_BAD_PORTS); // bad ri 0
1214 smartlist_add_strdup(chunks, EX_EI_MAXIMAL); // ei 0
1215 smartlist_add_strdup(chunks, EX_EI_BAD_SIG2); // bad ei --
1216 smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME);// bad ei 0
1217 smartlist_add_strdup(chunks, EX_RI_BAD_SIG1); // bad ri --
1218 smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED); // bad ei 1
1219 smartlist_add_strdup(chunks, EX_RI_MAXIMAL); // ri 1
1220 smartlist_add_strdup(chunks, EX_RI_BAD_FAMILY); // bad ri 1
1221 smartlist_add_strdup(chunks, EX_EI_MINIMAL); // ei 1
1223 list = smartlist_join_strings(chunks, "", 0, NULL);
1225 /* First, parse the routers. */
1226 cp = list;
1227 tt_int_op(0,OP_EQ,
1228 router_parse_list_from_string(&cp, NULL, dest, SAVED_NOWHERE,
1229 0, 0, NULL, invalid));
1230 tt_int_op(2, OP_EQ, smartlist_len(dest));
1231 tt_ptr_op(cp, OP_EQ, list + strlen(list));
1233 routerinfo_t *r = smartlist_get(dest, 0);
1234 tt_mem_op(r->cache_info.signed_descriptor_body, OP_EQ,
1235 EX_RI_MINIMAL, strlen(EX_RI_MINIMAL));
1236 r = smartlist_get(dest, 1);
1237 tt_mem_op(r->cache_info.signed_descriptor_body, OP_EQ,
1238 EX_RI_MAXIMAL, strlen(EX_RI_MAXIMAL));
1240 setup_ei_digests();
1242 tt_int_op(2, OP_EQ, smartlist_len(invalid));
1244 test_memeq_hex(smartlist_get(invalid, 0),
1245 "10F951AF93AED0D3BC7FA5FFA232EB8C17747ACE");
1246 test_memeq_hex(smartlist_get(invalid, 1),
1247 "41D8723CDD4B1AADCCE538C28CDE7F69828C73D0");
1249 /* Now tidy up */
1250 SMARTLIST_FOREACH(dest, routerinfo_t *, rinfo, routerinfo_free(rinfo));
1251 SMARTLIST_FOREACH(invalid, uint8_t *, dig, tor_free(dig));
1252 smartlist_clear(dest);
1253 smartlist_clear(invalid);
1255 /* And check extrainfos. */
1256 dest_has_ri = 0;
1257 map = (digestmap_t*)router_get_routerlist()->identity_map;
1258 ADD(EX_EI_MINIMAL);
1259 ADD(EX_EI_MAXIMAL);
1260 ADD(EX_EI_BAD_NICKNAME);
1261 ADD(EX_EI_BAD_PUBLISHED);
1262 ADD(EX_EI_BAD_SIG2);
1263 cp = list;
1264 tt_int_op(0,OP_EQ,
1265 router_parse_list_from_string(&cp, NULL, dest, SAVED_NOWHERE,
1266 1, 0, NULL, invalid));
1267 tt_int_op(2, OP_EQ, smartlist_len(dest));
1268 extrainfo_t *e = smartlist_get(dest, 0);
1269 tt_mem_op(e->cache_info.signed_descriptor_body, OP_EQ,
1270 EX_EI_MAXIMAL, strlen(EX_EI_MAXIMAL));
1271 e = smartlist_get(dest, 1);
1272 tt_mem_op(e->cache_info.signed_descriptor_body, OP_EQ,
1273 EX_EI_MINIMAL, strlen(EX_EI_MINIMAL));
1275 tt_int_op(3, OP_EQ, smartlist_len(invalid));
1276 tt_mem_op(smartlist_get(invalid, 0),
1277 OP_EQ,
1278 digest_ei_bad_sig2, DIGEST_LEN);
1279 tt_mem_op(smartlist_get(invalid, 1),
1280 OP_EQ,
1281 digest_ei_bad_nickname, DIGEST_LEN);
1282 tt_mem_op(smartlist_get(invalid, 2),
1283 OP_EQ,
1284 digest_ei_bad_published, DIGEST_LEN);
1286 done:
1287 tor_free(list);
1288 if (dest_has_ri)
1289 SMARTLIST_FOREACH(dest, routerinfo_t *, rt, routerinfo_free(rt));
1290 else
1291 SMARTLIST_FOREACH(dest, extrainfo_t *, ei, extrainfo_free(ei));
1292 smartlist_free(dest);
1293 SMARTLIST_FOREACH(invalid, uint8_t *, dig, tor_free(dig));
1294 smartlist_free(invalid);
1295 SMARTLIST_FOREACH(chunks, char *, chunk, tor_free(chunk));
1296 smartlist_free(chunks);
1297 routerinfo_free(ri);
1298 if (map) {
1299 digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_);
1300 router_get_routerlist()->identity_map =
1301 (struct digest_ri_map_t*)digestmap_new();
1303 tor_free(mem_op_hex_tmp);
1305 #undef ADD
1308 /* Made with chutney and a patched tor: Has no onion-key or
1309 * onion-key-crosscert */
1310 static const char ROUTERDESC_NO_ONION_KEY[] =
1311 "router test001a 127.0.0.1 5001 0 7001\n"
1312 "identity-ed25519\n"
1313 "-----BEGIN ED25519 CERT-----\n"
1314 "AQQAB0xWARbCJfDrX0OTtpM0fDxU9cLweMnZeUq/KBfAN1wwWHtMAQAgBADBQJ1o\n"
1315 "ClrXUenWC90FYEUQDpMSdxdxKlrR83rYy+keGe61WQHYP0ebowJC19UvPnYryLeA\n"
1316 "Gnhko2WwmbUDGicdnY4j2VSFU15oxBjln65IznZJyiZM4zGE1GkNZzKGmQY=\n"
1317 "-----END ED25519 CERT-----\n"
1318 "master-key-ed25519 wUCdaApa11Hp1gvdBWBFEA6TEncXcSpa0fN62MvpHhk\n"
1319 "or-address [::]:5001\n"
1320 "platform Tor 0.4.9.0-alpha-dev on Linux\n"
1321 "proto Conflux=1 Cons=1-2 Desc=1-2 DirCache=2 FlowCtrl=1-2 HSDir=2 "
1322 "HSIntro=4-5 HSRend=1-2 Link=1-5 LinkAuth=1,3 Microdesc=1-2 Padding=2 "
1323 "Relay=1-4\n"
1324 "published 2024-06-24 21:34:22\n"
1325 "fingerprint FD3A 6FA4 E716 C379 3CBA FEC3 39EA 01C8 B49D 7189\n"
1326 "uptime 0\n"
1327 "bandwidth 1073741824 1073741824 0\n"
1328 "extra-info-digest 9946CAC41485EDFFDD83F7DAF1A088C30563126C "
1329 "lpAMRlRTy9QR2xVCu1nnnxOHA2I05TTKvCSPPcr1geo\n"
1330 "caches-extra-info\n"
1331 "signing-key\n"
1332 "-----BEGIN RSA PUBLIC KEY-----\n"
1333 "MIGJAoGBALcIIij7gNpvSZPvaCLDDNyyQZq7fR0aXiHgmiIc5hYVcBl+zF5sTX6a\n"
1334 "jQF+GQdbSHcRzA1IMWPXnA7+nGOxSNayrQwExuf7ESsBaQHU81/dmV+rgTwtcd3K\n"
1335 "9lobTQUm+idLvGjVF5P1XJkduPvURIgpIfXT1ZHJUQhwxWSw8MmnAgMBAAE=\n"
1336 "-----END RSA PUBLIC KEY-----\n"
1337 "ntor-onion-key-crosscert 1\n"
1338 "-----BEGIN ED25519 CERT-----\n"
1339 "AQoAB0wmAcFAnWgKWtdR6dYL3QVgRRAOkxJ3F3EqWtHzetjL6R4ZAFPSCMLyQ82v\n"
1340 "dvcpZDa7C/qp8TsJn2Z8v77RjRc2QD1KYDzGfg5euwlB1lu8+IR38l3mmC1PXXhe\n"
1341 "ZB84q4aUdAA=\n"
1342 "-----END ED25519 CERT-----\n"
1343 "hidden-service-dir\n"
1344 "contact auth1@test.test\n"
1345 "ntor-onion-key m0dedSB2vjtvz08bNu+LCdIApVuspRlzXbsphXZ62zQ\n"
1346 "reject *:*\n"
1347 "tunnelled-dir-server\n"
1348 "router-sig-ed25519 VMwmiN9KhWWFSFSuVZxG1g46mb2QhMhv0UlatvPKyAV+1jPl"
1349 "EbDFaO1Qur0335Rn0ToysC6UqB1p78pefX67Aw\n"
1350 "router-signature\n"
1351 "-----BEGIN SIGNATURE-----\n"
1352 "q9Hxy4FJVIK2ks/ByBv8P1p7Pc68ie/TTlDN+tce9opPlijy9+ze9/Gd2SKonRm1\n"
1353 "J+WBj/kKYKw+YoUExIT0qMfa6QTCOe/ecp1sNmgeW0YfloP4Nv8goi3S0k4yrPk/\n"
1354 "qw6TIXGYJpvrdR1Qe7+MEl2K1Okqsy5amtOU400lYRA=\n"
1355 "-----END SIGNATURE-----\n"
1358 static void
1359 test_dir_parse_no_onion_keyrouter_list(void *arg)
1361 (void) arg;
1363 routerinfo_t *ri =
1364 router_parse_entry_from_string(ROUTERDESC_NO_ONION_KEY, NULL,
1365 0, 1, 0, NULL);
1367 tt_assert(ri);
1368 tt_assert(ri->tap_onion_pkey == NULL);
1370 done:
1371 routerinfo_free(ri);
1374 static download_status_t dls_minimal;
1375 static download_status_t dls_maximal;
1376 static download_status_t dls_bad_fingerprint;
1377 static download_status_t dls_bad_sig1;
1378 static download_status_t dls_bad_ports;
1379 static download_status_t dls_bad_tokens;
1381 static uint8_t digest_minimal[20];
1382 static uint8_t digest_maximal[20];
1383 static uint8_t digest_bad_fingerprint[20];
1384 static uint8_t digest_bad_sig1[20];
1385 static uint8_t digest_bad_ports[20];
1386 static uint8_t digest_bad_tokens[20];
1388 static void
1389 setup_dls_digests(void)
1391 #define SETUP(string, name) \
1392 do { \
1393 router_get_router_hash(string, strlen(string), (char*)digest_##name); \
1394 } while (0)
1396 SETUP(EX_RI_MINIMAL, minimal);
1397 SETUP(EX_RI_MAXIMAL, maximal);
1398 SETUP(EX_RI_BAD_FINGERPRINT, bad_fingerprint);
1399 SETUP(EX_RI_BAD_SIG1, bad_sig1);
1400 SETUP(EX_RI_BAD_PORTS, bad_ports);
1401 SETUP(EX_RI_BAD_TOKENS, bad_tokens);
1402 #undef SETUP
1405 static int mock_router_get_dl_status_unrecognized = 0;
1406 static int mock_router_get_dl_status_calls = 0;
1408 static download_status_t *
1409 mock_router_get_dl_status(const char *d)
1411 ++mock_router_get_dl_status_calls;
1412 #define CHECK(name) \
1413 do { \
1414 if (fast_memeq(d, digest_##name, DIGEST_LEN)) \
1415 return &dls_##name; \
1416 } while (0)
1418 CHECK(minimal);
1419 CHECK(maximal);
1420 CHECK(bad_fingerprint);
1421 CHECK(bad_sig1);
1422 CHECK(bad_ports);
1423 CHECK(bad_tokens);
1425 ++mock_router_get_dl_status_unrecognized;
1426 return NULL;
1427 #undef CHECK
1430 static void
1431 test_dir_load_routers(void *arg)
1433 (void) arg;
1434 smartlist_t *chunks = smartlist_new();
1435 smartlist_t *wanted = smartlist_new();
1436 char buf[DIGEST_LEN];
1437 char *mem_op_hex_tmp = NULL;
1438 char *list = NULL;
1440 #define ADD(str) \
1441 do { \
1442 tt_int_op(0,OP_EQ,router_get_router_hash(str, strlen(str), buf)); \
1443 smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN)); \
1444 } while (0)
1446 setup_dls_digests();
1448 MOCK(router_get_dl_status_by_descriptor_digest, mock_router_get_dl_status);
1450 update_approx_time(1412510400);
1452 smartlist_add_strdup(chunks, EX_RI_MINIMAL);
1453 smartlist_add_strdup(chunks, EX_RI_BAD_FINGERPRINT);
1454 smartlist_add_strdup(chunks, EX_RI_BAD_SIG1);
1455 smartlist_add_strdup(chunks, EX_RI_MAXIMAL);
1456 smartlist_add_strdup(chunks, EX_RI_BAD_PORTS);
1457 smartlist_add_strdup(chunks, EX_RI_BAD_TOKENS);
1459 /* not ADDing MINIMAL */
1460 ADD(EX_RI_MAXIMAL);
1461 ADD(EX_RI_BAD_FINGERPRINT);
1462 ADD(EX_RI_BAD_SIG1);
1463 /* Not ADDing BAD_PORTS */
1464 ADD(EX_RI_BAD_TOKENS);
1466 list = smartlist_join_strings(chunks, "", 0, NULL);
1467 tt_int_op(1, OP_EQ,
1468 router_load_routers_from_string(list, NULL, SAVED_IN_JOURNAL,
1469 wanted, 1, NULL));
1471 /* The "maximal" router was added. */
1472 /* "minimal" was not. */
1473 tt_int_op(smartlist_len(router_get_routerlist()->routers),OP_EQ,1);
1474 routerinfo_t *r = smartlist_get(router_get_routerlist()->routers, 0);
1475 test_memeq_hex(r->cache_info.signed_descriptor_digest,
1476 "1F437798ACD1FC9CBD1C3C04DBF80F7E9F819C3F");
1477 tt_int_op(dls_minimal.n_download_failures, OP_EQ, 0);
1478 tt_int_op(dls_maximal.n_download_failures, OP_EQ, 0);
1480 /* "Bad fingerprint" and "Bad tokens" should have gotten marked
1481 * non-retriable. */
1482 tt_want_int_op(mock_router_get_dl_status_calls, OP_EQ, 2);
1483 tt_want_int_op(mock_router_get_dl_status_unrecognized, OP_EQ, 0);
1484 tt_int_op(dls_bad_fingerprint.n_download_failures, OP_EQ, 255);
1485 tt_int_op(dls_bad_tokens.n_download_failures, OP_EQ, 255);
1487 /* bad_sig2 and bad ports" are retriable -- one since only the signature
1488 * was bad, and one because we didn't ask for it. */
1489 tt_int_op(dls_bad_sig1.n_download_failures, OP_EQ, 0);
1490 tt_int_op(dls_bad_ports.n_download_failures, OP_EQ, 0);
1492 tt_int_op(smartlist_len(wanted), OP_EQ, 1);
1493 tt_str_op(smartlist_get(wanted, 0), OP_EQ,
1494 "3BB7D03C1C4DBC1DDE840096FF3C330914757B77");
1496 #undef ADD
1498 done:
1499 tor_free(mem_op_hex_tmp);
1500 UNMOCK(router_get_dl_status_by_descriptor_digest);
1501 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
1502 smartlist_free(chunks);
1503 SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
1504 smartlist_free(wanted);
1505 tor_free(list);
1508 static int mock_get_by_ei_dd_calls = 0;
1509 static int mock_get_by_ei_dd_unrecognized = 0;
1511 static signed_descriptor_t sd_ei_minimal;
1512 static signed_descriptor_t sd_ei_bad_nickname;
1513 static signed_descriptor_t sd_ei_maximal;
1514 static signed_descriptor_t sd_ei_bad_tokens;
1515 static signed_descriptor_t sd_ei_bad_sig2;
1517 static void
1518 setup_ei_digests(void)
1520 #define SETUP(string, name) \
1521 do { \
1522 router_get_extrainfo_hash(string, strlen(string), \
1523 (char*)digest_ei_##name); \
1524 } while (0)
1526 SETUP(EX_EI_MINIMAL, minimal);
1527 SETUP(EX_EI_MAXIMAL, maximal);
1528 SETUP(EX_EI_BAD_NICKNAME, bad_nickname);
1529 SETUP(EX_EI_BAD_TOKENS, bad_tokens);
1530 SETUP(EX_EI_BAD_SIG2, bad_sig2);
1531 SETUP(EX_EI_BAD_PUBLISHED, bad_published);
1533 #undef SETUP
1536 static signed_descriptor_t *
1537 mock_get_by_ei_desc_digest(const char *d)
1539 ++mock_get_by_ei_dd_calls;
1540 #define CHECK(name) \
1541 do { \
1542 if (fast_memeq(d, digest_ei_##name, DIGEST_LEN)) \
1543 return &sd_ei_##name; \
1544 } while (0)
1546 CHECK(minimal);
1547 CHECK(maximal);
1548 CHECK(bad_nickname);
1549 CHECK(bad_sig2);
1550 CHECK(bad_tokens);
1551 ++mock_get_by_ei_dd_unrecognized;
1552 return NULL;
1553 #undef CHECK
1556 static signed_descriptor_t *
1557 mock_ei_get_by_ei_digest(const char *d)
1559 signed_descriptor_t *sd = &sd_ei_minimal;
1561 if (fast_memeq(d, digest_ei_minimal, DIGEST_LEN)) {
1562 sd->signed_descriptor_body = (char *)EX_EI_MINIMAL;
1563 sd->signed_descriptor_len = sizeof(EX_EI_MINIMAL);
1564 sd->annotations_len = 0;
1565 sd->saved_location = SAVED_NOWHERE;
1566 return sd;
1568 return NULL;
1571 static smartlist_t *mock_ei_insert_list = NULL;
1572 static was_router_added_t
1573 mock_ei_insert(routerlist_t *rl, extrainfo_t *ei, int warn_if_incompatible)
1575 (void) rl;
1576 (void) warn_if_incompatible;
1577 smartlist_add(mock_ei_insert_list, ei);
1578 return ROUTER_ADDED_SUCCESSFULLY;
1581 static void
1582 test_dir_load_extrainfo(void *arg)
1584 (void) arg;
1585 smartlist_t *chunks = smartlist_new();
1586 smartlist_t *wanted = smartlist_new();
1587 char buf[DIGEST_LEN];
1588 char *mem_op_hex_tmp = NULL;
1589 char *list = NULL;
1591 #define ADD(str) \
1592 do { \
1593 tt_int_op(0,OP_EQ,router_get_extrainfo_hash(str, strlen(str), buf)); \
1594 smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN)); \
1595 } while (0)
1597 setup_ei_digests();
1598 mock_ei_insert_list = smartlist_new();
1599 MOCK(router_get_by_extrainfo_digest, mock_get_by_ei_desc_digest);
1600 MOCK(extrainfo_insert, mock_ei_insert);
1602 smartlist_add_strdup(chunks, EX_EI_MINIMAL);
1603 smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME);
1604 smartlist_add_strdup(chunks, EX_EI_MAXIMAL);
1605 smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED);
1606 smartlist_add_strdup(chunks, EX_EI_BAD_TOKENS);
1608 /* not ADDing MINIMAL */
1609 ADD(EX_EI_MAXIMAL);
1610 ADD(EX_EI_BAD_NICKNAME);
1611 /* Not ADDing BAD_PUBLISHED */
1612 ADD(EX_EI_BAD_TOKENS);
1613 ADD(EX_EI_BAD_SIG2);
1615 list = smartlist_join_strings(chunks, "", 0, NULL);
1616 router_load_extrainfo_from_string(list, NULL, SAVED_IN_JOURNAL, wanted, 1);
1618 /* The "maximal" router was added. */
1619 /* "minimal" was also added, even though we didn't ask for it, since
1620 * that's what we do with extrainfos. */
1621 tt_int_op(smartlist_len(mock_ei_insert_list),OP_EQ,2);
1623 extrainfo_t *e = smartlist_get(mock_ei_insert_list, 0);
1624 tt_mem_op(e->cache_info.signed_descriptor_digest, OP_EQ,
1625 digest_ei_minimal, DIGEST_LEN);
1627 e = smartlist_get(mock_ei_insert_list, 1);
1628 tt_mem_op(e->cache_info.signed_descriptor_digest, OP_EQ,
1629 digest_ei_maximal, DIGEST_LEN);
1630 tt_int_op(dls_minimal.n_download_failures, OP_EQ, 0);
1631 tt_int_op(dls_maximal.n_download_failures, OP_EQ, 0);
1633 /* "Bad nickname" and "Bad tokens" should have gotten marked
1634 * non-retriable. */
1635 tt_want_int_op(mock_get_by_ei_dd_calls, OP_EQ, 2);
1636 tt_want_int_op(mock_get_by_ei_dd_unrecognized, OP_EQ, 0);
1637 tt_int_op(sd_ei_bad_nickname.ei_dl_status.n_download_failures, OP_EQ, 255);
1638 tt_int_op(sd_ei_bad_tokens.ei_dl_status.n_download_failures, OP_EQ, 255);
1640 /* bad_ports is retriable -- because we didn't ask for it. */
1641 tt_int_op(dls_bad_ports.n_download_failures, OP_EQ, 0);
1643 /* Wanted still contains "BAD_SIG2" */
1644 tt_int_op(smartlist_len(wanted), OP_EQ, 1);
1645 const char *got_wanted =smartlist_get(wanted, 0);
1646 tt_int_op(strlen(got_wanted), OP_EQ, HEX_DIGEST_LEN);
1647 char d[DIGEST_LEN];
1648 base16_decode(d, DIGEST_LEN, got_wanted, strlen(got_wanted));
1649 tt_mem_op(d, OP_EQ, digest_ei_bad_sig2, DIGEST_LEN);
1651 #undef ADD
1653 done:
1654 tor_free(mem_op_hex_tmp);
1655 UNMOCK(router_get_by_extrainfo_digest);
1656 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
1657 smartlist_free(chunks);
1658 SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
1659 smartlist_free(wanted);
1660 tor_free(list);
1663 static void
1664 test_dir_getinfo_extra(void *arg)
1666 int r;
1667 char *answer = NULL;
1668 const char *errmsg = NULL;
1669 char buf[128];
1670 char hexdigest[HEX_DIGEST_LEN+1];
1671 (void)arg;
1673 setup_ei_digests();
1674 base16_encode(hexdigest, sizeof(hexdigest),
1675 (const char*)digest_ei_minimal, DIGEST_LEN);
1676 tor_snprintf(buf, sizeof(buf), "extra-info/digest/%s", hexdigest);
1678 MOCK(extrainfo_get_by_descriptor_digest, mock_ei_get_by_ei_digest);
1679 r = getinfo_helper_dir(NULL, buf, &answer, &errmsg);
1680 tt_int_op(0, OP_EQ, r);
1681 tt_ptr_op(NULL, OP_EQ, errmsg);
1682 tt_str_op(answer, OP_EQ, EX_EI_MINIMAL);
1683 tor_free(answer);
1685 answer = NULL;
1686 r = getinfo_helper_dir(NULL, "extra-info/digest/"
1687 "NOTAVALIDHEXSTRINGNOTAVALIDHEXSTRINGNOTA", &answer,
1688 &errmsg);
1689 tt_int_op(0, OP_EQ, r);
1690 /* getinfo_helper_dir() should maybe return an error here but doesn't */
1691 tt_ptr_op(NULL, OP_EQ, errmsg);
1692 /* In any case, there should be no answer for an invalid hex string. */
1693 tt_ptr_op(NULL, OP_EQ, answer);
1695 done:
1696 UNMOCK(extrainfo_get_by_descriptor_digest);
1699 static void
1700 test_dir_versions(void *arg)
1702 tor_version_t ver1;
1704 /* Try out version parsing functionality */
1705 (void)arg;
1706 tt_int_op(0,OP_EQ, tor_version_parse("0.3.4pre2-cvs", &ver1));
1707 tt_int_op(0,OP_EQ, ver1.major);
1708 tt_int_op(3,OP_EQ, ver1.minor);
1709 tt_int_op(4,OP_EQ, ver1.micro);
1710 tt_int_op(VER_PRE,OP_EQ, ver1.status);
1711 tt_int_op(2,OP_EQ, ver1.patchlevel);
1712 tt_int_op(0,OP_EQ, tor_version_parse("0.3.4rc1", &ver1));
1713 tt_int_op(0,OP_EQ, ver1.major);
1714 tt_int_op(3,OP_EQ, ver1.minor);
1715 tt_int_op(4,OP_EQ, ver1.micro);
1716 tt_int_op(VER_RC,OP_EQ, ver1.status);
1717 tt_int_op(1,OP_EQ, ver1.patchlevel);
1718 tt_int_op(0,OP_EQ, tor_version_parse("1.3.4", &ver1));
1719 tt_int_op(1,OP_EQ, ver1.major);
1720 tt_int_op(3,OP_EQ, ver1.minor);
1721 tt_int_op(4,OP_EQ, ver1.micro);
1722 tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1723 tt_int_op(0,OP_EQ, ver1.patchlevel);
1724 tt_int_op(0,OP_EQ, tor_version_parse("1.3.4.999", &ver1));
1725 tt_int_op(1,OP_EQ, ver1.major);
1726 tt_int_op(3,OP_EQ, ver1.minor);
1727 tt_int_op(4,OP_EQ, ver1.micro);
1728 tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1729 tt_int_op(999,OP_EQ, ver1.patchlevel);
1730 tt_int_op(0,OP_EQ, tor_version_parse("0.1.2.4-alpha", &ver1));
1731 tt_int_op(0,OP_EQ, ver1.major);
1732 tt_int_op(1,OP_EQ, ver1.minor);
1733 tt_int_op(2,OP_EQ, ver1.micro);
1734 tt_int_op(4,OP_EQ, ver1.patchlevel);
1735 tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1736 tt_str_op("alpha",OP_EQ, ver1.status_tag);
1737 tt_int_op(0,OP_EQ, tor_version_parse("0.1.2.4", &ver1));
1738 tt_int_op(0,OP_EQ, ver1.major);
1739 tt_int_op(1,OP_EQ, ver1.minor);
1740 tt_int_op(2,OP_EQ, ver1.micro);
1741 tt_int_op(4,OP_EQ, ver1.patchlevel);
1742 tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1743 tt_str_op("",OP_EQ, ver1.status_tag);
1745 tt_int_op(0, OP_EQ, tor_version_parse("10.1", &ver1));
1746 tt_int_op(10, OP_EQ, ver1.major);
1747 tt_int_op(1, OP_EQ, ver1.minor);
1748 tt_int_op(0, OP_EQ, ver1.micro);
1749 tt_int_op(0, OP_EQ, ver1.patchlevel);
1750 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1751 tt_str_op("", OP_EQ, ver1.status_tag);
1752 tt_int_op(0, OP_EQ, tor_version_parse("5.99.999", &ver1));
1753 tt_int_op(5, OP_EQ, ver1.major);
1754 tt_int_op(99, OP_EQ, ver1.minor);
1755 tt_int_op(999, OP_EQ, ver1.micro);
1756 tt_int_op(0, OP_EQ, ver1.patchlevel);
1757 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1758 tt_str_op("", OP_EQ, ver1.status_tag);
1759 tt_int_op(0, OP_EQ, tor_version_parse("10.1-alpha", &ver1));
1760 tt_int_op(10, OP_EQ, ver1.major);
1761 tt_int_op(1, OP_EQ, ver1.minor);
1762 tt_int_op(0, OP_EQ, ver1.micro);
1763 tt_int_op(0, OP_EQ, ver1.patchlevel);
1764 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1765 tt_str_op("alpha", OP_EQ, ver1.status_tag);
1766 /* Go through the full set of status tags */
1767 tt_int_op(0, OP_EQ, tor_version_parse("2.1.700-alpha", &ver1));
1768 tt_int_op(2, OP_EQ, ver1.major);
1769 tt_int_op(1, OP_EQ, ver1.minor);
1770 tt_int_op(700, OP_EQ, ver1.micro);
1771 tt_int_op(0, OP_EQ, ver1.patchlevel);
1772 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1773 tt_str_op("alpha", OP_EQ, ver1.status_tag);
1774 tt_int_op(0, OP_EQ, tor_version_parse("1.6.8-alpha-dev", &ver1));
1775 tt_int_op(1, OP_EQ, ver1.major);
1776 tt_int_op(6, OP_EQ, ver1.minor);
1777 tt_int_op(8, OP_EQ, ver1.micro);
1778 tt_int_op(0, OP_EQ, ver1.patchlevel);
1779 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1780 tt_str_op("alpha-dev", OP_EQ, ver1.status_tag);
1781 tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.5-rc", &ver1));
1782 tt_int_op(0, OP_EQ, ver1.major);
1783 tt_int_op(2, OP_EQ, ver1.minor);
1784 tt_int_op(9, OP_EQ, ver1.micro);
1785 tt_int_op(5, OP_EQ, ver1.patchlevel);
1786 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1787 tt_str_op("rc", OP_EQ, ver1.status_tag);
1788 tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.6-rc-dev", &ver1));
1789 tt_int_op(0, OP_EQ, ver1.major);
1790 tt_int_op(2, OP_EQ, ver1.minor);
1791 tt_int_op(9, OP_EQ, ver1.micro);
1792 tt_int_op(6, OP_EQ, ver1.patchlevel);
1793 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1794 tt_str_op("rc-dev", OP_EQ, ver1.status_tag);
1795 tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.8", &ver1));
1796 tt_int_op(0, OP_EQ, ver1.major);
1797 tt_int_op(2, OP_EQ, ver1.minor);
1798 tt_int_op(9, OP_EQ, ver1.micro);
1799 tt_int_op(8, OP_EQ, ver1.patchlevel);
1800 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1801 tt_str_op("", OP_EQ, ver1.status_tag);
1802 tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.9-dev", &ver1));
1803 tt_int_op(0, OP_EQ, ver1.major);
1804 tt_int_op(2, OP_EQ, ver1.minor);
1805 tt_int_op(9, OP_EQ, ver1.micro);
1806 tt_int_op(9, OP_EQ, ver1.patchlevel);
1807 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1808 tt_str_op("dev", OP_EQ, ver1.status_tag);
1809 /* In #21450, we fixed an inconsistency in parsing versions > INT32_MAX
1810 * between i386 and x86_64, as we used tor_parse_long, and then cast to int
1812 tt_int_op(0, OP_EQ, tor_version_parse("0.2147483647.0", &ver1));
1813 tt_int_op(0, OP_EQ, ver1.major);
1814 tt_int_op(2147483647, OP_EQ, ver1.minor);
1815 tt_int_op(0, OP_EQ, ver1.micro);
1816 tt_int_op(0, OP_EQ, ver1.patchlevel);
1817 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1818 tt_str_op("", OP_EQ, ver1.status_tag);
1819 tt_int_op(-1, OP_EQ, tor_version_parse("0.2147483648.0", &ver1));
1820 tt_int_op(-1, OP_EQ, tor_version_parse("0.4294967295.0", &ver1));
1821 /* In #21278, we reject negative version components */
1822 tt_int_op(-1, OP_EQ, tor_version_parse("0.-1.0", &ver1));
1823 tt_int_op(-1, OP_EQ, tor_version_parse("0.-2147483648.0", &ver1));
1824 tt_int_op(-1, OP_EQ, tor_version_parse("0.-4294967295.0", &ver1));
1825 /* In #21507, we reject version components with non-numeric prefixes */
1826 tt_int_op(-1, OP_EQ, tor_version_parse("0.-0.0", &ver1));
1827 tt_int_op(-1, OP_EQ, tor_version_parse("+1.0.0", &ver1));
1828 /* use the list in isspace() */
1829 tt_int_op(-1, OP_EQ, tor_version_parse("0.\t0.0", &ver1));
1830 tt_int_op(-1, OP_EQ, tor_version_parse("0.\n0.0", &ver1));
1831 tt_int_op(-1, OP_EQ, tor_version_parse("0.\v0.0", &ver1));
1832 tt_int_op(-1, OP_EQ, tor_version_parse("0.\f0.0", &ver1));
1833 tt_int_op(-1, OP_EQ, tor_version_parse("0.\r0.0", &ver1));
1834 tt_int_op(-1, OP_EQ, tor_version_parse("0. 0.0", &ver1));
1836 #define tt_versionstatus_op(vs1, op, vs2) \
1837 tt_assert_test_type(vs1,vs2,#vs1" "#op" "#vs2,version_status_t, \
1838 (val1_ op val2_),"%d",TT_EXIT_TEST_FUNCTION)
1839 #define test_v_i_o(val, ver, lst) \
1840 tt_versionstatus_op(val, OP_EQ, tor_version_is_obsolete(ver, lst))
1842 /* make sure tor_version_is_obsolete() works */
1843 test_v_i_o(VS_OLD, "0.0.1", "Tor 0.0.2");
1844 test_v_i_o(VS_OLD, "0.0.1", "0.0.2, Tor 0.0.3");
1845 test_v_i_o(VS_OLD, "0.0.1", "0.0.2,Tor 0.0.3");
1846 test_v_i_o(VS_OLD, "0.0.1","0.0.3,BetterTor 0.0.1");
1847 test_v_i_o(VS_RECOMMENDED, "0.0.2", "Tor 0.0.2,Tor 0.0.3");
1848 test_v_i_o(VS_NEW_IN_SERIES, "0.0.2", "Tor 0.0.2pre1,Tor 0.0.3");
1849 test_v_i_o(VS_OLD, "0.0.2", "Tor 0.0.2.1,Tor 0.0.3");
1850 test_v_i_o(VS_NEW, "0.1.0", "Tor 0.0.2,Tor 0.0.3");
1851 test_v_i_o(VS_RECOMMENDED, "0.0.7rc2", "0.0.7,Tor 0.0.7rc2,Tor 0.0.8");
1852 test_v_i_o(VS_OLD, "0.0.5.0", "0.0.5.1-cvs");
1853 test_v_i_o(VS_NEW_IN_SERIES, "0.0.5.1-cvs", "0.0.5, 0.0.6");
1854 test_v_i_o(VS_NEW, "0.2.9.9-dev", "0.2.9.9");
1855 /* Not on list, but newer than any in same series. */
1856 test_v_i_o(VS_NEW_IN_SERIES, "0.1.0.3",
1857 "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1858 /* Series newer than any on list. */
1859 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");
1860 /* Series older than any on list. */
1861 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");
1862 /* Not on list, not newer than any on same series. */
1863 test_v_i_o(VS_UNRECOMMENDED, "0.1.0.1",
1864 "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1865 /* On list, not newer than any on same series. */
1866 test_v_i_o(VS_UNRECOMMENDED,
1867 "0.1.0.1", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1868 tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.0.5", "0.0.9pre1-cvs"));
1869 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1870 "Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
1871 "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh",
1872 "0.0.8rc2"));
1873 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1874 "Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
1875 "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh", "0.0.8.2"));
1877 /* Now try svn revisions. */
1878 tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
1879 "Tor 0.2.1.0-dev (r99)"));
1880 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1881 "Tor 0.2.1.0-dev (r100) on Banana Jr",
1882 "Tor 0.2.1.0-dev (r99) on Hal 9000"));
1883 tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
1884 "Tor 0.2.1.0-dev on Colossus"));
1885 tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r99)",
1886 "Tor 0.2.1.0-dev (r100)"));
1887 tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r99) on MCP",
1888 "Tor 0.2.1.0-dev (r100) on AM"));
1889 tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev",
1890 "Tor 0.2.1.0-dev (r99)"));
1891 tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.1",
1892 "Tor 0.2.1.0-dev (r99)"));
1893 /* And git revisions */
1894 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1895 "Tor 0.2.9.9 (git-56788a2489127072)",
1896 "Tor 0.2.9.9 (git-56788a2489127072)"));
1897 /* a git revision is newer than no git revision */
1898 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1899 "Tor 0.2.9.9 (git-56788a2489127072)",
1900 "Tor 0.2.9.9"));
1901 /* a longer git revision is newer than a shorter git revision
1902 * this should be true if they prefix-match, but if they don't, they are
1903 * incomparable, because hashes aren't ordered (but we compare their bytes
1904 * anyway) */
1905 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1906 "Tor 0.2.9.9 (git-56788a2489127072d513cf4baf35a8ff475f3c7b)",
1907 "Tor 0.2.9.9 (git-56788a2489127072)"));
1908 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1909 "Tor 0.2.9.9 (git-0102)",
1910 "Tor 0.2.9.9 (git-03)"));
1911 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1912 "Tor 0.2.9.9 (git-0102)",
1913 "Tor 0.2.9.9 (git-00)"));
1914 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1915 "Tor 0.2.9.9 (git-01)",
1916 "Tor 0.2.9.9 (git-00)"));
1917 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1918 "Tor 0.2.9.9 (git-00)",
1919 "Tor 0.2.9.9 (git-01)"));
1920 /* In #21278, we compare without integer overflows.
1921 * But since #21450 limits version components to [0, INT32_MAX], it is no
1922 * longer possible to cause an integer overflow in tor_version_compare() */
1923 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1924 "Tor 0.0.0.0",
1925 "Tor 2147483647.0.0.0"));
1926 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1927 "Tor 2147483647.0.0.0",
1928 "Tor 0.0.0.0"));
1929 /* These versions used to cause an overflow, now they don't parse
1930 * (and authorities reject their descriptors), and log a BUG message */
1931 setup_full_capture_of_logs(LOG_WARN);
1932 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1933 "Tor 0.0.0.0",
1934 "Tor 0.-2147483648.0.0"));
1935 expect_single_log_msg_containing("unparseable");
1936 mock_clean_saved_logs();
1937 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1938 "Tor 0.2147483647.0.0",
1939 "Tor 0.-1.0.0"));
1940 expect_single_log_msg_containing("unparseable");
1941 mock_clean_saved_logs();
1942 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1943 "Tor 0.2147483647.0.0",
1944 "Tor 0.-2147483648.0.0"));
1945 expect_single_log_msg_containing("unparseable");
1946 mock_clean_saved_logs();
1947 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1948 "Tor 4294967295.0.0.0",
1949 "Tor 0.0.0.0"));
1950 expect_no_log_entry();
1951 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1952 "Tor 0.4294967295.0.0",
1953 "Tor 0.-4294967295.0.0"));
1954 expect_single_log_msg_containing("unparseable");
1955 mock_clean_saved_logs();
1956 teardown_capture_of_logs();
1958 /* Now try git revisions */
1959 tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00ff)", &ver1));
1960 tt_int_op(0,OP_EQ, ver1.major);
1961 tt_int_op(5,OP_EQ, ver1.minor);
1962 tt_int_op(6,OP_EQ, ver1.micro);
1963 tt_int_op(7,OP_EQ, ver1.patchlevel);
1964 tt_int_op(3,OP_EQ, ver1.git_tag_len);
1965 tt_mem_op(ver1.git_tag,OP_EQ, "\xff\x00\xff", 3);
1966 /* reject bad hex digits */
1967 tt_int_op(-1,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00xx)", &ver1));
1968 /* reject odd hex digit count */
1969 tt_int_op(-1,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00fff)", &ver1));
1970 /* ignore "git " */
1971 tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git ff00fff)", &ver1));
1972 /* standard length is 16 hex digits */
1973 tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git-0010203040506070)",
1974 &ver1));
1975 /* length limit is 40 hex digits */
1976 tt_int_op(0,OP_EQ, tor_version_parse(
1977 "0.5.6.7 (git-000102030405060708090a0b0c0d0e0f10111213)",
1978 &ver1));
1979 tt_int_op(-1,OP_EQ, tor_version_parse(
1980 "0.5.6.7 (git-000102030405060708090a0b0c0d0e0f1011121314)",
1981 &ver1));
1982 done:
1983 teardown_capture_of_logs();
1986 /** Run unit tests for directory fp_pair functions. */
1987 static void
1988 test_dir_fp_pairs(void *arg)
1990 smartlist_t *sl = smartlist_new();
1991 fp_pair_t *pair;
1993 (void)arg;
1994 dir_split_resource_into_fingerprint_pairs(
1995 /* Two pairs, out of order, with one duplicate. */
1996 "73656372657420646174612E0000000000FFFFFF-"
1997 "557365204145532d32353620696e73746561642e+"
1998 "73656372657420646174612E0000000000FFFFFF-"
1999 "557365204145532d32353620696e73746561642e+"
2000 "48657861646563696d616c2069736e277420736f-"
2001 "676f6f6420666f7220686964696e6720796f7572.z", sl);
2003 tt_int_op(smartlist_len(sl),OP_EQ, 2);
2004 pair = smartlist_get(sl, 0);
2005 tt_mem_op(pair->first,OP_EQ, "Hexadecimal isn't so", DIGEST_LEN);
2006 tt_mem_op(pair->second,OP_EQ, "good for hiding your", DIGEST_LEN);
2007 pair = smartlist_get(sl, 1);
2008 tt_mem_op(pair->first,OP_EQ, "secret data.\0\0\0\0\0\xff\xff\xff",
2009 DIGEST_LEN);
2010 tt_mem_op(pair->second,OP_EQ, "Use AES-256 instead.", DIGEST_LEN);
2012 done:
2013 SMARTLIST_FOREACH(sl, fp_pair_t *, pair_to_free, tor_free(pair_to_free));
2014 smartlist_free(sl);
2017 static void
2018 test_dir_split_fps(void *testdata)
2020 smartlist_t *sl = smartlist_new();
2021 char *mem_op_hex_tmp = NULL;
2022 (void)testdata;
2024 /* Some example hex fingerprints and their base64 equivalents */
2025 #define HEX1 "Fe0daff89127389bc67558691231234551193EEE"
2026 #define HEX2 "Deadbeef99999991111119999911111111f00ba4"
2027 #define HEX3 "b33ff00db33ff00db33ff00db33ff00db33ff00d"
2028 #define HEX256_1 \
2029 "f3f3f3f3fbbbbf3f3f3f3fbbbf3f3f3f3fbbbbf3f3f3f3fbbbf3f3f3f3fbbbbf"
2030 #define HEX256_2 \
2031 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccCCc"
2032 #define HEX256_3 \
2033 "0123456789ABCdef0123456789ABCdef0123456789ABCdef0123456789ABCdef"
2034 #define B64_1 "/g2v+JEnOJvGdVhpEjEjRVEZPu4"
2035 #define B64_2 "3q2+75mZmZERERmZmRERERHwC6Q"
2036 #define B64_256_1 "8/Pz8/u7vz8/Pz+7vz8/Pz+7u/Pz8/P7u/Pz8/P7u78"
2037 #define B64_256_2 "zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMw"
2039 /* no flags set */
2040 dir_split_resource_into_fingerprints("A+C+B", sl, NULL, 0);
2041 tt_int_op(smartlist_len(sl), OP_EQ, 3);
2042 tt_str_op(smartlist_get(sl, 0), OP_EQ, "A");
2043 tt_str_op(smartlist_get(sl, 1), OP_EQ, "C");
2044 tt_str_op(smartlist_get(sl, 2), OP_EQ, "B");
2045 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2046 smartlist_clear(sl);
2048 /* uniq strings. */
2049 dir_split_resource_into_fingerprints("A+C+B+A+B+B", sl, NULL, DSR_SORT_UNIQ);
2050 tt_int_op(smartlist_len(sl), OP_EQ, 3);
2051 tt_str_op(smartlist_get(sl, 0), OP_EQ, "A");
2052 tt_str_op(smartlist_get(sl, 1), OP_EQ, "B");
2053 tt_str_op(smartlist_get(sl, 2), OP_EQ, "C");
2054 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2055 smartlist_clear(sl);
2057 /* Decode hex. */
2058 dir_split_resource_into_fingerprints(HEX1"+"HEX2, sl, NULL, DSR_HEX);
2059 tt_int_op(smartlist_len(sl), OP_EQ, 2);
2060 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX1);
2061 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
2062 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2063 smartlist_clear(sl);
2065 /* decode hex and drop weirdness. */
2066 dir_split_resource_into_fingerprints(HEX1"+bogus+"HEX2"+"HEX256_1,
2067 sl, NULL, DSR_HEX);
2068 tt_int_op(smartlist_len(sl), OP_EQ, 2);
2069 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX1);
2070 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
2071 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2072 smartlist_clear(sl);
2074 /* Decode long hex */
2075 dir_split_resource_into_fingerprints(HEX256_1"+"HEX256_2"+"HEX2"+"HEX256_3,
2076 sl, NULL, DSR_HEX|DSR_DIGEST256);
2077 tt_int_op(smartlist_len(sl), OP_EQ, 3);
2078 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_1);
2079 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX256_2);
2080 test_mem_op_hex(smartlist_get(sl, 2), OP_EQ, HEX256_3);
2081 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2082 smartlist_clear(sl);
2084 /* Decode hex and sort. */
2085 dir_split_resource_into_fingerprints(HEX1"+"HEX2"+"HEX3"+"HEX2,
2086 sl, NULL, DSR_HEX|DSR_SORT_UNIQ);
2087 tt_int_op(smartlist_len(sl), OP_EQ, 3);
2088 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX3);
2089 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
2090 test_mem_op_hex(smartlist_get(sl, 2), OP_EQ, HEX1);
2091 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2092 smartlist_clear(sl);
2094 /* Decode long hex and sort */
2095 dir_split_resource_into_fingerprints(HEX256_1"+"HEX256_2"+"HEX256_3
2096 "+"HEX256_1,
2097 sl, NULL,
2098 DSR_HEX|DSR_DIGEST256|DSR_SORT_UNIQ);
2099 tt_int_op(smartlist_len(sl), OP_EQ, 3);
2100 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_3);
2101 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX256_2);
2102 test_mem_op_hex(smartlist_get(sl, 2), OP_EQ, HEX256_1);
2103 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2104 smartlist_clear(sl);
2106 /* Decode base64 */
2107 dir_split_resource_into_fingerprints(B64_1"-"B64_2, sl, NULL, DSR_BASE64);
2108 tt_int_op(smartlist_len(sl), OP_EQ, 2);
2109 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX1);
2110 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
2111 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2112 smartlist_clear(sl);
2114 /* Decode long base64 */
2115 dir_split_resource_into_fingerprints(B64_256_1"-"B64_256_2,
2116 sl, NULL, DSR_BASE64|DSR_DIGEST256);
2117 tt_int_op(smartlist_len(sl), OP_EQ, 2);
2118 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_1);
2119 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX256_2);
2120 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2121 smartlist_clear(sl);
2123 dir_split_resource_into_fingerprints(B64_256_1,
2124 sl, NULL, DSR_BASE64|DSR_DIGEST256);
2125 tt_int_op(smartlist_len(sl), OP_EQ, 1);
2126 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_1);
2127 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2128 smartlist_clear(sl);
2130 done:
2131 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2132 smartlist_free(sl);
2133 tor_free(mem_op_hex_tmp);
2136 static void
2137 test_dir_measured_bw_kb(void *arg)
2139 measured_bw_line_t mbwl;
2140 int i;
2141 const char *lines_pass[] = {
2142 "node_id=$557365204145532d32353620696e73746561642e bw=1024\n",
2143 /* check whether node_id does not need the dollar sign at the start */
2144 "node_id=557365204145532d32353620696e73746561642e bw=1024\n",
2145 "node_id=$557365204145532d32353620696e73746561642e\t bw=1024 \n",
2146 " node_id=$557365204145532d32353620696e73746561642e bw=1024\n",
2147 "\tnoise\tnode_id=$557365204145532d32353620696e73746561642e "
2148 "bw=1024 junk=007\n",
2149 "misc=junk node_id=$557365204145532d32353620696e73746561642e "
2150 "bw=1024 junk=007\n",
2151 /* check whether node_id can be at the end */
2152 "bw=1024 node_id=$557365204145532d32353620696e73746561642e\n",
2153 /* check whether node_id can be at the end and bw has something in front*/
2154 "foo=bar bw=1024 node_id=$557365204145532d32353620696e73746561642e\n",
2155 /* check whether node_id can be at the end and something in the
2156 * in the middle of bw and node_id */
2157 "bw=1024 foo=bar node_id=$557365204145532d32353620696e73746561642e\n",
2159 /* Test that a line with vote=1 will pass. */
2160 "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=1\n",
2161 /* Test that a line with unmeasured=1 will pass. */
2162 "node_id=$557365204145532d32353620696e73746561642e bw=1024 unmeasured=1\n",
2163 /* Test that a line with vote=1 and unmeasured=1 will pass. */
2164 "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=1"
2165 "unmeasured=1\n",
2166 /* Test that a line with unmeasured=0 will pass. */
2167 "node_id=$557365204145532d32353620696e73746561642e bw=1024 unmeasured=0\n",
2168 /* Test that a line with vote=1 and unmeasured=0 will pass. */
2169 "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=1"
2170 "unmeasured=0\n",
2171 "end"
2173 const char *lines_fail[] = {
2174 /* Test possible python stupidity on input */
2175 "node_id=None bw=1024\n",
2176 "node_id=$None bw=1024\n",
2177 "node_id=$557365204145532d32353620696e73746561642e bw=None\n",
2178 "node_id=$557365204145532d32353620696e73746561642e bw=1024.0\n",
2179 "node_id=$557365204145532d32353620696e73746561642e bw=.1024\n",
2180 "node_id=$557365204145532d32353620696e73746561642e bw=1.024\n",
2181 "node_id=$557365204145532d32353620696e73746561642e bw=1024 bw=0\n",
2182 "node_id=$557365204145532d32353620696e73746561642e bw=1024 bw=None\n",
2183 "node_id=$557365204145532d32353620696e73746561642e bw=-1024\n",
2184 /* Test incomplete writes due to race conditions, partial copies, etc */
2185 "node_i",
2186 "node_i\n",
2187 "node_id=",
2188 "node_id=\n",
2189 "node_id=$557365204145532d32353620696e73746561642e bw=",
2190 "node_id=$557365204145532d32353620696e73746561642e bw=1024",
2191 "node_id=$557365204145532d32353620696e73746561642e bw=\n",
2192 "node_id=$557365204145532d32353620696e7374",
2193 "node_id=$557365204145532d32353620696e7374\n",
2195 "\n",
2196 " \n ",
2197 " \n\n",
2198 /* Test assorted noise */
2199 " node_id= ",
2200 "node_id==$557365204145532d32353620696e73746561642e bw==1024\n",
2201 "node_id=$55736520414552d32353620696e73746561642e bw=1024\n",
2202 "node_id= $557365204145532d32353620696e73746561642e bw=0.23\n",
2204 /* Test that a line with vote=0 will fail too, so that it is ignored. */
2205 "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=0\n",
2206 /* Test that a line with vote=0 will fail even if unmeasured=0. */
2207 ("node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=0 "
2208 "unmeasured=0\n"),
2209 "end"
2212 (void)arg;
2213 for (i = 0; strcmp(lines_fail[i], "end"); i++) {
2214 //fprintf(stderr, "Testing: %s\n", lines_fail[i]);
2215 /* Testing only with line_is_after_headers = 1. Tests with
2216 * line_is_after_headers = 0 in
2217 * test_dir_measured_bw_kb_line_is_after_headers */
2218 tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 1) == -1);
2221 for (i = 0; strcmp(lines_pass[i], "end"); i++) {
2222 //fprintf(stderr, "Testing: %s %d\n", lines_pass[i], TOR_ISSPACE('\n'));
2223 /* Testing only with line_is_after_headers = 1. Tests with
2224 * line_is_after_headers = 0 in
2225 * test_dir_measured_bw_kb_line_is_after_headers */
2226 tt_assert(measured_bw_line_parse(&mbwl, lines_pass[i], 1) == 0);
2227 tt_assert(mbwl.bw_kb == 1024);
2228 tt_assert(strcmp(mbwl.node_hex,
2229 "557365204145532d32353620696e73746561642e") == 0);
2232 done:
2233 return;
2236 /* Unit tests for measured_bw_line_parse using line_is_after_headers flag.
2237 * When the end of the header is detected (a first complete bw line is parsed),
2238 * incomplete lines fail and give warnings, but do not give warnings if
2239 * the header is not ended, allowing to ignore additional header lines. */
2240 static void
2241 test_dir_measured_bw_kb_line_is_after_headers(void *arg)
2243 (void)arg;
2244 measured_bw_line_t mbwl;
2245 const char *line_pass = \
2246 "node_id=$557365204145532d32353620696e73746561642e bw=1024\n";
2247 int i;
2248 const char *lines_fail[] = {
2249 "node_id=$557365204145532d32353620696e73746561642e \n",
2250 "bw=1024\n",
2251 "rtt=300\n",
2252 "end"
2255 setup_capture_of_logs(LOG_DEBUG);
2257 /* Test bw lines when header has ended */
2258 for (i = 0; strcmp(lines_fail[i], "end"); i++) {
2259 tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 1) == -1);
2260 expect_log_msg_containing("Incomplete line in bandwidth file:");
2261 mock_clean_saved_logs();
2264 tt_assert(measured_bw_line_parse(&mbwl, line_pass, 1) == 0);
2266 /* Test bw lines when header has not ended */
2267 for (i = 0; strcmp(lines_fail[i], "end"); i++) {
2268 tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 0) == -1);
2269 expect_log_msg_containing("Missing bw or node_id in bandwidth file line:");
2270 mock_clean_saved_logs();
2273 tt_assert(measured_bw_line_parse(&mbwl, line_pass, 0) == 0);
2275 done:
2276 teardown_capture_of_logs();
2279 /* Test dirserv_read_measured_bandwidths with headers and complete files. */
2280 static void
2281 test_dir_dirserv_read_measured_bandwidths(void *arg)
2283 (void)arg;
2284 char *content = NULL;
2285 time_t timestamp = time(NULL);
2286 char *fname = tor_strdup(get_fname("V3BandwidthsFile"));
2287 smartlist_t *bw_file_headers = smartlist_new();
2288 /* bw file strings in vote */
2289 char *bw_file_headers_str = NULL;
2290 char *bw_file_headers_str_v100 = NULL;
2291 char *bw_file_headers_str_v110 = NULL;
2292 char *bw_file_headers_str_bad = NULL;
2293 char *bw_file_headers_str_extra = NULL;
2294 char bw_file_headers_str_long[MAX_BW_FILE_HEADER_COUNT_IN_VOTE * 8 + 1] = "";
2295 /* string header lines in bw file */
2296 char *header_lines_v100 = NULL;
2297 char *header_lines_v110_no_terminator = NULL;
2298 char *header_lines_v110 = NULL;
2299 char header_lines_long[MAX_BW_FILE_HEADER_COUNT_IN_VOTE * 8 + 1] = "";
2300 int i;
2301 const char *header_lines_v110_no_terminator_no_timestamp =
2302 "version=1.1.0\n"
2303 "software=sbws\n"
2304 "software_version=0.1.0\n"
2305 "earliest_bandwidth=2018-05-08T16:13:26\n"
2306 "file_created=2018-04-16T21:49:18\n"
2307 "generator_started=2018-05-08T16:13:25\n"
2308 "latest_bandwidth=2018-04-16T20:49:18\n";
2309 const char *bw_file_headers_str_v110_no_timestamp =
2310 "version=1.1.0 software=sbws "
2311 "software_version=0.1.0 "
2312 "earliest_bandwidth=2018-05-08T16:13:26 "
2313 "file_created=2018-04-16T21:49:18 "
2314 "generator_started=2018-05-08T16:13:25 "
2315 "latest_bandwidth=2018-04-16T20:49:18";
2316 const char *relay_lines_v100 =
2317 "node_id=$557365204145532d32353620696e73746561642e bw=1024 "
2318 "nick=Test measured_at=1523911725 updated_at=1523911725 "
2319 "pid_error=4.11374090719 pid_error_sum=4.11374090719 "
2320 "pid_bw=57136645 pid_delta=2.12168374577 circ_fail=0.2 "
2321 "scanner=/filepath\n";
2322 const char *relay_lines_v110 =
2323 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 "
2324 "master_key_ed25519=YaqV4vbvPYKucElk297eVdNArDz9HtIwUoIeo0+cVIpQ "
2325 "bw=760 nick=Test rtt=380 time=2018-05-08T16:13:26\n";
2326 const char *relay_lines_bad =
2327 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A\n";
2329 tor_asprintf(&header_lines_v100, "%ld\n", (long)timestamp);
2330 tor_asprintf(&header_lines_v110_no_terminator, "%ld\n%s", (long)timestamp,
2331 header_lines_v110_no_terminator_no_timestamp);
2332 tor_asprintf(&header_lines_v110, "%s%s",
2333 header_lines_v110_no_terminator, BW_FILE_HEADERS_TERMINATOR);
2335 tor_asprintf(&bw_file_headers_str_v100, "timestamp=%ld",(long)timestamp);
2336 tor_asprintf(&bw_file_headers_str_v110, "timestamp=%ld %s",
2337 (long)timestamp, bw_file_headers_str_v110_no_timestamp);
2338 tor_asprintf(&bw_file_headers_str_bad, "%s "
2339 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A",
2340 bw_file_headers_str_v110);
2342 for (i=0; i<MAX_BW_FILE_HEADER_COUNT_IN_VOTE; i++) {
2343 strlcat(header_lines_long, "foo=bar\n",
2344 sizeof(header_lines_long));
2346 /* 8 is the number of v110 lines in header_lines_v110 */
2347 for (i=0; i<MAX_BW_FILE_HEADER_COUNT_IN_VOTE - 8 - 1; i++) {
2348 strlcat(bw_file_headers_str_long, "foo=bar ",
2349 sizeof(bw_file_headers_str_long));
2351 strlcat(bw_file_headers_str_long, "foo=bar",
2352 sizeof(bw_file_headers_str_long));
2353 tor_asprintf(&bw_file_headers_str_extra,
2354 "%s %s",
2355 bw_file_headers_str_v110,
2356 bw_file_headers_str_long);
2358 /* Test an empty bandwidth file. bw_file_headers will be empty string */
2359 write_str_to_file(fname, "", 0);
2360 setup_capture_of_logs(LOG_WARN);
2361 tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2362 bw_file_headers,
2363 NULL));
2364 expect_log_msg("Empty bandwidth file\n");
2365 teardown_capture_of_logs();
2366 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2367 tt_str_op("", OP_EQ, bw_file_headers_str);
2368 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2369 smartlist_free(bw_file_headers);
2370 tor_free(bw_file_headers_str);
2372 /* Test bandwidth file with only timestamp.
2373 * bw_file_headers will be empty string */
2374 bw_file_headers = smartlist_new();
2375 tor_asprintf(&content, "%ld", (long)timestamp);
2376 write_str_to_file(fname, content, 0);
2377 tor_free(content);
2378 tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2379 bw_file_headers,
2380 NULL));
2382 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2383 tt_str_op("", OP_EQ, bw_file_headers_str);
2384 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2385 smartlist_free(bw_file_headers);
2386 tor_free(bw_file_headers_str);
2388 /* Test v1.0.0 bandwidth file headers */
2389 write_str_to_file(fname, header_lines_v100, 0);
2390 bw_file_headers = smartlist_new();
2391 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2392 bw_file_headers,
2393 NULL));
2395 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2396 tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
2397 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2398 smartlist_free(bw_file_headers);
2399 tor_free(bw_file_headers_str);
2401 /* Test v1.0.0 complete bandwidth file */
2402 bw_file_headers = smartlist_new();
2403 tor_asprintf(&content, "%s%s", header_lines_v100, relay_lines_v100);
2404 write_str_to_file(fname, content, 0);
2405 tor_free(content);
2406 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2407 bw_file_headers,
2408 NULL));
2410 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2411 tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
2412 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2413 smartlist_free(bw_file_headers);
2414 tor_free(bw_file_headers_str);
2416 /* Test v1.0.0 complete bandwidth file with NULL bw_file_headers. */
2417 tor_asprintf(&content, "%s%s", header_lines_v100, relay_lines_v100);
2418 write_str_to_file(fname, content, 0);
2419 tor_free(content);
2420 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, NULL,
2421 NULL));
2423 /* Test bandwidth file including v1.1.0 bandwidth headers and
2424 * v1.0.0 relay lines. bw_file_headers will contain the v1.1.0 headers. */
2425 bw_file_headers = smartlist_new();
2426 tor_asprintf(&content, "%s%s%s", header_lines_v100, header_lines_v110,
2427 relay_lines_v100);
2428 write_str_to_file(fname, content, 0);
2429 tor_free(content);
2430 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2431 bw_file_headers,
2432 NULL));
2434 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2435 tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2436 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2437 smartlist_free(bw_file_headers);
2438 tor_free(bw_file_headers_str);
2440 /* Test v1.0.0 complete bandwidth file with v1.1.0 headers at the end.
2441 * bw_file_headers will contain only v1.0.0 headers and the additional
2442 * headers will be interpreted as malformed relay lines. */
2443 bw_file_headers = smartlist_new();
2444 tor_asprintf(&content, "%s%s%s", header_lines_v100, relay_lines_v100,
2445 header_lines_v110);
2446 write_str_to_file(fname, content, 0);
2447 tor_free(content);
2448 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2449 bw_file_headers,
2450 NULL));
2452 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2453 tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
2454 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2455 smartlist_free(bw_file_headers);
2456 tor_free(bw_file_headers_str);
2458 /* Test v1.0.0 complete bandwidth file, the v1.1.0 headers and more relay
2459 * lines. bw_file_headers will contain only v1.0.0 headers, the additional
2460 * headers will be interpreted as malformed relay lines and the last relay
2461 * lines will be correctly interpreted as relay lines. */
2462 bw_file_headers = smartlist_new();
2463 tor_asprintf(&content, "%s%s%s%s", header_lines_v100, relay_lines_v100,
2464 header_lines_v110, relay_lines_v100);
2465 write_str_to_file(fname, content, 0);
2466 tor_free(content);
2467 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2468 bw_file_headers,
2469 NULL));
2471 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2472 tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
2473 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2474 smartlist_free(bw_file_headers);
2475 tor_free(bw_file_headers_str);
2477 /* Test v1.1.0 bandwidth headers without terminator */
2478 bw_file_headers = smartlist_new();
2479 write_str_to_file(fname, header_lines_v110_no_terminator, 0);
2480 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2481 bw_file_headers,
2482 NULL));
2484 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2485 tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2486 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2487 smartlist_free(bw_file_headers);
2488 tor_free(bw_file_headers_str);
2490 /* Test v1.1.0 bandwidth headers with terminator */
2491 bw_file_headers = smartlist_new();
2492 write_str_to_file(fname, header_lines_v110, 0);
2493 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2494 bw_file_headers,
2495 NULL));
2497 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2498 tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2499 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2500 smartlist_free(bw_file_headers);
2501 tor_free(bw_file_headers_str);
2503 /* Test v1.1.0 bandwidth file without terminator, then relay lines.
2504 * bw_file_headers will contain the v1.1.0 headers. */
2505 bw_file_headers = smartlist_new();
2506 tor_asprintf(&content, "%s%s",
2507 header_lines_v110_no_terminator, relay_lines_v110);
2508 write_str_to_file(fname, content, 0);
2509 tor_free(content);
2510 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2511 bw_file_headers,
2512 NULL));
2514 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2515 tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2516 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2517 smartlist_free(bw_file_headers);
2518 tor_free(bw_file_headers_str);
2520 /* Test v1.1.0 bandwidth headers with terminator, then relay lines
2521 * bw_file_headers will contain the v1.1.0 headers. */
2522 bw_file_headers = smartlist_new();
2523 tor_asprintf(&content, "%s%s",
2524 header_lines_v110, relay_lines_v110);
2525 write_str_to_file(fname, content, 0);
2526 tor_free(content);
2527 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2528 bw_file_headers,
2529 NULL));
2531 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2532 tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2533 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2534 smartlist_free(bw_file_headers);
2535 tor_free(bw_file_headers_str);
2537 /* Test v1.1.0 bandwidth headers with terminator, then bad relay lines,
2538 * then terminator, then relay_lines_bad.
2539 * bw_file_headers will contain the v1.1.0 headers. */
2540 bw_file_headers = smartlist_new();
2541 tor_asprintf(&content, "%s%s%s%s", header_lines_v110, relay_lines_bad,
2542 BW_FILE_HEADERS_TERMINATOR, relay_lines_bad);
2543 write_str_to_file(fname, content, 0);
2544 tor_free(content);
2545 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2546 bw_file_headers,
2547 NULL));
2549 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2550 tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2551 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2552 smartlist_free(bw_file_headers);
2553 tor_free(bw_file_headers_str);
2555 /* Test v1.1.0 bandwidth headers without terminator, then bad relay lines,
2556 * then relay lines. bw_file_headers will contain the v1.1.0 headers and
2557 * the bad relay lines. */
2558 bw_file_headers = smartlist_new();
2559 tor_asprintf(&content, "%s%s%s",
2560 header_lines_v110_no_terminator, relay_lines_bad,
2561 relay_lines_v110);
2562 write_str_to_file(fname, content, 0);
2563 tor_free(content);
2564 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2565 bw_file_headers,
2566 NULL));
2568 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2569 tt_str_op(bw_file_headers_str_bad, OP_EQ, bw_file_headers_str);
2570 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2571 smartlist_free(bw_file_headers);
2572 tor_free(bw_file_headers_str);
2574 /* Test v1.1.0 bandwidth headers without terminator,
2575 * then many bad relay lines, then relay lines.
2576 * bw_file_headers will contain the v1.1.0 headers and the bad relay lines
2577 * to a maximum of MAX_BW_FILE_HEADER_COUNT_IN_VOTE header lines. */
2578 bw_file_headers = smartlist_new();
2579 tor_asprintf(&content, "%s%s%s",
2580 header_lines_v110_no_terminator, header_lines_long,
2581 relay_lines_v110);
2582 write_str_to_file(fname, content, 0);
2583 tor_free(content);
2584 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2585 bw_file_headers,
2586 NULL));
2588 tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_EQ,
2589 smartlist_len(bw_file_headers));
2590 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2591 tt_str_op(bw_file_headers_str_extra, OP_EQ, bw_file_headers_str);
2592 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2593 smartlist_free(bw_file_headers);
2594 tor_free(bw_file_headers_str);
2596 /* Test v1.1.0 bandwidth headers without terminator,
2597 * then many bad relay lines, then relay lines.
2598 * bw_file_headers will contain the v1.1.0 headers and the bad relay lines.
2599 * Force bw_file_headers to have more than MAX_BW_FILE_HEADER_COUNT_IN_VOTE
2600 * This test is needed while there is not dirvote test. */
2601 bw_file_headers = smartlist_new();
2602 tor_asprintf(&content, "%s%s%s",
2603 header_lines_v110_no_terminator, header_lines_long,
2604 relay_lines_v110);
2605 write_str_to_file(fname, content, 0);
2606 tor_free(content);
2607 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2608 bw_file_headers,
2609 NULL));
2611 tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_EQ,
2612 smartlist_len(bw_file_headers));
2613 /* force bw_file_headers to be bigger than
2614 * MAX_BW_FILE_HEADER_COUNT_IN_VOTE */
2615 char line[8] = "foo=bar\0";
2616 smartlist_add_strdup(bw_file_headers, line);
2617 tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_LT,
2618 smartlist_len(bw_file_headers));
2619 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2620 smartlist_free(bw_file_headers);
2621 tor_free(bw_file_headers_str);
2623 /* Test v1.x.x bandwidth line with vote=0.
2624 * It will be ignored it and logged it at debug level. */
2625 const char *relay_lines_ignore =
2626 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=0\n"
2627 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=0"
2628 "unmeasured=1\n"
2629 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=0"
2630 "unmeasured=0\n";
2632 /* Create the bandwidth file */
2633 tor_asprintf(&content, "%ld\n%s", (long)timestamp, relay_lines_ignore);
2634 write_str_to_file(fname, content, 0);
2635 tor_free(content);
2637 /* Read the bandwidth file */
2638 setup_full_capture_of_logs(LOG_DEBUG);
2639 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, NULL,
2640 NULL));
2641 expect_log_msg_containing("Ignoring bandwidth file line");
2642 teardown_capture_of_logs();
2644 /* Test v1.x.x bandwidth line with "vote=1" or "unmeasured=1" or
2645 * "unmeasured=0".
2646 * They will not be ignored. */
2647 /* Create the bandwidth file */
2648 const char *relay_lines_vote =
2649 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=1\n"
2650 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 unmeasured=0\n"
2651 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 unmeasured=1\n";
2652 tor_asprintf(&content, "%ld\n%s", (long)timestamp, relay_lines_vote);
2653 write_str_to_file(fname, content, 0);
2654 tor_free(content);
2656 /* Read the bandwidth file */
2657 setup_full_capture_of_logs(LOG_DEBUG);
2658 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, NULL,
2659 NULL));
2660 expect_log_msg_not_containing("Ignoring bandwidth file line");
2661 teardown_capture_of_logs();
2663 done:
2664 unlink(fname);
2665 tor_free(fname);
2666 tor_free(header_lines_v100);
2667 tor_free(header_lines_v110_no_terminator);
2668 tor_free(header_lines_v110);
2669 tor_free(bw_file_headers_str_v100);
2670 tor_free(bw_file_headers_str_v110);
2671 tor_free(bw_file_headers_str_bad);
2672 tor_free(bw_file_headers_str_extra);
2675 #define MBWC_INIT_TIME 1000
2677 /** Do the measured bandwidth cache unit test */
2678 static void
2679 test_dir_measured_bw_kb_cache(void *arg)
2681 /* Initial fake time_t for testing */
2682 time_t curr = MBWC_INIT_TIME;
2683 /* Some measured_bw_line_ts */
2684 measured_bw_line_t mbwl[3];
2685 /* For receiving output on cache queries */
2686 long bw;
2687 time_t as_of;
2689 /* First, clear the cache and assert that it's empty */
2690 (void)arg;
2691 dirserv_clear_measured_bw_cache();
2692 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 0);
2694 * Set up test mbwls; none of the dirserv_cache_*() functions care about
2695 * the node_hex field.
2697 memset(mbwl[0].node_id, 0x01, DIGEST_LEN);
2698 mbwl[0].bw_kb = 20;
2699 memset(mbwl[1].node_id, 0x02, DIGEST_LEN);
2700 mbwl[1].bw_kb = 40;
2701 memset(mbwl[2].node_id, 0x03, DIGEST_LEN);
2702 mbwl[2].bw_kb = 80;
2703 /* Try caching something */
2704 dirserv_cache_measured_bw(&(mbwl[0]), curr);
2705 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 1);
2706 /* Okay, let's see if we can retrieve it */
2707 tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, &as_of));
2708 tt_int_op(bw,OP_EQ, 20);
2709 tt_int_op(as_of,OP_EQ, MBWC_INIT_TIME);
2710 /* Try retrieving it without some outputs */
2711 tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL, NULL));
2712 tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, NULL));
2713 tt_int_op(bw,OP_EQ, 20);
2714 tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL,&as_of));
2715 tt_int_op(as_of,OP_EQ, MBWC_INIT_TIME);
2716 /* Now expire it */
2717 curr += MAX_MEASUREMENT_AGE + 1;
2718 dirserv_expire_measured_bw_cache(curr);
2719 /* Check that the cache is empty */
2720 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 0);
2721 /* Check that we can't retrieve it */
2722 tt_assert(!dirserv_query_measured_bw_cache_kb(mbwl[0].node_id, NULL,NULL));
2723 /* Try caching a few things now */
2724 dirserv_cache_measured_bw(&(mbwl[0]), curr);
2725 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 1);
2726 curr += MAX_MEASUREMENT_AGE / 4;
2727 dirserv_cache_measured_bw(&(mbwl[1]), curr);
2728 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 2);
2729 curr += MAX_MEASUREMENT_AGE / 4;
2730 dirserv_cache_measured_bw(&(mbwl[2]), curr);
2731 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 3);
2732 curr += MAX_MEASUREMENT_AGE / 4 + 1;
2733 /* Do an expire that's too soon to get any of them */
2734 dirserv_expire_measured_bw_cache(curr);
2735 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 3);
2736 /* Push the oldest one off the cliff */
2737 curr += MAX_MEASUREMENT_AGE / 4;
2738 dirserv_expire_measured_bw_cache(curr);
2739 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 2);
2740 /* And another... */
2741 curr += MAX_MEASUREMENT_AGE / 4;
2742 dirserv_expire_measured_bw_cache(curr);
2743 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 1);
2744 /* This should empty it out again */
2745 curr += MAX_MEASUREMENT_AGE / 4;
2746 dirserv_expire_measured_bw_cache(curr);
2747 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 0);
2749 done:
2750 return;
2753 static char *
2754 my_dirvote_compute_params(smartlist_t *votes, int method,
2755 int total_authorities)
2757 smartlist_t *s = dirvote_compute_params(votes, method, total_authorities);
2758 tor_assert(s);
2759 char *res = smartlist_join_strings(s, " ", 0, NULL);
2760 SMARTLIST_FOREACH(s, char *, cp, tor_free(cp));
2761 smartlist_free(s);
2762 return res;
2765 #define dirvote_compute_params my_dirvote_compute_params
2767 static void
2768 test_dir_param_voting(void *arg)
2770 networkstatus_t vote1, vote2, vote3, vote4;
2771 smartlist_t *votes = smartlist_new();
2772 char *res = NULL;
2774 /* dirvote_compute_params only looks at the net_params field of the votes,
2775 so that's all we need to set.
2777 (void)arg;
2778 memset(&vote1, 0, sizeof(vote1));
2779 memset(&vote2, 0, sizeof(vote2));
2780 memset(&vote3, 0, sizeof(vote3));
2781 memset(&vote4, 0, sizeof(vote4));
2782 vote1.net_params = smartlist_new();
2783 vote2.net_params = smartlist_new();
2784 vote3.net_params = smartlist_new();
2785 vote4.net_params = smartlist_new();
2786 smartlist_split_string(vote1.net_params,
2787 "ab=90 abcd=20 cw=50 x-yz=-99", NULL, 0, 0);
2788 smartlist_split_string(vote2.net_params,
2789 "ab=27 cw=5 x-yz=88", NULL, 0, 0);
2790 smartlist_split_string(vote3.net_params,
2791 "abcd=20 c=60 cw=500 x-yz=-9 zzzzz=101", NULL, 0, 0);
2792 smartlist_split_string(vote4.net_params,
2793 "ab=900 abcd=200 c=1 cw=51 x-yz=100", NULL, 0, 0);
2794 tt_int_op(100,OP_EQ, networkstatus_get_param(&vote4, "x-yz", 50, 0, 300));
2795 tt_int_op(222,OP_EQ, networkstatus_get_param(&vote4, "foobar", 222, 0, 300));
2796 tt_int_op(80,OP_EQ, networkstatus_get_param(&vote4, "ab", 12, 0, 80));
2797 tt_int_op(-8,OP_EQ, networkstatus_get_param(&vote4, "ab", -12, -100, -8));
2798 tt_int_op(0,OP_EQ, networkstatus_get_param(&vote4, "foobar", 0, -100, 8));
2800 tt_int_op(100,OP_EQ, networkstatus_get_overridable_param(
2801 &vote4, -1, "x-yz", 50, 0, 300));
2802 tt_int_op(30,OP_EQ, networkstatus_get_overridable_param(
2803 &vote4, 30, "x-yz", 50, 0, 300));
2804 tt_int_op(0,OP_EQ, networkstatus_get_overridable_param(
2805 &vote4, -101, "foobar", 0, -100, 8));
2806 tt_int_op(-99,OP_EQ, networkstatus_get_overridable_param(
2807 &vote4, -99, "foobar", 0, -100, 8));
2809 smartlist_add(votes, &vote1);
2811 /* Do the first tests without adding all the other votes, for
2812 * networks without many dirauths. */
2814 res = dirvote_compute_params(votes, 12, 2);
2815 tt_str_op(res,OP_EQ, "");
2816 tor_free(res);
2818 res = dirvote_compute_params(votes, 12, 1);
2819 tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-99");
2820 tor_free(res);
2822 smartlist_add(votes, &vote2);
2824 res = dirvote_compute_params(votes, 12, 2);
2825 tt_str_op(res,OP_EQ, "ab=27 cw=5 x-yz=-99");
2826 tor_free(res);
2828 res = dirvote_compute_params(votes, 12, 3);
2829 tt_str_op(res,OP_EQ, "ab=27 cw=5 x-yz=-99");
2830 tor_free(res);
2832 res = dirvote_compute_params(votes, 12, 6);
2833 tt_str_op(res,OP_EQ, "");
2834 tor_free(res);
2836 smartlist_add(votes, &vote3);
2838 res = dirvote_compute_params(votes, 12, 3);
2839 tt_str_op(res,OP_EQ, "ab=27 abcd=20 cw=50 x-yz=-9");
2840 tor_free(res);
2842 res = dirvote_compute_params(votes, 12, 5);
2843 tt_str_op(res,OP_EQ, "cw=50 x-yz=-9");
2844 tor_free(res);
2846 res = dirvote_compute_params(votes, 12, 9);
2847 tt_str_op(res,OP_EQ, "cw=50 x-yz=-9");
2848 tor_free(res);
2850 smartlist_add(votes, &vote4);
2852 res = dirvote_compute_params(votes, 12, 4);
2853 tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
2854 tor_free(res);
2856 res = dirvote_compute_params(votes, 12, 5);
2857 tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
2858 tor_free(res);
2860 /* Test that the special-cased "at least three dirauths voted for
2861 * this param" logic works as expected. */
2862 res = dirvote_compute_params(votes, 12, 6);
2863 tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
2864 tor_free(res);
2866 res = dirvote_compute_params(votes, 12, 10);
2867 tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
2868 tor_free(res);
2870 done:
2871 tor_free(res);
2872 SMARTLIST_FOREACH(vote1.net_params, char *, cp, tor_free(cp));
2873 SMARTLIST_FOREACH(vote2.net_params, char *, cp, tor_free(cp));
2874 SMARTLIST_FOREACH(vote3.net_params, char *, cp, tor_free(cp));
2875 SMARTLIST_FOREACH(vote4.net_params, char *, cp, tor_free(cp));
2876 smartlist_free(vote1.net_params);
2877 smartlist_free(vote2.net_params);
2878 smartlist_free(vote3.net_params);
2879 smartlist_free(vote4.net_params);
2880 smartlist_free(votes);
2882 return;
2885 static void
2886 test_dir_param_voting_lookup(void *arg)
2888 (void)arg;
2889 smartlist_t *lst = smartlist_new();
2891 smartlist_split_string(lst,
2892 "moomin=9 moomin=10 moomintroll=5 fred "
2893 "jack= electricity=sdk opa=6z abc=9 abcd=99",
2894 NULL, 0, 0);
2896 tt_int_op(1000,
2897 OP_EQ, dirvote_get_intermediate_param_value(lst, "ab", 1000));
2898 tt_int_op(9, OP_EQ, dirvote_get_intermediate_param_value(lst, "abc", 1000));
2899 tt_int_op(99, OP_EQ,
2900 dirvote_get_intermediate_param_value(lst, "abcd", 1000));
2902 #ifndef ALL_BUGS_ARE_FATAL
2903 /* moomin appears twice. That's a bug. */
2904 tor_capture_bugs_(1);
2905 tt_int_op(-100, OP_EQ,
2906 dirvote_get_intermediate_param_value(lst, "moomin", -100));
2907 tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
2908 tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
2909 "n_found == 0");
2910 tor_end_capture_bugs_();
2911 /* There is no 'fred=', so that is treated as not existing. */
2912 tt_int_op(-100, OP_EQ,
2913 dirvote_get_intermediate_param_value(lst, "fred", -100));
2914 /* jack is truncated */
2915 tor_capture_bugs_(1);
2916 tt_int_op(-100, OP_EQ,
2917 dirvote_get_intermediate_param_value(lst, "jack", -100));
2918 tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
2919 tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
2920 "!(!ok)");
2921 tor_end_capture_bugs_();
2922 /* electricity and opa aren't integers. */
2923 tor_capture_bugs_(1);
2924 tt_int_op(-100, OP_EQ,
2925 dirvote_get_intermediate_param_value(lst, "electricity", -100));
2926 tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
2927 tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
2928 "!(!ok)");
2929 tor_end_capture_bugs_();
2931 tor_capture_bugs_(1);
2932 tt_int_op(-100, OP_EQ,
2933 dirvote_get_intermediate_param_value(lst, "opa", -100));
2934 tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
2935 tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
2936 "!(!ok)");
2937 tor_end_capture_bugs_();
2938 #endif /* !defined(ALL_BUGS_ARE_FATAL) */
2940 done:
2941 SMARTLIST_FOREACH(lst, char *, cp, tor_free(cp));
2942 smartlist_free(lst);
2943 tor_end_capture_bugs_();
2946 #undef dirvote_compute_params
2948 /** Helper: Test that two networkstatus_voter_info_t do in fact represent the
2949 * same voting authority, and that they do in fact have all the same
2950 * information. */
2951 static void
2952 test_same_voter(networkstatus_voter_info_t *v1,
2953 networkstatus_voter_info_t *v2)
2955 tt_str_op(v1->nickname,OP_EQ, v2->nickname);
2956 tt_mem_op(v1->identity_digest,OP_EQ, v2->identity_digest, DIGEST_LEN);
2957 tt_str_op(v1->address,OP_EQ, v2->address);
2958 tt_assert(tor_addr_eq(&v1->ipv4_addr, &v2->ipv4_addr));
2959 tt_int_op(v1->ipv4_dirport,OP_EQ, v2->ipv4_dirport);
2960 tt_int_op(v1->ipv4_orport,OP_EQ, v2->ipv4_orport);
2961 tt_str_op(v1->contact,OP_EQ, v2->contact);
2962 tt_mem_op(v1->vote_digest,OP_EQ, v2->vote_digest, DIGEST_LEN);
2963 done:
2967 /** Helper: get a detached signatures document for one or two
2968 * consensuses. */
2969 static char *
2970 get_detached_sigs(networkstatus_t *ns, networkstatus_t *ns2)
2972 char *r;
2973 smartlist_t *sl;
2974 tor_assert(ns && ns->flavor == FLAV_NS);
2975 sl = smartlist_new();
2976 smartlist_add(sl,ns);
2977 if (ns2)
2978 smartlist_add(sl,ns2);
2979 r = networkstatus_get_detached_signatures(sl);
2980 smartlist_free(sl);
2981 return r;
2984 /** Apply tweaks to the vote list for each voter */
2985 static int
2986 vote_tweaks_for_v3ns(networkstatus_t *v, int voter, time_t now)
2988 vote_routerstatus_t *vrs;
2989 const char *msg = NULL;
2991 tt_assert(v);
2992 (void)now;
2994 if (voter == 1) {
2995 measured_bw_line_t mbw;
2996 memset(mbw.node_id, 33, sizeof(mbw.node_id));
2997 mbw.bw_kb = 1024;
2998 tt_int_op(measured_bw_line_apply(&mbw, v->routerstatus_list), OP_EQ, 1);
2999 } else if (voter == 2 || voter == 3) {
3000 /* Monkey around with the list a bit */
3001 vrs = smartlist_get(v->routerstatus_list, 2);
3002 smartlist_del_keeporder(v->routerstatus_list, 2);
3003 vote_routerstatus_free(vrs);
3004 vrs = smartlist_get(v->routerstatus_list, 0);
3005 vrs->status.is_fast = 1;
3007 if (voter == 3) {
3008 vrs = smartlist_get(v->routerstatus_list, 0);
3009 smartlist_del_keeporder(v->routerstatus_list, 0);
3010 vote_routerstatus_free(vrs);
3011 vrs = smartlist_get(v->routerstatus_list, 0);
3012 memset(vrs->status.descriptor_digest, (int)'Z', DIGEST_LEN);
3013 tt_assert(router_add_to_routerlist(
3014 dir_common_generate_ri_from_rs(vrs), &msg,0,0) >= 0);
3018 done:
3019 return 0;
3023 * Test a parsed vote_routerstatus_t for v3_networkstatus test
3025 static void
3026 test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
3028 routerstatus_t *rs;
3029 tor_addr_t addr_ipv6;
3031 tt_assert(vrs);
3032 rs = &(vrs->status);
3033 tt_assert(rs);
3035 /* Split out by digests to test */
3036 if (tor_memeq(rs->identity_digest,
3037 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
3038 "\x3\x3\x3\x3",
3039 DIGEST_LEN) &&
3040 (voter == 1)) {
3041 /* Check the first routerstatus. */
3042 tt_str_op(vrs->version,OP_EQ, "0.1.2.14");
3043 tt_int_op(vrs->published_on,OP_EQ, now-1500);
3044 tt_str_op(rs->nickname,OP_EQ, "router2");
3045 tt_mem_op(rs->identity_digest,OP_EQ,
3046 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
3047 "\x3\x3\x3\x3",
3048 DIGEST_LEN);
3049 tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
3050 tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99008801));
3051 tt_int_op(rs->ipv4_orport,OP_EQ, 443);
3052 tt_int_op(rs->ipv4_dirport,OP_EQ, 8000);
3053 /* no flags except "running" (16) and "v2dir" (64) and "valid" (128) */
3054 tt_u64_op(vrs->flags, OP_EQ, UINT64_C(0xd0));
3055 } else if (tor_memeq(rs->identity_digest,
3056 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
3057 "\x5\x5\x5\x5",
3058 DIGEST_LEN) &&
3059 (voter == 1 || voter == 2)) {
3060 tt_mem_op(rs->identity_digest,OP_EQ,
3061 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
3062 "\x5\x5\x5\x5",
3063 DIGEST_LEN);
3065 if (voter == 1) {
3066 /* Check the second routerstatus. */
3067 tt_str_op(vrs->version,OP_EQ, "0.2.0.5");
3068 tt_int_op(vrs->published_on,OP_EQ, now-1000);
3069 tt_str_op(rs->nickname,OP_EQ, "router1");
3071 tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
3072 tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
3073 tt_int_op(rs->ipv4_orport,OP_EQ, 443);
3074 tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
3075 tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
3076 tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
3077 tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
3078 if (voter == 1) {
3079 /* all except "authority" (1) */
3080 tt_u64_op(vrs->flags, OP_EQ, UINT64_C(254));
3081 } else {
3082 /* 1023 - authority(1) - madeofcheese(16) - madeoftin(32) */
3083 tt_u64_op(vrs->flags, OP_EQ, UINT64_C(974));
3085 } else if (tor_memeq(rs->identity_digest,
3086 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
3087 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
3088 DIGEST_LEN) &&
3089 (voter == 1 || voter == 2)) {
3090 /* Check the measured bandwidth bits */
3091 tt_assert(vrs->has_measured_bw &&
3092 vrs->measured_bw_kb == 1024);
3093 } else {
3095 * Didn't expect this, but the old unit test only checked some of them,
3096 * so don't assert.
3098 /* tt_assert(0); */
3101 done:
3102 return;
3106 * Test a consensus for v3_networkstatus_test
3108 static void
3109 test_consensus_for_v3ns(networkstatus_t *con, time_t now)
3111 (void)now;
3113 tt_assert(con);
3114 tt_ptr_op(con->cert, OP_EQ, NULL);
3115 tt_int_op(2,OP_EQ, smartlist_len(con->routerstatus_list));
3116 /* There should be two listed routers: one with identity 3, one with
3117 * identity 5. */
3119 done:
3120 return;
3124 * Test a router list entry for v3_networkstatus test
3126 static void
3127 test_routerstatus_for_v3ns(routerstatus_t *rs, time_t now)
3129 (void)now;
3130 tor_addr_t addr_ipv6;
3132 tt_assert(rs);
3134 /* There should be two listed routers: one with identity 3, one with
3135 * identity 5. */
3136 /* This one showed up in 2 digests. */
3137 if (tor_memeq(rs->identity_digest,
3138 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
3139 "\x3\x3",
3140 DIGEST_LEN)) {
3141 tt_mem_op(rs->identity_digest,OP_EQ,
3142 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
3143 DIGEST_LEN);
3144 tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
3145 tt_assert(!rs->is_authority);
3146 tt_assert(!rs->is_exit);
3147 tt_assert(!rs->is_fast);
3148 tt_assert(!rs->is_possible_guard);
3149 tt_assert(!rs->is_stable);
3150 /* (If it wasn't running it wouldn't be here) */
3151 tt_assert(rs->is_flagged_running);
3152 tt_assert(rs->is_valid);
3153 tt_assert(!rs->is_named);
3154 tt_assert(rs->is_v2_dir);
3155 /* XXXX check version */
3156 } else if (tor_memeq(rs->identity_digest,
3157 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
3158 "\x5\x5\x5\x5",
3159 DIGEST_LEN)) {
3160 /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */
3161 tt_mem_op(rs->identity_digest,OP_EQ,
3162 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
3163 DIGEST_LEN);
3164 tt_str_op(rs->nickname,OP_EQ, "router1");
3165 tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
3166 tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
3167 tt_int_op(rs->ipv4_orport,OP_EQ, 443);
3168 tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
3169 tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
3170 tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
3171 tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
3172 tt_assert(!rs->is_authority);
3173 tt_assert(rs->is_exit);
3174 tt_assert(rs->is_fast);
3175 tt_assert(rs->is_possible_guard);
3176 tt_assert(rs->is_stable);
3177 tt_assert(rs->is_flagged_running);
3178 tt_assert(rs->is_valid);
3179 tt_assert(rs->is_v2_dir);
3180 tt_assert(!rs->is_named);
3181 /* XXXX check version */
3182 } else {
3183 /* Weren't expecting this... */
3184 tt_abort();
3187 done:
3188 return;
3191 static void
3192 test_dir_networkstatus_compute_bw_weights_v10(void *arg)
3194 (void) arg;
3195 smartlist_t *chunks = smartlist_new();
3196 int64_t G, M, E, D, T, weight_scale;
3197 int ret;
3198 weight_scale = 10000;
3200 /* no case. one or more of the values is 0 */
3201 G = M = E = D = 0;
3202 T = G + M + E + D;
3203 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3204 weight_scale);
3205 tt_int_op(ret, OP_EQ, 0);
3206 tt_int_op(smartlist_len(chunks), OP_EQ, 0);
3208 /* case 1 */
3209 /* XXX dir-spec not followed? See #20272. If it isn't closed, then this is
3210 * testing current behavior, not spec. */
3211 G = E = 10;
3212 M = D = 1;
3213 T = G + M + E + D;
3214 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3215 weight_scale);
3216 tt_int_op(ret, OP_EQ, 1);
3217 tt_int_op(smartlist_len(chunks), OP_EQ, 1);
3218 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=3333 "
3219 "Wbe=3000 Wbg=3000 Wbm=10000 Wdb=10000 Web=10000 Wed=3333 Wee=7000 "
3220 "Weg=3333 Wem=7000 Wgb=10000 Wgd=3333 Wgg=7000 Wgm=7000 Wmb=10000 "
3221 "Wmd=3333 Wme=3000 Wmg=3000 Wmm=10000\n");
3222 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3223 smartlist_clear(chunks);
3225 /* case 2a E scarce */
3226 M = 100;
3227 G = 20;
3228 E = D = 5;
3229 T = G + M + E + D;
3230 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3231 weight_scale);
3232 tt_int_op(ret, OP_EQ, 1);
3233 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
3234 "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
3235 "Wem=10000 Wgb=10000 Wgd=0 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 Wme=0 "
3236 "Wmg=0 Wmm=10000\n");
3237 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3238 smartlist_clear(chunks);
3240 /* case 2a G scarce */
3241 M = 100;
3242 E = 20;
3243 G = D = 5;
3244 T = G + M + E + D;
3245 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3246 weight_scale);
3247 tt_int_op(ret, OP_EQ, 1);
3248 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
3249 "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=10000 Weg=0 Wem=10000 "
3250 "Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 Wme=0 Wmg=0 "
3251 "Wmm=10000\n");
3252 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3253 smartlist_clear(chunks);
3255 /* case 2b1 (Wgg=1, Wmd=Wgd) */
3256 M = 10;
3257 E = 30;
3258 G = 10;
3259 D = 100;
3260 T = G + M + E + D;
3261 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3262 weight_scale);
3263 tt_int_op(ret, OP_EQ, 1);
3264 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=4000 "
3265 "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=2000 Wee=10000 Weg=2000 "
3266 "Wem=10000 Wgb=10000 Wgd=4000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=4000 "
3267 "Wme=0 Wmg=0 Wmm=10000\n");
3268 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3269 smartlist_clear(chunks);
3271 /* case 2b2 */
3272 M = 60;
3273 E = 30;
3274 G = 10;
3275 D = 100;
3276 T = G + M + E + D;
3277 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3278 weight_scale);
3279 tt_int_op(ret, OP_EQ, 1);
3280 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=666 Wbe=0 "
3281 "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=3666 Wee=10000 Weg=3666 "
3282 "Wem=10000 Wgb=10000 Wgd=5668 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=666 "
3283 "Wme=0 Wmg=0 Wmm=10000\n");
3284 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3285 smartlist_clear(chunks);
3287 /* case 2b3 */
3288 /* XXX I can't get a combination of values that hits this case without error,
3289 * so this just tests that it fails. See #20285. Also see #20284 as 2b3 does
3290 * not follow dir-spec. */
3291 /* (E < T/3 && G < T/3) && (E+D>=G || G+D>=E) && (M > T/3) */
3292 M = 80;
3293 E = 30;
3294 G = 30;
3295 D = 30;
3296 T = G + M + E + D;
3297 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3298 weight_scale);
3299 tt_int_op(ret, OP_EQ, 0);
3300 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3301 smartlist_clear(chunks);
3303 /* case 3a G scarce */
3304 M = 10;
3305 E = 30;
3306 G = 10;
3307 D = 5;
3308 T = G + M + E + D;
3309 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3310 weight_scale);
3311 tt_int_op(ret, OP_EQ, 1);
3312 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 "
3313 "Wbe=3333 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=6667 Weg=0 "
3314 "Wem=6667 Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 "
3315 "Wme=3333 Wmg=0 Wmm=10000\n");
3316 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3317 smartlist_clear(chunks);
3319 /* case 3a E scarce */
3320 M = 10;
3321 E = 10;
3322 G = 30;
3323 D = 5;
3324 T = G + M + E + D;
3325 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3326 weight_scale);
3327 tt_int_op(ret, OP_EQ, 1);
3328 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
3329 "Wbg=3333 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
3330 "Wem=10000 Wgb=10000 Wgd=0 Wgg=6667 Wgm=6667 Wmb=10000 Wmd=0 Wme=0 "
3331 "Wmg=3333 Wmm=10000\n");
3332 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3333 smartlist_clear(chunks);
3335 /* case 3bg */
3336 M = 10;
3337 E = 30;
3338 G = 10;
3339 D = 10;
3340 T = G + M + E + D;
3341 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3342 weight_scale);
3343 tt_int_op(ret, OP_EQ, 1);
3344 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 "
3345 "Wbe=3334 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=6666 Weg=0 "
3346 "Wem=6666 Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 "
3347 "Wme=3334 Wmg=0 Wmm=10000\n");
3348 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3349 smartlist_clear(chunks);
3351 /* case 3be */
3352 M = 10;
3353 E = 10;
3354 G = 30;
3355 D = 10;
3356 T = G + M + E + D;
3357 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3358 weight_scale);
3359 tt_int_op(ret, OP_EQ, 1);
3360 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
3361 "Wbg=3334 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
3362 "Wem=10000 Wgb=10000 Wgd=0 Wgg=6666 Wgm=6666 Wmb=10000 Wmd=0 Wme=0 "
3363 "Wmg=3334 Wmm=10000\n");
3364 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3365 smartlist_clear(chunks);
3367 /* case from 21 Jul 2013 (3be) */
3368 G = 5483409;
3369 M = 1455379;
3370 E = 980834;
3371 D = 3385803;
3372 T = 11305425;
3373 tt_i64_op(G+M+E+D, OP_EQ, T);
3374 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3375 weight_scale);
3376 tt_assert(ret);
3377 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=883 Wbe=0 "
3378 "Wbg=3673 Wbm=10000 Wdb=10000 Web=10000 Wed=8233 Wee=10000 Weg=8233 "
3379 "Wem=10000 Wgb=10000 Wgd=883 Wgg=6327 Wgm=6327 Wmb=10000 Wmd=883 Wme=0 "
3380 "Wmg=3673 Wmm=10000\n");
3381 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3382 smartlist_clear(chunks);
3384 /* case from 04 Oct 2016 (3a E scarce) */
3385 G=29322240;
3386 M=4721546;
3387 E=1522058;
3388 D=9273571;
3389 T=44839415;
3390 tt_i64_op(G+M+E+D, OP_EQ, T);
3391 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3392 weight_scale);
3393 tt_assert(ret);
3394 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
3395 "Wbg=4194 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
3396 "Wem=10000 Wgb=10000 Wgd=0 Wgg=5806 Wgm=5806 Wmb=10000 Wmd=0 Wme=0 "
3397 "Wmg=4194 Wmm=10000\n");
3398 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3399 smartlist_clear(chunks);
3401 /* case from 04 Sep 2013 (2b1) */
3402 G=3091352;
3403 M=1838837;
3404 E=2109300;
3405 D=2469369;
3406 T=9508858;
3407 tt_i64_op(G+M+E+D, OP_EQ, T);
3408 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3409 weight_scale);
3410 tt_assert(ret);
3411 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=317 "
3412 "Wbe=5938 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=9366 Wee=4061 "
3413 "Weg=9366 Wem=4061 Wgb=10000 Wgd=317 Wgg=10000 Wgm=10000 Wmb=10000 "
3414 "Wmd=317 Wme=5938 Wmg=0 Wmm=10000\n");
3415 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3416 smartlist_clear(chunks);
3418 /* explicitly test initializing weights to 1*/
3419 G=1;
3420 M=1;
3421 E=1;
3422 D=1;
3423 T=4;
3424 tt_i64_op(G+M+E+D, OP_EQ, T);
3425 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3426 weight_scale);
3427 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=3333 "
3428 "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=3333 Wee=10000 Weg=3333 "
3429 "Wem=10000 Wgb=10000 Wgd=3333 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=3333 "
3430 "Wme=0 Wmg=0 Wmm=10000\n");
3431 tt_assert(ret);
3433 done:
3434 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3435 smartlist_free(chunks);
3438 static authority_cert_t *mock_cert;
3440 static authority_cert_t *
3441 get_my_v3_authority_cert_m(void)
3443 tor_assert(mock_cert);
3444 return mock_cert;
3447 /** Run a unit tests for generating and parsing networkstatuses, with
3448 * the supply test fns. */
3449 static void
3450 test_a_networkstatus(
3451 vote_routerstatus_t * (*vrs_gen)(int idx, time_t now),
3452 int (*vote_tweaks)(networkstatus_t *v, int voter, time_t now),
3453 void (*vrs_test)(vote_routerstatus_t *vrs, int voter, time_t now),
3454 void (*consensus_test)(networkstatus_t *con, time_t now),
3455 void (*rs_test)(routerstatus_t *rs, time_t now))
3457 authority_cert_t *cert1=NULL, *cert2=NULL, *cert3=NULL;
3458 crypto_pk_t *sign_skey_1=NULL, *sign_skey_2=NULL, *sign_skey_3=NULL;
3459 crypto_pk_t *sign_skey_leg1=NULL;
3461 * Sum the non-zero returns from vote_tweaks() we've seen; if vote_tweaks()
3462 * returns non-zero, it changed net_params and we should skip the tests for
3463 * that later as they will fail.
3465 int params_tweaked = 0;
3467 time_t now = time(NULL);
3468 networkstatus_voter_info_t *voter;
3469 document_signature_t *sig;
3470 networkstatus_t *vote=NULL, *v1=NULL, *v2=NULL, *v3=NULL, *con=NULL,
3471 *con_md=NULL;
3472 vote_routerstatus_t *vrs;
3473 routerstatus_t *rs;
3474 int idx, n_rs, n_vrs;
3475 char *consensus_text=NULL, *cp=NULL;
3476 smartlist_t *votes = smartlist_new();
3478 /* For generating the two other consensuses. */
3479 char *detached_text1=NULL, *detached_text2=NULL;
3480 char *consensus_text2=NULL, *consensus_text3=NULL;
3481 char *consensus_text_md2=NULL, *consensus_text_md3=NULL;
3482 char *consensus_text_md=NULL;
3483 networkstatus_t *con2=NULL, *con_md2=NULL, *con3=NULL, *con_md3=NULL;
3484 ns_detached_signatures_t *dsig1=NULL, *dsig2=NULL;
3486 tt_assert(vrs_gen);
3487 tt_assert(rs_test);
3488 tt_assert(vrs_test);
3490 MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
3492 /* Parse certificates and keys. */
3493 cert1 = mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1,
3494 strlen(AUTHORITY_CERT_1),
3495 NULL);
3496 tt_assert(cert1);
3497 cert2 = authority_cert_parse_from_string(AUTHORITY_CERT_2,
3498 strlen(AUTHORITY_CERT_2),
3499 NULL);
3500 tt_assert(cert2);
3501 cert3 = authority_cert_parse_from_string(AUTHORITY_CERT_3,
3502 strlen(AUTHORITY_CERT_3),
3503 NULL);
3504 tt_assert(cert3);
3505 sign_skey_1 = crypto_pk_new();
3506 sign_skey_2 = crypto_pk_new();
3507 sign_skey_3 = crypto_pk_new();
3508 sign_skey_leg1 = pk_generate(4);
3509 dirauth_sched_recalculate_timing(get_options(), now);
3510 sr_state_init(0, 0);
3512 tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_1,
3513 AUTHORITY_SIGNKEY_1, -1));
3514 tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_2,
3515 AUTHORITY_SIGNKEY_2, -1));
3516 tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_3,
3517 AUTHORITY_SIGNKEY_3, -1));
3519 tt_assert(!crypto_pk_cmp_keys(sign_skey_1, cert1->signing_key));
3520 tt_assert(!crypto_pk_cmp_keys(sign_skey_2, cert2->signing_key));
3522 tt_assert(!dir_common_construct_vote_1(&vote, cert1, sign_skey_1, vrs_gen,
3523 &v1, &n_vrs, now, 1));
3524 tt_assert(v1);
3526 /* Make sure the parsed thing was right. */
3527 tt_int_op(v1->type,OP_EQ, NS_TYPE_VOTE);
3528 tt_int_op(v1->published,OP_EQ, vote->published);
3529 tt_int_op(v1->valid_after,OP_EQ, vote->valid_after);
3530 tt_int_op(v1->fresh_until,OP_EQ, vote->fresh_until);
3531 tt_int_op(v1->valid_until,OP_EQ, vote->valid_until);
3532 tt_int_op(v1->vote_seconds,OP_EQ, vote->vote_seconds);
3533 tt_int_op(v1->dist_seconds,OP_EQ, vote->dist_seconds);
3534 tt_str_op(v1->client_versions,OP_EQ, vote->client_versions);
3535 tt_str_op(v1->server_versions,OP_EQ, vote->server_versions);
3536 tt_assert(v1->voters && smartlist_len(v1->voters));
3537 voter = smartlist_get(v1->voters, 0);
3538 tt_str_op(voter->nickname,OP_EQ, "Voter1");
3539 tt_str_op(voter->address,OP_EQ, "1.2.3.4");
3540 tt_assert(tor_addr_eq_ipv4h(&voter->ipv4_addr, 0x01020304));
3541 tt_int_op(voter->ipv4_dirport,OP_EQ, 80);
3542 tt_int_op(voter->ipv4_orport,OP_EQ, 9000);
3543 tt_str_op(voter->contact,OP_EQ, "voter@example.com");
3544 tt_assert(v1->cert);
3545 tt_assert(!crypto_pk_cmp_keys(sign_skey_1, v1->cert->signing_key));
3546 cp = smartlist_join_strings(v1->known_flags, ":", 0, NULL);
3547 tt_str_op(cp,OP_EQ, "Authority:Exit:Fast:Guard:Running:Stable:V2Dir:Valid");
3548 tor_free(cp);
3549 tt_int_op(smartlist_len(v1->routerstatus_list),OP_EQ, n_vrs);
3550 networkstatus_vote_free(vote);
3551 vote = NULL;
3553 if (vote_tweaks) params_tweaked += vote_tweaks(v1, 1, now);
3555 /* Check the routerstatuses. */
3556 for (idx = 0; idx < n_vrs; ++idx) {
3557 vrs = smartlist_get(v1->routerstatus_list, idx);
3558 tt_assert(vrs);
3559 vrs_test(vrs, 1, now);
3562 /* Generate second vote. It disagrees on some of the times,
3563 * and doesn't list versions, and knows some crazy flags.
3564 * Generate and parse v2. */
3565 tt_assert(!dir_common_construct_vote_2(&vote, cert2, sign_skey_2, vrs_gen,
3566 &v2, &n_vrs, now, 1));
3567 tt_assert(v2);
3569 if (vote_tweaks) params_tweaked += vote_tweaks(v2, 2, now);
3571 /* Check that flags come out right.*/
3572 cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
3573 tt_str_op(cp,OP_EQ, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
3574 "Running:Stable:V2Dir:Valid");
3575 tor_free(cp);
3577 /* Check the routerstatuses. */
3578 n_vrs = smartlist_len(v2->routerstatus_list);
3579 for (idx = 0; idx < n_vrs; ++idx) {
3580 vrs = smartlist_get(v2->routerstatus_list, idx);
3581 tt_assert(vrs);
3582 vrs_test(vrs, 2, now);
3584 networkstatus_vote_free(vote);
3585 vote = NULL;
3587 /* Generate the third vote with a legacy id. */
3588 tt_assert(!dir_common_construct_vote_3(&vote, cert3, sign_skey_3, vrs_gen,
3589 &v3, &n_vrs, now, 1));
3590 tt_assert(v3);
3592 if (vote_tweaks) params_tweaked += vote_tweaks(v3, 3, now);
3594 /* Compute a consensus as voter 3. */
3595 smartlist_add(votes, v3);
3596 smartlist_add(votes, v1);
3597 smartlist_add(votes, v2);
3598 consensus_text = networkstatus_compute_consensus(votes, 3,
3599 cert3->identity_key,
3600 sign_skey_3,
3601 "AAAAAAAAAAAAAAAAAAAA",
3602 sign_skey_leg1,
3603 FLAV_NS);
3604 tt_assert(consensus_text);
3605 con = networkstatus_parse_vote_from_string_(consensus_text, NULL,
3606 NS_TYPE_CONSENSUS);
3607 tt_assert(con);
3608 //log_notice(LD_GENERAL, "<<%s>>\n<<%s>>\n<<%s>>\n",
3609 // v1_text, v2_text, v3_text);
3610 consensus_text_md = networkstatus_compute_consensus(votes, 3,
3611 cert3->identity_key,
3612 sign_skey_3,
3613 "AAAAAAAAAAAAAAAAAAAA",
3614 sign_skey_leg1,
3615 FLAV_MICRODESC);
3616 tt_assert(consensus_text_md);
3617 con_md = networkstatus_parse_vote_from_string_(consensus_text_md, NULL,
3618 NS_TYPE_CONSENSUS);
3619 tt_assert(con_md);
3620 tt_int_op(con_md->flavor,OP_EQ, FLAV_MICRODESC);
3622 /* Check consensus contents. */
3623 tt_assert(con->type == NS_TYPE_CONSENSUS);
3624 tt_int_op(con->published,OP_EQ, 0); /* this field only appears in votes. */
3625 tt_int_op(con->valid_after,OP_EQ, now+1000);
3626 tt_int_op(con->fresh_until,OP_EQ, now+2003); /* median */
3627 tt_int_op(con->valid_until,OP_EQ, now+3000);
3628 tt_int_op(con->vote_seconds,OP_EQ, 100);
3629 tt_int_op(con->dist_seconds,OP_EQ, 250); /* median */
3630 tt_str_op(con->client_versions,OP_EQ, "0.1.2.14");
3631 tt_str_op(con->server_versions,OP_EQ, "0.1.2.15,0.1.2.16");
3632 cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
3633 tt_str_op(cp,OP_EQ, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
3634 "Running:Stable:V2Dir:Valid");
3635 tor_free(cp);
3636 if (!params_tweaked) {
3637 /* Skip this one if vote_tweaks() messed with the param lists */
3638 cp = smartlist_join_strings(con->net_params, ":", 0, NULL);
3639 tt_str_op(cp,OP_EQ, "circuitwindow=80:foo=660");
3640 tor_free(cp);
3643 tt_int_op(4,OP_EQ, smartlist_len(con->voters)); /*3 voters, 1 legacy key.*/
3644 /* The voter id digests should be in this order. */
3645 tt_assert(fast_memcmp(cert2->cache_info.identity_digest,
3646 cert1->cache_info.identity_digest,DIGEST_LEN)<0);
3647 tt_assert(fast_memcmp(cert1->cache_info.identity_digest,
3648 cert3->cache_info.identity_digest,DIGEST_LEN)<0);
3649 test_same_voter(smartlist_get(con->voters, 1),
3650 smartlist_get(v2->voters, 0));
3651 test_same_voter(smartlist_get(con->voters, 2),
3652 smartlist_get(v1->voters, 0));
3653 test_same_voter(smartlist_get(con->voters, 3),
3654 smartlist_get(v3->voters, 0));
3656 consensus_test(con, now);
3658 /* Check the routerstatuses. */
3659 n_rs = smartlist_len(con->routerstatus_list);
3660 tt_assert(n_rs);
3661 for (idx = 0; idx < n_rs; ++idx) {
3662 rs = smartlist_get(con->routerstatus_list, idx);
3663 tt_assert(rs);
3664 rs_test(rs, now);
3667 n_rs = smartlist_len(con_md->routerstatus_list);
3668 tt_assert(n_rs);
3669 for (idx = 0; idx < n_rs; ++idx) {
3670 rs = smartlist_get(con_md->routerstatus_list, idx);
3671 tt_assert(rs);
3674 /* Check signatures. the first voter is a pseudo-entry with a legacy key.
3675 * The second one hasn't signed. The fourth one has signed: validate it. */
3676 voter = smartlist_get(con->voters, 1);
3677 tt_int_op(smartlist_len(voter->sigs),OP_EQ, 0);
3679 voter = smartlist_get(con->voters, 3);
3680 tt_int_op(smartlist_len(voter->sigs),OP_EQ, 1);
3681 sig = smartlist_get(voter->sigs, 0);
3682 tt_assert(sig->signature);
3683 tt_assert(!sig->good_signature);
3684 tt_assert(!sig->bad_signature);
3686 tt_assert(!networkstatus_check_document_signature(con, sig, cert3));
3687 tt_assert(sig->signature);
3688 tt_assert(sig->good_signature);
3689 tt_assert(!sig->bad_signature);
3692 const char *msg=NULL;
3693 /* Compute the other two signed consensuses. */
3694 smartlist_shuffle(votes);
3695 consensus_text2 = networkstatus_compute_consensus(votes, 3,
3696 cert2->identity_key,
3697 sign_skey_2, NULL,NULL,
3698 FLAV_NS);
3699 consensus_text_md2 = networkstatus_compute_consensus(votes, 3,
3700 cert2->identity_key,
3701 sign_skey_2, NULL,NULL,
3702 FLAV_MICRODESC);
3703 smartlist_shuffle(votes);
3704 consensus_text3 = networkstatus_compute_consensus(votes, 3,
3705 cert1->identity_key,
3706 sign_skey_1, NULL,NULL,
3707 FLAV_NS);
3708 consensus_text_md3 = networkstatus_compute_consensus(votes, 3,
3709 cert1->identity_key,
3710 sign_skey_1, NULL,NULL,
3711 FLAV_MICRODESC);
3712 tt_assert(consensus_text2);
3713 tt_assert(consensus_text3);
3714 tt_assert(consensus_text_md2);
3715 tt_assert(consensus_text_md3);
3716 con2 = networkstatus_parse_vote_from_string_(consensus_text2, NULL,
3717 NS_TYPE_CONSENSUS);
3718 con3 = networkstatus_parse_vote_from_string_(consensus_text3, NULL,
3719 NS_TYPE_CONSENSUS);
3720 con_md2 = networkstatus_parse_vote_from_string_(consensus_text_md2, NULL,
3721 NS_TYPE_CONSENSUS);
3722 con_md3 = networkstatus_parse_vote_from_string_(consensus_text_md3, NULL,
3723 NS_TYPE_CONSENSUS);
3724 tt_assert(con2);
3725 tt_assert(con3);
3726 tt_assert(con_md2);
3727 tt_assert(con_md3);
3729 /* All three should have the same digest. */
3730 tt_mem_op(&con->digests,OP_EQ, &con2->digests, sizeof(common_digests_t));
3731 tt_mem_op(&con->digests,OP_EQ, &con3->digests, sizeof(common_digests_t));
3733 tt_mem_op(&con_md->digests,OP_EQ, &con_md2->digests,
3734 sizeof(common_digests_t));
3735 tt_mem_op(&con_md->digests,OP_EQ, &con_md3->digests,
3736 sizeof(common_digests_t));
3738 /* Extract a detached signature from con3. */
3739 detached_text1 = get_detached_sigs(con3, con_md3);
3740 tt_assert(detached_text1);
3741 /* Try to parse it. */
3742 dsig1 = networkstatus_parse_detached_signatures(detached_text1, NULL);
3743 tt_assert(dsig1);
3745 /* Are parsed values as expected? */
3746 tt_int_op(dsig1->valid_after,OP_EQ, con3->valid_after);
3747 tt_int_op(dsig1->fresh_until,OP_EQ, con3->fresh_until);
3748 tt_int_op(dsig1->valid_until,OP_EQ, con3->valid_until);
3750 common_digests_t *dsig_digests = strmap_get(dsig1->digests, "ns");
3751 tt_assert(dsig_digests);
3752 tt_mem_op(dsig_digests->d[DIGEST_SHA1], OP_EQ,
3753 con3->digests.d[DIGEST_SHA1], DIGEST_LEN);
3754 dsig_digests = strmap_get(dsig1->digests, "microdesc");
3755 tt_assert(dsig_digests);
3756 tt_mem_op(dsig_digests->d[DIGEST_SHA256],OP_EQ,
3757 con_md3->digests.d[DIGEST_SHA256],
3758 DIGEST256_LEN);
3761 smartlist_t *dsig_signatures = strmap_get(dsig1->signatures, "ns");
3762 tt_assert(dsig_signatures);
3763 tt_int_op(1,OP_EQ, smartlist_len(dsig_signatures));
3764 sig = smartlist_get(dsig_signatures, 0);
3765 tt_mem_op(sig->identity_digest,OP_EQ, cert1->cache_info.identity_digest,
3766 DIGEST_LEN);
3767 tt_int_op(sig->alg,OP_EQ, DIGEST_SHA1);
3769 dsig_signatures = strmap_get(dsig1->signatures, "microdesc");
3770 tt_assert(dsig_signatures);
3771 tt_int_op(1,OP_EQ, smartlist_len(dsig_signatures));
3772 sig = smartlist_get(dsig_signatures, 0);
3773 tt_mem_op(sig->identity_digest,OP_EQ, cert1->cache_info.identity_digest,
3774 DIGEST_LEN);
3775 tt_int_op(sig->alg,OP_EQ, DIGEST_SHA256);
3778 /* Try adding it to con2. */
3779 detached_text2 = get_detached_sigs(con2,con_md2);
3780 tt_int_op(1,OP_EQ, networkstatus_add_detached_signatures(con2, dsig1,
3781 "test", LOG_INFO, &msg));
3782 tor_free(detached_text2);
3783 tt_int_op(1,OP_EQ,
3784 networkstatus_add_detached_signatures(con_md2, dsig1, "test",
3785 LOG_INFO, &msg));
3786 tor_free(detached_text2);
3787 detached_text2 = get_detached_sigs(con2,con_md2);
3788 //printf("\n<%s>\n", detached_text2);
3789 dsig2 = networkstatus_parse_detached_signatures(detached_text2, NULL);
3790 tt_assert(dsig2);
3792 printf("\n");
3793 SMARTLIST_FOREACH(dsig2->signatures, networkstatus_voter_info_t *, vi, {
3794 char hd[64];
3795 base16_encode(hd, sizeof(hd), vi->identity_digest, DIGEST_LEN);
3796 printf("%s\n", hd);
3799 tt_int_op(2,OP_EQ,
3800 smartlist_len((smartlist_t*)strmap_get(dsig2->signatures, "ns")));
3801 tt_int_op(2,OP_EQ,
3802 smartlist_len((smartlist_t*)strmap_get(dsig2->signatures,
3803 "microdesc")));
3805 /* Try adding to con2 twice; verify that nothing changes. */
3806 tt_int_op(0,OP_EQ, networkstatus_add_detached_signatures(con2, dsig1,
3807 "test", LOG_INFO, &msg));
3809 /* Add to con. */
3810 tt_int_op(2,OP_EQ, networkstatus_add_detached_signatures(con, dsig2,
3811 "test", LOG_INFO, &msg));
3812 /* Check signatures */
3813 voter = smartlist_get(con->voters, 1);
3814 sig = smartlist_get(voter->sigs, 0);
3815 tt_assert(sig);
3816 tt_assert(!networkstatus_check_document_signature(con, sig, cert2));
3817 voter = smartlist_get(con->voters, 2);
3818 sig = smartlist_get(voter->sigs, 0);
3819 tt_assert(sig);
3820 tt_assert(!networkstatus_check_document_signature(con, sig, cert1));
3823 done:
3824 tor_free(cp);
3825 smartlist_free(votes);
3826 tor_free(consensus_text);
3827 tor_free(consensus_text_md);
3829 networkstatus_vote_free(vote);
3830 networkstatus_vote_free(v1);
3831 networkstatus_vote_free(v2);
3832 networkstatus_vote_free(v3);
3833 networkstatus_vote_free(con);
3834 networkstatus_vote_free(con_md);
3835 crypto_pk_free(sign_skey_1);
3836 crypto_pk_free(sign_skey_2);
3837 crypto_pk_free(sign_skey_3);
3838 crypto_pk_free(sign_skey_leg1);
3839 authority_cert_free(cert1);
3840 authority_cert_free(cert2);
3841 authority_cert_free(cert3);
3843 tor_free(consensus_text2);
3844 tor_free(consensus_text3);
3845 tor_free(consensus_text_md2);
3846 tor_free(consensus_text_md3);
3847 tor_free(detached_text1);
3848 tor_free(detached_text2);
3850 networkstatus_vote_free(con2);
3851 networkstatus_vote_free(con3);
3852 networkstatus_vote_free(con_md2);
3853 networkstatus_vote_free(con_md3);
3854 ns_detached_signatures_free(dsig1);
3855 ns_detached_signatures_free(dsig2);
3858 /** Run unit tests for generating and parsing V3 consensus networkstatus
3859 * documents. */
3860 static void
3861 test_dir_v3_networkstatus(void *arg)
3863 (void)arg;
3864 test_a_networkstatus(dir_common_gen_routerstatus_for_v3ns,
3865 vote_tweaks_for_v3ns,
3866 test_vrs_for_v3ns,
3867 test_consensus_for_v3ns,
3868 test_routerstatus_for_v3ns);
3871 static void
3872 test_dir_scale_bw(void *testdata)
3874 double v[8] = { 2.0/3,
3875 7.0,
3876 1.0,
3877 3.0,
3878 1.0/5,
3879 1.0/7,
3880 12.0,
3881 24.0 };
3882 double vals_dbl[8];
3883 uint64_t vals_u64[8];
3884 uint64_t total;
3885 int i;
3887 (void) testdata;
3889 for (i=0; i<8; ++i)
3890 vals_dbl[i] = v[i];
3892 scale_array_elements_to_u64(vals_u64, vals_dbl, 8, &total);
3894 tt_int_op((int)total, OP_EQ, 48);
3895 total = 0;
3896 for (i=0; i<8; ++i) {
3897 total += vals_u64[i];
3899 tt_assert(total >= (UINT64_C(1)<<60));
3900 tt_assert(total <= (UINT64_C(1)<<62));
3902 for (i=0; i<8; ++i) {
3903 /* vals[2].u64 is the scaled value of 1.0 */
3904 double ratio = ((double)vals_u64[i]) / vals_u64[2];
3905 tt_double_op(fabs(ratio - v[i]), OP_LT, .00001);
3908 /* test handling of no entries */
3909 total = 1;
3910 scale_array_elements_to_u64(vals_u64, vals_dbl, 0, &total);
3911 tt_assert(total == 0);
3913 /* make sure we don't read the array when we have no entries
3914 * may require compiler flags to catch NULL dereferences */
3915 total = 1;
3916 scale_array_elements_to_u64(NULL, NULL, 0, &total);
3917 tt_assert(total == 0);
3919 scale_array_elements_to_u64(NULL, NULL, 0, NULL);
3921 /* test handling of zero totals */
3922 total = 1;
3923 vals_dbl[0] = 0.0;
3924 scale_array_elements_to_u64(vals_u64, vals_dbl, 1, &total);
3925 tt_assert(total == 0);
3926 tt_assert(vals_u64[0] == 0);
3928 vals_dbl[0] = 0.0;
3929 vals_dbl[1] = 0.0;
3930 scale_array_elements_to_u64(vals_u64, vals_dbl, 2, NULL);
3931 tt_assert(vals_u64[0] == 0);
3932 tt_assert(vals_u64[1] == 0);
3934 done:
3938 static void
3939 test_dir_random_weighted(void *testdata)
3941 int histogram[10];
3942 uint64_t vals[10] = {3,1,2,4,6,0,7,5,8,9}, total=0;
3943 uint64_t inp_u64[10];
3944 int i, choice;
3945 const int n = 50000;
3946 double max_sq_error;
3947 (void) testdata;
3949 /* Try a ten-element array with values from 0 through 10. The values are
3950 * in a scrambled order to make sure we don't depend on order. */
3951 memset(histogram,0,sizeof(histogram));
3952 for (i=0; i<10; ++i) {
3953 inp_u64[i] = vals[i];
3954 total += vals[i];
3956 tt_u64_op(total, OP_EQ, 45);
3957 for (i=0; i<n; ++i) {
3958 choice = choose_array_element_by_weight(inp_u64, 10);
3959 tt_int_op(choice, OP_GE, 0);
3960 tt_int_op(choice, OP_LT, 10);
3961 histogram[choice]++;
3964 /* Now see if we chose things about frequently enough. */
3965 max_sq_error = 0;
3966 for (i=0; i<10; ++i) {
3967 int expected = (int)(n*vals[i]/total);
3968 double frac_diff = 0, sq;
3969 TT_BLATHER((" %d : %5d vs %5d\n", (int)vals[i], histogram[i], expected));
3970 if (expected)
3971 frac_diff = (histogram[i] - expected) / ((double)expected);
3972 else
3973 tt_int_op(histogram[i], OP_EQ, 0);
3975 sq = frac_diff * frac_diff;
3976 if (sq > max_sq_error)
3977 max_sq_error = sq;
3979 /* It should almost always be much much less than this. If you want to
3980 * figure out the odds, please feel free. */
3981 tt_double_op(max_sq_error, OP_LT, .05);
3983 /* Now try a singleton; do we choose it? */
3984 for (i = 0; i < 100; ++i) {
3985 choice = choose_array_element_by_weight(inp_u64, 1);
3986 tt_int_op(choice, OP_EQ, 0);
3989 /* Now try an array of zeros. We should choose randomly. */
3990 memset(histogram,0,sizeof(histogram));
3991 for (i = 0; i < 5; ++i)
3992 inp_u64[i] = 0;
3993 for (i = 0; i < n; ++i) {
3994 choice = choose_array_element_by_weight(inp_u64, 5);
3995 tt_int_op(choice, OP_GE, 0);
3996 tt_int_op(choice, OP_LT, 5);
3997 histogram[choice]++;
3999 /* Now see if we chose things about frequently enough. */
4000 max_sq_error = 0;
4001 for (i=0; i<5; ++i) {
4002 int expected = n/5;
4003 double frac_diff = 0, sq;
4004 TT_BLATHER((" %d : %5d vs %5d\n", (int)vals[i], histogram[i], expected));
4005 frac_diff = (histogram[i] - expected) / ((double)expected);
4006 sq = frac_diff * frac_diff;
4007 if (sq > max_sq_error)
4008 max_sq_error = sq;
4010 /* It should almost always be much much less than this. If you want to
4011 * figure out the odds, please feel free. */
4012 tt_double_op(max_sq_error, OP_LT, .05);
4013 done:
4017 /* Function pointers for test_dir_clip_unmeasured_bw_kb() */
4019 static uint32_t alternate_clip_bw = 0;
4022 * Generate a routerstatus for clip_unmeasured_bw_kb test; based on the
4023 * v3_networkstatus ones.
4025 static vote_routerstatus_t *
4026 gen_routerstatus_for_umbw(int idx, time_t now)
4028 vote_routerstatus_t *vrs = NULL;
4029 routerstatus_t *rs;
4030 tor_addr_t addr_ipv6;
4031 uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
4032 alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
4034 switch (idx) {
4035 case 0:
4036 /* Generate the first routerstatus. */
4037 vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
4038 rs = &vrs->status;
4039 vrs->version = tor_strdup("0.1.2.14");
4040 vrs->published_on = now-1500;
4041 strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
4042 memset(rs->identity_digest, 3, DIGEST_LEN);
4043 memset(rs->descriptor_digest, 78, DIGEST_LEN);
4044 tor_addr_from_ipv4h(&rs->ipv4_addr, 0x99008801);
4045 rs->ipv4_orport = 443;
4046 rs->ipv4_dirport = 8000;
4047 /* all flags but running and valid cleared */
4048 rs->is_flagged_running = 1;
4049 rs->is_valid = 1;
4051 * This one has measured bandwidth below the clip cutoff, and
4052 * so shouldn't be clipped; we'll have to test that it isn't
4053 * later.
4055 vrs->has_measured_bw = 1;
4056 rs->has_bandwidth = 1;
4057 vrs->measured_bw_kb = rs->bandwidth_kb = max_unmeasured_bw_kb / 2;
4058 vrs->protocols = tor_strdup("Link=2 Wombat=40");
4059 break;
4060 case 1:
4061 /* Generate the second routerstatus. */
4062 vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
4063 rs = &vrs->status;
4064 vrs->version = tor_strdup("0.2.0.5");
4065 vrs->published_on = now-1000;
4066 strlcpy(rs->nickname, "router1", sizeof(rs->nickname));
4067 memset(rs->identity_digest, 5, DIGEST_LEN);
4068 memset(rs->descriptor_digest, 77, DIGEST_LEN);
4069 tor_addr_from_ipv4h(&rs->ipv4_addr, 0x99009901);
4070 rs->ipv4_orport = 443;
4071 rs->ipv4_dirport = 0;
4072 tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
4073 tor_addr_copy(&rs->ipv6_addr, &addr_ipv6);
4074 rs->ipv6_orport = 4711;
4075 rs->is_exit = rs->is_stable = rs->is_fast = rs->is_flagged_running =
4076 rs->is_valid = rs->is_possible_guard = 1;
4078 * This one has measured bandwidth above the clip cutoff, and
4079 * so shouldn't be clipped; we'll have to test that it isn't
4080 * later.
4082 vrs->has_measured_bw = 1;
4083 rs->has_bandwidth = 1;
4084 vrs->measured_bw_kb = rs->bandwidth_kb = 2 * max_unmeasured_bw_kb;
4085 vrs->protocols = tor_strdup("Link=2 Wombat=40");
4086 break;
4087 case 2:
4088 /* Generate the third routerstatus. */
4089 vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
4090 rs = &vrs->status;
4091 vrs->version = tor_strdup("0.1.0.3");
4092 vrs->published_on = now-1000;
4093 strlcpy(rs->nickname, "router3", sizeof(rs->nickname));
4094 memset(rs->identity_digest, 0x33, DIGEST_LEN);
4095 memset(rs->descriptor_digest, 79, DIGEST_LEN);
4096 tor_addr_from_ipv4h(&rs->ipv4_addr, 0xAA009901);
4097 rs->ipv4_orport = 400;
4098 rs->ipv4_dirport = 9999;
4099 rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
4100 rs->is_flagged_running = rs->is_valid =
4101 rs->is_possible_guard = 1;
4103 * This one has unmeasured bandwidth above the clip cutoff, and
4104 * so should be clipped; we'll have to test that it isn't
4105 * later.
4107 vrs->has_measured_bw = 0;
4108 rs->has_bandwidth = 1;
4109 vrs->measured_bw_kb = 0;
4110 rs->bandwidth_kb = 2 * max_unmeasured_bw_kb;
4111 vrs->protocols = tor_strdup("Link=2 Wombat=40");
4112 break;
4113 case 3:
4114 /* Generate a fourth routerstatus that is not running. */
4115 vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
4116 rs = &vrs->status;
4117 vrs->version = tor_strdup("0.1.6.3");
4118 vrs->published_on = now-1000;
4119 strlcpy(rs->nickname, "router4", sizeof(rs->nickname));
4120 memset(rs->identity_digest, 0x34, DIGEST_LEN);
4121 memset(rs->descriptor_digest, 47, DIGEST_LEN);
4122 tor_addr_from_ipv4h(&rs->ipv4_addr, 0xC0000203);
4123 rs->ipv4_orport = 500;
4124 rs->ipv4_dirport = 1999;
4125 /* all flags but running and valid cleared */
4126 rs->is_flagged_running = 1;
4127 rs->is_valid = 1;
4129 * This one has unmeasured bandwidth below the clip cutoff, and
4130 * so shouldn't be clipped; we'll have to test that it isn't
4131 * later.
4133 vrs->has_measured_bw = 0;
4134 rs->has_bandwidth = 1;
4135 vrs->measured_bw_kb = 0;
4136 rs->bandwidth_kb = max_unmeasured_bw_kb / 2;
4137 vrs->protocols = tor_strdup("Link=2 Wombat=40");
4138 break;
4139 case 4:
4140 /* No more for this test; return NULL */
4141 vrs = NULL;
4142 break;
4143 default:
4144 /* Shouldn't happen */
4145 tt_abort();
4147 if (vrs) {
4148 vrs->microdesc = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
4149 tor_asprintf(&vrs->microdesc->microdesc_hash_line,
4150 "m 32,33 "
4151 "sha256=xyzajkldsdsajdadlsdjaslsdksdjlsdjsdaskdaaa%d\n",
4152 idx);
4155 done:
4156 return vrs;
4159 /** Apply tweaks to the vote list for each voter; for the umbw test this is
4160 * just adding the right consensus methods to let clipping happen */
4161 static int
4162 vote_tweaks_for_umbw(networkstatus_t *v, int voter, time_t now)
4164 char *maxbw_param = NULL;
4165 int rv = 0;
4167 tt_assert(v);
4168 (void)voter;
4169 (void)now;
4171 tt_assert(v->supported_methods);
4172 SMARTLIST_FOREACH(v->supported_methods, char *, c, tor_free(c));
4173 smartlist_clear(v->supported_methods);
4174 smartlist_split_string(v->supported_methods,
4175 "32 33",
4176 NULL, 0, -1);
4177 /* If we're using a non-default clip bandwidth, add it to net_params */
4178 if (alternate_clip_bw > 0) {
4179 tor_asprintf(&maxbw_param, "maxunmeasuredbw=%u", alternate_clip_bw);
4180 tt_assert(maxbw_param);
4181 if (maxbw_param) {
4182 smartlist_add(v->net_params, maxbw_param);
4183 rv = 1;
4187 done:
4188 return rv;
4192 * Test a parsed vote_routerstatus_t for umbw test.
4194 static void
4195 test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now)
4197 routerstatus_t *rs;
4198 tor_addr_t addr_ipv6;
4199 uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
4200 alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
4202 (void)voter;
4203 tt_assert(vrs);
4204 rs = &(vrs->status);
4205 tt_assert(rs);
4207 /* Split out by digests to test */
4208 if (tor_memeq(rs->identity_digest,
4209 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
4210 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
4211 DIGEST_LEN)) {
4213 * Check the first routerstatus - measured bandwidth below the clip
4214 * cutoff.
4216 tt_str_op(vrs->version,OP_EQ, "0.1.2.14");
4217 tt_int_op(vrs->published_on,OP_EQ, now-1500);
4218 tt_str_op(rs->nickname,OP_EQ, "router2");
4219 tt_mem_op(rs->identity_digest,OP_EQ,
4220 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
4221 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
4222 DIGEST_LEN);
4223 tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
4224 tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99008801));
4225 tt_int_op(rs->ipv4_orport,OP_EQ, 443);
4226 tt_int_op(rs->ipv4_dirport,OP_EQ, 8000);
4227 tt_assert(rs->has_bandwidth);
4228 tt_assert(vrs->has_measured_bw);
4229 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
4230 tt_int_op(vrs->measured_bw_kb,OP_EQ, max_unmeasured_bw_kb / 2);
4231 } else if (tor_memeq(rs->identity_digest,
4232 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
4233 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
4234 DIGEST_LEN)) {
4237 * Check the second routerstatus - measured bandwidth above the clip
4238 * cutoff.
4240 tt_str_op(vrs->version,OP_EQ, "0.2.0.5");
4241 tt_int_op(vrs->published_on,OP_EQ, now-1000);
4242 tt_str_op(rs->nickname,OP_EQ, "router1");
4243 tt_mem_op(rs->identity_digest,OP_EQ,
4244 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
4245 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
4246 DIGEST_LEN);
4247 tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
4248 tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
4249 tt_int_op(rs->ipv4_orport,OP_EQ, 443);
4250 tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
4251 tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
4252 tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
4253 tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
4254 tt_assert(rs->has_bandwidth);
4255 tt_assert(vrs->has_measured_bw);
4256 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb * 2);
4257 tt_int_op(vrs->measured_bw_kb,OP_EQ, max_unmeasured_bw_kb * 2);
4258 } else if (tor_memeq(rs->identity_digest,
4259 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
4260 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
4261 DIGEST_LEN)) {
4263 * Check the third routerstatus - unmeasured bandwidth above the clip
4264 * cutoff; this one should be clipped later on in the consensus, but
4265 * appears unclipped in the vote.
4267 tt_assert(rs->has_bandwidth);
4268 tt_assert(!(vrs->has_measured_bw));
4269 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb * 2);
4270 tt_int_op(vrs->measured_bw_kb,OP_EQ, 0);
4271 } else if (tor_memeq(rs->identity_digest,
4272 "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34"
4273 "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34",
4274 DIGEST_LEN)) {
4276 * Check the fourth routerstatus - unmeasured bandwidth below the clip
4277 * cutoff; this one should not be clipped.
4279 tt_assert(rs->has_bandwidth);
4280 tt_assert(!(vrs->has_measured_bw));
4281 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
4282 tt_int_op(vrs->measured_bw_kb,OP_EQ, 0);
4283 } else {
4284 tt_abort();
4287 done:
4288 return;
4292 * Test a consensus for v3_networkstatus_test
4294 static void
4295 test_consensus_for_umbw(networkstatus_t *con, time_t now)
4297 (void)now;
4299 tt_assert(con);
4300 tt_ptr_op(con->cert, OP_EQ, NULL);
4301 // tt_assert(con->consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB);
4302 tt_int_op(con->consensus_method, OP_GE, 16);
4303 tt_int_op(4,OP_EQ, smartlist_len(con->routerstatus_list));
4304 /* There should be four listed routers; all voters saw the same in this */
4306 done:
4307 return;
4311 * Test a router list entry for umbw test
4313 static void
4314 test_routerstatus_for_umbw(routerstatus_t *rs, time_t now)
4316 (void)now;
4317 tor_addr_t addr_ipv6;
4318 uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
4319 alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
4321 tt_assert(rs);
4323 /* There should be four listed routers, as constructed above */
4324 if (tor_memeq(rs->identity_digest,
4325 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
4326 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
4327 DIGEST_LEN)) {
4328 tt_mem_op(rs->identity_digest,OP_EQ,
4329 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
4330 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
4331 DIGEST_LEN);
4332 tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
4333 tt_assert(!rs->is_authority);
4334 tt_assert(!rs->is_exit);
4335 tt_assert(!rs->is_fast);
4336 tt_assert(!rs->is_possible_guard);
4337 tt_assert(!rs->is_stable);
4338 /* (If it wasn't running and valid it wouldn't be here) */
4339 tt_assert(rs->is_flagged_running);
4340 tt_assert(rs->is_valid);
4341 tt_assert(!rs->is_named);
4342 /* This one should have measured bandwidth below the clip cutoff */
4343 tt_assert(rs->has_bandwidth);
4344 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
4345 tt_assert(!(rs->bw_is_unmeasured));
4346 } else if (tor_memeq(rs->identity_digest,
4347 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
4348 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
4349 DIGEST_LEN)) {
4350 /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */
4351 tt_mem_op(rs->identity_digest,OP_EQ,
4352 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
4353 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
4354 DIGEST_LEN);
4355 tt_str_op(rs->nickname,OP_EQ, "router1");
4356 tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
4357 tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
4358 tt_int_op(rs->ipv4_orport,OP_EQ, 443);
4359 tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
4360 tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
4361 tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
4362 tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
4363 tt_assert(!rs->is_authority);
4364 tt_assert(rs->is_exit);
4365 tt_assert(rs->is_fast);
4366 tt_assert(rs->is_possible_guard);
4367 tt_assert(rs->is_stable);
4368 tt_assert(rs->is_flagged_running);
4369 tt_assert(rs->is_valid);
4370 tt_assert(!rs->is_named);
4371 /* This one should have measured bandwidth above the clip cutoff */
4372 tt_assert(rs->has_bandwidth);
4373 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb * 2);
4374 tt_assert(!(rs->bw_is_unmeasured));
4375 } else if (tor_memeq(rs->identity_digest,
4376 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
4377 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
4378 DIGEST_LEN)) {
4380 * This one should have unmeasured bandwidth above the clip cutoff,
4381 * and so should be clipped
4383 tt_assert(rs->has_bandwidth);
4384 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb);
4385 tt_assert(rs->bw_is_unmeasured);
4386 } else if (tor_memeq(rs->identity_digest,
4387 "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34"
4388 "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34",
4389 DIGEST_LEN)) {
4391 * This one should have unmeasured bandwidth below the clip cutoff,
4392 * and so should not be clipped
4394 tt_assert(rs->has_bandwidth);
4395 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
4396 tt_assert(rs->bw_is_unmeasured);
4397 } else {
4398 /* Weren't expecting this... */
4399 tt_abort();
4402 done:
4403 return;
4407 * Compute a consensus involving clipping unmeasured bandwidth with consensus
4408 * method 17; this uses the same test_a_networkstatus() function that the
4409 * v3_networkstatus test uses.
4412 static void
4413 test_dir_clip_unmeasured_bw_kb(void *arg)
4415 /* Run the test with the default clip bandwidth */
4416 (void)arg;
4417 alternate_clip_bw = 0;
4418 test_a_networkstatus(gen_routerstatus_for_umbw,
4419 vote_tweaks_for_umbw,
4420 test_vrs_for_umbw,
4421 test_consensus_for_umbw,
4422 test_routerstatus_for_umbw);
4426 * This version of test_dir_clip_unmeasured_bw_kb() uses a non-default choice
4427 * of clip bandwidth.
4430 static void
4431 test_dir_clip_unmeasured_bw_kb_alt(void *arg)
4434 * Try a different one; this value is chosen so that the below-the-cutoff
4435 * unmeasured nodes the test uses, at alternate_clip_bw / 2, will be above
4436 * DEFAULT_MAX_UNMEASURED_BW_KB and if the consensus incorrectly uses that
4437 * cutoff it will fail the test.
4439 (void)arg;
4440 alternate_clip_bw = 3 * DEFAULT_MAX_UNMEASURED_BW_KB;
4441 test_a_networkstatus(gen_routerstatus_for_umbw,
4442 vote_tweaks_for_umbw,
4443 test_vrs_for_umbw,
4444 test_consensus_for_umbw,
4445 test_routerstatus_for_umbw);
4448 static void
4449 test_dir_fmt_control_ns(void *arg)
4451 char *s = NULL;
4452 routerstatus_t rs;
4453 (void)arg;
4455 memset(&rs, 0, sizeof(rs));
4456 strlcpy(rs.nickname, "TetsuoMilk", sizeof(rs.nickname));
4457 memcpy(rs.identity_digest, "Stately, plump Buck ", DIGEST_LEN);
4458 memcpy(rs.descriptor_digest, "Mulligan came up fro", DIGEST_LEN);
4459 tor_addr_from_ipv4h(&rs.ipv4_addr, 0x20304050);
4460 rs.ipv4_orport = 9001;
4461 rs.ipv4_dirport = 9002;
4462 rs.is_exit = 1;
4463 rs.is_fast = 1;
4464 rs.is_flagged_running = 1;
4465 rs.has_bandwidth = 1;
4466 rs.is_v2_dir = 1;
4467 rs.bandwidth_kb = 1000;
4469 s = networkstatus_getinfo_helper_single(&rs);
4470 tt_assert(s);
4471 tt_str_op(s, OP_EQ,
4472 "r TetsuoMilk U3RhdGVseSwgcGx1bXAgQnVjayA "
4473 "TXVsbGlnYW4gY2FtZSB1cCBmcm8 2038-01-01 00:00:00 "
4474 "32.48.64.80 9001 9002\n"
4475 "s Exit Fast Running V2Dir\n"
4476 "w Bandwidth=1000\n");
4478 done:
4479 tor_free(s);
4482 static int mock_get_options_calls = 0;
4483 static or_options_t *mock_options = NULL;
4485 static void
4486 reset_options(or_options_t *options, int *get_options_calls)
4488 memset(options, 0, sizeof(or_options_t));
4489 options->TestingTorNetwork = 1;
4491 *get_options_calls = 0;
4494 static const or_options_t *
4495 mock_get_options(void)
4497 ++mock_get_options_calls;
4498 tor_assert(mock_options);
4499 return mock_options;
4503 * Test dirauth_get_b64_digest_bw_file.
4504 * This function should be near the other bwauth functions, but it needs
4505 * mock_get_options, that is only defined here.
4508 static void
4509 test_dir_bwauth_bw_file_digest256(void *arg)
4511 (void)arg;
4512 const char *content =
4513 "1541171221\n"
4514 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 "
4515 "master_key_ed25519=YaqV4vbvPYKucElk297eVdNArDz9HtIwUoIeo0+cVIpQ "
4516 "bw=760 nick=Test time=2018-05-08T16:13:26\n";
4518 char *fname = tor_strdup(get_fname("V3BandwidthsFile"));
4519 /* Initialize to a wrong digest. */
4520 uint8_t digest[DIGEST256_LEN] = "01234567890123456789abcdefghijkl";
4522 /* Digest of an empty string. Initialize to a wrong digest. */
4523 char digest_empty_str[DIGEST256_LEN] = "01234567890123456789abcdefghijkl";
4524 crypto_digest256(digest_empty_str, "", 0, DIGEST_SHA256);
4526 /* Digest of the content. Initialize to a wrong digest. */
4527 char digest_expected[DIGEST256_LEN] = "01234567890123456789abcdefghijkl";
4528 crypto_digest256(digest_expected, content, strlen(content), DIGEST_SHA256);
4530 /* When the bandwidth file can not be found. */
4531 tt_int_op(-1, OP_EQ,
4532 dirserv_read_measured_bandwidths(fname,
4533 NULL, NULL, digest));
4534 tt_mem_op(digest, OP_EQ, digest_empty_str, DIGEST256_LEN);
4536 /* When there is a timestamp but it is too old. */
4537 write_str_to_file(fname, content, 0);
4538 tt_int_op(-1, OP_EQ,
4539 dirserv_read_measured_bandwidths(fname,
4540 NULL, NULL, digest));
4541 /* The digest will be correct. */
4542 tt_mem_op(digest, OP_EQ, digest_expected, DIGEST256_LEN);
4544 update_approx_time(1541171221);
4546 /* When there is a bandwidth file and it can be read. */
4547 tt_int_op(0, OP_EQ,
4548 dirserv_read_measured_bandwidths(fname,
4549 NULL, NULL, digest));
4550 tt_mem_op(digest, OP_EQ, digest_expected, DIGEST256_LEN);
4552 done:
4553 unlink(fname);
4554 tor_free(fname);
4555 update_approx_time(time(NULL));
4558 static void
4559 reset_routerstatus(routerstatus_t *rs,
4560 const char *hex_identity_digest,
4561 uint32_t ipv4_addr)
4563 memset(rs, 0, sizeof(routerstatus_t));
4564 base16_decode(rs->identity_digest, sizeof(rs->identity_digest),
4565 hex_identity_digest, HEX_DIGEST_LEN);
4566 /* A zero address matches everything, so the address needs to be set.
4567 * But the specific value is irrelevant. */
4568 tor_addr_from_ipv4h(&rs->ipv4_addr, ipv4_addr);
4571 #define ROUTER_A_ID_STR "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
4572 #define ROUTER_A_IPV4 0xAA008801
4573 #define ROUTER_B_ID_STR "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
4574 #define ROUTER_B_IPV4 0xBB008801
4576 #define ROUTERSET_ALL_STR "*"
4577 #define ROUTERSET_A_STR ROUTER_A_ID_STR
4578 #define ROUTERSET_NONE_STR ""
4581 * Test that dirserv_set_routerstatus_testing sets router flags correctly
4582 * Using "*" sets flags on A and B
4583 * Using "A" sets flags on A
4584 * Using "" sets flags on Neither
4585 * If the router is not included:
4586 * - if *Strict is set, the flag is set to 0,
4587 * - otherwise, the flag is not modified. */
4588 static void
4589 test_dir_dirserv_set_routerstatus_testing(void *arg)
4591 (void)arg;
4593 /* Init options */
4594 dirauth_options_t *dirauth_options =
4595 tor_malloc_zero(sizeof(dirauth_options_t));
4597 mock_options = tor_malloc(sizeof(or_options_t));
4598 reset_options(mock_options, &mock_get_options_calls);
4599 MOCK(get_options, mock_get_options);
4600 dirauth_set_options(dirauth_options);
4602 /* Init routersets */
4603 routerset_t *routerset_all = routerset_new();
4604 routerset_parse(routerset_all, ROUTERSET_ALL_STR, "All routers");
4606 routerset_t *routerset_a = routerset_new();
4607 routerset_parse(routerset_a, ROUTERSET_A_STR, "Router A only");
4609 routerset_t *routerset_none = routerset_new();
4610 /* Routersets are empty when provided by routerset_new(),
4611 * so this is not strictly necessary */
4612 routerset_parse(routerset_none, ROUTERSET_NONE_STR, "No routers");
4614 /* Init routerstatuses */
4615 routerstatus_t *rs_a = tor_malloc(sizeof(routerstatus_t));
4616 reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
4618 routerstatus_t *rs_b = tor_malloc(sizeof(routerstatus_t));
4619 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4621 /* Sanity check that routersets correspond to routerstatuses.
4622 * Return values are {2, 3, 4} */
4624 /* We want 3 ("*" means match all addresses) */
4625 tt_int_op(routerset_contains_routerstatus(routerset_all, rs_a, 0), OP_EQ, 3);
4626 tt_int_op(routerset_contains_routerstatus(routerset_all, rs_b, 0), OP_EQ, 3);
4628 /* We want 4 (match id_digest [or nickname]) */
4629 tt_int_op(routerset_contains_routerstatus(routerset_a, rs_a, 0), OP_EQ, 4);
4630 tt_int_op(routerset_contains_routerstatus(routerset_a, rs_b, 0), OP_EQ, 0);
4632 tt_int_op(routerset_contains_routerstatus(routerset_none, rs_a, 0), OP_EQ,
4634 tt_int_op(routerset_contains_routerstatus(routerset_none, rs_b, 0), OP_EQ,
4637 /* Check that "*" sets flags on all routers: Exit
4638 * Check the flags aren't being confused with each other */
4639 reset_options(mock_options, &mock_get_options_calls);
4640 memset(dirauth_options, 0, sizeof(*dirauth_options));
4641 reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
4642 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4644 dirauth_options->TestingDirAuthVoteExit = routerset_all;
4645 dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
4647 dirserv_set_routerstatus_testing(rs_a);
4648 dirserv_set_routerstatus_testing(rs_b);
4650 tt_uint_op(rs_a->is_exit, OP_EQ, 1);
4651 tt_uint_op(rs_b->is_exit, OP_EQ, 1);
4652 /* Be paranoid - check no other flags are set */
4653 tt_uint_op(rs_a->is_possible_guard, OP_EQ, 0);
4654 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
4655 tt_uint_op(rs_a->is_hs_dir, OP_EQ, 0);
4656 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
4658 /* Check that "*" sets flags on all routers: Guard & HSDir
4659 * Cover the remaining flags in one test */
4660 reset_options(mock_options, &mock_get_options_calls);
4661 memset(dirauth_options, 0, sizeof(*dirauth_options));
4662 reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
4663 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4665 dirauth_options->TestingDirAuthVoteGuard = routerset_all;
4666 dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
4667 dirauth_options->TestingDirAuthVoteHSDir = routerset_all;
4668 dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
4670 dirserv_set_routerstatus_testing(rs_a);
4671 dirserv_set_routerstatus_testing(rs_b);
4673 tt_uint_op(rs_a->is_possible_guard, OP_EQ, 1);
4674 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1);
4675 tt_uint_op(rs_a->is_hs_dir, OP_EQ, 1);
4676 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1);
4677 /* Be paranoid - check exit isn't set */
4678 tt_uint_op(rs_a->is_exit, OP_EQ, 0);
4679 tt_uint_op(rs_b->is_exit, OP_EQ, 0);
4681 /* Check routerset A sets all flags on router A,
4682 * but leaves router B unmodified */
4683 reset_options(mock_options, &mock_get_options_calls);
4684 memset(dirauth_options, 0, sizeof(*dirauth_options));
4685 reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
4686 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4688 dirauth_options->TestingDirAuthVoteExit = routerset_a;
4689 dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
4690 dirauth_options->TestingDirAuthVoteGuard = routerset_a;
4691 dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
4692 dirauth_options->TestingDirAuthVoteHSDir = routerset_a;
4693 dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
4695 dirserv_set_routerstatus_testing(rs_a);
4696 dirserv_set_routerstatus_testing(rs_b);
4698 tt_uint_op(rs_a->is_exit, OP_EQ, 1);
4699 tt_uint_op(rs_b->is_exit, OP_EQ, 0);
4700 tt_uint_op(rs_a->is_possible_guard, OP_EQ, 1);
4701 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
4702 tt_uint_op(rs_a->is_hs_dir, OP_EQ, 1);
4703 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
4705 /* Check routerset A unsets all flags on router B when Strict is set */
4706 reset_options(mock_options, &mock_get_options_calls);
4707 memset(dirauth_options, 0, sizeof(*dirauth_options));
4708 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4710 dirauth_options->TestingDirAuthVoteExit = routerset_a;
4711 dirauth_options->TestingDirAuthVoteExitIsStrict = 1;
4712 dirauth_options->TestingDirAuthVoteGuard = routerset_a;
4713 dirauth_options->TestingDirAuthVoteGuardIsStrict = 1;
4714 dirauth_options->TestingDirAuthVoteHSDir = routerset_a;
4715 dirauth_options->TestingDirAuthVoteHSDirIsStrict = 1;
4717 rs_b->is_exit = 1;
4718 rs_b->is_possible_guard = 1;
4719 rs_b->is_hs_dir = 1;
4721 dirserv_set_routerstatus_testing(rs_b);
4723 tt_uint_op(rs_b->is_exit, OP_EQ, 0);
4724 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
4725 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
4727 /* Check routerset A doesn't modify flags on router B without Strict set */
4728 reset_options(mock_options, &mock_get_options_calls);
4729 memset(dirauth_options, 0, sizeof(*dirauth_options));
4730 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4732 dirauth_options->TestingDirAuthVoteExit = routerset_a;
4733 dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
4734 dirauth_options->TestingDirAuthVoteGuard = routerset_a;
4735 dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
4736 dirauth_options->TestingDirAuthVoteHSDir = routerset_a;
4737 dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
4739 rs_b->is_exit = 1;
4740 rs_b->is_possible_guard = 1;
4741 rs_b->is_hs_dir = 1;
4743 dirserv_set_routerstatus_testing(rs_b);
4745 tt_uint_op(rs_b->is_exit, OP_EQ, 1);
4746 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1);
4747 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1);
4749 /* Check the empty routerset zeroes all flags
4750 * on routers A & B with Strict set */
4751 reset_options(mock_options, &mock_get_options_calls);
4752 memset(dirauth_options, 0, sizeof(*dirauth_options));
4753 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4755 dirauth_options->TestingDirAuthVoteExit = routerset_none;
4756 dirauth_options->TestingDirAuthVoteExitIsStrict = 1;
4757 dirauth_options->TestingDirAuthVoteGuard = routerset_none;
4758 dirauth_options->TestingDirAuthVoteGuardIsStrict = 1;
4759 dirauth_options->TestingDirAuthVoteHSDir = routerset_none;
4760 dirauth_options->TestingDirAuthVoteHSDirIsStrict = 1;
4762 rs_b->is_exit = 1;
4763 rs_b->is_possible_guard = 1;
4764 rs_b->is_hs_dir = 1;
4766 dirserv_set_routerstatus_testing(rs_b);
4768 tt_uint_op(rs_b->is_exit, OP_EQ, 0);
4769 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
4770 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
4772 /* Check the empty routerset doesn't modify any flags
4773 * on A or B without Strict set */
4774 reset_options(mock_options, &mock_get_options_calls);
4775 memset(dirauth_options, 0, sizeof(*dirauth_options));
4776 reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
4777 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4779 dirauth_options->TestingDirAuthVoteExit = routerset_none;
4780 dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
4781 dirauth_options->TestingDirAuthVoteGuard = routerset_none;
4782 dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
4783 dirauth_options->TestingDirAuthVoteHSDir = routerset_none;
4784 dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
4786 rs_b->is_exit = 1;
4787 rs_b->is_possible_guard = 1;
4788 rs_b->is_hs_dir = 1;
4790 dirserv_set_routerstatus_testing(rs_a);
4791 dirserv_set_routerstatus_testing(rs_b);
4793 tt_uint_op(rs_a->is_exit, OP_EQ, 0);
4794 tt_uint_op(rs_a->is_possible_guard, OP_EQ, 0);
4795 tt_uint_op(rs_a->is_hs_dir, OP_EQ, 0);
4796 tt_uint_op(rs_b->is_exit, OP_EQ, 1);
4797 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1);
4798 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1);
4800 done:
4801 tor_free(mock_options);
4802 tor_free(dirauth_options);
4803 mock_options = NULL;
4805 UNMOCK(get_options);
4807 routerset_free(routerset_all);
4808 routerset_free(routerset_a);
4809 routerset_free(routerset_none);
4811 tor_free(rs_a);
4812 tor_free(rs_b);
4815 static void
4816 test_dir_http_handling(void *args)
4818 char *url = NULL;
4819 (void)args;
4821 /* Parse http url tests: */
4822 /* Good headers */
4823 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1\r\n"
4824 "Host: example.com\r\n"
4825 "User-Agent: Mozilla/5.0 (Windows;"
4826 " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
4827 &url),OP_EQ, 0);
4828 tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
4829 tor_free(url);
4831 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.0\r\n", &url),OP_EQ, 0);
4832 tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
4833 tor_free(url);
4835 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.600\r\n", &url),
4836 OP_EQ, 0);
4837 tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
4838 tor_free(url);
4840 /* Should prepend '/tor/' to url if required */
4841 tt_int_op(parse_http_url("GET /a/b/c.txt HTTP/1.1\r\n"
4842 "Host: example.com\r\n"
4843 "User-Agent: Mozilla/5.0 (Windows;"
4844 " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
4845 &url),OP_EQ, 0);
4846 tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
4847 tor_free(url);
4849 /* Bad headers -- no HTTP/1.x*/
4850 tt_int_op(parse_http_url("GET /a/b/c.txt\r\n"
4851 "Host: example.com\r\n"
4852 "User-Agent: Mozilla/5.0 (Windows;"
4853 " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
4854 &url),OP_EQ, -1);
4855 tt_ptr_op(url, OP_EQ, NULL);
4857 /* Bad headers */
4858 tt_int_op(parse_http_url("GET /a/b/c.txt\r\n"
4859 "Host: example.com\r\n"
4860 "User-Agent: Mozilla/5.0 (Windows;"
4861 " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
4862 &url),OP_EQ, -1);
4863 tt_ptr_op(url, OP_EQ, NULL);
4865 tt_int_op(parse_http_url("GET /tor/a/b/c.txt", &url),OP_EQ, -1);
4866 tt_ptr_op(url, OP_EQ, NULL);
4868 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1", &url),OP_EQ, -1);
4869 tt_ptr_op(url, OP_EQ, NULL);
4871 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1x\r\n", &url),
4872 OP_EQ, -1);
4873 tt_ptr_op(url, OP_EQ, NULL);
4875 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.", &url),OP_EQ, -1);
4876 tt_ptr_op(url, OP_EQ, NULL);
4878 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.\r", &url),OP_EQ, -1);
4879 tt_ptr_op(url, OP_EQ, NULL);
4881 done:
4882 tor_free(url);
4885 static void
4886 test_dir_purpose_needs_anonymity_returns_true_by_default(void *arg)
4888 (void)arg;
4890 #ifdef ALL_BUGS_ARE_FATAL
4891 /* Coverity (and maybe clang analyser) complain that the code following
4892 * tt_skip() is unconditionally unreachable. */
4893 #if !defined(__COVERITY__) && !defined(__clang_analyzer__)
4894 tt_skip();
4895 #endif
4896 #endif /* defined(ALL_BUGS_ARE_FATAL) */
4898 tor_capture_bugs_(1);
4899 setup_full_capture_of_logs(LOG_WARN);
4900 tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, 0, NULL));
4901 tt_int_op(1, OP_EQ, smartlist_len(tor_get_captured_bug_log_()));
4902 expect_single_log_msg_containing("Called with dir_purpose=0");
4904 tor_end_capture_bugs_();
4905 done:
4906 tor_end_capture_bugs_();
4907 teardown_capture_of_logs();
4910 static void
4911 test_dir_purpose_needs_anonymity_returns_true_for_bridges(void *arg)
4913 (void)arg;
4915 tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE, NULL));
4916 tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE,
4917 "foobar"));
4918 done: ;
4921 static void
4922 test_dir_purpose_needs_anonymity_returns_false_for_own_bridge_desc(void *arg)
4924 (void)arg;
4925 tt_int_op(0, OP_EQ, purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC,
4926 ROUTER_PURPOSE_BRIDGE,
4927 "authority.z"));
4928 done: ;
4931 static void
4932 test_dir_purpose_needs_anonymity_ret_false_for_non_sensitive_conn(void *arg)
4934 (void)arg;
4936 tt_int_op(0, OP_EQ, purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_DIR,
4937 ROUTER_PURPOSE_GENERAL, NULL));
4938 tt_int_op(0, OP_EQ,
4939 purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_VOTE, 0, NULL));
4940 tt_int_op(0, OP_EQ,
4941 purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_SIGNATURES, 0, NULL));
4942 tt_int_op(0, OP_EQ,
4943 purpose_needs_anonymity(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL));
4944 tt_int_op(0, OP_EQ, purpose_needs_anonymity(
4945 DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0, NULL));
4946 tt_int_op(0, OP_EQ,
4947 purpose_needs_anonymity(DIR_PURPOSE_FETCH_CONSENSUS, 0, NULL));
4948 tt_int_op(0, OP_EQ,
4949 purpose_needs_anonymity(DIR_PURPOSE_FETCH_CERTIFICATE, 0, NULL));
4950 tt_int_op(0, OP_EQ,
4951 purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC, 0, NULL));
4952 tt_int_op(0, OP_EQ,
4953 purpose_needs_anonymity(DIR_PURPOSE_FETCH_EXTRAINFO, 0, NULL));
4954 tt_int_op(0, OP_EQ,
4955 purpose_needs_anonymity(DIR_PURPOSE_FETCH_MICRODESC, 0, NULL));
4956 done: ;
4959 static void
4960 test_dir_fetch_type(void *arg)
4962 (void)arg;
4964 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_BRIDGE,
4965 NULL), OP_EQ, EXTRAINFO_DIRINFO | BRIDGE_DIRINFO);
4966 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_GENERAL,
4967 NULL), OP_EQ, EXTRAINFO_DIRINFO | V3_DIRINFO);
4969 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_SERVERDESC, ROUTER_PURPOSE_BRIDGE,
4970 NULL), OP_EQ, BRIDGE_DIRINFO);
4971 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_SERVERDESC,
4972 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4974 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_STATUS_VOTE,
4975 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4976 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
4977 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4978 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CERTIFICATE,
4979 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4981 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CONSENSUS, ROUTER_PURPOSE_GENERAL,
4982 "microdesc"), OP_EQ, V3_DIRINFO|MICRODESC_DIRINFO);
4983 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CONSENSUS, ROUTER_PURPOSE_GENERAL,
4984 NULL), OP_EQ, V3_DIRINFO);
4986 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_MICRODESC, ROUTER_PURPOSE_GENERAL,
4987 NULL), OP_EQ, MICRODESC_DIRINFO);
4989 done:
4990 teardown_capture_of_logs();
4993 static void
4994 test_dir_packages(void *arg)
4996 smartlist_t *votes = smartlist_new();
4997 char *res = NULL;
4998 (void)arg;
5000 #define BAD(s) \
5001 tt_int_op(0, OP_EQ, validate_recommended_package_line(s));
5002 #define GOOD(s) \
5003 tt_int_op(1, OP_EQ, validate_recommended_package_line(s));
5004 GOOD("tor 0.2.6.3-alpha "
5005 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
5006 "sha256=sssdlkfjdsklfjdskfljasdklfj");
5007 GOOD("tor 0.2.6.3-alpha "
5008 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
5009 "sha256=sssdlkfjdsklfjdskfljasdklfj blake2b=fred");
5010 BAD("tor 0.2.6.3-alpha "
5011 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
5012 "sha256=sssdlkfjdsklfjdskfljasdklfj=");
5013 BAD("tor 0.2.6.3-alpha "
5014 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
5015 "sha256=sssdlkfjdsklfjdskfljasdklfj blake2b");
5016 BAD("tor 0.2.6.3-alpha "
5017 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz ");
5018 BAD("tor 0.2.6.3-alpha "
5019 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz");
5020 BAD("tor 0.2.6.3-alpha ");
5021 BAD("tor 0.2.6.3-alpha");
5022 BAD("tor ");
5023 BAD("tor");
5024 BAD("");
5025 BAD("=foobar sha256="
5026 "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
5027 BAD("= = sha256="
5028 "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
5030 BAD("sha512= sha256="
5031 "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
5033 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
5034 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
5035 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
5036 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
5037 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
5038 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
5039 SMARTLIST_FOREACH(votes, networkstatus_t *, ns,
5040 ns->package_lines = smartlist_new());
5042 #define ADD(i, s) \
5043 smartlist_add(((networkstatus_t*)smartlist_get(votes, (i)))->package_lines, \
5044 (void*)(s));
5046 /* Only one vote for this one. */
5047 ADD(4, "cisco 99z http://foobar.example.com/ sha256=blahblah");
5049 /* Only two matching entries for this one, but 3 voters */
5050 ADD(1, "mystic 99y http://barfoo.example.com/ sha256=blahblah");
5051 ADD(3, "mystic 99y http://foobar.example.com/ sha256=blahblah");
5052 ADD(4, "mystic 99y http://foobar.example.com/ sha256=blahblah");
5054 /* Only two matching entries for this one, but at least 4 voters */
5055 ADD(1, "mystic 99p http://barfoo.example.com/ sha256=ggggggg");
5056 ADD(3, "mystic 99p http://foobar.example.com/ sha256=blahblah");
5057 ADD(4, "mystic 99p http://foobar.example.com/ sha256=blahblah");
5058 ADD(5, "mystic 99p http://foobar.example.com/ sha256=ggggggg");
5060 /* This one has only invalid votes. */
5061 ADD(0, "haffenreffer 1.2 http://foobar.example.com/ sha256");
5062 ADD(1, "haffenreffer 1.2 http://foobar.example.com/ ");
5063 ADD(2, "haffenreffer 1.2 ");
5064 ADD(3, "haffenreffer ");
5065 ADD(4, "haffenreffer");
5067 /* Three matching votes for this; it should actually go in! */
5068 ADD(2, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
5069 ADD(3, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
5070 ADD(4, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
5071 ADD(1, "element 0.66.1 http://quum.example.com/ sha256=abcdef");
5072 ADD(0, "element 0.66.1 http://quux.example.com/ sha256=abcde");
5074 /* Three votes for A, three votes for B */
5075 ADD(0, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
5076 ADD(1, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
5077 ADD(2, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
5078 ADD(3, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
5079 ADD(4, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
5080 ADD(5, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
5082 /* Three votes for A, two votes for B */
5083 ADD(1, "clownshoes 22alpha3 http://quumble.example.com/ blake2=foob");
5084 ADD(2, "clownshoes 22alpha3 http://quumble.example.com/ blake2=foob");
5085 ADD(3, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
5086 ADD(4, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
5087 ADD(5, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
5089 /* Four votes for A, two for B. */
5090 ADD(0, "clownshoes 22alpha4 http://quumble.example.com/ blake2=foob");
5091 ADD(1, "clownshoes 22alpha4 http://quumble.example.com/ blake2=foob");
5092 ADD(2, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5093 ADD(3, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5094 ADD(4, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5095 ADD(5, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5097 /* Five votes for A ... all from the same authority. Three for B. */
5098 ADD(0, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
5099 ADD(1, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
5100 ADD(3, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
5101 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5102 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5103 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5104 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5105 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5107 /* As above but new replaces old: no two match. */
5108 ADD(0, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
5109 ADD(1, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
5110 ADD(1, "cbc 99.1.11.1.2 http://example.com/cbc/x cubehash=ahooy sha512=m");
5111 ADD(2, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
5112 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5113 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5114 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5115 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5116 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5118 res = compute_consensus_package_lines(votes);
5119 tt_assert(res);
5120 tt_str_op(res, OP_EQ,
5121 "package cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m\n"
5122 "package clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz\n"
5123 "package clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa\n"
5124 "package element 0.66.1 http://quux.example.com/ sha256=abcdef\n"
5125 "package mystic 99y http://foobar.example.com/ sha256=blahblah\n"
5128 #undef ADD
5129 #undef BAD
5130 #undef GOOD
5131 done:
5132 SMARTLIST_FOREACH(votes, networkstatus_t *, ns,
5133 { smartlist_free(ns->package_lines); tor_free(ns); });
5134 smartlist_free(votes);
5135 tor_free(res);
5138 static void
5139 download_status_random_backoff_helper(int min_delay)
5141 download_status_t dls_random =
5142 { 0, 0, 0, DL_SCHED_GENERIC, DL_WANT_AUTHORITY,
5143 DL_SCHED_INCREMENT_FAILURE, 0, 0 };
5144 int increment = -1;
5145 int old_increment = -1;
5146 time_t current_time = time(NULL);
5148 /* Check the random backoff cases */
5149 int n_attempts = 0;
5150 do {
5151 increment = download_status_schedule_get_delay(&dls_random,
5152 min_delay,
5153 current_time);
5155 log_debug(LD_DIR, "Min: %d, Inc: %d, Old Inc: %d",
5156 min_delay, increment, old_increment);
5158 /* Regression test for 20534 and friends
5159 * increment must always increase after the first */
5160 if (dls_random.last_backoff_position > 0) {
5161 /* Always increment the exponential backoff */
5162 tt_int_op(increment, OP_GE, 1);
5165 /* Test */
5166 tt_int_op(increment, OP_GE, min_delay);
5168 /* Advance */
5169 if (dls_random.n_download_attempts < IMPOSSIBLE_TO_DOWNLOAD - 1) {
5170 ++(dls_random.n_download_attempts);
5171 ++(dls_random.n_download_failures);
5174 /* Try another maybe */
5175 old_increment = increment;
5176 } while (++n_attempts < 1000);
5178 done:
5179 return;
5182 static void
5183 test_dir_download_status_random_backoff(void *arg)
5185 (void)arg;
5187 /* Do a standard test */
5188 download_status_random_backoff_helper(0);
5189 /* regression tests for 17750: initial delay */
5190 download_status_random_backoff_helper(10);
5191 download_status_random_backoff_helper(20);
5193 /* Pathological cases */
5194 download_status_random_backoff_helper(INT_MAX/2);
5197 static void
5198 test_dir_download_status_random_backoff_ranges(void *arg)
5200 (void)arg;
5201 int lo, hi;
5202 next_random_exponential_delay_range(&lo, &hi, 0, 10);
5203 tt_int_op(lo, OP_EQ, 10);
5204 tt_int_op(hi, OP_EQ, 11);
5206 next_random_exponential_delay_range(&lo, &hi, 6, 10);
5207 tt_int_op(lo, OP_EQ, 10);
5208 tt_int_op(hi, OP_EQ, 6*3);
5210 next_random_exponential_delay_range(&lo, &hi, 13, 10);
5211 tt_int_op(lo, OP_EQ, 10);
5212 tt_int_op(hi, OP_EQ, 13 * 3);
5214 next_random_exponential_delay_range(&lo, &hi, 37, 10);
5215 tt_int_op(lo, OP_EQ, 10);
5216 tt_int_op(hi, OP_EQ, 111);
5218 next_random_exponential_delay_range(&lo, &hi, 123, 10);
5219 tt_int_op(lo, OP_EQ, 10);
5220 tt_int_op(hi, OP_EQ, 369);
5222 next_random_exponential_delay_range(&lo, &hi, INT_MAX-5, 10);
5223 tt_int_op(lo, OP_EQ, 10);
5224 tt_int_op(hi, OP_EQ, INT_MAX);
5225 done:
5229 static void
5230 test_dir_download_status_increment(void *arg)
5232 (void)arg;
5233 download_status_t dls_exp = { 0, 0, 0, DL_SCHED_GENERIC,
5234 DL_WANT_ANY_DIRSERVER,
5235 DL_SCHED_INCREMENT_ATTEMPT,
5236 0, 0 };
5237 or_options_t test_options;
5238 time_t current_time = time(NULL);
5240 const int delay0 = 10;
5241 const int no_delay = 0;
5242 const int schedule = 10;
5243 const int schedule_no_initial_delay = 0;
5245 /* Put it in the options */
5246 mock_options = &test_options;
5247 reset_options(mock_options, &mock_get_options_calls);
5248 mock_options->TestingBridgeBootstrapDownloadInitialDelay = schedule;
5249 mock_options->TestingClientDownloadInitialDelay = schedule;
5251 MOCK(get_options, mock_get_options);
5253 /* Check that the initial value of the schedule is the first value used,
5254 * whether or not it was reset before being used */
5256 /* regression test for 17750: no initial delay */
5257 mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay;
5258 mock_get_options_calls = 0;
5259 /* we really want to test that it's equal to time(NULL) + delay0, but that's
5260 * an unrealiable test, because time(NULL) might change. */
5262 /* regression test for 17750: exponential, no initial delay */
5263 mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay;
5264 mock_get_options_calls = 0;
5265 /* we really want to test that it's equal to time(NULL) + delay0, but that's
5266 * an unrealiable test, because time(NULL) might change. */
5267 tt_assert(download_status_get_next_attempt_at(&dls_exp)
5268 >= current_time + no_delay);
5269 tt_assert(download_status_get_next_attempt_at(&dls_exp)
5270 != TIME_MAX);
5271 tt_int_op(download_status_get_n_failures(&dls_exp), OP_EQ, 0);
5272 tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0);
5273 tt_int_op(mock_get_options_calls, OP_GE, 1);
5275 /* regression test for 17750: exponential, initial delay */
5276 mock_options->TestingClientDownloadInitialDelay = schedule;
5277 mock_get_options_calls = 0;
5278 /* we really want to test that it's equal to time(NULL) + delay0, but that's
5279 * an unrealiable test, because time(NULL) might change. */
5280 tt_assert(download_status_get_next_attempt_at(&dls_exp)
5281 >= current_time + delay0);
5282 tt_assert(download_status_get_next_attempt_at(&dls_exp)
5283 != TIME_MAX);
5284 tt_int_op(download_status_get_n_failures(&dls_exp), OP_EQ, 0);
5285 tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0);
5286 tt_int_op(mock_get_options_calls, OP_GE, 1);
5288 done:
5289 UNMOCK(get_options);
5290 mock_options = NULL;
5291 mock_get_options_calls = 0;
5292 teardown_capture_of_logs();
5295 static void
5296 test_dir_authdir_type_to_string(void *data)
5298 (void)data;
5299 char *res;
5301 tt_str_op(res = authdir_type_to_string(NO_DIRINFO), OP_EQ,
5302 "[Not an authority]");
5303 tor_free(res);
5305 tt_str_op(res = authdir_type_to_string(EXTRAINFO_DIRINFO), OP_EQ,
5306 "[Not an authority]");
5307 tor_free(res);
5309 tt_str_op(res = authdir_type_to_string(MICRODESC_DIRINFO), OP_EQ,
5310 "[Not an authority]");
5311 tor_free(res);
5313 tt_str_op(res = authdir_type_to_string(V3_DIRINFO), OP_EQ, "V3");
5314 tor_free(res);
5316 tt_str_op(res = authdir_type_to_string(BRIDGE_DIRINFO), OP_EQ, "Bridge");
5317 tor_free(res);
5319 tt_str_op(res = authdir_type_to_string(
5320 V3_DIRINFO | BRIDGE_DIRINFO | EXTRAINFO_DIRINFO), OP_EQ,
5321 "V3, Bridge");
5322 done:
5323 tor_free(res);
5326 static void
5327 test_dir_conn_purpose_to_string(void *data)
5329 (void)data;
5331 #define EXPECT_CONN_PURPOSE(purpose, expected) \
5332 tt_str_op(dir_conn_purpose_to_string(purpose), OP_EQ, expected);
5334 EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_DIR, "server descriptor upload");
5335 EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_VOTE, "consensus vote upload");
5336 EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_SIGNATURES,
5337 "consensus signature upload");
5338 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_SERVERDESC, "server descriptor fetch");
5339 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_EXTRAINFO, "extra-info fetch");
5340 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_CONSENSUS,
5341 "consensus network-status fetch");
5342 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_CERTIFICATE, "authority cert fetch");
5343 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_STATUS_VOTE, "status vote fetch");
5344 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
5345 "consensus signature fetch");
5346 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_MICRODESC, "microdescriptor fetch");
5348 /* This will give a warning, because there is no purpose 1024. */
5349 setup_full_capture_of_logs(LOG_WARN);
5350 EXPECT_CONN_PURPOSE(1024, "(unknown)");
5351 expect_single_log_msg_containing("Called with unknown purpose 1024");
5353 done:
5354 teardown_capture_of_logs();
5357 static int dir_tests_public_server_mode(const or_options_t *options);
5358 ATTR_UNUSED static int dir_tests_public_server_mode_called = 0;
5360 static int
5361 dir_tests_public_server_mode(const or_options_t *options)
5363 (void)options;
5365 if (dir_tests_public_server_mode_called++ == 0) {
5366 return 1;
5369 return 0;
5372 static void
5373 test_dir_should_use_directory_guards(void *data)
5375 or_options_t *options;
5376 char *errmsg = NULL;
5377 (void)data;
5379 MOCK(public_server_mode,
5380 dir_tests_public_server_mode);
5382 options = options_new();
5383 options_init(options);
5385 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5386 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 1);
5388 options->UseEntryGuards = 1;
5389 options->DownloadExtraInfo = 0;
5390 options->FetchDirInfoEarly = 0;
5391 options->FetchDirInfoExtraEarly = 0;
5392 options->FetchUselessDescriptors = 0;
5393 tt_int_op(should_use_directory_guards(options), OP_EQ, 1);
5394 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 2);
5396 options->UseEntryGuards = 0;
5397 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5398 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 3);
5399 options->UseEntryGuards = 1;
5401 options->DownloadExtraInfo = 1;
5402 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5403 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 4);
5404 options->DownloadExtraInfo = 0;
5406 options->FetchDirInfoEarly = 1;
5407 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5408 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 5);
5409 options->FetchDirInfoEarly = 0;
5411 options->FetchDirInfoExtraEarly = 1;
5412 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5413 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 6);
5414 options->FetchDirInfoExtraEarly = 0;
5416 options->FetchUselessDescriptors = 1;
5417 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5418 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 7);
5419 options->FetchUselessDescriptors = 0;
5421 done:
5422 UNMOCK(public_server_mode);
5423 or_options_free(options);
5424 tor_free(errmsg);
5427 static void dir_tests_directory_initiate_request(directory_request_t *req);
5428 ATTR_UNUSED static int dir_tests_directory_initiate_request_called = 0;
5430 static void
5431 test_dir_should_not_init_request_to_ourselves(void *data)
5433 char digest[DIGEST_LEN];
5434 dir_server_t *ourself = NULL;
5435 crypto_pk_t *key = pk_generate(2);
5436 (void) data;
5438 MOCK(directory_initiate_request,
5439 dir_tests_directory_initiate_request);
5441 clear_dir_servers();
5442 routerlist_free_all();
5444 set_server_identity_key(key);
5445 crypto_pk_get_digest(key, (char*) &digest);
5446 ourself = trusted_dir_server_new("ourself", "127.0.0.1", 9059, 9060,
5447 NULL, digest,
5448 NULL, V3_DIRINFO, 1.0);
5450 tt_assert(ourself);
5451 dir_server_add(ourself);
5453 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
5454 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5456 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
5457 NULL);
5459 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5461 done:
5462 UNMOCK(directory_initiate_request);
5463 clear_dir_servers();
5464 routerlist_free_all();
5465 crypto_pk_free(key);
5468 static void
5469 test_dir_should_not_init_request_to_dir_auths_without_v3_info(void *data)
5471 dir_server_t *ds = NULL;
5472 dirinfo_type_t dirinfo_type = BRIDGE_DIRINFO | EXTRAINFO_DIRINFO \
5473 | MICRODESC_DIRINFO;
5474 (void) data;
5476 MOCK(directory_initiate_request,
5477 dir_tests_directory_initiate_request);
5479 clear_dir_servers();
5480 routerlist_free_all();
5482 ds = trusted_dir_server_new("ds", "10.0.0.1", 9059, 9060, NULL,
5483 "12345678901234567890", NULL, dirinfo_type, 1.0);
5484 tt_assert(ds);
5485 dir_server_add(ds);
5487 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
5488 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5490 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
5491 NULL);
5492 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5494 done:
5495 UNMOCK(directory_initiate_request);
5496 clear_dir_servers();
5497 routerlist_free_all();
5500 static void
5501 test_dir_should_init_request_to_dir_auths(void *data)
5503 dir_server_t *ds = NULL;
5504 (void) data;
5506 MOCK(directory_initiate_request,
5507 dir_tests_directory_initiate_request);
5509 clear_dir_servers();
5510 routerlist_free_all();
5512 ds = trusted_dir_server_new("ds", "10.0.0.1", 9059, 9060, NULL,
5513 "12345678901234567890", NULL, V3_DIRINFO, 1.0);
5514 tt_assert(ds);
5515 dir_server_add(ds);
5517 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
5518 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 1);
5520 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
5521 NULL);
5522 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 2);
5524 done:
5525 UNMOCK(directory_initiate_request);
5526 clear_dir_servers();
5527 routerlist_free_all();
5530 void
5531 dir_tests_directory_initiate_request(directory_request_t *req)
5533 (void)req;
5534 dir_tests_directory_initiate_request_called++;
5538 * Mock check_private_dir(), and always succeed - no need to actually
5539 * look at or create anything on the filesystem.
5542 static int
5543 mock_check_private_dir(const char *dirname, cpd_check_t check,
5544 const char *effective_user)
5546 (void)dirname;
5547 (void)check;
5548 (void)effective_user;
5550 return 0;
5554 * This really mocks options_get_datadir_fname2_suffix(), but for testing
5555 * dump_desc(), we only care about get_datadir_fname(sub1), which is defined
5556 * in config.h as:
5558 * options_get_datadir_fname2_suffix(get_options(), sub1, NULL, NULL)
5561 static char *
5562 mock_get_datadir_fname(const or_options_t *options,
5563 directory_root_t roottype,
5564 const char *sub1, const char *sub2,
5565 const char *suffix)
5567 (void) roottype;
5568 char *rv = NULL;
5571 * Assert we were called like get_datadir_fname2() or get_datadir_fname(),
5572 * since that's all we implement here.
5574 tt_ptr_op(options, OP_NE, NULL);
5575 tt_ptr_op(sub1, OP_NE, NULL);
5577 * No particular assertions about sub2, since we could be in the
5578 * get_datadir_fname() or get_datadir_fname2() case.
5580 tt_ptr_op(suffix, OP_EQ, NULL);
5582 /* Just duplicate the basename and return it for this mock */
5583 if (sub2) {
5584 /* If we have sub2, it's the basename, otherwise sub1 */
5585 rv = tor_strdup(sub2);
5586 } else {
5587 rv = tor_strdup(sub1);
5590 done:
5591 return rv;
5594 static char *last_unlinked_path = NULL;
5595 static int unlinked_count = 0;
5597 static void
5598 mock_unlink_reset(void)
5600 tor_free(last_unlinked_path);
5601 unlinked_count = 0;
5604 static int
5605 mock_unlink(const char *path)
5607 tt_ptr_op(path, OP_NE, NULL);
5609 tor_free(last_unlinked_path);
5610 last_unlinked_path = tor_strdup(path);
5611 ++unlinked_count;
5613 done:
5614 return 0;
5617 static char *last_write_str_path = NULL;
5618 static uint8_t last_write_str_hash[DIGEST256_LEN];
5619 static int write_str_count = 0;
5621 static void
5622 mock_write_str_to_file_reset(void)
5624 tor_free(last_write_str_path);
5625 write_str_count = 0;
5628 static int
5629 mock_write_str_to_file(const char *path, const char *str, int bin)
5631 size_t len;
5632 uint8_t hash[DIGEST256_LEN];
5634 (void)bin;
5636 tt_ptr_op(path, OP_NE, NULL);
5637 tt_ptr_op(str, OP_NE, NULL);
5639 len = strlen(str);
5640 crypto_digest256((char *)hash, str, len, DIGEST_SHA256);
5642 tor_free(last_write_str_path);
5643 last_write_str_path = tor_strdup(path);
5644 memcpy(last_write_str_hash, hash, sizeof(last_write_str_hash));
5645 ++write_str_count;
5647 done:
5648 return 0;
5651 static void
5652 test_dir_dump_unparseable_descriptors(void *data)
5655 * These bogus descriptors look nothing at all like real bogus descriptors
5656 * we might see, but we're only testing dump_desc() here, not the parser.
5658 const char *test_desc_type = "squamous";
5659 /* strlen(test_desc_1) = 583 bytes */
5660 const char *test_desc_1 =
5661 "The most merciful thing in the world, I think, is the inability of the "
5662 "human mind to correlate all its contents. We live on a placid island of"
5663 " ignorance in the midst of black seas of infinity, and it was not meant"
5664 " that we should voyage far. The sciences, each straining in its own dir"
5665 "ection, have hitherto harmed us little; but some day the piecing togeth"
5666 "er of dissociated knowledge will open up such terrifying vistas of real"
5667 "ity, and of our frightful position therein, that we shall either go mad"
5668 "from the revelation or flee from the light into the peace and safety of"
5669 "a new dark age.";
5670 uint8_t test_desc_1_hash[DIGEST256_LEN];
5671 char test_desc_1_hash_str[HEX_DIGEST256_LEN+1];
5672 /* strlen(test_desc_2) = 650 bytes */
5673 const char *test_desc_2 =
5674 "I think their predominant colour was a greyish-green, though they had w"
5675 "hite bellies. They were mostly shiny and slippery, but the ridges of th"
5676 "eir backs were scaly. Their forms vaguely suggested the anthropoid, whi"
5677 "le their heads were the heads of fish, with prodigious bulging eyes tha"
5678 "t never closed. At the sides of their necks were palpitating gills, and"
5679 "their long paws were webbed. They hopped irregularly, sometimes on two "
5680 "legs and sometimes on four. I was somehow glad that they had no more th"
5681 "an four limbs. Their croaking, baying voices, clearly wed tar articulat"
5682 "e speech, held all the dark shades of expression which their staring fa"
5683 "ces lacked.";
5684 uint8_t test_desc_2_hash[DIGEST256_LEN];
5685 char test_desc_2_hash_str[HEX_DIGEST256_LEN+1];
5686 /* strlen(test_desc_3) = 700 bytes */
5687 const char *test_desc_3 =
5688 "Without knowing what futurism is like, Johansen achieved something very"
5689 "close to it when he spoke of the city; for instead of describing any de"
5690 "finite structure or building, he dwells only on broad impressions of va"
5691 "st angles and stone surfaces - surfaces too great to belong to anything"
5692 "right or proper for this earth, and impious with horrible images and hi"
5693 "eroglyphs. I mention his talk about angles because it suggests somethin"
5694 "g Wilcox had told me of his awful dreams. He said that the geometry of "
5695 "the dream-place he saw was abnormal, non-Euclidean, and loathsomely red"
5696 "olent of spheres and dimensions apart from ours. Now an unlettered seam"
5697 "an felt the same thing whilst gazing at the terrible reality.";
5698 uint8_t test_desc_3_hash[DIGEST256_LEN];
5699 char test_desc_3_hash_str[HEX_DIGEST256_LEN+1];
5700 /* strlen(test_desc_3) = 604 bytes */
5701 const char *test_desc_4 =
5702 "So we glanced back simultaneously, it would appear; though no doubt the"
5703 "incipient motion of one prompted the imitation of the other. As we did "
5704 "so we flashed both torches full strength at the momentarily thinned mis"
5705 "t; either from sheer primitive anxiety to see all we could, or in a les"
5706 "s primitive but equally unconscious effort to dazzle the entity before "
5707 "we dimmed our light and dodged among the penguins of the labyrinth cent"
5708 "er ahead. Unhappy act! Not Orpheus himself, or Lot's wife, paid much mo"
5709 "re dearly for a backward glance. And again came that shocking, wide-ran"
5710 "ged piping - \"Tekeli-li! Tekeli-li!\"";
5711 uint8_t test_desc_4_hash[DIGEST256_LEN];
5712 char test_desc_4_hash_str[HEX_DIGEST256_LEN+1];
5713 (void)data;
5716 * Set up options mock so we can force a tiny FIFO size and generate
5717 * cleanups.
5719 mock_options = tor_malloc(sizeof(or_options_t));
5720 reset_options(mock_options, &mock_get_options_calls);
5721 mock_options->MaxUnparseableDescSizeToLog = 1536;
5722 MOCK(get_options, mock_get_options);
5723 MOCK(check_private_dir, mock_check_private_dir);
5724 MOCK(options_get_dir_fname2_suffix,
5725 mock_get_datadir_fname);
5728 * Set up unlink and write mocks
5730 MOCK(tor_unlink, mock_unlink);
5731 mock_unlink_reset();
5732 MOCK(write_str_to_file, mock_write_str_to_file);
5733 mock_write_str_to_file_reset();
5736 * Compute hashes we'll need to recognize which descriptor is which
5738 crypto_digest256((char *)test_desc_1_hash, test_desc_1,
5739 strlen(test_desc_1), DIGEST_SHA256);
5740 base16_encode(test_desc_1_hash_str, sizeof(test_desc_1_hash_str),
5741 (const char *)test_desc_1_hash,
5742 sizeof(test_desc_1_hash));
5743 crypto_digest256((char *)test_desc_2_hash, test_desc_2,
5744 strlen(test_desc_2), DIGEST_SHA256);
5745 base16_encode(test_desc_2_hash_str, sizeof(test_desc_2_hash_str),
5746 (const char *)test_desc_2_hash,
5747 sizeof(test_desc_2_hash));
5748 crypto_digest256((char *)test_desc_3_hash, test_desc_3,
5749 strlen(test_desc_3), DIGEST_SHA256);
5750 base16_encode(test_desc_3_hash_str, sizeof(test_desc_3_hash_str),
5751 (const char *)test_desc_3_hash,
5752 sizeof(test_desc_3_hash));
5753 crypto_digest256((char *)test_desc_4_hash, test_desc_4,
5754 strlen(test_desc_4), DIGEST_SHA256);
5755 base16_encode(test_desc_4_hash_str, sizeof(test_desc_4_hash_str),
5756 (const char *)test_desc_4_hash,
5757 sizeof(test_desc_4_hash));
5760 * Reset the FIFO and check its state
5762 dump_desc_fifo_cleanup();
5763 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5764 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5767 * (1) Fire off dump_desc() once; these descriptors should all be safely
5768 * smaller than configured FIFO size.
5771 dump_desc(test_desc_1, test_desc_type);
5774 * Assert things about the FIFO state
5776 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_1));
5777 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5780 * Assert things about the mocks
5782 tt_int_op(unlinked_count, OP_EQ, 0);
5783 tt_int_op(write_str_count, OP_EQ, 1);
5784 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
5787 * Reset the FIFO and check its state
5789 dump_desc_fifo_cleanup();
5790 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5791 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5794 * Reset the mocks and check their state
5796 mock_unlink_reset();
5797 mock_write_str_to_file_reset();
5798 tt_int_op(unlinked_count, OP_EQ, 0);
5799 tt_int_op(write_str_count, OP_EQ, 0);
5802 * (2) Fire off dump_desc() twice; this still should trigger no cleanup.
5805 /* First time */
5806 dump_desc(test_desc_2, test_desc_type);
5809 * Assert things about the FIFO state
5811 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_2));
5812 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5815 * Assert things about the mocks
5817 tt_int_op(unlinked_count, OP_EQ, 0);
5818 tt_int_op(write_str_count, OP_EQ, 1);
5819 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
5821 /* Second time */
5822 dump_desc(test_desc_3, test_desc_type);
5825 * Assert things about the FIFO state
5827 tt_u64_op(len_descs_dumped, OP_EQ,
5828 strlen(test_desc_2) + strlen(test_desc_3));
5829 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5832 * Assert things about the mocks
5834 tt_int_op(unlinked_count, OP_EQ, 0);
5835 tt_int_op(write_str_count, OP_EQ, 2);
5836 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
5839 * Reset the FIFO and check its state
5841 dump_desc_fifo_cleanup();
5842 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5843 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5846 * Reset the mocks and check their state
5848 mock_unlink_reset();
5849 mock_write_str_to_file_reset();
5850 tt_int_op(unlinked_count, OP_EQ, 0);
5851 tt_int_op(write_str_count, OP_EQ, 0);
5854 * (3) Three calls to dump_desc cause a FIFO cleanup
5857 /* First time */
5858 dump_desc(test_desc_4, test_desc_type);
5861 * Assert things about the FIFO state
5863 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_4));
5864 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5867 * Assert things about the mocks
5869 tt_int_op(unlinked_count, OP_EQ, 0);
5870 tt_int_op(write_str_count, OP_EQ, 1);
5871 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
5873 /* Second time */
5874 dump_desc(test_desc_1, test_desc_type);
5877 * Assert things about the FIFO state
5879 tt_u64_op(len_descs_dumped, OP_EQ,
5880 strlen(test_desc_4) + strlen(test_desc_1));
5881 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5884 * Assert things about the mocks
5886 tt_int_op(unlinked_count, OP_EQ, 0);
5887 tt_int_op(write_str_count, OP_EQ, 2);
5888 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
5890 /* Third time - we should unlink the dump of test_desc_4 here */
5891 dump_desc(test_desc_2, test_desc_type);
5894 * Assert things about the FIFO state
5896 tt_u64_op(len_descs_dumped, OP_EQ,
5897 strlen(test_desc_1) + strlen(test_desc_2));
5898 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5901 * Assert things about the mocks
5903 tt_int_op(unlinked_count, OP_EQ, 1);
5904 tt_int_op(write_str_count, OP_EQ, 3);
5905 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
5908 * Reset the FIFO and check its state
5910 dump_desc_fifo_cleanup();
5911 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5912 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5915 * Reset the mocks and check their state
5917 mock_unlink_reset();
5918 mock_write_str_to_file_reset();
5919 tt_int_op(unlinked_count, OP_EQ, 0);
5920 tt_int_op(write_str_count, OP_EQ, 0);
5923 * (4) But repeating one (A B B) doesn't overflow and cleanup
5926 /* First time */
5927 dump_desc(test_desc_3, test_desc_type);
5930 * Assert things about the FIFO state
5932 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_3));
5933 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5936 * Assert things about the mocks
5938 tt_int_op(unlinked_count, OP_EQ, 0);
5939 tt_int_op(write_str_count, OP_EQ, 1);
5940 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
5942 /* Second time */
5943 dump_desc(test_desc_4, test_desc_type);
5946 * Assert things about the FIFO state
5948 tt_u64_op(len_descs_dumped, OP_EQ,
5949 strlen(test_desc_3) + strlen(test_desc_4));
5950 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5953 * Assert things about the mocks
5955 tt_int_op(unlinked_count, OP_EQ, 0);
5956 tt_int_op(write_str_count, OP_EQ, 2);
5957 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
5959 /* Third time */
5960 dump_desc(test_desc_4, test_desc_type);
5963 * Assert things about the FIFO state
5965 tt_u64_op(len_descs_dumped, OP_EQ,
5966 strlen(test_desc_3) + strlen(test_desc_4));
5967 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5970 * Assert things about the mocks
5972 tt_int_op(unlinked_count, OP_EQ, 0);
5973 tt_int_op(write_str_count, OP_EQ, 2);
5974 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
5977 * Reset the FIFO and check its state
5979 dump_desc_fifo_cleanup();
5980 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5981 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5984 * Reset the mocks and check their state
5986 mock_unlink_reset();
5987 mock_write_str_to_file_reset();
5988 tt_int_op(unlinked_count, OP_EQ, 0);
5989 tt_int_op(write_str_count, OP_EQ, 0);
5992 * (5) Same for the (A B A) repetition
5995 /* First time */
5996 dump_desc(test_desc_1, test_desc_type);
5999 * Assert things about the FIFO state
6001 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_1));
6002 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
6005 * Assert things about the mocks
6007 tt_int_op(unlinked_count, OP_EQ, 0);
6008 tt_int_op(write_str_count, OP_EQ, 1);
6009 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
6011 /* Second time */
6012 dump_desc(test_desc_2, test_desc_type);
6015 * Assert things about the FIFO state
6017 tt_u64_op(len_descs_dumped, OP_EQ,
6018 strlen(test_desc_1) + strlen(test_desc_2));
6019 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6022 * Assert things about the mocks
6024 tt_int_op(unlinked_count, OP_EQ, 0);
6025 tt_int_op(write_str_count, OP_EQ, 2);
6026 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
6028 /* Third time */
6029 dump_desc(test_desc_1, test_desc_type);
6032 * Assert things about the FIFO state
6034 tt_u64_op(len_descs_dumped, OP_EQ,
6035 strlen(test_desc_1) + strlen(test_desc_2));
6036 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6039 * Assert things about the mocks
6041 tt_int_op(unlinked_count, OP_EQ, 0);
6042 tt_int_op(write_str_count, OP_EQ, 2);
6043 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
6046 * Reset the FIFO and check its state
6048 dump_desc_fifo_cleanup();
6049 tt_u64_op(len_descs_dumped, OP_EQ, 0);
6050 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
6053 * Reset the mocks and check their state
6055 mock_unlink_reset();
6056 mock_write_str_to_file_reset();
6057 tt_int_op(unlinked_count, OP_EQ, 0);
6058 tt_int_op(write_str_count, OP_EQ, 0);
6061 * (6) (A B B C) triggering overflow on C causes A, not B to be unlinked
6064 /* First time */
6065 dump_desc(test_desc_3, test_desc_type);
6068 * Assert things about the FIFO state
6070 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_3));
6071 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
6074 * Assert things about the mocks
6076 tt_int_op(unlinked_count, OP_EQ, 0);
6077 tt_int_op(write_str_count, OP_EQ, 1);
6078 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
6080 /* Second time */
6081 dump_desc(test_desc_4, test_desc_type);
6084 * Assert things about the FIFO state
6086 tt_u64_op(len_descs_dumped, OP_EQ,
6087 strlen(test_desc_3) + strlen(test_desc_4));
6088 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6091 * Assert things about the mocks
6093 tt_int_op(unlinked_count, OP_EQ, 0);
6094 tt_int_op(write_str_count, OP_EQ, 2);
6095 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
6097 /* Third time */
6098 dump_desc(test_desc_4, test_desc_type);
6101 * Assert things about the FIFO state
6103 tt_u64_op(len_descs_dumped, OP_EQ,
6104 strlen(test_desc_3) + strlen(test_desc_4));
6105 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6108 * Assert things about the mocks
6110 tt_int_op(unlinked_count, OP_EQ, 0);
6111 tt_int_op(write_str_count, OP_EQ, 2);
6112 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
6114 /* Fourth time - we should unlink the dump of test_desc_3 here */
6115 dump_desc(test_desc_1, test_desc_type);
6118 * Assert things about the FIFO state
6120 tt_u64_op(len_descs_dumped, OP_EQ,
6121 strlen(test_desc_4) + strlen(test_desc_1));
6122 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6125 * Assert things about the mocks
6127 tt_int_op(unlinked_count, OP_EQ, 1);
6128 tt_int_op(write_str_count, OP_EQ, 3);
6129 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
6132 * Reset the FIFO and check its state
6134 dump_desc_fifo_cleanup();
6135 tt_u64_op(len_descs_dumped, OP_EQ, 0);
6136 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
6139 * Reset the mocks and check their state
6141 mock_unlink_reset();
6142 mock_write_str_to_file_reset();
6143 tt_int_op(unlinked_count, OP_EQ, 0);
6144 tt_int_op(write_str_count, OP_EQ, 0);
6147 * (7) (A B A C) triggering overflow on C causes B, not A to be unlinked
6150 /* First time */
6151 dump_desc(test_desc_2, test_desc_type);
6154 * Assert things about the FIFO state
6156 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_2));
6157 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
6160 * Assert things about the mocks
6162 tt_int_op(unlinked_count, OP_EQ, 0);
6163 tt_int_op(write_str_count, OP_EQ, 1);
6164 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
6166 /* Second time */
6167 dump_desc(test_desc_3, test_desc_type);
6170 * Assert things about the FIFO state
6172 tt_u64_op(len_descs_dumped, OP_EQ,
6173 strlen(test_desc_2) + strlen(test_desc_3));
6174 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6177 * Assert things about the mocks
6179 tt_int_op(unlinked_count, OP_EQ, 0);
6180 tt_int_op(write_str_count, OP_EQ, 2);
6181 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
6183 /* Third time */
6184 dump_desc(test_desc_2, test_desc_type);
6187 * Assert things about the FIFO state
6189 tt_u64_op(len_descs_dumped, OP_EQ,
6190 strlen(test_desc_2) + strlen(test_desc_3));
6191 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6194 * Assert things about the mocks
6196 tt_int_op(unlinked_count, OP_EQ, 0);
6197 tt_int_op(write_str_count, OP_EQ, 2);
6198 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
6200 /* Fourth time - we should unlink the dump of test_desc_3 here */
6201 dump_desc(test_desc_4, test_desc_type);
6204 * Assert things about the FIFO state
6206 tt_u64_op(len_descs_dumped, OP_EQ,
6207 strlen(test_desc_2) + strlen(test_desc_4));
6208 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6211 * Assert things about the mocks
6213 tt_int_op(unlinked_count, OP_EQ, 1);
6214 tt_int_op(write_str_count, OP_EQ, 3);
6215 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
6218 * Reset the FIFO and check its state
6220 dump_desc_fifo_cleanup();
6221 tt_u64_op(len_descs_dumped, OP_EQ, 0);
6222 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
6225 * Reset the mocks and check their state
6227 mock_unlink_reset();
6228 mock_write_str_to_file_reset();
6229 tt_int_op(unlinked_count, OP_EQ, 0);
6230 tt_int_op(write_str_count, OP_EQ, 0);
6232 done:
6234 /* Clean up the fifo */
6235 dump_desc_fifo_cleanup();
6237 /* Remove mocks */
6238 UNMOCK(tor_unlink);
6239 mock_unlink_reset();
6240 UNMOCK(write_str_to_file);
6241 mock_write_str_to_file_reset();
6242 UNMOCK(options_get_dir_fname2_suffix);
6243 UNMOCK(check_private_dir);
6244 UNMOCK(get_options);
6245 tor_free(mock_options);
6246 mock_options = NULL;
6248 return;
6251 /* Variables for reset_read_file_to_str_mock() */
6253 static int enforce_expected_filename = 0;
6254 static char *expected_filename = NULL;
6255 static char *file_content = NULL;
6256 static size_t file_content_len = 0;
6257 static struct stat file_stat;
6258 static int read_count = 0, read_call_count = 0;
6260 static void
6261 reset_read_file_to_str_mock(void)
6263 tor_free(expected_filename);
6264 tor_free(file_content);
6265 file_content_len = 0;
6266 memset(&file_stat, 0, sizeof(file_stat));
6267 read_count = 0;
6268 read_call_count = 0;
6271 static char *
6272 read_file_to_str_mock(const char *filename, int flags,
6273 struct stat *stat_out) {
6274 char *result = NULL;
6276 /* Insist we got a filename */
6277 tt_ptr_op(filename, OP_NE, NULL);
6279 /* We ignore flags */
6280 (void)flags;
6282 /* Bump the call count */
6283 ++read_call_count;
6285 if (enforce_expected_filename) {
6286 tt_assert(expected_filename);
6287 tt_str_op(filename, OP_EQ, expected_filename);
6290 if (expected_filename != NULL &&
6291 file_content != NULL &&
6292 strcmp(filename, expected_filename) == 0) {
6293 /* You asked for it, you got it */
6296 * This is the same behavior as the real read_file_to_str();
6297 * if there's a NUL, the real size ends up in stat_out.
6299 result = tor_malloc(file_content_len + 1);
6300 if (file_content_len > 0) {
6301 memcpy(result, file_content, file_content_len);
6303 result[file_content_len] = '\0';
6305 /* Do we need to set up stat_out? */
6306 if (stat_out != NULL) {
6307 memcpy(stat_out, &file_stat, sizeof(file_stat));
6308 /* We always return the correct length here */
6309 stat_out->st_size = file_content_len;
6312 /* Wooo, we have a return value - bump the counter */
6313 ++read_count;
6315 /* else no match, return NULL */
6317 done:
6318 return result;
6321 /* This one tests dump_desc_populate_one_file() */
6322 static void
6323 test_dir_populate_dump_desc_fifo(void *data)
6325 const char *dirname = "foo";
6326 const char *fname = NULL;
6327 dumped_desc_t *ent;
6329 (void)data;
6332 * Set up unlink and read_file_to_str mocks
6334 MOCK(tor_unlink, mock_unlink);
6335 mock_unlink_reset();
6336 MOCK(read_file_to_str, read_file_to_str_mock);
6337 reset_read_file_to_str_mock();
6339 /* Check state of unlink mock */
6340 tt_int_op(unlinked_count, OP_EQ, 0);
6342 /* Some cases that should fail before trying to read the file */
6343 ent = dump_desc_populate_one_file(dirname, "bar");
6344 tt_ptr_op(ent, OP_EQ, NULL);
6345 tt_int_op(unlinked_count, OP_EQ, 1);
6346 tt_int_op(read_count, OP_EQ, 0);
6347 tt_int_op(read_call_count, OP_EQ, 0);
6349 ent = dump_desc_populate_one_file(dirname, "unparseable-desc");
6350 tt_ptr_op(ent, OP_EQ, NULL);
6351 tt_int_op(unlinked_count, OP_EQ, 2);
6352 tt_int_op(read_count, OP_EQ, 0);
6353 tt_int_op(read_call_count, OP_EQ, 0);
6355 ent = dump_desc_populate_one_file(dirname, "unparseable-desc.baz");
6356 tt_ptr_op(ent, OP_EQ, NULL);
6357 tt_int_op(unlinked_count, OP_EQ, 3);
6358 tt_int_op(read_count, OP_EQ, 0);
6359 tt_int_op(read_call_count, OP_EQ, 0);
6361 ent = dump_desc_populate_one_file(
6362 dirname,
6363 "unparseable-desc.08AE85E90461F59E");
6364 tt_ptr_op(ent, OP_EQ, NULL);
6365 tt_int_op(unlinked_count, OP_EQ, 4);
6366 tt_int_op(read_count, OP_EQ, 0);
6367 tt_int_op(read_call_count, OP_EQ, 0);
6369 ent = dump_desc_populate_one_file(
6370 dirname,
6371 "unparseable-desc.08AE85E90461F59EDF0981323F3A70D02B55AB54B44B04F"
6372 "287D72F7B72F242E85C8CB0EDA8854A99");
6373 tt_ptr_op(ent, OP_EQ, NULL);
6374 tt_int_op(unlinked_count, OP_EQ, 5);
6375 tt_int_op(read_count, OP_EQ, 0);
6376 tt_int_op(read_call_count, OP_EQ, 0);
6378 /* This is a correct-length digest but base16_decode() will fail */
6379 ent = dump_desc_populate_one_file(
6380 dirname,
6381 "unparseable-desc.68219B8BGE64B705A6FFC728C069DC596216D60A7D7520C"
6382 "D5ECE250D912E686B");
6383 tt_ptr_op(ent, OP_EQ, NULL);
6384 tt_int_op(unlinked_count, OP_EQ, 6);
6385 tt_int_op(read_count, OP_EQ, 0);
6386 tt_int_op(read_call_count, OP_EQ, 0);
6388 /* This one has a correctly formed filename and should try reading */
6390 /* Read fails */
6391 ent = dump_desc_populate_one_file(
6392 dirname,
6393 "unparseable-desc.DF0981323F3A70D02B55AB54B44B04F287D72F7B72F242E"
6394 "85C8CB0EDA8854A99");
6395 tt_ptr_op(ent, OP_EQ, NULL);
6396 tt_int_op(unlinked_count, OP_EQ, 7);
6397 tt_int_op(read_count, OP_EQ, 0);
6398 tt_int_op(read_call_count, OP_EQ, 1);
6400 /* This read will succeed but the digest won't match the file content */
6401 fname =
6402 "unparseable-desc."
6403 "DF0981323F3A70D02B55AB54B44B04F287D72F7B72F242E85C8CB0EDA8854A99";
6404 enforce_expected_filename = 1;
6405 tor_asprintf(&expected_filename, "%s%s%s", dirname, PATH_SEPARATOR, fname);
6406 file_content = tor_strdup("hanc culpam maiorem an illam dicam?");
6407 file_content_len = strlen(file_content);
6408 file_stat.st_mtime = 123456;
6409 ent = dump_desc_populate_one_file(dirname, fname);
6410 enforce_expected_filename = 0;
6411 tt_ptr_op(ent, OP_EQ, NULL);
6412 tt_int_op(unlinked_count, OP_EQ, 8);
6413 tt_int_op(read_count, OP_EQ, 1);
6414 tt_int_op(read_call_count, OP_EQ, 2);
6415 tor_free(expected_filename);
6416 tor_free(file_content);
6418 /* This one will match */
6419 fname =
6420 "unparseable-desc."
6421 "0786C7173447B7FB033FFCA2FC47C3CF71C30DD47CA8236D3FC7FF35853271C6";
6422 tor_asprintf(&expected_filename, "%s%s%s", dirname, PATH_SEPARATOR, fname);
6423 file_content = tor_strdup("hanc culpam maiorem an illam dicam?");
6424 file_content_len = strlen(file_content);
6425 file_stat.st_mtime = 789012;
6426 ent = dump_desc_populate_one_file(dirname, fname);
6427 tt_ptr_op(ent, OP_NE, NULL);
6428 tt_int_op(unlinked_count, OP_EQ, 8);
6429 tt_int_op(read_count, OP_EQ, 2);
6430 tt_int_op(read_call_count, OP_EQ, 3);
6431 tt_str_op(ent->filename, OP_EQ, expected_filename);
6432 tt_int_op(ent->len, OP_EQ, file_content_len);
6433 tt_int_op(ent->when, OP_EQ, file_stat.st_mtime);
6434 tor_free(ent->filename);
6435 tor_free(ent);
6436 tor_free(expected_filename);
6439 * Reset the mocks and check their state
6441 mock_unlink_reset();
6442 tt_int_op(unlinked_count, OP_EQ, 0);
6443 reset_read_file_to_str_mock();
6444 tt_int_op(read_count, OP_EQ, 0);
6446 done:
6448 UNMOCK(tor_unlink);
6449 mock_unlink_reset();
6450 UNMOCK(read_file_to_str);
6451 reset_read_file_to_str_mock();
6453 tor_free(file_content);
6455 return;
6458 static smartlist_t *
6459 listdir_mock(const char *dname)
6461 smartlist_t *l;
6463 /* Ignore the name, always return this list */
6464 (void)dname;
6466 l = smartlist_new();
6467 smartlist_add_strdup(l, "foo");
6468 smartlist_add_strdup(l, "bar");
6469 smartlist_add_strdup(l, "baz");
6471 return l;
6474 static dumped_desc_t *
6475 pop_one_mock(const char *dirname, const char *f)
6477 dumped_desc_t *ent = NULL;
6479 if (dirname != NULL && strcmp(dirname, "d") == 0) {
6480 if (f != NULL && strcmp(f, "foo") == 0) {
6481 ent = tor_malloc_zero(sizeof(*ent));
6482 ent->filename = tor_strdup("d/foo");
6483 ent->len = 123;
6484 ent->digest_sha256[0] = 1;
6485 ent->when = 1024;
6486 } else if (f != NULL && strcmp(f, "bar") == 0) {
6487 ent = tor_malloc_zero(sizeof(*ent));
6488 ent->filename = tor_strdup("d/bar");
6489 ent->len = 456;
6490 ent->digest_sha256[0] = 2;
6492 * Note that the timestamps are in a different order than
6493 * listdir_mock() returns; we're testing the sort order.
6495 ent->when = 512;
6496 } else if (f != NULL && strcmp(f, "baz") == 0) {
6497 ent = tor_malloc_zero(sizeof(*ent));
6498 ent->filename = tor_strdup("d/baz");
6499 ent->len = 789;
6500 ent->digest_sha256[0] = 3;
6501 ent->when = 768;
6505 return ent;
6508 /* This one tests dump_desc_populate_fifo_from_directory() */
6509 static void
6510 test_dir_populate_dump_desc_fifo_2(void *data)
6512 dumped_desc_t *ent = NULL;
6514 (void)data;
6516 /* Set up the mocks */
6517 MOCK(tor_listdir, listdir_mock);
6518 MOCK(dump_desc_populate_one_file, pop_one_mock);
6520 /* Run dump_desc_populate_fifo_from_directory() */
6521 descs_dumped = NULL;
6522 len_descs_dumped = 0;
6523 dump_desc_populate_fifo_from_directory("d");
6524 tt_assert(descs_dumped != NULL);
6525 tt_int_op(smartlist_len(descs_dumped), OP_EQ, 3);
6526 tt_u64_op(len_descs_dumped, OP_EQ, 1368);
6527 ent = smartlist_get(descs_dumped, 0);
6528 tt_str_op(ent->filename, OP_EQ, "d/bar");
6529 tt_int_op(ent->len, OP_EQ, 456);
6530 tt_int_op(ent->when, OP_EQ, 512);
6531 ent = smartlist_get(descs_dumped, 1);
6532 tt_str_op(ent->filename, OP_EQ, "d/baz");
6533 tt_int_op(ent->len, OP_EQ, 789);
6534 tt_int_op(ent->when, OP_EQ, 768);
6535 ent = smartlist_get(descs_dumped, 2);
6536 tt_str_op(ent->filename, OP_EQ, "d/foo");
6537 tt_int_op(ent->len, OP_EQ, 123);
6538 tt_int_op(ent->when, OP_EQ, 1024);
6540 done:
6541 dump_desc_fifo_cleanup();
6543 UNMOCK(dump_desc_populate_one_file);
6544 UNMOCK(tor_listdir);
6546 return;
6549 static int mock_networkstatus_consensus_is_bootstrapping_value = 0;
6550 static int
6551 mock_networkstatus_consensus_is_bootstrapping(time_t now)
6553 (void)now;
6554 return mock_networkstatus_consensus_is_bootstrapping_value;
6557 static int mock_networkstatus_consensus_can_use_extra_fallbacks_value = 0;
6558 static int
6559 mock_networkstatus_consensus_can_use_extra_fallbacks(
6560 const or_options_t *options)
6562 (void)options;
6563 return mock_networkstatus_consensus_can_use_extra_fallbacks_value;
6566 static int mock_num_bridges_usable_value = 0;
6567 static int
6568 mock_num_bridges_usable(int use_maybe_reachable)
6570 (void)use_maybe_reachable;
6571 return mock_num_bridges_usable_value;
6574 /* data is a 3 character nul-terminated string.
6575 * If data[0] is 'b', set bootstrapping, anything else means not bootstrapping
6576 * If data[1] is 'f', set extra fallbacks, anything else means no extra
6577 * If data[2] is 'f', set running bridges, anything else means no extra
6578 * fallbacks.
6580 static void
6581 test_dir_find_dl_min_delay(void* data)
6583 const char *str = (const char *)data;
6585 tt_assert(strlen(data) == 3);
6587 if (str[0] == 'b') {
6588 mock_networkstatus_consensus_is_bootstrapping_value = 1;
6589 } else {
6590 mock_networkstatus_consensus_is_bootstrapping_value = 0;
6593 if (str[1] == 'f') {
6594 mock_networkstatus_consensus_can_use_extra_fallbacks_value = 1;
6595 } else {
6596 mock_networkstatus_consensus_can_use_extra_fallbacks_value = 0;
6599 if (str[2] == 'r') {
6600 /* Any positive, non-zero value should work */
6601 mock_num_bridges_usable_value = 2;
6602 } else {
6603 mock_num_bridges_usable_value = 0;
6606 MOCK(networkstatus_consensus_is_bootstrapping,
6607 mock_networkstatus_consensus_is_bootstrapping);
6608 MOCK(networkstatus_consensus_can_use_extra_fallbacks,
6609 mock_networkstatus_consensus_can_use_extra_fallbacks);
6610 MOCK(num_bridges_usable,
6611 mock_num_bridges_usable);
6613 download_status_t dls;
6615 const int server=10, client=20, server_cons=30, client_cons=40;
6616 const int client_boot_auth_only_cons=50, client_boot_auth_cons=60;
6617 const int client_boot_fallback_cons=70, bridge=80, bridge_bootstrap=90;
6619 mock_options = tor_malloc(sizeof(or_options_t));
6620 reset_options(mock_options, &mock_get_options_calls);
6621 MOCK(get_options, mock_get_options);
6623 mock_options->TestingServerDownloadInitialDelay = server;
6624 mock_options->TestingClientDownloadInitialDelay = client;
6625 mock_options->TestingServerConsensusDownloadInitialDelay = server_cons;
6626 mock_options->TestingClientConsensusDownloadInitialDelay = client_cons;
6627 mock_options->ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay =
6628 client_boot_auth_only_cons;
6629 mock_options->ClientBootstrapConsensusAuthorityDownloadInitialDelay =
6630 client_boot_auth_cons;
6631 mock_options->ClientBootstrapConsensusFallbackDownloadInitialDelay =
6632 client_boot_fallback_cons;
6633 mock_options->TestingBridgeDownloadInitialDelay = bridge;
6634 mock_options->TestingBridgeBootstrapDownloadInitialDelay = bridge_bootstrap;
6636 dls.schedule = DL_SCHED_GENERIC;
6637 /* client */
6638 mock_options->ClientOnly = 1;
6639 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, client);
6640 mock_options->ClientOnly = 0;
6642 /* dir mode */
6643 mock_options->DirPort_set = 1;
6644 mock_options->DirCache = 1;
6645 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server);
6646 mock_options->DirPort_set = 0;
6647 mock_options->DirCache = 0;
6649 dls.schedule = DL_SCHED_CONSENSUS;
6650 /* public server mode */
6651 mock_options->ORPort_set = 1;
6652 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server_cons);
6653 mock_options->ORPort_set = 0;
6655 /* client and bridge modes */
6656 if (networkstatus_consensus_is_bootstrapping(time(NULL))) {
6657 if (networkstatus_consensus_can_use_extra_fallbacks(mock_options)) {
6658 dls.want_authority = 1;
6659 /* client */
6660 mock_options->ClientOnly = 1;
6661 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6662 client_boot_auth_cons);
6663 mock_options->ClientOnly = 0;
6665 /* bridge relay */
6666 mock_options->ORPort_set = 1;
6667 mock_options->BridgeRelay = 1;
6668 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6669 client_boot_auth_cons);
6670 mock_options->ORPort_set = 0;
6671 mock_options->BridgeRelay = 0;
6673 dls.want_authority = 0;
6674 /* client */
6675 mock_options->ClientOnly = 1;
6676 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6677 client_boot_fallback_cons);
6678 mock_options->ClientOnly = 0;
6680 /* bridge relay */
6681 mock_options->ORPort_set = 1;
6682 mock_options->BridgeRelay = 1;
6683 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6684 client_boot_fallback_cons);
6685 mock_options->ORPort_set = 0;
6686 mock_options->BridgeRelay = 0;
6688 } else {
6689 /* dls.want_authority is ignored */
6690 /* client */
6691 mock_options->ClientOnly = 1;
6692 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6693 client_boot_auth_only_cons);
6694 mock_options->ClientOnly = 0;
6696 /* bridge relay */
6697 mock_options->ORPort_set = 1;
6698 mock_options->BridgeRelay = 1;
6699 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6700 client_boot_auth_only_cons);
6701 mock_options->ORPort_set = 0;
6702 mock_options->BridgeRelay = 0;
6704 } else {
6705 /* client */
6706 mock_options->ClientOnly = 1;
6707 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6708 client_cons);
6709 mock_options->ClientOnly = 0;
6711 /* bridge relay */
6712 mock_options->ORPort_set = 1;
6713 mock_options->BridgeRelay = 1;
6714 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6715 client_cons);
6716 mock_options->ORPort_set = 0;
6717 mock_options->BridgeRelay = 0;
6720 dls.schedule = DL_SCHED_BRIDGE;
6721 /* client */
6722 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge_bootstrap);
6724 done:
6725 UNMOCK(networkstatus_consensus_is_bootstrapping);
6726 UNMOCK(networkstatus_consensus_can_use_extra_fallbacks);
6727 UNMOCK(num_bridges_usable);
6728 UNMOCK(get_options);
6729 tor_free(mock_options);
6730 mock_options = NULL;
6733 static void
6734 test_dir_matching_flags(void *arg)
6736 (void) arg;
6737 routerstatus_t *rs_noflags = NULL;
6738 routerstatus_t *rs = NULL;
6739 char *s = NULL;
6741 smartlist_t *tokens = smartlist_new();
6742 memarea_t *area = memarea_new();
6744 int expected_val_when_unused = 0;
6746 const char *ex_noflags =
6747 "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 "
6748 "192.168.0.1 9001 0\n"
6749 "m thisoneislongerbecauseitisa256bitmddigest33\n"
6750 "s\n"
6751 "pr Link=4\n";
6752 const char *cp = ex_noflags;
6753 rs_noflags = routerstatus_parse_entry_from_string(
6754 area, &cp,
6755 cp + strlen(cp),
6756 tokens, NULL, NULL,
6757 MAX_SUPPORTED_CONSENSUS_METHOD, FLAV_MICRODESC);
6758 tt_assert(rs_noflags);
6760 #define FLAG(string, field) STMT_BEGIN { \
6761 tor_asprintf(&s,\
6762 "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 " \
6763 "192.168.0.1 9001 0\n" \
6764 "m thisoneislongerbecauseitisa256bitmddigest33\n" \
6765 "pr Link=4\n" \
6766 "s %s\n", string); \
6767 cp = s; \
6768 rs = routerstatus_parse_entry_from_string( \
6769 area, &cp, \
6770 cp + strlen(cp), \
6771 tokens, NULL, NULL, \
6772 MAX_SUPPORTED_CONSENSUS_METHOD, FLAV_MICRODESC); \
6773 /* the field should usually be 0 when no flags are listed */ \
6774 tt_int_op(rs_noflags->field, OP_EQ, expected_val_when_unused); \
6775 /* the field should be 1 when this flags islisted */ \
6776 tt_int_op(rs->field, OP_EQ, 1); \
6777 tor_free(s); \
6778 routerstatus_free(rs); \
6779 } STMT_END
6781 FLAG("Authority", is_authority);
6782 FLAG("BadExit", is_bad_exit);
6783 FLAG("Exit", is_exit);
6784 FLAG("Fast", is_fast);
6785 FLAG("Guard", is_possible_guard);
6786 FLAG("HSDir", is_hs_dir);
6787 FLAG("Stable", is_stable);
6788 FLAG("StaleDesc", is_staledesc);
6789 FLAG("V2Dir", is_v2_dir);
6791 // These flags are assumed to be set whether they're declared or not.
6792 expected_val_when_unused = 1;
6793 FLAG("Running", is_flagged_running);
6794 FLAG("Valid", is_valid);
6795 expected_val_when_unused = 0;
6797 // These flags are no longer used, but still parsed.
6798 FLAG("Named", is_named);
6799 FLAG("Unnamed", is_unnamed);
6801 done:
6802 tor_free(s);
6803 routerstatus_free(rs);
6804 routerstatus_free(rs_noflags);
6805 memarea_drop_all(area);
6806 smartlist_free(tokens);
6809 static void
6810 test_dir_assumed_flags(void *arg)
6812 (void)arg;
6813 smartlist_t *tokens = smartlist_new();
6814 memarea_t *area = memarea_new();
6815 routerstatus_t *rs = NULL;
6817 /* We can assume that consensus method is higher than 24, so Running and
6818 * Valid are always implicitly set */
6819 const char *str1 =
6820 "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 "
6821 "192.168.0.1 9001 0\n"
6822 "m thisoneislongerbecauseitisa256bitmddigest33\n"
6823 "s Fast Guard Stable\n"
6824 "pr Link=4\n";
6825 const char *eos = str1 + strlen(str1);
6827 const char *cp = str1;
6828 rs = routerstatus_parse_entry_from_string(area, &cp, eos, tokens, NULL, NULL,
6829 24, FLAV_MICRODESC);
6830 tt_assert(rs);
6831 tt_assert(rs->is_flagged_running);
6832 tt_assert(rs->is_valid);
6833 tt_assert(! rs->is_exit);
6834 tt_assert(rs->is_fast);
6836 done:
6837 smartlist_free(tokens);
6838 memarea_drop_all(area);
6839 routerstatus_free(rs);
6842 static void
6843 test_dir_post_parsing(void *arg)
6845 (void) arg;
6847 /* Test the version parsing from an HS descriptor publish request. */
6849 const char *end;
6850 const char *prefix = "/tor/hs/";
6851 int version = parse_hs_version_from_post("/tor/hs//publish", prefix, &end);
6852 tt_int_op(version, OP_EQ, -1);
6853 tt_ptr_op(end, OP_EQ, NULL);
6854 version = parse_hs_version_from_post("/tor/hs/a/publish", prefix, &end);
6855 tt_int_op(version, OP_EQ, -1);
6856 tt_ptr_op(end, OP_EQ, NULL);
6857 version = parse_hs_version_from_post("/tor/hs/3/publish", prefix, &end);
6858 tt_int_op(version, OP_EQ, 3);
6859 tt_str_op(end, OP_EQ, "/publish");
6860 version = parse_hs_version_from_post("/tor/hs/42/publish", prefix, &end);
6861 tt_int_op(version, OP_EQ, 42);
6862 tt_str_op(end, OP_EQ, "/publish");
6863 version = parse_hs_version_from_post("/tor/hs/18163/publish",prefix, &end);
6864 tt_int_op(version, OP_EQ, 18163);
6865 tt_str_op(end, OP_EQ, "/publish");
6866 version = parse_hs_version_from_post("JUNKJUNKJUNK", prefix, &end);
6867 tt_int_op(version, OP_EQ, -1);
6868 tt_ptr_op(end, OP_EQ, NULL);
6869 version = parse_hs_version_from_post("/tor/hs/3/publish", "blah", &end);
6870 tt_int_op(version, OP_EQ, -1);
6871 tt_ptr_op(end, OP_EQ, NULL);
6872 /* Missing the '/' at the end of the prefix. */
6873 version = parse_hs_version_from_post("/tor/hs/3/publish", "/tor/hs", &end);
6874 tt_int_op(version, OP_EQ, -1);
6875 tt_ptr_op(end, OP_EQ, NULL);
6876 version = parse_hs_version_from_post("/random/blah/tor/hs/3/publish",
6877 prefix, &end);
6878 tt_int_op(version, OP_EQ, -1);
6879 tt_ptr_op(end, OP_EQ, NULL);
6880 version = parse_hs_version_from_post("/tor/hs/3/publish/random/junk",
6881 prefix, &end);
6882 tt_int_op(version, OP_EQ, 3);
6883 tt_str_op(end, OP_EQ, "/publish/random/junk");
6884 version = parse_hs_version_from_post("/tor/hs/-1/publish", prefix, &end);
6885 tt_int_op(version, OP_EQ, -1);
6886 tt_ptr_op(end, OP_EQ, NULL);
6887 /* INT_MAX */
6888 version = parse_hs_version_from_post("/tor/hs/2147483647/publish",
6889 prefix, &end);
6890 tt_int_op(version, OP_EQ, INT_MAX);
6891 tt_str_op(end, OP_EQ, "/publish");
6892 /* INT_MAX + 1*/
6893 version = parse_hs_version_from_post("/tor/hs/2147483648/publish",
6894 prefix, &end);
6895 tt_int_op(version, OP_EQ, -1);
6896 tt_ptr_op(end, OP_EQ, NULL);
6899 done:
6903 static void
6904 test_dir_platform_str(void *arg)
6906 char platform[256];
6907 (void)arg;
6908 platform[0] = 0;
6909 get_platform_str(platform, sizeof(platform));
6910 tt_int_op((int)strlen(platform), OP_GT, 0);
6911 tt_assert(!strcmpstart(platform, "Tor "));
6913 tor_version_t ver;
6914 // make sure this is a tor version, a real actual tor version.
6915 tt_int_op(tor_version_parse_platform(platform, &ver, 1), OP_EQ, 1);
6917 TT_BLATHER(("%d.%d.%d.%d", ver.major, ver.minor, ver.micro, ver.patchlevel));
6919 // Handle an example version.
6920 tt_int_op(tor_version_parse_platform(
6921 "Tor 0.3.3.3 (foo) (git-xyzzy) on a potato", &ver, 1), OP_EQ, 1);
6922 done:
6926 static void
6927 test_dir_format_versions_list(void *arg)
6929 (void)arg;
6930 char *s = NULL;
6931 config_line_t *lines = NULL;
6933 setup_capture_of_logs(LOG_WARN);
6934 s = format_recommended_version_list(lines, 1);
6935 tt_str_op(s, OP_EQ, "");
6937 tor_free(s);
6938 config_line_append(&lines, "ignored", "0.3.4.1, 0.2.9.111-alpha, 4.4.4-rc");
6939 s = format_recommended_version_list(lines, 1);
6940 tt_str_op(s, OP_EQ, "0.2.9.111-alpha,0.3.4.1,4.4.4-rc");
6942 tor_free(s);
6943 config_line_append(&lines, "ignored", "0.1.2.3,0.2.9.10 ");
6944 s = format_recommended_version_list(lines, 1);
6945 tt_str_op(s, OP_EQ, "0.1.2.3,0.2.9.10,0.2.9.111-alpha,0.3.4.1,4.4.4-rc");
6947 /* There should be no warnings so far. */
6948 expect_no_log_entry();
6950 /* Now try a line with a space in it. */
6951 tor_free(s);
6952 config_line_append(&lines, "ignored", "1.3.3.8 1.3.3.7");
6953 s = format_recommended_version_list(lines, 1);
6954 tt_str_op(s, OP_EQ, "0.1.2.3,0.2.9.10,0.2.9.111-alpha,0.3.4.1,"
6955 "1.3.3.7,1.3.3.8,4.4.4-rc");
6957 expect_single_log_msg_containing(
6958 "Unexpected space in versions list member \"1.3.3.8 1.3.3.7\"." );
6960 /* Start over, with a line containing a bogus version */
6961 config_free_lines(lines);
6962 lines = NULL;
6963 tor_free(s);
6964 mock_clean_saved_logs();
6965 config_line_append(&lines, "ignored", "0.1.2.3, alpha-complex, 0.1.1.8-rc");
6966 s = format_recommended_version_list(lines,1);
6967 tt_str_op(s, OP_EQ, "0.1.1.8-rc,0.1.2.3,alpha-complex");
6968 expect_single_log_msg_containing(
6969 "Recommended version \"alpha-complex\" does not look valid.");
6971 done:
6972 tor_free(s);
6973 config_free_lines(lines);
6974 teardown_capture_of_logs();
6977 static void
6978 test_dir_add_fingerprint(void *arg)
6980 (void)arg;
6981 authdir_config_t *list;
6982 int ret;
6983 ed25519_secret_key_t seckey;
6984 ed25519_public_key_t pubkey_good, pubkey_bad;
6986 authdir_init_fingerprint_list();
6987 list = authdir_return_fingerprint_list();
6989 setup_capture_of_logs(LOG_WARN);
6991 /* RSA test - successful */
6992 ret = add_rsa_fingerprint_to_dir("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
6993 list, 0);
6994 tt_int_op(ret, OP_EQ, 0);
6996 /* RSA test - failure */
6997 ret = add_rsa_fingerprint_to_dir("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
6998 list, 0);
6999 tt_int_op(ret, OP_EQ, -1);
7001 /* ed25519 test - successful */
7002 ed25519_secret_key_generate(&seckey, 0);
7003 ed25519_public_key_generate(&pubkey_good, &seckey);
7005 ret = add_ed25519_to_dir(&pubkey_good, list, 0);
7006 tt_int_op(ret, OP_EQ, 0);
7008 /* ed25519 test - failure */
7009 digest256_from_base64((char *) pubkey_bad.pubkey, "gibberish");
7011 ret = add_ed25519_to_dir(&pubkey_bad, list, 0);
7012 tt_int_op(ret, OP_EQ, -1);
7014 done:
7015 teardown_capture_of_logs();
7016 dirserv_free_fingerprint_list();
7019 static void
7020 test_dir_dirserv_load_fingerprint_file(void *arg)
7022 (void)arg;
7023 char *fname = tor_strdup(get_fname("approved-routers"));
7025 // Neither RSA nor ed25519
7026 const char *router_lines_invalid =
7027 "!badexit notafingerprint";
7028 const char *router_lines_too_long =
7029 "!badexit thisisareallylongstringthatislongerthanafingerprint\n";
7030 const char *router_lines_bad_fmt_str =
7031 "!badexit ABCDEFGH|%1$p|%2$p|%3$p|%4$p|%5$p|%6$p\n";
7032 const char *router_lines_valid_rsa =
7033 "!badexit AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n";
7034 const char *router_lines_invalid_rsa =
7035 "!badexit ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\n";
7036 const char *router_lines_valid_ed25519 =
7037 "!badexit wqfLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx/Q\n";
7038 const char *router_lines_invalid_ed25519 =
7039 "!badexit --fLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx--\n";
7041 // Test: Invalid Fingerprint (not RSA or ed25519)
7042 setup_capture_of_logs(LOG_NOTICE);
7043 write_str_to_file(fname, router_lines_invalid, 0);
7044 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7045 expect_log_msg_containing("Invalid fingerprint");
7046 teardown_capture_of_logs();
7048 // Test: Very long string (longer than RSA or ed25519 key)
7049 setup_capture_of_logs(LOG_NOTICE);
7050 write_str_to_file(fname, router_lines_too_long, 0);
7051 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7052 expect_log_msg_containing("Invalid fingerprint");
7053 teardown_capture_of_logs();
7055 // Test: Format string exploit
7056 setup_capture_of_logs(LOG_NOTICE);
7057 write_str_to_file(fname, router_lines_bad_fmt_str, 0);
7058 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7059 expect_log_msg_containing("Invalid fingerprint");
7060 teardown_capture_of_logs();
7062 // Test: Valid RSA
7063 setup_capture_of_logs(LOG_NOTICE);
7064 write_str_to_file(fname, router_lines_valid_rsa, 0);
7065 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7066 teardown_capture_of_logs();
7068 // Test: Invalid RSA
7069 setup_capture_of_logs(LOG_NOTICE);
7070 write_str_to_file(fname, router_lines_invalid_rsa, 0);
7071 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7072 expect_log_msg_containing("Invalid fingerprint");
7073 teardown_capture_of_logs();
7075 // Test: Valid ed25519
7076 setup_capture_of_logs(LOG_NOTICE);
7077 write_str_to_file(fname, router_lines_valid_ed25519, 0);
7078 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7079 teardown_capture_of_logs();
7081 // Test: Invalid ed25519
7082 setup_capture_of_logs(LOG_NOTICE);
7083 write_str_to_file(fname, router_lines_invalid_ed25519, 0);
7084 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7085 expect_log_msg_containing("Invalid fingerprint");
7086 teardown_capture_of_logs();
7088 done:
7089 tor_free(fname);
7090 dirserv_free_fingerprint_list();
7093 #define RESET_FP_LIST(list) STMT_BEGIN \
7094 dirserv_free_fingerprint_list(); \
7095 authdir_init_fingerprint_list(); \
7096 list = authdir_return_fingerprint_list(); \
7097 STMT_END
7099 static void
7100 test_dir_dirserv_router_get_status(void *arg)
7102 authdir_config_t *list;
7103 routerinfo_t *ri = NULL;
7104 ed25519_keypair_t kp1, kp2;
7105 char d[DIGEST_LEN];
7106 char fp[HEX_DIGEST_LEN+1];
7107 int ret;
7108 const char *msg;
7109 time_t now = time(NULL);
7111 (void)arg;
7113 crypto_pk_t *pk = pk_generate(0);
7115 authdir_init_fingerprint_list();
7116 list = authdir_return_fingerprint_list();
7118 /* Set up the routerinfo */
7119 ri = tor_malloc_zero(sizeof(routerinfo_t));
7120 tor_addr_from_ipv4h(&ri->ipv4_addr, 0xc0a80001u);
7121 ri->ipv4_orport = 9001;
7122 ri->platform = tor_strdup("0.4.0.1-alpha");
7123 ri->nickname = tor_strdup("Jessica");
7124 ri->identity_pkey = crypto_pk_dup_key(pk);
7126 curve25519_keypair_t ri_onion_keypair;
7127 curve25519_keypair_generate(&ri_onion_keypair, 0);
7128 ri->onion_curve25519_pkey = tor_memdup(&ri_onion_keypair.pubkey,
7129 sizeof(curve25519_public_key_t));
7131 ed25519_secret_key_from_seed(&kp1.seckey,
7132 (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
7133 ed25519_public_key_generate(&kp1.pubkey, &kp1.seckey);
7134 ed25519_secret_key_from_seed(&kp2.seckey,
7135 (const uint8_t*)"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
7136 ed25519_public_key_generate(&kp2.pubkey, &kp2.seckey);
7137 ri->cache_info.signing_key_cert = tor_cert_create_ed25519(&kp1,
7138 CERT_TYPE_ID_SIGNING,
7139 &kp2.pubkey,
7140 now, 86400,
7141 CERT_FLAG_INCLUDE_SIGNING_KEY);
7143 crypto_pk_get_digest(ri->identity_pkey, d);
7144 base16_encode(fp, HEX_DIGEST_LEN + 1, d, DIGEST_LEN);
7146 /* Try on an empty fingerprint list */
7147 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7148 tt_int_op(ret, OP_EQ, 0);
7149 RESET_FP_LIST(list);
7151 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7152 tt_int_op(ret, OP_EQ, 0);
7153 RESET_FP_LIST(list);
7155 /* Try an accepted router */
7156 add_rsa_fingerprint_to_dir(fp, list, 0);
7157 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7158 tt_int_op(ret, OP_EQ, 0);
7159 RESET_FP_LIST(list);
7161 add_ed25519_to_dir(&kp1.pubkey, list, 0);
7162 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7163 tt_int_op(ret, OP_EQ, 0);
7164 RESET_FP_LIST(list);
7166 /* Try a rejected router */
7167 add_rsa_fingerprint_to_dir(fp, list, RTR_REJECT);
7168 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7169 tt_int_op(ret, OP_EQ, RTR_REJECT);
7170 RESET_FP_LIST(list);
7172 add_ed25519_to_dir(&kp1.pubkey, list, RTR_REJECT);
7173 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7174 tt_int_op(ret, OP_EQ, RTR_REJECT);
7175 RESET_FP_LIST(list);
7177 done:
7178 dirserv_free_fingerprint_list();
7179 routerinfo_free(ri);
7180 crypto_pk_free(pk);
7183 static void
7184 test_dir_dirserv_would_reject_router(void *arg)
7186 authdir_config_t *list;
7187 routerstatus_t rs;
7188 vote_routerstatus_t vrs;
7189 ed25519_keypair_t kp;
7190 char fp[HEX_DIGEST_LEN+1];
7192 (void)arg;
7194 authdir_init_fingerprint_list();
7195 list = authdir_return_fingerprint_list();
7197 /* Set up the routerstatus */
7198 memset(&rs, 0, sizeof(rs));
7199 tor_addr_from_ipv4h(&rs.ipv4_addr, 0xc0a80001u);
7200 rs.ipv4_orport = 9001;
7201 strlcpy(rs.nickname, "Nicole", sizeof(rs.nickname));
7202 memcpy(rs.identity_digest, "Cloud nine is great ", DIGEST_LEN);
7204 ed25519_secret_key_from_seed(&kp.seckey,
7205 (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
7206 ed25519_public_key_generate(&kp.pubkey, &kp.seckey);
7208 base16_encode(fp, HEX_DIGEST_LEN + 1, rs.identity_digest, DIGEST_LEN);
7210 /* Setup the vote_routerstatus_t. */
7211 memcpy(vrs.ed25519_id, &kp.pubkey, ED25519_PUBKEY_LEN);
7213 /* Try an empty fingerprint list */
7214 tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7215 RESET_FP_LIST(list);
7217 tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7218 RESET_FP_LIST(list);
7220 /* Try an accepted router */
7221 add_rsa_fingerprint_to_dir(fp, list, 0);
7222 tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7223 RESET_FP_LIST(list);
7225 add_ed25519_to_dir(&kp.pubkey, list, 0);
7226 tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7227 RESET_FP_LIST(list);
7229 /* Try a rejected router */
7230 add_rsa_fingerprint_to_dir(fp, list, RTR_REJECT);
7231 tt_assert(dirserv_would_reject_router(&rs, &vrs));
7232 RESET_FP_LIST(list);
7234 add_ed25519_to_dir(&kp.pubkey, list, RTR_REJECT);
7235 tt_assert(dirserv_would_reject_router(&rs, &vrs));
7236 RESET_FP_LIST(list);
7238 done:
7239 dirserv_free_fingerprint_list();
7242 static void
7243 test_dir_dirserv_add_own_fingerprint(void *arg)
7245 authdir_config_t *list;
7246 char digest[DIGEST_LEN];
7247 crypto_pk_t *pk = pk_generate(0);
7249 (void)arg;
7251 init_mock_ed_keys(pk);
7252 authdir_init_fingerprint_list();
7253 list = authdir_return_fingerprint_list();
7254 dirserv_add_own_fingerprint(pk, get_master_identity_key());
7256 /* Check if we have a RSA key. */
7257 crypto_pk_get_digest(pk, digest);
7258 tt_assert(digestmap_get(list->status_by_digest, digest));
7260 /* Check if we have a ed25519 key. */
7261 tt_assert(digest256map_get(list->status_by_digest256,
7262 get_master_identity_key()->pubkey));
7264 RESET_FP_LIST(list);
7266 done:
7267 dirserv_free_fingerprint_list();
7268 crypto_pk_free(pk);
7271 #ifndef COCCI
7272 #define DIR_LEGACY(name) \
7273 { #name, test_dir_ ## name , TT_FORK, NULL, NULL }
7275 #define DIR(name,flags) \
7276 { #name, test_dir_##name, (flags), NULL, NULL }
7278 /* where arg is a string constant */
7279 #define DIR_ARG(name,flags,arg) \
7280 { #name "_" arg, test_dir_##name, (flags), &passthrough_setup, (void*) arg }
7281 #endif /* !defined(COCCI) */
7283 struct testcase_t dir_tests[] = {
7284 DIR_LEGACY(nicknames),
7285 /* extrainfo without any stats */
7286 DIR_ARG(formats_rsa_ed25519, TT_FORK, ""),
7287 /* on a bridge */
7288 DIR_ARG(formats_rsa_ed25519, TT_FORK, "b"),
7289 /* extrainfo with basic stats */
7290 DIR_ARG(formats_rsa_ed25519, TT_FORK, "e"),
7291 DIR_ARG(formats_rsa_ed25519, TT_FORK, "be"),
7292 /* extrainfo with all stats */
7293 DIR_ARG(formats_rsa_ed25519, TT_FORK, "es"),
7294 DIR_ARG(formats_rsa_ed25519, TT_FORK, "bes"),
7295 DIR(routerinfo_parsing, 0),
7296 DIR(extrainfo_parsing, 0),
7297 DIR(parse_router_list, TT_FORK),
7298 DIR(parse_no_onion_keyrouter_list, TT_FORK),
7299 DIR(load_routers, TT_FORK),
7300 DIR(load_extrainfo, TT_FORK),
7301 DIR(getinfo_extra, 0),
7302 DIR_LEGACY(versions),
7303 DIR_LEGACY(fp_pairs),
7304 DIR(split_fps, 0),
7305 DIR_LEGACY(measured_bw_kb),
7306 DIR_LEGACY(measured_bw_kb_line_is_after_headers),
7307 DIR_LEGACY(measured_bw_kb_cache),
7308 DIR_LEGACY(dirserv_read_measured_bandwidths),
7309 DIR(bwauth_bw_file_digest256, 0),
7310 DIR_LEGACY(param_voting),
7311 DIR(param_voting_lookup, 0),
7312 DIR_LEGACY(v3_networkstatus),
7313 DIR(random_weighted, 0),
7314 DIR(scale_bw, 0),
7315 DIR_LEGACY(clip_unmeasured_bw_kb),
7316 DIR_LEGACY(clip_unmeasured_bw_kb_alt),
7317 DIR(fmt_control_ns, 0),
7318 DIR(dirserv_set_routerstatus_testing, TT_FORK),
7319 DIR(http_handling, 0),
7320 DIR(purpose_needs_anonymity_returns_true_for_bridges, 0),
7321 DIR(purpose_needs_anonymity_returns_false_for_own_bridge_desc, 0),
7322 DIR(purpose_needs_anonymity_returns_true_by_default, 0),
7323 DIR(purpose_needs_anonymity_ret_false_for_non_sensitive_conn, 0),
7324 DIR(post_parsing, 0),
7325 DIR(fetch_type, 0),
7326 DIR(packages, 0),
7327 DIR(download_status_random_backoff, 0),
7328 DIR(download_status_random_backoff_ranges, 0),
7329 DIR(download_status_increment, TT_FORK),
7330 DIR(authdir_type_to_string, 0),
7331 DIR(conn_purpose_to_string, 0),
7332 DIR(should_use_directory_guards, 0),
7333 DIR(should_not_init_request_to_ourselves, TT_FORK),
7334 DIR(should_not_init_request_to_dir_auths_without_v3_info, 0),
7335 DIR(should_init_request_to_dir_auths, 0),
7336 DIR(dump_unparseable_descriptors, 0),
7337 DIR(populate_dump_desc_fifo, 0),
7338 DIR(populate_dump_desc_fifo_2, 0),
7339 DIR_ARG(find_dl_min_delay, TT_FORK, "bfd"),
7340 DIR_ARG(find_dl_min_delay, TT_FORK, "bad"),
7341 DIR_ARG(find_dl_min_delay, TT_FORK, "cfd"),
7342 DIR_ARG(find_dl_min_delay, TT_FORK, "cad"),
7343 DIR_ARG(find_dl_min_delay, TT_FORK, "bfr"),
7344 DIR_ARG(find_dl_min_delay, TT_FORK, "bar"),
7345 DIR_ARG(find_dl_min_delay, TT_FORK, "cfr"),
7346 DIR_ARG(find_dl_min_delay, TT_FORK, "car"),
7347 DIR(assumed_flags, 0),
7348 DIR(matching_flags, 0),
7349 DIR(networkstatus_compute_bw_weights_v10, 0),
7350 DIR(platform_str, 0),
7351 DIR(format_versions_list, TT_FORK),
7352 DIR(add_fingerprint, TT_FORK),
7353 DIR(dirserv_load_fingerprint_file, TT_FORK),
7354 DIR(dirserv_router_get_status, TT_FORK),
7355 DIR(dirserv_would_reject_router, TT_FORK),
7356 DIR(dirserv_add_own_fingerprint, TT_FORK),
7357 END_OF_TESTCASES