Update copyrights to 2021, using "make update-copyright"
[tor.git] / src / test / test_dir.c
blob9624a9fdc4b20955012816764ddeb93f64cde911
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->onion_pkey, &r1->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->onion_pkey,
386 r1->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->onion_pkey,
591 r1->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(rp1->onion_pkey, \
647 rp1->onion_pkey_len); \
648 crypto_pk_t *r1_onion_pkey = router_get_rsa_onion_pkey(r1->onion_pkey, \
649 r1->onion_pkey_len); \
650 tt_int_op(crypto_pk_cmp_keys(rp1_onion_pkey, r1_onion_pkey), OP_EQ, 0); \
651 crypto_pk_free(rp1_onion_pkey); \
652 crypto_pk_free(r1_onion_pkey); \
653 tt_int_op(crypto_pk_cmp_keys(rp1->identity_pkey, r1->identity_pkey), \
654 OP_EQ, 0); \
655 tt_int_op(rp1->supports_tunnelled_dir_requests, OP_EQ, \
656 r1->supports_tunnelled_dir_requests); \
657 STMT_END
659 /* Check that routerinfo r1 and extrainfo e1 are consistent.
660 * Only performs some basic checks.
662 #define CHECK_EXTRAINFO_CONSISTENCY(r1, e1) \
663 STMT_BEGIN \
664 tt_assert(r1); \
665 tt_assert(e1); \
667 tt_str_op(e1->nickname, OP_EQ, r1->nickname); \
668 STMT_END
670 /* Check that the exit policy in rp2 is as expected. */
671 #define CHECK_PARSED_EXIT_POLICY(rp2) \
672 STMT_BEGIN \
673 tt_int_op(smartlist_len(rp2->exit_policy),OP_EQ, 2); \
675 p = smartlist_get(rp2->exit_policy, 0); \
676 tt_int_op(p->policy_type,OP_EQ, ADDR_POLICY_ACCEPT); \
677 tt_assert(tor_addr_is_null(&p->addr)); \
678 tt_int_op(p->maskbits,OP_EQ, 0); \
679 tt_int_op(p->prt_min,OP_EQ, 80); \
680 tt_int_op(p->prt_max,OP_EQ, 80); \
682 p = smartlist_get(rp2->exit_policy, 1); \
683 tt_int_op(p->policy_type,OP_EQ, ADDR_POLICY_REJECT); \
684 tt_assert(tor_addr_eq(&p->addr, &ex2->addr)); \
685 tt_int_op(p->maskbits,OP_EQ, 8); \
686 tt_int_op(p->prt_min,OP_EQ, 24); \
687 tt_int_op(p->prt_max,OP_EQ, 24); \
688 STMT_END
690 /** Run unit tests for router descriptor generation logic for a RSA + ed25519
691 * router.
693 static void
694 test_dir_formats_rsa_ed25519(void *arg)
696 char *buf = NULL;
697 char *buf2 = NULL;
698 char *cp = NULL;
700 crypto_pk_t *r2_onion_pkey = NULL;
701 char cert_buf[256];
702 uint8_t *rsa_cc = NULL;
703 time_t now = time(NULL);
705 routerinfo_t *r2 = NULL;
706 extrainfo_t *e2 = NULL;
707 routerinfo_t *r2_out = NULL;
708 routerinfo_t *rp2 = NULL;
709 extrainfo_t *ep2 = NULL;
710 addr_policy_t *ex1, *ex2;
711 const addr_policy_t *p;
713 smartlist_t *chunks = NULL;
714 int rv = -1;
716 or_options_t *options = get_options_mutable();
717 setup_dir_formats_options((const char *)arg, options);
719 hibernate_set_state_for_testing_(HIBERNATE_STATE_LIVE);
721 /* r2 is a RSA + ed25519 descriptor, with an exit policy, but no DirPort or
722 * IPv6 */
723 r2 = basic_routerinfo_new("Fred", 0x0a030201u /* 10.3.2.1 */,
724 9005, 0,
725 3000, 3000, 3000,
727 &r2_onion_pkey);
729 /* Fake just enough of an ntor key to get by */
730 curve25519_keypair_t r2_onion_keypair;
731 curve25519_keypair_generate(&r2_onion_keypair, 0);
732 r2->onion_curve25519_pkey = tor_memdup(&r2_onion_keypair.pubkey,
733 sizeof(curve25519_public_key_t));
735 /* Now add relay ed25519 keys
736 * We can't use init_mock_ed_keys() here, because the keys are seeded */
737 ed25519_keypair_t kp1, kp2;
738 ed25519_secret_key_from_seed(&kp1.seckey,
739 (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
740 ed25519_public_key_generate(&kp1.pubkey, &kp1.seckey);
741 ed25519_secret_key_from_seed(&kp2.seckey,
742 (const uint8_t*)"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
743 ed25519_public_key_generate(&kp2.pubkey, &kp2.seckey);
744 r2->cache_info.signing_key_cert = tor_cert_create_ed25519(&kp1,
745 CERT_TYPE_ID_SIGNING,
746 &kp2.pubkey,
747 now, 86400,
748 CERT_FLAG_INCLUDE_SIGNING_KEY);
750 /* Now add an exit policy */
751 ex1 = tor_malloc_zero(sizeof(addr_policy_t));
752 ex2 = tor_malloc_zero(sizeof(addr_policy_t));
753 ex1->policy_type = ADDR_POLICY_ACCEPT;
754 tor_addr_from_ipv4h(&ex1->addr, 0);
755 ex1->maskbits = 0;
756 ex1->prt_min = ex1->prt_max = 80;
757 ex2->policy_type = ADDR_POLICY_REJECT;
758 tor_addr_from_ipv4h(&ex2->addr, 18<<24);
759 ex2->maskbits = 8;
760 ex2->prt_min = ex2->prt_max = 24;
762 r2->exit_policy = smartlist_new();
763 smartlist_add(r2->exit_policy, ex1);
764 smartlist_add(r2->exit_policy, ex2);
766 /* Fake just enough of an ORPort to get by */
767 setup_mock_configured_ports(r2->ipv4_orport, 0);
769 buf = router_dump_router_to_string(r2,
770 r2->identity_pkey, r2_onion_pkey,
771 &r2_onion_keypair, &kp2);
772 tt_assert(buf);
774 cleanup_mock_configured_ports();
776 chunks = smartlist_new();
778 /* Synthesise a router descriptor, without the signatures */
779 smartlist_add(chunks, get_new_router_line(r2));
781 smartlist_add_strdup(chunks,
782 "identity-ed25519\n"
783 "-----BEGIN ED25519 CERT-----\n");
784 base64_encode(cert_buf, sizeof(cert_buf),
785 (const char*)r2->cache_info.signing_key_cert->encoded,
786 r2->cache_info.signing_key_cert->encoded_len,
787 BASE64_ENCODE_MULTILINE);
788 smartlist_add_strdup(chunks, cert_buf);
789 smartlist_add_strdup(chunks, "-----END ED25519 CERT-----\n");
791 smartlist_add_strdup(chunks, "master-key-ed25519 ");
793 char k[ED25519_BASE64_LEN+1];
794 ed25519_public_to_base64(k, &r2->cache_info.signing_key_cert->signing_key);
795 smartlist_add_strdup(chunks, k);
796 smartlist_add_strdup(chunks, "\n");
799 smartlist_add(chunks, get_new_platform_line());
800 smartlist_add_asprintf(chunks,
801 "proto %s\n", protover_get_supported_protocols());
802 smartlist_add(chunks, get_new_published_line(r2));
803 smartlist_add(chunks, get_new_fingerprint_line(r2));
805 smartlist_add(chunks, get_new_uptime_line(0));
806 smartlist_add(chunks, get_new_bandwidth_line(r2));
808 smartlist_add(chunks, get_new_onion_key_block(r2));
809 smartlist_add(chunks, get_new_signing_key_block(r2));
811 int rsa_cc_len;
812 rsa_cc = make_tap_onion_key_crosscert(r2_onion_pkey,
813 &kp1.pubkey,
814 r2->identity_pkey,
815 &rsa_cc_len);
816 tt_assert(rsa_cc);
817 base64_encode(cert_buf, sizeof(cert_buf), (char*)rsa_cc, rsa_cc_len,
818 BASE64_ENCODE_MULTILINE);
819 smartlist_add_strdup(chunks, "onion-key-crosscert\n"
820 "-----BEGIN CROSSCERT-----\n");
821 smartlist_add_strdup(chunks, cert_buf);
822 smartlist_add_strdup(chunks, "-----END CROSSCERT-----\n");
823 int ntor_cc_sign;
825 tor_cert_t *ntor_cc = NULL;
826 ntor_cc = make_ntor_onion_key_crosscert(&r2_onion_keypair,
827 &kp1.pubkey,
828 r2->cache_info.published_on,
829 get_onion_key_lifetime(),
830 &ntor_cc_sign);
831 tt_assert(ntor_cc);
832 base64_encode(cert_buf, sizeof(cert_buf),
833 (char*)ntor_cc->encoded, ntor_cc->encoded_len,
834 BASE64_ENCODE_MULTILINE);
835 tor_cert_free(ntor_cc);
837 smartlist_add_asprintf(chunks,
838 "ntor-onion-key-crosscert %d\n"
839 "-----BEGIN ED25519 CERT-----\n"
840 "%s"
841 "-----END ED25519 CERT-----\n", ntor_cc_sign, cert_buf);
843 smartlist_add_strdup(chunks, "hidden-service-dir\n");
845 smartlist_add(chunks, get_new_bridge_distribution_request_line(options));
846 smartlist_add(chunks, get_new_ntor_onion_key_line(&r2_onion_keypair.pubkey));
847 smartlist_add_strdup(chunks, "accept *:80\nreject 18.0.0.0/8:24\n");
848 smartlist_add_strdup(chunks, "tunnelled-dir-server\n");
850 smartlist_add_strdup(chunks, "router-sig-ed25519 ");
852 size_t len_out = 0;
853 buf2 = smartlist_join_strings(chunks, "", 0, &len_out);
854 SMARTLIST_FOREACH(chunks, char *, s, tor_free(s));
855 smartlist_free(chunks);
857 tt_assert(len_out > 0);
859 buf[strlen(buf2)] = '\0'; /* Don't compare either sig; they're never the same
860 * twice */
862 tt_str_op(buf, OP_EQ, buf2);
863 tor_free(buf);
865 setup_mock_configured_ports(r2->ipv4_orport, 0);
867 buf = router_dump_router_to_string(r2, r2->identity_pkey,
868 r2_onion_pkey,
869 &r2_onion_keypair, &kp2);
870 tt_assert(buf);
872 cleanup_mock_configured_ports();
874 /* Now, try to parse buf */
875 cp = buf;
876 rp2 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL);
878 CHECK_ROUTERINFO_CONSISTENCY(r2, rp2);
880 tt_mem_op(rp2->onion_curve25519_pkey->public_key,OP_EQ,
881 r2->onion_curve25519_pkey->public_key,
882 CURVE25519_PUBKEY_LEN);
884 CHECK_PARSED_EXIT_POLICY(rp2);
886 tor_free(buf);
887 routerinfo_free(rp2);
889 /* Test extrainfo creation. */
891 /* Set up standard mocks and data */
892 setup_mocks_for_fresh_descriptor(r2, r2_onion_pkey);
894 /* router_build_fresh_descriptor() requires
895 * router_build_fresh_unsigned_routerinfo(), but the implementation is
896 * too complex. Instead, we re-use r2.
898 mocked_routerinfo = r2;
899 MOCK(router_build_fresh_unsigned_routerinfo,
900 mock_router_build_fresh_unsigned_routerinfo);
902 /* r2 uses ed25519, so we need to mock the ed key functions */
903 mocked_master_signing_key = &kp2;
904 MOCK(get_master_signing_keypair, mock_get_master_signing_keypair);
906 mocked_signing_key_cert = r2->cache_info.signing_key_cert;
907 MOCK(get_master_signing_key_cert, mock_get_master_signing_key_cert);
909 mocked_curve25519_onion_key = &r2_onion_keypair;
910 MOCK(get_current_curve25519_keypair, mock_get_current_curve25519_keypair);
912 /* Fake just enough of an ORPort to get by */
913 setup_mock_configured_ports(r2->ipv4_orport, 0);
915 /* Test the high-level interface. */
916 rv = router_build_fresh_descriptor(&r2_out, &e2);
917 if (rv < 0) {
918 /* router_build_fresh_descriptor() frees r2 on failure. */
919 r2 = NULL;
920 /* Get rid of an alias to rp2 */
921 r2_out = NULL;
923 tt_assert(rv == 0);
924 tt_assert(r2_out);
925 tt_assert(e2);
926 /* Guaranteed by mock_router_build_fresh_unsigned_routerinfo() */
927 tt_ptr_op(r2_out, OP_EQ, r2);
928 /* Get rid of an alias to r2 */
929 r2_out = NULL;
931 /* Now cleanup */
932 cleanup_mocks_for_fresh_descriptor();
934 mocked_routerinfo = NULL;
935 UNMOCK(router_build_fresh_unsigned_routerinfo);
936 mocked_master_signing_key = NULL;
937 UNMOCK(get_master_signing_keypair);
938 mocked_signing_key_cert = NULL;
939 UNMOCK(get_master_signing_key_cert);
940 mocked_curve25519_onion_key = NULL;
941 UNMOCK(get_current_curve25519_keypair);
943 cleanup_mock_configured_ports();
945 CHECK_EXTRAINFO_CONSISTENCY(r2, e2);
947 /* Test that the signed ri is parseable */
948 tt_assert(r2->cache_info.signed_descriptor_body);
949 cp = r2->cache_info.signed_descriptor_body;
950 rp2 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL);
952 CHECK_ROUTERINFO_CONSISTENCY(r2, rp2);
954 tt_mem_op(rp2->onion_curve25519_pkey->public_key,OP_EQ,
955 r2->onion_curve25519_pkey->public_key,
956 CURVE25519_PUBKEY_LEN);
958 CHECK_PARSED_EXIT_POLICY(rp2);
960 routerinfo_free(rp2);
962 /* Test that the signed ei is parseable */
963 tt_assert(e2->cache_info.signed_descriptor_body);
964 cp = e2->cache_info.signed_descriptor_body;
965 ep2 = extrainfo_parse_entry_from_string((const char*)cp,NULL,1,NULL,NULL);
967 CHECK_EXTRAINFO_CONSISTENCY(r2, ep2);
969 /* In future tests, we could check the actual extrainfo statistics. */
971 extrainfo_free(ep2);
973 done:
974 dirserv_free_fingerprint_list();
976 tor_free(options->Nickname);
978 cleanup_mock_configured_ports();
979 cleanup_mocks_for_fresh_descriptor();
981 if (chunks) {
982 SMARTLIST_FOREACH(chunks, char *, s, tor_free(s));
983 smartlist_free(chunks);
986 routerinfo_free(r2);
987 routerinfo_free(r2_out);
988 routerinfo_free(rp2);
990 extrainfo_free(e2);
991 extrainfo_free(ep2);
993 tor_free(rsa_cc);
994 crypto_pk_free(r2_onion_pkey);
996 tor_free(buf);
997 tor_free(buf2);
1000 #include "failing_routerdescs.inc"
1002 static void
1003 test_dir_routerinfo_parsing(void *arg)
1005 (void) arg;
1007 int again;
1008 routerinfo_t *ri = NULL;
1010 #define CHECK_OK(s) \
1011 do { \
1012 routerinfo_free(ri); \
1013 ri = router_parse_entry_from_string((s), NULL, 0, 0, NULL, NULL); \
1014 tt_assert(ri); \
1015 } while (0)
1016 #define CHECK_FAIL(s, againval) \
1017 do { \
1018 routerinfo_free(ri); \
1019 again = 999; \
1020 ri = router_parse_entry_from_string((s), NULL, 0, 0, NULL, &again); \
1021 tt_assert(ri == NULL); \
1022 tt_int_op(again, OP_EQ, (againval)); \
1023 } while (0)
1025 CHECK_OK(EX_RI_MINIMAL);
1026 CHECK_OK(EX_RI_MAXIMAL);
1028 /* good annotations prepended */
1029 routerinfo_free(ri);
1030 ri = router_parse_entry_from_string(EX_RI_MINIMAL, NULL, 0, 0,
1031 "@purpose bridge\n", NULL);
1032 tt_ptr_op(ri, OP_NE, NULL);
1033 tt_assert(ri->purpose == ROUTER_PURPOSE_BRIDGE);
1034 routerinfo_free(ri);
1036 /* bad annotations prepended. */
1037 ri = router_parse_entry_from_string(EX_RI_MINIMAL,
1038 NULL, 0, 0, "@purpose\n", NULL);
1039 tt_ptr_op(ri, OP_EQ, NULL);
1041 /* bad annotations on router. */
1042 ri = router_parse_entry_from_string("@purpose\nrouter x\n", NULL, 0, 1,
1043 NULL, NULL);
1044 tt_ptr_op(ri, OP_EQ, NULL);
1046 /* unwanted annotations on router. */
1047 ri = router_parse_entry_from_string("@purpose foo\nrouter x\n", NULL, 0, 0,
1048 NULL, NULL);
1049 tt_ptr_op(ri, OP_EQ, NULL);
1051 /* No signature. */
1052 ri = router_parse_entry_from_string("router x\n", NULL, 0, 0,
1053 NULL, NULL);
1054 tt_ptr_op(ri, OP_EQ, NULL);
1056 /* Not a router */
1057 routerinfo_free(ri);
1058 ri = router_parse_entry_from_string("hello\n", NULL, 0, 0, NULL, NULL);
1059 tt_ptr_op(ri, OP_EQ, NULL);
1061 CHECK_FAIL(EX_RI_BAD_SIG1, 1);
1062 CHECK_FAIL(EX_RI_BAD_TOKENS, 0);
1063 CHECK_FAIL(EX_RI_BAD_PUBLISHED, 0);
1064 CHECK_FAIL(EX_RI_NEG_BANDWIDTH, 0);
1065 CHECK_FAIL(EX_RI_BAD_BANDWIDTH, 0);
1066 CHECK_FAIL(EX_RI_BAD_BANDWIDTH2, 0);
1067 CHECK_FAIL(EX_RI_BAD_BANDWIDTH3, 0);
1068 CHECK_FAIL(EX_RI_BAD_ONIONKEY, 0);
1069 CHECK_FAIL(EX_RI_BAD_PORTS, 0);
1070 CHECK_FAIL(EX_RI_BAD_IP, 0);
1071 CHECK_FAIL(EX_RI_BAD_DIRPORT, 0);
1072 CHECK_FAIL(EX_RI_BAD_NAME2, 0);
1073 CHECK_FAIL(EX_RI_BAD_UPTIME, 0);
1075 CHECK_FAIL(EX_RI_BAD_BANDWIDTH3, 0);
1076 CHECK_FAIL(EX_RI_BAD_NTOR_KEY, 0);
1077 CHECK_FAIL(EX_RI_BAD_FINGERPRINT, 0);
1078 CHECK_FAIL(EX_RI_MISMATCHED_FINGERPRINT, 0);
1079 CHECK_FAIL(EX_RI_BAD_HAS_ACCEPT6, 0);
1080 CHECK_FAIL(EX_RI_BAD_NO_EXIT_POLICY, 0);
1081 CHECK_FAIL(EX_RI_BAD_IPV6_EXIT_POLICY, 0);
1082 CHECK_FAIL(EX_RI_BAD_FAMILY, 0);
1083 CHECK_FAIL(EX_RI_ZERO_ORPORT, 0);
1085 CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT, 0);
1086 CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT2, 0);
1087 CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT_SIGN, 0);
1088 CHECK_FAIL(EX_RI_ED_BAD_SIG1, 0);
1089 CHECK_FAIL(EX_RI_ED_BAD_SIG2, 0);
1090 CHECK_FAIL(EX_RI_ED_BAD_SIG3, 0);
1091 CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT1, 0);
1092 CHECK_FAIL(EX_RI_ED_MISPLACED1, 0);
1093 CHECK_FAIL(EX_RI_ED_MISPLACED2, 0);
1094 CHECK_FAIL(EX_RI_ED_BAD_CERT1, 0);
1096 #undef CHECK_FAIL
1097 #undef CHECK_OK
1098 done:
1099 routerinfo_free(ri);
1102 #include "example_extrainfo.inc"
1104 static void
1105 routerinfo_free_wrapper_(void *arg)
1107 routerinfo_free_(arg);
1110 static void
1111 test_dir_extrainfo_parsing(void *arg)
1113 (void) arg;
1115 #define CHECK_OK(s) \
1116 do { \
1117 extrainfo_free(ei); \
1118 ei = extrainfo_parse_entry_from_string((s), NULL, 0, map, NULL); \
1119 tt_assert(ei); \
1120 } while (0)
1121 #define CHECK_FAIL(s, againval) \
1122 do { \
1123 extrainfo_free(ei); \
1124 again = 999; \
1125 ei = extrainfo_parse_entry_from_string((s), NULL, 0, map, &again); \
1126 tt_assert(ei == NULL); \
1127 tt_int_op(again, OP_EQ, (againval)); \
1128 } while (0)
1129 #define ADD(name) \
1130 do { \
1131 ri = tor_malloc_zero(sizeof(routerinfo_t)); \
1132 crypto_pk_t *pk = ri->identity_pkey = crypto_pk_new(); \
1133 tt_assert(! crypto_pk_read_public_key_from_string(pk, \
1134 name##_KEY, strlen(name##_KEY))); \
1135 tt_int_op(20,OP_EQ,base16_decode(d, 20, name##_FP, strlen(name##_FP))); \
1136 digestmap_set((digestmap_t*)map, d, ri); \
1137 ri = NULL; \
1138 } while (0)
1140 routerinfo_t *ri = NULL;
1141 char d[20];
1142 struct digest_ri_map_t *map = NULL;
1143 extrainfo_t *ei = NULL;
1144 int again;
1146 CHECK_OK(EX_EI_MINIMAL);
1147 tt_assert(ei->pending_sig);
1148 CHECK_OK(EX_EI_MAXIMAL);
1149 tt_assert(ei->pending_sig);
1151 map = (struct digest_ri_map_t *)digestmap_new();
1152 ADD(EX_EI_MINIMAL);
1153 ADD(EX_EI_MAXIMAL);
1154 ADD(EX_EI_BAD_NICKNAME);
1155 ADD(EX_EI_BAD_TOKENS);
1156 ADD(EX_EI_BAD_START);
1157 ADD(EX_EI_BAD_PUBLISHED);
1159 ADD(EX_EI_ED_MISSING_SIG);
1160 ADD(EX_EI_ED_MISSING_CERT);
1161 ADD(EX_EI_ED_BAD_CERT1);
1162 ADD(EX_EI_ED_BAD_CERT2);
1163 ADD(EX_EI_ED_MISPLACED_CERT);
1164 ADD(EX_EI_ED_MISPLACED_SIG);
1166 CHECK_OK(EX_EI_MINIMAL);
1167 tt_ptr_op(ei->pending_sig, OP_EQ, NULL);
1168 CHECK_OK(EX_EI_MAXIMAL);
1169 tt_ptr_op(ei->pending_sig, OP_EQ, NULL);
1171 CHECK_FAIL(EX_EI_BAD_SIG1,1);
1172 CHECK_FAIL(EX_EI_BAD_SIG2,0);
1173 CHECK_FAIL(EX_EI_BAD_NICKNAME,0);
1174 CHECK_FAIL(EX_EI_BAD_TOKENS,0);
1175 CHECK_FAIL(EX_EI_BAD_START,0);
1176 CHECK_FAIL(EX_EI_BAD_PUBLISHED,0);
1178 CHECK_FAIL(EX_EI_ED_MISSING_SIG,0);
1179 CHECK_FAIL(EX_EI_ED_MISSING_CERT,0);
1180 CHECK_FAIL(EX_EI_ED_BAD_CERT1,0);
1181 CHECK_FAIL(EX_EI_ED_BAD_CERT2,0);
1182 CHECK_FAIL(EX_EI_ED_MISPLACED_CERT,0);
1183 CHECK_FAIL(EX_EI_ED_MISPLACED_SIG,0);
1185 #undef CHECK_OK
1186 #undef CHECK_FAIL
1188 done:
1189 escaped(NULL);
1190 extrainfo_free(ei);
1191 routerinfo_free(ri);
1192 digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_);
1195 static void
1196 test_dir_parse_router_list(void *arg)
1198 (void) arg;
1199 smartlist_t *invalid = smartlist_new();
1200 smartlist_t *dest = smartlist_new();
1201 smartlist_t *chunks = smartlist_new();
1202 int dest_has_ri = 1;
1203 char *list = NULL;
1204 const char *cp;
1205 digestmap_t *map = NULL;
1206 char *mem_op_hex_tmp = NULL;
1207 routerinfo_t *ri = NULL;
1208 char d[DIGEST_LEN];
1210 smartlist_add_strdup(chunks, EX_RI_MINIMAL); // ri 0
1211 smartlist_add_strdup(chunks, EX_RI_BAD_PORTS); // bad ri 0
1212 smartlist_add_strdup(chunks, EX_EI_MAXIMAL); // ei 0
1213 smartlist_add_strdup(chunks, EX_EI_BAD_SIG2); // bad ei --
1214 smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME);// bad ei 0
1215 smartlist_add_strdup(chunks, EX_RI_BAD_SIG1); // bad ri --
1216 smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED); // bad ei 1
1217 smartlist_add_strdup(chunks, EX_RI_MAXIMAL); // ri 1
1218 smartlist_add_strdup(chunks, EX_RI_BAD_FAMILY); // bad ri 1
1219 smartlist_add_strdup(chunks, EX_EI_MINIMAL); // ei 1
1221 list = smartlist_join_strings(chunks, "", 0, NULL);
1223 /* First, parse the routers. */
1224 cp = list;
1225 tt_int_op(0,OP_EQ,
1226 router_parse_list_from_string(&cp, NULL, dest, SAVED_NOWHERE,
1227 0, 0, NULL, invalid));
1228 tt_int_op(2, OP_EQ, smartlist_len(dest));
1229 tt_ptr_op(cp, OP_EQ, list + strlen(list));
1231 routerinfo_t *r = smartlist_get(dest, 0);
1232 tt_mem_op(r->cache_info.signed_descriptor_body, OP_EQ,
1233 EX_RI_MINIMAL, strlen(EX_RI_MINIMAL));
1234 r = smartlist_get(dest, 1);
1235 tt_mem_op(r->cache_info.signed_descriptor_body, OP_EQ,
1236 EX_RI_MAXIMAL, strlen(EX_RI_MAXIMAL));
1238 setup_ei_digests();
1240 tt_int_op(2, OP_EQ, smartlist_len(invalid));
1242 test_memeq_hex(smartlist_get(invalid, 0),
1243 "10F951AF93AED0D3BC7FA5FFA232EB8C17747ACE");
1244 test_memeq_hex(smartlist_get(invalid, 1),
1245 "41D8723CDD4B1AADCCE538C28CDE7F69828C73D0");
1247 /* Now tidy up */
1248 SMARTLIST_FOREACH(dest, routerinfo_t *, rinfo, routerinfo_free(rinfo));
1249 SMARTLIST_FOREACH(invalid, uint8_t *, dig, tor_free(dig));
1250 smartlist_clear(dest);
1251 smartlist_clear(invalid);
1253 /* And check extrainfos. */
1254 dest_has_ri = 0;
1255 map = (digestmap_t*)router_get_routerlist()->identity_map;
1256 ADD(EX_EI_MINIMAL);
1257 ADD(EX_EI_MAXIMAL);
1258 ADD(EX_EI_BAD_NICKNAME);
1259 ADD(EX_EI_BAD_PUBLISHED);
1260 ADD(EX_EI_BAD_SIG2);
1261 cp = list;
1262 tt_int_op(0,OP_EQ,
1263 router_parse_list_from_string(&cp, NULL, dest, SAVED_NOWHERE,
1264 1, 0, NULL, invalid));
1265 tt_int_op(2, OP_EQ, smartlist_len(dest));
1266 extrainfo_t *e = smartlist_get(dest, 0);
1267 tt_mem_op(e->cache_info.signed_descriptor_body, OP_EQ,
1268 EX_EI_MAXIMAL, strlen(EX_EI_MAXIMAL));
1269 e = smartlist_get(dest, 1);
1270 tt_mem_op(e->cache_info.signed_descriptor_body, OP_EQ,
1271 EX_EI_MINIMAL, strlen(EX_EI_MINIMAL));
1273 tt_int_op(3, OP_EQ, smartlist_len(invalid));
1274 tt_mem_op(smartlist_get(invalid, 0),
1275 OP_EQ,
1276 digest_ei_bad_sig2, DIGEST_LEN);
1277 tt_mem_op(smartlist_get(invalid, 1),
1278 OP_EQ,
1279 digest_ei_bad_nickname, DIGEST_LEN);
1280 tt_mem_op(smartlist_get(invalid, 2),
1281 OP_EQ,
1282 digest_ei_bad_published, DIGEST_LEN);
1284 done:
1285 tor_free(list);
1286 if (dest_has_ri)
1287 SMARTLIST_FOREACH(dest, routerinfo_t *, rt, routerinfo_free(rt));
1288 else
1289 SMARTLIST_FOREACH(dest, extrainfo_t *, ei, extrainfo_free(ei));
1290 smartlist_free(dest);
1291 SMARTLIST_FOREACH(invalid, uint8_t *, dig, tor_free(dig));
1292 smartlist_free(invalid);
1293 SMARTLIST_FOREACH(chunks, char *, chunk, tor_free(chunk));
1294 smartlist_free(chunks);
1295 routerinfo_free(ri);
1296 if (map) {
1297 digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_);
1298 router_get_routerlist()->identity_map =
1299 (struct digest_ri_map_t*)digestmap_new();
1301 tor_free(mem_op_hex_tmp);
1303 #undef ADD
1306 static download_status_t dls_minimal;
1307 static download_status_t dls_maximal;
1308 static download_status_t dls_bad_fingerprint;
1309 static download_status_t dls_bad_sig1;
1310 static download_status_t dls_bad_ports;
1311 static download_status_t dls_bad_tokens;
1313 static uint8_t digest_minimal[20];
1314 static uint8_t digest_maximal[20];
1315 static uint8_t digest_bad_fingerprint[20];
1316 static uint8_t digest_bad_sig1[20];
1317 static uint8_t digest_bad_ports[20];
1318 static uint8_t digest_bad_tokens[20];
1320 static void
1321 setup_dls_digests(void)
1323 #define SETUP(string, name) \
1324 do { \
1325 router_get_router_hash(string, strlen(string), (char*)digest_##name); \
1326 } while (0)
1328 SETUP(EX_RI_MINIMAL, minimal);
1329 SETUP(EX_RI_MAXIMAL, maximal);
1330 SETUP(EX_RI_BAD_FINGERPRINT, bad_fingerprint);
1331 SETUP(EX_RI_BAD_SIG1, bad_sig1);
1332 SETUP(EX_RI_BAD_PORTS, bad_ports);
1333 SETUP(EX_RI_BAD_TOKENS, bad_tokens);
1334 #undef SETUP
1337 static int mock_router_get_dl_status_unrecognized = 0;
1338 static int mock_router_get_dl_status_calls = 0;
1340 static download_status_t *
1341 mock_router_get_dl_status(const char *d)
1343 ++mock_router_get_dl_status_calls;
1344 #define CHECK(name) \
1345 do { \
1346 if (fast_memeq(d, digest_##name, DIGEST_LEN)) \
1347 return &dls_##name; \
1348 } while (0)
1350 CHECK(minimal);
1351 CHECK(maximal);
1352 CHECK(bad_fingerprint);
1353 CHECK(bad_sig1);
1354 CHECK(bad_ports);
1355 CHECK(bad_tokens);
1357 ++mock_router_get_dl_status_unrecognized;
1358 return NULL;
1359 #undef CHECK
1362 static void
1363 test_dir_load_routers(void *arg)
1365 (void) arg;
1366 smartlist_t *chunks = smartlist_new();
1367 smartlist_t *wanted = smartlist_new();
1368 char buf[DIGEST_LEN];
1369 char *mem_op_hex_tmp = NULL;
1370 char *list = NULL;
1372 #define ADD(str) \
1373 do { \
1374 tt_int_op(0,OP_EQ,router_get_router_hash(str, strlen(str), buf)); \
1375 smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN)); \
1376 } while (0)
1378 setup_dls_digests();
1380 MOCK(router_get_dl_status_by_descriptor_digest, mock_router_get_dl_status);
1382 update_approx_time(1412510400);
1384 smartlist_add_strdup(chunks, EX_RI_MINIMAL);
1385 smartlist_add_strdup(chunks, EX_RI_BAD_FINGERPRINT);
1386 smartlist_add_strdup(chunks, EX_RI_BAD_SIG1);
1387 smartlist_add_strdup(chunks, EX_RI_MAXIMAL);
1388 smartlist_add_strdup(chunks, EX_RI_BAD_PORTS);
1389 smartlist_add_strdup(chunks, EX_RI_BAD_TOKENS);
1391 /* not ADDing MINIMAL */
1392 ADD(EX_RI_MAXIMAL);
1393 ADD(EX_RI_BAD_FINGERPRINT);
1394 ADD(EX_RI_BAD_SIG1);
1395 /* Not ADDing BAD_PORTS */
1396 ADD(EX_RI_BAD_TOKENS);
1398 list = smartlist_join_strings(chunks, "", 0, NULL);
1399 tt_int_op(1, OP_EQ,
1400 router_load_routers_from_string(list, NULL, SAVED_IN_JOURNAL,
1401 wanted, 1, NULL));
1403 /* The "maximal" router was added. */
1404 /* "minimal" was not. */
1405 tt_int_op(smartlist_len(router_get_routerlist()->routers),OP_EQ,1);
1406 routerinfo_t *r = smartlist_get(router_get_routerlist()->routers, 0);
1407 test_memeq_hex(r->cache_info.signed_descriptor_digest,
1408 "1F437798ACD1FC9CBD1C3C04DBF80F7E9F819C3F");
1409 tt_int_op(dls_minimal.n_download_failures, OP_EQ, 0);
1410 tt_int_op(dls_maximal.n_download_failures, OP_EQ, 0);
1412 /* "Bad fingerprint" and "Bad tokens" should have gotten marked
1413 * non-retriable. */
1414 tt_want_int_op(mock_router_get_dl_status_calls, OP_EQ, 2);
1415 tt_want_int_op(mock_router_get_dl_status_unrecognized, OP_EQ, 0);
1416 tt_int_op(dls_bad_fingerprint.n_download_failures, OP_EQ, 255);
1417 tt_int_op(dls_bad_tokens.n_download_failures, OP_EQ, 255);
1419 /* bad_sig2 and bad ports" are retriable -- one since only the signature
1420 * was bad, and one because we didn't ask for it. */
1421 tt_int_op(dls_bad_sig1.n_download_failures, OP_EQ, 0);
1422 tt_int_op(dls_bad_ports.n_download_failures, OP_EQ, 0);
1424 tt_int_op(smartlist_len(wanted), OP_EQ, 1);
1425 tt_str_op(smartlist_get(wanted, 0), OP_EQ,
1426 "3BB7D03C1C4DBC1DDE840096FF3C330914757B77");
1428 #undef ADD
1430 done:
1431 tor_free(mem_op_hex_tmp);
1432 UNMOCK(router_get_dl_status_by_descriptor_digest);
1433 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
1434 smartlist_free(chunks);
1435 SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
1436 smartlist_free(wanted);
1437 tor_free(list);
1440 static int mock_get_by_ei_dd_calls = 0;
1441 static int mock_get_by_ei_dd_unrecognized = 0;
1443 static signed_descriptor_t sd_ei_minimal;
1444 static signed_descriptor_t sd_ei_bad_nickname;
1445 static signed_descriptor_t sd_ei_maximal;
1446 static signed_descriptor_t sd_ei_bad_tokens;
1447 static signed_descriptor_t sd_ei_bad_sig2;
1449 static void
1450 setup_ei_digests(void)
1452 #define SETUP(string, name) \
1453 do { \
1454 router_get_extrainfo_hash(string, strlen(string), \
1455 (char*)digest_ei_##name); \
1456 } while (0)
1458 SETUP(EX_EI_MINIMAL, minimal);
1459 SETUP(EX_EI_MAXIMAL, maximal);
1460 SETUP(EX_EI_BAD_NICKNAME, bad_nickname);
1461 SETUP(EX_EI_BAD_TOKENS, bad_tokens);
1462 SETUP(EX_EI_BAD_SIG2, bad_sig2);
1463 SETUP(EX_EI_BAD_PUBLISHED, bad_published);
1465 #undef SETUP
1468 static signed_descriptor_t *
1469 mock_get_by_ei_desc_digest(const char *d)
1471 ++mock_get_by_ei_dd_calls;
1472 #define CHECK(name) \
1473 do { \
1474 if (fast_memeq(d, digest_ei_##name, DIGEST_LEN)) \
1475 return &sd_ei_##name; \
1476 } while (0)
1478 CHECK(minimal);
1479 CHECK(maximal);
1480 CHECK(bad_nickname);
1481 CHECK(bad_sig2);
1482 CHECK(bad_tokens);
1483 ++mock_get_by_ei_dd_unrecognized;
1484 return NULL;
1485 #undef CHECK
1488 static signed_descriptor_t *
1489 mock_ei_get_by_ei_digest(const char *d)
1491 signed_descriptor_t *sd = &sd_ei_minimal;
1493 if (fast_memeq(d, digest_ei_minimal, DIGEST_LEN)) {
1494 sd->signed_descriptor_body = (char *)EX_EI_MINIMAL;
1495 sd->signed_descriptor_len = sizeof(EX_EI_MINIMAL);
1496 sd->annotations_len = 0;
1497 sd->saved_location = SAVED_NOWHERE;
1498 return sd;
1500 return NULL;
1503 static smartlist_t *mock_ei_insert_list = NULL;
1504 static was_router_added_t
1505 mock_ei_insert(routerlist_t *rl, extrainfo_t *ei, int warn_if_incompatible)
1507 (void) rl;
1508 (void) warn_if_incompatible;
1509 smartlist_add(mock_ei_insert_list, ei);
1510 return ROUTER_ADDED_SUCCESSFULLY;
1513 static void
1514 test_dir_load_extrainfo(void *arg)
1516 (void) arg;
1517 smartlist_t *chunks = smartlist_new();
1518 smartlist_t *wanted = smartlist_new();
1519 char buf[DIGEST_LEN];
1520 char *mem_op_hex_tmp = NULL;
1521 char *list = NULL;
1523 #define ADD(str) \
1524 do { \
1525 tt_int_op(0,OP_EQ,router_get_extrainfo_hash(str, strlen(str), buf)); \
1526 smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN)); \
1527 } while (0)
1529 setup_ei_digests();
1530 mock_ei_insert_list = smartlist_new();
1531 MOCK(router_get_by_extrainfo_digest, mock_get_by_ei_desc_digest);
1532 MOCK(extrainfo_insert, mock_ei_insert);
1534 smartlist_add_strdup(chunks, EX_EI_MINIMAL);
1535 smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME);
1536 smartlist_add_strdup(chunks, EX_EI_MAXIMAL);
1537 smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED);
1538 smartlist_add_strdup(chunks, EX_EI_BAD_TOKENS);
1540 /* not ADDing MINIMAL */
1541 ADD(EX_EI_MAXIMAL);
1542 ADD(EX_EI_BAD_NICKNAME);
1543 /* Not ADDing BAD_PUBLISHED */
1544 ADD(EX_EI_BAD_TOKENS);
1545 ADD(EX_EI_BAD_SIG2);
1547 list = smartlist_join_strings(chunks, "", 0, NULL);
1548 router_load_extrainfo_from_string(list, NULL, SAVED_IN_JOURNAL, wanted, 1);
1550 /* The "maximal" router was added. */
1551 /* "minimal" was also added, even though we didn't ask for it, since
1552 * that's what we do with extrainfos. */
1553 tt_int_op(smartlist_len(mock_ei_insert_list),OP_EQ,2);
1555 extrainfo_t *e = smartlist_get(mock_ei_insert_list, 0);
1556 tt_mem_op(e->cache_info.signed_descriptor_digest, OP_EQ,
1557 digest_ei_minimal, DIGEST_LEN);
1559 e = smartlist_get(mock_ei_insert_list, 1);
1560 tt_mem_op(e->cache_info.signed_descriptor_digest, OP_EQ,
1561 digest_ei_maximal, DIGEST_LEN);
1562 tt_int_op(dls_minimal.n_download_failures, OP_EQ, 0);
1563 tt_int_op(dls_maximal.n_download_failures, OP_EQ, 0);
1565 /* "Bad nickname" and "Bad tokens" should have gotten marked
1566 * non-retriable. */
1567 tt_want_int_op(mock_get_by_ei_dd_calls, OP_EQ, 2);
1568 tt_want_int_op(mock_get_by_ei_dd_unrecognized, OP_EQ, 0);
1569 tt_int_op(sd_ei_bad_nickname.ei_dl_status.n_download_failures, OP_EQ, 255);
1570 tt_int_op(sd_ei_bad_tokens.ei_dl_status.n_download_failures, OP_EQ, 255);
1572 /* bad_ports is retriable -- because we didn't ask for it. */
1573 tt_int_op(dls_bad_ports.n_download_failures, OP_EQ, 0);
1575 /* Wanted still contains "BAD_SIG2" */
1576 tt_int_op(smartlist_len(wanted), OP_EQ, 1);
1577 const char *got_wanted =smartlist_get(wanted, 0);
1578 tt_int_op(strlen(got_wanted), OP_EQ, HEX_DIGEST_LEN);
1579 char d[DIGEST_LEN];
1580 base16_decode(d, DIGEST_LEN, got_wanted, strlen(got_wanted));
1581 tt_mem_op(d, OP_EQ, digest_ei_bad_sig2, DIGEST_LEN);
1583 #undef ADD
1585 done:
1586 tor_free(mem_op_hex_tmp);
1587 UNMOCK(router_get_by_extrainfo_digest);
1588 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
1589 smartlist_free(chunks);
1590 SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
1591 smartlist_free(wanted);
1592 tor_free(list);
1595 static void
1596 test_dir_getinfo_extra(void *arg)
1598 int r;
1599 char *answer = NULL;
1600 const char *errmsg = NULL;
1601 char buf[128];
1602 char hexdigest[HEX_DIGEST_LEN+1];
1603 (void)arg;
1605 setup_ei_digests();
1606 base16_encode(hexdigest, sizeof(hexdigest),
1607 (const char*)digest_ei_minimal, DIGEST_LEN);
1608 tor_snprintf(buf, sizeof(buf), "extra-info/digest/%s", hexdigest);
1610 MOCK(extrainfo_get_by_descriptor_digest, mock_ei_get_by_ei_digest);
1611 r = getinfo_helper_dir(NULL, buf, &answer, &errmsg);
1612 tt_int_op(0, OP_EQ, r);
1613 tt_ptr_op(NULL, OP_EQ, errmsg);
1614 tt_str_op(answer, OP_EQ, EX_EI_MINIMAL);
1615 tor_free(answer);
1617 answer = NULL;
1618 r = getinfo_helper_dir(NULL, "extra-info/digest/"
1619 "NOTAVALIDHEXSTRINGNOTAVALIDHEXSTRINGNOTA", &answer,
1620 &errmsg);
1621 tt_int_op(0, OP_EQ, r);
1622 /* getinfo_helper_dir() should maybe return an error here but doesn't */
1623 tt_ptr_op(NULL, OP_EQ, errmsg);
1624 /* In any case, there should be no answer for an invalid hex string. */
1625 tt_ptr_op(NULL, OP_EQ, answer);
1627 done:
1628 UNMOCK(extrainfo_get_by_descriptor_digest);
1631 static void
1632 test_dir_versions(void *arg)
1634 tor_version_t ver1;
1636 /* Try out version parsing functionality */
1637 (void)arg;
1638 tt_int_op(0,OP_EQ, tor_version_parse("0.3.4pre2-cvs", &ver1));
1639 tt_int_op(0,OP_EQ, ver1.major);
1640 tt_int_op(3,OP_EQ, ver1.minor);
1641 tt_int_op(4,OP_EQ, ver1.micro);
1642 tt_int_op(VER_PRE,OP_EQ, ver1.status);
1643 tt_int_op(2,OP_EQ, ver1.patchlevel);
1644 tt_int_op(0,OP_EQ, tor_version_parse("0.3.4rc1", &ver1));
1645 tt_int_op(0,OP_EQ, ver1.major);
1646 tt_int_op(3,OP_EQ, ver1.minor);
1647 tt_int_op(4,OP_EQ, ver1.micro);
1648 tt_int_op(VER_RC,OP_EQ, ver1.status);
1649 tt_int_op(1,OP_EQ, ver1.patchlevel);
1650 tt_int_op(0,OP_EQ, tor_version_parse("1.3.4", &ver1));
1651 tt_int_op(1,OP_EQ, ver1.major);
1652 tt_int_op(3,OP_EQ, ver1.minor);
1653 tt_int_op(4,OP_EQ, ver1.micro);
1654 tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1655 tt_int_op(0,OP_EQ, ver1.patchlevel);
1656 tt_int_op(0,OP_EQ, tor_version_parse("1.3.4.999", &ver1));
1657 tt_int_op(1,OP_EQ, ver1.major);
1658 tt_int_op(3,OP_EQ, ver1.minor);
1659 tt_int_op(4,OP_EQ, ver1.micro);
1660 tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1661 tt_int_op(999,OP_EQ, ver1.patchlevel);
1662 tt_int_op(0,OP_EQ, tor_version_parse("0.1.2.4-alpha", &ver1));
1663 tt_int_op(0,OP_EQ, ver1.major);
1664 tt_int_op(1,OP_EQ, ver1.minor);
1665 tt_int_op(2,OP_EQ, ver1.micro);
1666 tt_int_op(4,OP_EQ, ver1.patchlevel);
1667 tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1668 tt_str_op("alpha",OP_EQ, ver1.status_tag);
1669 tt_int_op(0,OP_EQ, tor_version_parse("0.1.2.4", &ver1));
1670 tt_int_op(0,OP_EQ, ver1.major);
1671 tt_int_op(1,OP_EQ, ver1.minor);
1672 tt_int_op(2,OP_EQ, ver1.micro);
1673 tt_int_op(4,OP_EQ, ver1.patchlevel);
1674 tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1675 tt_str_op("",OP_EQ, ver1.status_tag);
1677 tt_int_op(0, OP_EQ, tor_version_parse("10.1", &ver1));
1678 tt_int_op(10, OP_EQ, ver1.major);
1679 tt_int_op(1, OP_EQ, ver1.minor);
1680 tt_int_op(0, OP_EQ, ver1.micro);
1681 tt_int_op(0, OP_EQ, ver1.patchlevel);
1682 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1683 tt_str_op("", OP_EQ, ver1.status_tag);
1684 tt_int_op(0, OP_EQ, tor_version_parse("5.99.999", &ver1));
1685 tt_int_op(5, OP_EQ, ver1.major);
1686 tt_int_op(99, OP_EQ, ver1.minor);
1687 tt_int_op(999, OP_EQ, ver1.micro);
1688 tt_int_op(0, OP_EQ, ver1.patchlevel);
1689 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1690 tt_str_op("", OP_EQ, ver1.status_tag);
1691 tt_int_op(0, OP_EQ, tor_version_parse("10.1-alpha", &ver1));
1692 tt_int_op(10, OP_EQ, ver1.major);
1693 tt_int_op(1, OP_EQ, ver1.minor);
1694 tt_int_op(0, OP_EQ, ver1.micro);
1695 tt_int_op(0, OP_EQ, ver1.patchlevel);
1696 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1697 tt_str_op("alpha", OP_EQ, ver1.status_tag);
1698 /* Go through the full set of status tags */
1699 tt_int_op(0, OP_EQ, tor_version_parse("2.1.700-alpha", &ver1));
1700 tt_int_op(2, OP_EQ, ver1.major);
1701 tt_int_op(1, OP_EQ, ver1.minor);
1702 tt_int_op(700, OP_EQ, ver1.micro);
1703 tt_int_op(0, OP_EQ, ver1.patchlevel);
1704 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1705 tt_str_op("alpha", OP_EQ, ver1.status_tag);
1706 tt_int_op(0, OP_EQ, tor_version_parse("1.6.8-alpha-dev", &ver1));
1707 tt_int_op(1, OP_EQ, ver1.major);
1708 tt_int_op(6, OP_EQ, ver1.minor);
1709 tt_int_op(8, OP_EQ, ver1.micro);
1710 tt_int_op(0, OP_EQ, ver1.patchlevel);
1711 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1712 tt_str_op("alpha-dev", OP_EQ, ver1.status_tag);
1713 tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.5-rc", &ver1));
1714 tt_int_op(0, OP_EQ, ver1.major);
1715 tt_int_op(2, OP_EQ, ver1.minor);
1716 tt_int_op(9, OP_EQ, ver1.micro);
1717 tt_int_op(5, OP_EQ, ver1.patchlevel);
1718 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1719 tt_str_op("rc", OP_EQ, ver1.status_tag);
1720 tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.6-rc-dev", &ver1));
1721 tt_int_op(0, OP_EQ, ver1.major);
1722 tt_int_op(2, OP_EQ, ver1.minor);
1723 tt_int_op(9, OP_EQ, ver1.micro);
1724 tt_int_op(6, OP_EQ, ver1.patchlevel);
1725 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1726 tt_str_op("rc-dev", OP_EQ, ver1.status_tag);
1727 tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.8", &ver1));
1728 tt_int_op(0, OP_EQ, ver1.major);
1729 tt_int_op(2, OP_EQ, ver1.minor);
1730 tt_int_op(9, OP_EQ, ver1.micro);
1731 tt_int_op(8, OP_EQ, ver1.patchlevel);
1732 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1733 tt_str_op("", OP_EQ, ver1.status_tag);
1734 tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.9-dev", &ver1));
1735 tt_int_op(0, OP_EQ, ver1.major);
1736 tt_int_op(2, OP_EQ, ver1.minor);
1737 tt_int_op(9, OP_EQ, ver1.micro);
1738 tt_int_op(9, OP_EQ, ver1.patchlevel);
1739 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1740 tt_str_op("dev", OP_EQ, ver1.status_tag);
1741 /* In #21450, we fixed an inconsistency in parsing versions > INT32_MAX
1742 * between i386 and x86_64, as we used tor_parse_long, and then cast to int
1744 tt_int_op(0, OP_EQ, tor_version_parse("0.2147483647.0", &ver1));
1745 tt_int_op(0, OP_EQ, ver1.major);
1746 tt_int_op(2147483647, OP_EQ, ver1.minor);
1747 tt_int_op(0, OP_EQ, ver1.micro);
1748 tt_int_op(0, OP_EQ, ver1.patchlevel);
1749 tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1750 tt_str_op("", OP_EQ, ver1.status_tag);
1751 tt_int_op(-1, OP_EQ, tor_version_parse("0.2147483648.0", &ver1));
1752 tt_int_op(-1, OP_EQ, tor_version_parse("0.4294967295.0", &ver1));
1753 /* In #21278, we reject negative version components */
1754 tt_int_op(-1, OP_EQ, tor_version_parse("0.-1.0", &ver1));
1755 tt_int_op(-1, OP_EQ, tor_version_parse("0.-2147483648.0", &ver1));
1756 tt_int_op(-1, OP_EQ, tor_version_parse("0.-4294967295.0", &ver1));
1757 /* In #21507, we reject version components with non-numeric prefixes */
1758 tt_int_op(-1, OP_EQ, tor_version_parse("0.-0.0", &ver1));
1759 tt_int_op(-1, OP_EQ, tor_version_parse("+1.0.0", &ver1));
1760 /* use the list in isspace() */
1761 tt_int_op(-1, OP_EQ, tor_version_parse("0.\t0.0", &ver1));
1762 tt_int_op(-1, OP_EQ, tor_version_parse("0.\n0.0", &ver1));
1763 tt_int_op(-1, OP_EQ, tor_version_parse("0.\v0.0", &ver1));
1764 tt_int_op(-1, OP_EQ, tor_version_parse("0.\f0.0", &ver1));
1765 tt_int_op(-1, OP_EQ, tor_version_parse("0.\r0.0", &ver1));
1766 tt_int_op(-1, OP_EQ, tor_version_parse("0. 0.0", &ver1));
1768 #define tt_versionstatus_op(vs1, op, vs2) \
1769 tt_assert_test_type(vs1,vs2,#vs1" "#op" "#vs2,version_status_t, \
1770 (val1_ op val2_),"%d",TT_EXIT_TEST_FUNCTION)
1771 #define test_v_i_o(val, ver, lst) \
1772 tt_versionstatus_op(val, OP_EQ, tor_version_is_obsolete(ver, lst))
1774 /* make sure tor_version_is_obsolete() works */
1775 test_v_i_o(VS_OLD, "0.0.1", "Tor 0.0.2");
1776 test_v_i_o(VS_OLD, "0.0.1", "0.0.2, Tor 0.0.3");
1777 test_v_i_o(VS_OLD, "0.0.1", "0.0.2,Tor 0.0.3");
1778 test_v_i_o(VS_OLD, "0.0.1","0.0.3,BetterTor 0.0.1");
1779 test_v_i_o(VS_RECOMMENDED, "0.0.2", "Tor 0.0.2,Tor 0.0.3");
1780 test_v_i_o(VS_NEW_IN_SERIES, "0.0.2", "Tor 0.0.2pre1,Tor 0.0.3");
1781 test_v_i_o(VS_OLD, "0.0.2", "Tor 0.0.2.1,Tor 0.0.3");
1782 test_v_i_o(VS_NEW, "0.1.0", "Tor 0.0.2,Tor 0.0.3");
1783 test_v_i_o(VS_RECOMMENDED, "0.0.7rc2", "0.0.7,Tor 0.0.7rc2,Tor 0.0.8");
1784 test_v_i_o(VS_OLD, "0.0.5.0", "0.0.5.1-cvs");
1785 test_v_i_o(VS_NEW_IN_SERIES, "0.0.5.1-cvs", "0.0.5, 0.0.6");
1786 test_v_i_o(VS_NEW, "0.2.9.9-dev", "0.2.9.9");
1787 /* Not on list, but newer than any in same series. */
1788 test_v_i_o(VS_NEW_IN_SERIES, "0.1.0.3",
1789 "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1790 /* Series newer than any on list. */
1791 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");
1792 /* Series older than any on list. */
1793 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");
1794 /* Not on list, not newer than any on same series. */
1795 test_v_i_o(VS_UNRECOMMENDED, "0.1.0.1",
1796 "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1797 /* On list, not newer than any on same series. */
1798 test_v_i_o(VS_UNRECOMMENDED,
1799 "0.1.0.1", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1800 tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.0.5", "0.0.9pre1-cvs"));
1801 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1802 "Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
1803 "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh",
1804 "0.0.8rc2"));
1805 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1806 "Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
1807 "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh", "0.0.8.2"));
1809 /* Now try svn revisions. */
1810 tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
1811 "Tor 0.2.1.0-dev (r99)"));
1812 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1813 "Tor 0.2.1.0-dev (r100) on Banana Jr",
1814 "Tor 0.2.1.0-dev (r99) on Hal 9000"));
1815 tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
1816 "Tor 0.2.1.0-dev on Colossus"));
1817 tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r99)",
1818 "Tor 0.2.1.0-dev (r100)"));
1819 tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r99) on MCP",
1820 "Tor 0.2.1.0-dev (r100) on AM"));
1821 tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev",
1822 "Tor 0.2.1.0-dev (r99)"));
1823 tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.1",
1824 "Tor 0.2.1.0-dev (r99)"));
1825 /* And git revisions */
1826 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1827 "Tor 0.2.9.9 (git-56788a2489127072)",
1828 "Tor 0.2.9.9 (git-56788a2489127072)"));
1829 /* a git revision is newer than no git revision */
1830 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1831 "Tor 0.2.9.9 (git-56788a2489127072)",
1832 "Tor 0.2.9.9"));
1833 /* a longer git revision is newer than a shorter git revision
1834 * this should be true if they prefix-match, but if they don't, they are
1835 * incomparable, because hashes aren't ordered (but we compare their bytes
1836 * anyway) */
1837 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1838 "Tor 0.2.9.9 (git-56788a2489127072d513cf4baf35a8ff475f3c7b)",
1839 "Tor 0.2.9.9 (git-56788a2489127072)"));
1840 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1841 "Tor 0.2.9.9 (git-0102)",
1842 "Tor 0.2.9.9 (git-03)"));
1843 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1844 "Tor 0.2.9.9 (git-0102)",
1845 "Tor 0.2.9.9 (git-00)"));
1846 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1847 "Tor 0.2.9.9 (git-01)",
1848 "Tor 0.2.9.9 (git-00)"));
1849 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1850 "Tor 0.2.9.9 (git-00)",
1851 "Tor 0.2.9.9 (git-01)"));
1852 /* In #21278, we compare without integer overflows.
1853 * But since #21450 limits version components to [0, INT32_MAX], it is no
1854 * longer possible to cause an integer overflow in tor_version_compare() */
1855 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1856 "Tor 0.0.0.0",
1857 "Tor 2147483647.0.0.0"));
1858 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1859 "Tor 2147483647.0.0.0",
1860 "Tor 0.0.0.0"));
1861 /* These versions used to cause an overflow, now they don't parse
1862 * (and authorities reject their descriptors), and log a BUG message */
1863 setup_full_capture_of_logs(LOG_WARN);
1864 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1865 "Tor 0.0.0.0",
1866 "Tor 0.-2147483648.0.0"));
1867 expect_single_log_msg_containing("unparseable");
1868 mock_clean_saved_logs();
1869 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1870 "Tor 0.2147483647.0.0",
1871 "Tor 0.-1.0.0"));
1872 expect_single_log_msg_containing("unparseable");
1873 mock_clean_saved_logs();
1874 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1875 "Tor 0.2147483647.0.0",
1876 "Tor 0.-2147483648.0.0"));
1877 expect_single_log_msg_containing("unparseable");
1878 mock_clean_saved_logs();
1879 tt_int_op(1,OP_EQ, tor_version_as_new_as(
1880 "Tor 4294967295.0.0.0",
1881 "Tor 0.0.0.0"));
1882 expect_no_log_entry();
1883 tt_int_op(0,OP_EQ, tor_version_as_new_as(
1884 "Tor 0.4294967295.0.0",
1885 "Tor 0.-4294967295.0.0"));
1886 expect_single_log_msg_containing("unparseable");
1887 mock_clean_saved_logs();
1888 teardown_capture_of_logs();
1890 /* Now try git revisions */
1891 tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00ff)", &ver1));
1892 tt_int_op(0,OP_EQ, ver1.major);
1893 tt_int_op(5,OP_EQ, ver1.minor);
1894 tt_int_op(6,OP_EQ, ver1.micro);
1895 tt_int_op(7,OP_EQ, ver1.patchlevel);
1896 tt_int_op(3,OP_EQ, ver1.git_tag_len);
1897 tt_mem_op(ver1.git_tag,OP_EQ, "\xff\x00\xff", 3);
1898 /* reject bad hex digits */
1899 tt_int_op(-1,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00xx)", &ver1));
1900 /* reject odd hex digit count */
1901 tt_int_op(-1,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00fff)", &ver1));
1902 /* ignore "git " */
1903 tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git ff00fff)", &ver1));
1904 /* standard length is 16 hex digits */
1905 tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git-0010203040506070)",
1906 &ver1));
1907 /* length limit is 40 hex digits */
1908 tt_int_op(0,OP_EQ, tor_version_parse(
1909 "0.5.6.7 (git-000102030405060708090a0b0c0d0e0f10111213)",
1910 &ver1));
1911 tt_int_op(-1,OP_EQ, tor_version_parse(
1912 "0.5.6.7 (git-000102030405060708090a0b0c0d0e0f1011121314)",
1913 &ver1));
1914 done:
1915 teardown_capture_of_logs();
1918 /** Run unit tests for directory fp_pair functions. */
1919 static void
1920 test_dir_fp_pairs(void *arg)
1922 smartlist_t *sl = smartlist_new();
1923 fp_pair_t *pair;
1925 (void)arg;
1926 dir_split_resource_into_fingerprint_pairs(
1927 /* Two pairs, out of order, with one duplicate. */
1928 "73656372657420646174612E0000000000FFFFFF-"
1929 "557365204145532d32353620696e73746561642e+"
1930 "73656372657420646174612E0000000000FFFFFF-"
1931 "557365204145532d32353620696e73746561642e+"
1932 "48657861646563696d616c2069736e277420736f-"
1933 "676f6f6420666f7220686964696e6720796f7572.z", sl);
1935 tt_int_op(smartlist_len(sl),OP_EQ, 2);
1936 pair = smartlist_get(sl, 0);
1937 tt_mem_op(pair->first,OP_EQ, "Hexadecimal isn't so", DIGEST_LEN);
1938 tt_mem_op(pair->second,OP_EQ, "good for hiding your", DIGEST_LEN);
1939 pair = smartlist_get(sl, 1);
1940 tt_mem_op(pair->first,OP_EQ, "secret data.\0\0\0\0\0\xff\xff\xff",
1941 DIGEST_LEN);
1942 tt_mem_op(pair->second,OP_EQ, "Use AES-256 instead.", DIGEST_LEN);
1944 done:
1945 SMARTLIST_FOREACH(sl, fp_pair_t *, pair_to_free, tor_free(pair_to_free));
1946 smartlist_free(sl);
1949 static void
1950 test_dir_split_fps(void *testdata)
1952 smartlist_t *sl = smartlist_new();
1953 char *mem_op_hex_tmp = NULL;
1954 (void)testdata;
1956 /* Some example hex fingerprints and their base64 equivalents */
1957 #define HEX1 "Fe0daff89127389bc67558691231234551193EEE"
1958 #define HEX2 "Deadbeef99999991111119999911111111f00ba4"
1959 #define HEX3 "b33ff00db33ff00db33ff00db33ff00db33ff00d"
1960 #define HEX256_1 \
1961 "f3f3f3f3fbbbbf3f3f3f3fbbbf3f3f3f3fbbbbf3f3f3f3fbbbf3f3f3f3fbbbbf"
1962 #define HEX256_2 \
1963 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccCCc"
1964 #define HEX256_3 \
1965 "0123456789ABCdef0123456789ABCdef0123456789ABCdef0123456789ABCdef"
1966 #define B64_1 "/g2v+JEnOJvGdVhpEjEjRVEZPu4"
1967 #define B64_2 "3q2+75mZmZERERmZmRERERHwC6Q"
1968 #define B64_256_1 "8/Pz8/u7vz8/Pz+7vz8/Pz+7u/Pz8/P7u/Pz8/P7u78"
1969 #define B64_256_2 "zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMw"
1971 /* no flags set */
1972 dir_split_resource_into_fingerprints("A+C+B", sl, NULL, 0);
1973 tt_int_op(smartlist_len(sl), OP_EQ, 3);
1974 tt_str_op(smartlist_get(sl, 0), OP_EQ, "A");
1975 tt_str_op(smartlist_get(sl, 1), OP_EQ, "C");
1976 tt_str_op(smartlist_get(sl, 2), OP_EQ, "B");
1977 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1978 smartlist_clear(sl);
1980 /* uniq strings. */
1981 dir_split_resource_into_fingerprints("A+C+B+A+B+B", sl, NULL, DSR_SORT_UNIQ);
1982 tt_int_op(smartlist_len(sl), OP_EQ, 3);
1983 tt_str_op(smartlist_get(sl, 0), OP_EQ, "A");
1984 tt_str_op(smartlist_get(sl, 1), OP_EQ, "B");
1985 tt_str_op(smartlist_get(sl, 2), OP_EQ, "C");
1986 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1987 smartlist_clear(sl);
1989 /* Decode hex. */
1990 dir_split_resource_into_fingerprints(HEX1"+"HEX2, sl, NULL, DSR_HEX);
1991 tt_int_op(smartlist_len(sl), OP_EQ, 2);
1992 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX1);
1993 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
1994 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1995 smartlist_clear(sl);
1997 /* decode hex and drop weirdness. */
1998 dir_split_resource_into_fingerprints(HEX1"+bogus+"HEX2"+"HEX256_1,
1999 sl, NULL, DSR_HEX);
2000 tt_int_op(smartlist_len(sl), OP_EQ, 2);
2001 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX1);
2002 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
2003 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2004 smartlist_clear(sl);
2006 /* Decode long hex */
2007 dir_split_resource_into_fingerprints(HEX256_1"+"HEX256_2"+"HEX2"+"HEX256_3,
2008 sl, NULL, DSR_HEX|DSR_DIGEST256);
2009 tt_int_op(smartlist_len(sl), OP_EQ, 3);
2010 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_1);
2011 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX256_2);
2012 test_mem_op_hex(smartlist_get(sl, 2), OP_EQ, HEX256_3);
2013 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2014 smartlist_clear(sl);
2016 /* Decode hex and sort. */
2017 dir_split_resource_into_fingerprints(HEX1"+"HEX2"+"HEX3"+"HEX2,
2018 sl, NULL, DSR_HEX|DSR_SORT_UNIQ);
2019 tt_int_op(smartlist_len(sl), OP_EQ, 3);
2020 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX3);
2021 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
2022 test_mem_op_hex(smartlist_get(sl, 2), OP_EQ, HEX1);
2023 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2024 smartlist_clear(sl);
2026 /* Decode long hex and sort */
2027 dir_split_resource_into_fingerprints(HEX256_1"+"HEX256_2"+"HEX256_3
2028 "+"HEX256_1,
2029 sl, NULL,
2030 DSR_HEX|DSR_DIGEST256|DSR_SORT_UNIQ);
2031 tt_int_op(smartlist_len(sl), OP_EQ, 3);
2032 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_3);
2033 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX256_2);
2034 test_mem_op_hex(smartlist_get(sl, 2), OP_EQ, HEX256_1);
2035 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2036 smartlist_clear(sl);
2038 /* Decode base64 */
2039 dir_split_resource_into_fingerprints(B64_1"-"B64_2, sl, NULL, DSR_BASE64);
2040 tt_int_op(smartlist_len(sl), OP_EQ, 2);
2041 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX1);
2042 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
2043 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2044 smartlist_clear(sl);
2046 /* Decode long base64 */
2047 dir_split_resource_into_fingerprints(B64_256_1"-"B64_256_2,
2048 sl, NULL, DSR_BASE64|DSR_DIGEST256);
2049 tt_int_op(smartlist_len(sl), OP_EQ, 2);
2050 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_1);
2051 test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX256_2);
2052 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2053 smartlist_clear(sl);
2055 dir_split_resource_into_fingerprints(B64_256_1,
2056 sl, NULL, DSR_BASE64|DSR_DIGEST256);
2057 tt_int_op(smartlist_len(sl), OP_EQ, 1);
2058 test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_1);
2059 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2060 smartlist_clear(sl);
2062 done:
2063 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2064 smartlist_free(sl);
2065 tor_free(mem_op_hex_tmp);
2068 static void
2069 test_dir_measured_bw_kb(void *arg)
2071 measured_bw_line_t mbwl;
2072 int i;
2073 const char *lines_pass[] = {
2074 "node_id=$557365204145532d32353620696e73746561642e bw=1024\n",
2075 "node_id=$557365204145532d32353620696e73746561642e\t bw=1024 \n",
2076 " node_id=$557365204145532d32353620696e73746561642e bw=1024\n",
2077 "\tnoise\tnode_id=$557365204145532d32353620696e73746561642e "
2078 "bw=1024 junk=007\n",
2079 "misc=junk node_id=$557365204145532d32353620696e73746561642e "
2080 "bw=1024 junk=007\n",
2081 /* check whether node_id can be at the end */
2082 "bw=1024 node_id=$557365204145532d32353620696e73746561642e\n",
2083 /* check whether node_id can be at the end and bw has something in front*/
2084 "foo=bar bw=1024 node_id=$557365204145532d32353620696e73746561642e\n",
2085 /* check whether node_id can be at the end and something in the
2086 * in the middle of bw and node_id */
2087 "bw=1024 foo=bar node_id=$557365204145532d32353620696e73746561642e\n",
2089 /* Test that a line with vote=1 will pass. */
2090 "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=1\n",
2091 /* Test that a line with unmeasured=1 will pass. */
2092 "node_id=$557365204145532d32353620696e73746561642e bw=1024 unmeasured=1\n",
2093 /* Test that a line with vote=1 and unmeasured=1 will pass. */
2094 "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=1"
2095 "unmeasured=1\n",
2096 /* Test that a line with unmeasured=0 will pass. */
2097 "node_id=$557365204145532d32353620696e73746561642e bw=1024 unmeasured=0\n",
2098 /* Test that a line with vote=1 and unmeasured=0 will pass. */
2099 "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=1"
2100 "unmeasured=0\n",
2101 "end"
2103 const char *lines_fail[] = {
2104 /* Test possible python stupidity on input */
2105 "node_id=None bw=1024\n",
2106 "node_id=$None bw=1024\n",
2107 "node_id=$557365204145532d32353620696e73746561642e bw=None\n",
2108 "node_id=$557365204145532d32353620696e73746561642e bw=1024.0\n",
2109 "node_id=$557365204145532d32353620696e73746561642e bw=.1024\n",
2110 "node_id=$557365204145532d32353620696e73746561642e bw=1.024\n",
2111 "node_id=$557365204145532d32353620696e73746561642e bw=1024 bw=0\n",
2112 "node_id=$557365204145532d32353620696e73746561642e bw=1024 bw=None\n",
2113 "node_id=$557365204145532d32353620696e73746561642e bw=-1024\n",
2114 /* Test incomplete writes due to race conditions, partial copies, etc */
2115 "node_i",
2116 "node_i\n",
2117 "node_id=",
2118 "node_id=\n",
2119 "node_id=$557365204145532d32353620696e73746561642e bw=",
2120 "node_id=$557365204145532d32353620696e73746561642e bw=1024",
2121 "node_id=$557365204145532d32353620696e73746561642e bw=\n",
2122 "node_id=$557365204145532d32353620696e7374",
2123 "node_id=$557365204145532d32353620696e7374\n",
2125 "\n",
2126 " \n ",
2127 " \n\n",
2128 /* Test assorted noise */
2129 " node_id= ",
2130 "node_id==$557365204145532d32353620696e73746561642e bw==1024\n",
2131 "node_id=$55736520414552d32353620696e73746561642e bw=1024\n",
2132 "node_id=557365204145532d32353620696e73746561642e bw=1024\n",
2133 "node_id= $557365204145532d32353620696e73746561642e bw=0.23\n",
2135 /* Test that a line with vote=0 will fail too, so that it is ignored. */
2136 "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=0\n",
2137 /* Test that a line with vote=0 will fail even if unmeasured=0. */
2138 "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=0 "
2139 "unmeasured=0\n",
2140 "end"
2143 (void)arg;
2144 for (i = 0; strcmp(lines_fail[i], "end"); i++) {
2145 //fprintf(stderr, "Testing: %s\n", lines_fail[i]);
2146 /* Testing only with line_is_after_headers = 1. Tests with
2147 * line_is_after_headers = 0 in
2148 * test_dir_measured_bw_kb_line_is_after_headers */
2149 tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 1) == -1);
2152 for (i = 0; strcmp(lines_pass[i], "end"); i++) {
2153 //fprintf(stderr, "Testing: %s %d\n", lines_pass[i], TOR_ISSPACE('\n'));
2154 /* Testing only with line_is_after_headers = 1. Tests with
2155 * line_is_after_headers = 0 in
2156 * test_dir_measured_bw_kb_line_is_after_headers */
2157 tt_assert(measured_bw_line_parse(&mbwl, lines_pass[i], 1) == 0);
2158 tt_assert(mbwl.bw_kb == 1024);
2159 tt_assert(strcmp(mbwl.node_hex,
2160 "557365204145532d32353620696e73746561642e") == 0);
2163 done:
2164 return;
2167 /* Unit tests for measured_bw_line_parse using line_is_after_headers flag.
2168 * When the end of the header is detected (a first complete bw line is parsed),
2169 * incomplete lines fail and give warnings, but do not give warnings if
2170 * the header is not ended, allowing to ignore additional header lines. */
2171 static void
2172 test_dir_measured_bw_kb_line_is_after_headers(void *arg)
2174 (void)arg;
2175 measured_bw_line_t mbwl;
2176 const char *line_pass = \
2177 "node_id=$557365204145532d32353620696e73746561642e bw=1024\n";
2178 int i;
2179 const char *lines_fail[] = {
2180 "node_id=$557365204145532d32353620696e73746561642e \n",
2181 "bw=1024\n",
2182 "rtt=300\n",
2183 "end"
2186 setup_capture_of_logs(LOG_DEBUG);
2188 /* Test bw lines when header has ended */
2189 for (i = 0; strcmp(lines_fail[i], "end"); i++) {
2190 tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 1) == -1);
2191 expect_log_msg_containing("Incomplete line in bandwidth file:");
2192 mock_clean_saved_logs();
2195 tt_assert(measured_bw_line_parse(&mbwl, line_pass, 1) == 0);
2197 /* Test bw lines when header has not ended */
2198 for (i = 0; strcmp(lines_fail[i], "end"); i++) {
2199 tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 0) == -1);
2200 expect_log_msg_containing("Missing bw or node_id in bandwidth file line:");
2201 mock_clean_saved_logs();
2204 tt_assert(measured_bw_line_parse(&mbwl, line_pass, 0) == 0);
2206 done:
2207 teardown_capture_of_logs();
2210 /* Test dirserv_read_measured_bandwidths with headers and complete files. */
2211 static void
2212 test_dir_dirserv_read_measured_bandwidths(void *arg)
2214 (void)arg;
2215 char *content = NULL;
2216 time_t timestamp = time(NULL);
2217 char *fname = tor_strdup(get_fname("V3BandwidthsFile"));
2218 smartlist_t *bw_file_headers = smartlist_new();
2219 /* bw file strings in vote */
2220 char *bw_file_headers_str = NULL;
2221 char *bw_file_headers_str_v100 = NULL;
2222 char *bw_file_headers_str_v110 = NULL;
2223 char *bw_file_headers_str_bad = NULL;
2224 char *bw_file_headers_str_extra = NULL;
2225 char bw_file_headers_str_long[MAX_BW_FILE_HEADER_COUNT_IN_VOTE * 8 + 1] = "";
2226 /* string header lines in bw file */
2227 char *header_lines_v100 = NULL;
2228 char *header_lines_v110_no_terminator = NULL;
2229 char *header_lines_v110 = NULL;
2230 char header_lines_long[MAX_BW_FILE_HEADER_COUNT_IN_VOTE * 8 + 1] = "";
2231 int i;
2232 const char *header_lines_v110_no_terminator_no_timestamp =
2233 "version=1.1.0\n"
2234 "software=sbws\n"
2235 "software_version=0.1.0\n"
2236 "earliest_bandwidth=2018-05-08T16:13:26\n"
2237 "file_created=2018-04-16T21:49:18\n"
2238 "generator_started=2018-05-08T16:13:25\n"
2239 "latest_bandwidth=2018-04-16T20:49:18\n";
2240 const char *bw_file_headers_str_v110_no_timestamp =
2241 "version=1.1.0 software=sbws "
2242 "software_version=0.1.0 "
2243 "earliest_bandwidth=2018-05-08T16:13:26 "
2244 "file_created=2018-04-16T21:49:18 "
2245 "generator_started=2018-05-08T16:13:25 "
2246 "latest_bandwidth=2018-04-16T20:49:18";
2247 const char *relay_lines_v100 =
2248 "node_id=$557365204145532d32353620696e73746561642e bw=1024 "
2249 "nick=Test measured_at=1523911725 updated_at=1523911725 "
2250 "pid_error=4.11374090719 pid_error_sum=4.11374090719 "
2251 "pid_bw=57136645 pid_delta=2.12168374577 circ_fail=0.2 "
2252 "scanner=/filepath\n";
2253 const char *relay_lines_v110 =
2254 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 "
2255 "master_key_ed25519=YaqV4vbvPYKucElk297eVdNArDz9HtIwUoIeo0+cVIpQ "
2256 "bw=760 nick=Test rtt=380 time=2018-05-08T16:13:26\n";
2257 const char *relay_lines_bad =
2258 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A\n";
2260 tor_asprintf(&header_lines_v100, "%ld\n", (long)timestamp);
2261 tor_asprintf(&header_lines_v110_no_terminator, "%ld\n%s", (long)timestamp,
2262 header_lines_v110_no_terminator_no_timestamp);
2263 tor_asprintf(&header_lines_v110, "%s%s",
2264 header_lines_v110_no_terminator, BW_FILE_HEADERS_TERMINATOR);
2266 tor_asprintf(&bw_file_headers_str_v100, "timestamp=%ld",(long)timestamp);
2267 tor_asprintf(&bw_file_headers_str_v110, "timestamp=%ld %s",
2268 (long)timestamp, bw_file_headers_str_v110_no_timestamp);
2269 tor_asprintf(&bw_file_headers_str_bad, "%s "
2270 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A",
2271 bw_file_headers_str_v110);
2273 for (i=0; i<MAX_BW_FILE_HEADER_COUNT_IN_VOTE; i++) {
2274 strlcat(header_lines_long, "foo=bar\n",
2275 sizeof(header_lines_long));
2277 /* 8 is the number of v110 lines in header_lines_v110 */
2278 for (i=0; i<MAX_BW_FILE_HEADER_COUNT_IN_VOTE - 8 - 1; i++) {
2279 strlcat(bw_file_headers_str_long, "foo=bar ",
2280 sizeof(bw_file_headers_str_long));
2282 strlcat(bw_file_headers_str_long, "foo=bar",
2283 sizeof(bw_file_headers_str_long));
2284 tor_asprintf(&bw_file_headers_str_extra,
2285 "%s %s",
2286 bw_file_headers_str_v110,
2287 bw_file_headers_str_long);
2289 /* Test an empty bandwidth file. bw_file_headers will be empty string */
2290 write_str_to_file(fname, "", 0);
2291 setup_capture_of_logs(LOG_WARN);
2292 tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2293 bw_file_headers,
2294 NULL));
2295 expect_log_msg("Empty bandwidth file\n");
2296 teardown_capture_of_logs();
2297 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2298 tt_str_op("", OP_EQ, bw_file_headers_str);
2299 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2300 smartlist_free(bw_file_headers);
2301 tor_free(bw_file_headers_str);
2303 /* Test bandwidth file with only timestamp.
2304 * bw_file_headers will be empty string */
2305 bw_file_headers = smartlist_new();
2306 tor_asprintf(&content, "%ld", (long)timestamp);
2307 write_str_to_file(fname, content, 0);
2308 tor_free(content);
2309 tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2310 bw_file_headers,
2311 NULL));
2313 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2314 tt_str_op("", OP_EQ, bw_file_headers_str);
2315 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2316 smartlist_free(bw_file_headers);
2317 tor_free(bw_file_headers_str);
2319 /* Test v1.0.0 bandwidth file headers */
2320 write_str_to_file(fname, header_lines_v100, 0);
2321 bw_file_headers = smartlist_new();
2322 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2323 bw_file_headers,
2324 NULL));
2326 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2327 tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
2328 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2329 smartlist_free(bw_file_headers);
2330 tor_free(bw_file_headers_str);
2332 /* Test v1.0.0 complete bandwidth file */
2333 bw_file_headers = smartlist_new();
2334 tor_asprintf(&content, "%s%s", header_lines_v100, relay_lines_v100);
2335 write_str_to_file(fname, content, 0);
2336 tor_free(content);
2337 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2338 bw_file_headers,
2339 NULL));
2341 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2342 tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
2343 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2344 smartlist_free(bw_file_headers);
2345 tor_free(bw_file_headers_str);
2347 /* Test v1.0.0 complete bandwidth file with NULL bw_file_headers. */
2348 tor_asprintf(&content, "%s%s", header_lines_v100, relay_lines_v100);
2349 write_str_to_file(fname, content, 0);
2350 tor_free(content);
2351 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, NULL,
2352 NULL));
2354 /* Test bandwidth file including v1.1.0 bandwidth headers and
2355 * v1.0.0 relay lines. bw_file_headers will contain the v1.1.0 headers. */
2356 bw_file_headers = smartlist_new();
2357 tor_asprintf(&content, "%s%s%s", header_lines_v100, header_lines_v110,
2358 relay_lines_v100);
2359 write_str_to_file(fname, content, 0);
2360 tor_free(content);
2361 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2362 bw_file_headers,
2363 NULL));
2365 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2366 tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2367 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2368 smartlist_free(bw_file_headers);
2369 tor_free(bw_file_headers_str);
2371 /* Test v1.0.0 complete bandwidth file with v1.1.0 headers at the end.
2372 * bw_file_headers will contain only v1.0.0 headers and the additional
2373 * headers will be interpreted as malformed relay lines. */
2374 bw_file_headers = smartlist_new();
2375 tor_asprintf(&content, "%s%s%s", header_lines_v100, relay_lines_v100,
2376 header_lines_v110);
2377 write_str_to_file(fname, content, 0);
2378 tor_free(content);
2379 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2380 bw_file_headers,
2381 NULL));
2383 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2384 tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
2385 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2386 smartlist_free(bw_file_headers);
2387 tor_free(bw_file_headers_str);
2389 /* Test v1.0.0 complete bandwidth file, the v1.1.0 headers and more relay
2390 * lines. bw_file_headers will contain only v1.0.0 headers, the additional
2391 * headers will be interpreted as malformed relay lines and the last relay
2392 * lines will be correctly interpreted as relay lines. */
2393 bw_file_headers = smartlist_new();
2394 tor_asprintf(&content, "%s%s%s%s", header_lines_v100, relay_lines_v100,
2395 header_lines_v110, relay_lines_v100);
2396 write_str_to_file(fname, content, 0);
2397 tor_free(content);
2398 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2399 bw_file_headers,
2400 NULL));
2402 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2403 tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
2404 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2405 smartlist_free(bw_file_headers);
2406 tor_free(bw_file_headers_str);
2408 /* Test v1.1.0 bandwidth headers without terminator */
2409 bw_file_headers = smartlist_new();
2410 write_str_to_file(fname, header_lines_v110_no_terminator, 0);
2411 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2412 bw_file_headers,
2413 NULL));
2415 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2416 tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2417 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2418 smartlist_free(bw_file_headers);
2419 tor_free(bw_file_headers_str);
2421 /* Test v1.1.0 bandwidth headers with terminator */
2422 bw_file_headers = smartlist_new();
2423 write_str_to_file(fname, header_lines_v110, 0);
2424 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2425 bw_file_headers,
2426 NULL));
2428 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2429 tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2430 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2431 smartlist_free(bw_file_headers);
2432 tor_free(bw_file_headers_str);
2434 /* Test v1.1.0 bandwidth file without terminator, then relay lines.
2435 * bw_file_headers will contain the v1.1.0 headers. */
2436 bw_file_headers = smartlist_new();
2437 tor_asprintf(&content, "%s%s",
2438 header_lines_v110_no_terminator, relay_lines_v110);
2439 write_str_to_file(fname, content, 0);
2440 tor_free(content);
2441 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2442 bw_file_headers,
2443 NULL));
2445 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2446 tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2447 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2448 smartlist_free(bw_file_headers);
2449 tor_free(bw_file_headers_str);
2451 /* Test v1.1.0 bandwidth headers with terminator, then relay lines
2452 * bw_file_headers will contain the v1.1.0 headers. */
2453 bw_file_headers = smartlist_new();
2454 tor_asprintf(&content, "%s%s",
2455 header_lines_v110, relay_lines_v110);
2456 write_str_to_file(fname, content, 0);
2457 tor_free(content);
2458 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2459 bw_file_headers,
2460 NULL));
2462 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2463 tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2464 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2465 smartlist_free(bw_file_headers);
2466 tor_free(bw_file_headers_str);
2468 /* Test v1.1.0 bandwidth headers with terminator, then bad relay lines,
2469 * then terminator, then relay_lines_bad.
2470 * bw_file_headers will contain the v1.1.0 headers. */
2471 bw_file_headers = smartlist_new();
2472 tor_asprintf(&content, "%s%s%s%s", header_lines_v110, relay_lines_bad,
2473 BW_FILE_HEADERS_TERMINATOR, relay_lines_bad);
2474 write_str_to_file(fname, content, 0);
2475 tor_free(content);
2476 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2477 bw_file_headers,
2478 NULL));
2480 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2481 tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2482 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2483 smartlist_free(bw_file_headers);
2484 tor_free(bw_file_headers_str);
2486 /* Test v1.1.0 bandwidth headers without terminator, then bad relay lines,
2487 * then relay lines. bw_file_headers will contain the v1.1.0 headers and
2488 * the bad relay lines. */
2489 bw_file_headers = smartlist_new();
2490 tor_asprintf(&content, "%s%s%s",
2491 header_lines_v110_no_terminator, relay_lines_bad,
2492 relay_lines_v110);
2493 write_str_to_file(fname, content, 0);
2494 tor_free(content);
2495 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2496 bw_file_headers,
2497 NULL));
2499 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2500 tt_str_op(bw_file_headers_str_bad, OP_EQ, bw_file_headers_str);
2501 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2502 smartlist_free(bw_file_headers);
2503 tor_free(bw_file_headers_str);
2505 /* Test v1.1.0 bandwidth headers without terminator,
2506 * then many bad relay lines, then relay lines.
2507 * bw_file_headers will contain the v1.1.0 headers and the bad relay lines
2508 * to a maximum of MAX_BW_FILE_HEADER_COUNT_IN_VOTE header lines. */
2509 bw_file_headers = smartlist_new();
2510 tor_asprintf(&content, "%s%s%s",
2511 header_lines_v110_no_terminator, header_lines_long,
2512 relay_lines_v110);
2513 write_str_to_file(fname, content, 0);
2514 tor_free(content);
2515 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2516 bw_file_headers,
2517 NULL));
2519 tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_EQ,
2520 smartlist_len(bw_file_headers));
2521 bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2522 tt_str_op(bw_file_headers_str_extra, OP_EQ, bw_file_headers_str);
2523 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2524 smartlist_free(bw_file_headers);
2525 tor_free(bw_file_headers_str);
2527 /* Test v1.1.0 bandwidth headers without terminator,
2528 * then many bad relay lines, then relay lines.
2529 * bw_file_headers will contain the v1.1.0 headers and the bad relay lines.
2530 * Force bw_file_headers to have more than MAX_BW_FILE_HEADER_COUNT_IN_VOTE
2531 * This test is needed while there is not dirvote test. */
2532 bw_file_headers = smartlist_new();
2533 tor_asprintf(&content, "%s%s%s",
2534 header_lines_v110_no_terminator, header_lines_long,
2535 relay_lines_v110);
2536 write_str_to_file(fname, content, 0);
2537 tor_free(content);
2538 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2539 bw_file_headers,
2540 NULL));
2542 tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_EQ,
2543 smartlist_len(bw_file_headers));
2544 /* force bw_file_headers to be bigger than
2545 * MAX_BW_FILE_HEADER_COUNT_IN_VOTE */
2546 char line[8] = "foo=bar\0";
2547 smartlist_add_strdup(bw_file_headers, line);
2548 tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_LT,
2549 smartlist_len(bw_file_headers));
2550 SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2551 smartlist_free(bw_file_headers);
2552 tor_free(bw_file_headers_str);
2554 /* Test v1.x.x bandwidth line with vote=0.
2555 * It will be ignored it and logged it at debug level. */
2556 const char *relay_lines_ignore =
2557 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=0\n"
2558 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=0"
2559 "unmeasured=1\n"
2560 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=0"
2561 "unmeasured=0\n";
2563 /* Create the bandwidth file */
2564 tor_asprintf(&content, "%ld\n%s", (long)timestamp, relay_lines_ignore);
2565 write_str_to_file(fname, content, 0);
2566 tor_free(content);
2568 /* Read the bandwidth file */
2569 setup_full_capture_of_logs(LOG_DEBUG);
2570 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, NULL,
2571 NULL));
2572 expect_log_msg_containing("Ignoring bandwidth file line");
2573 teardown_capture_of_logs();
2575 /* Test v1.x.x bandwidth line with "vote=1" or "unmeasured=1" or
2576 * "unmeasured=0".
2577 * They will not be ignored. */
2578 /* Create the bandwidth file */
2579 const char *relay_lines_vote =
2580 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=1\n"
2581 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 unmeasured=0\n"
2582 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 unmeasured=1\n";
2583 tor_asprintf(&content, "%ld\n%s", (long)timestamp, relay_lines_vote);
2584 write_str_to_file(fname, content, 0);
2585 tor_free(content);
2587 /* Read the bandwidth file */
2588 setup_full_capture_of_logs(LOG_DEBUG);
2589 tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, NULL,
2590 NULL));
2591 expect_log_msg_not_containing("Ignoring bandwidth file line");
2592 teardown_capture_of_logs();
2594 done:
2595 unlink(fname);
2596 tor_free(fname);
2597 tor_free(header_lines_v100);
2598 tor_free(header_lines_v110_no_terminator);
2599 tor_free(header_lines_v110);
2600 tor_free(bw_file_headers_str_v100);
2601 tor_free(bw_file_headers_str_v110);
2602 tor_free(bw_file_headers_str_bad);
2603 tor_free(bw_file_headers_str_extra);
2606 #define MBWC_INIT_TIME 1000
2608 /** Do the measured bandwidth cache unit test */
2609 static void
2610 test_dir_measured_bw_kb_cache(void *arg)
2612 /* Initial fake time_t for testing */
2613 time_t curr = MBWC_INIT_TIME;
2614 /* Some measured_bw_line_ts */
2615 measured_bw_line_t mbwl[3];
2616 /* For receiving output on cache queries */
2617 long bw;
2618 time_t as_of;
2620 /* First, clear the cache and assert that it's empty */
2621 (void)arg;
2622 dirserv_clear_measured_bw_cache();
2623 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 0);
2625 * Set up test mbwls; none of the dirserv_cache_*() functions care about
2626 * the node_hex field.
2628 memset(mbwl[0].node_id, 0x01, DIGEST_LEN);
2629 mbwl[0].bw_kb = 20;
2630 memset(mbwl[1].node_id, 0x02, DIGEST_LEN);
2631 mbwl[1].bw_kb = 40;
2632 memset(mbwl[2].node_id, 0x03, DIGEST_LEN);
2633 mbwl[2].bw_kb = 80;
2634 /* Try caching something */
2635 dirserv_cache_measured_bw(&(mbwl[0]), curr);
2636 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 1);
2637 /* Okay, let's see if we can retrieve it */
2638 tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, &as_of));
2639 tt_int_op(bw,OP_EQ, 20);
2640 tt_int_op(as_of,OP_EQ, MBWC_INIT_TIME);
2641 /* Try retrieving it without some outputs */
2642 tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL, NULL));
2643 tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, NULL));
2644 tt_int_op(bw,OP_EQ, 20);
2645 tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL,&as_of));
2646 tt_int_op(as_of,OP_EQ, MBWC_INIT_TIME);
2647 /* Now expire it */
2648 curr += MAX_MEASUREMENT_AGE + 1;
2649 dirserv_expire_measured_bw_cache(curr);
2650 /* Check that the cache is empty */
2651 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 0);
2652 /* Check that we can't retrieve it */
2653 tt_assert(!dirserv_query_measured_bw_cache_kb(mbwl[0].node_id, NULL,NULL));
2654 /* Try caching a few things now */
2655 dirserv_cache_measured_bw(&(mbwl[0]), curr);
2656 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 1);
2657 curr += MAX_MEASUREMENT_AGE / 4;
2658 dirserv_cache_measured_bw(&(mbwl[1]), curr);
2659 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 2);
2660 curr += MAX_MEASUREMENT_AGE / 4;
2661 dirserv_cache_measured_bw(&(mbwl[2]), curr);
2662 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 3);
2663 curr += MAX_MEASUREMENT_AGE / 4 + 1;
2664 /* Do an expire that's too soon to get any of them */
2665 dirserv_expire_measured_bw_cache(curr);
2666 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 3);
2667 /* Push the oldest one off the cliff */
2668 curr += MAX_MEASUREMENT_AGE / 4;
2669 dirserv_expire_measured_bw_cache(curr);
2670 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 2);
2671 /* And another... */
2672 curr += MAX_MEASUREMENT_AGE / 4;
2673 dirserv_expire_measured_bw_cache(curr);
2674 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 1);
2675 /* This should empty it out again */
2676 curr += MAX_MEASUREMENT_AGE / 4;
2677 dirserv_expire_measured_bw_cache(curr);
2678 tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 0);
2680 done:
2681 return;
2684 static char *
2685 my_dirvote_compute_params(smartlist_t *votes, int method,
2686 int total_authorities)
2688 smartlist_t *s = dirvote_compute_params(votes, method, total_authorities);
2689 tor_assert(s);
2690 char *res = smartlist_join_strings(s, " ", 0, NULL);
2691 SMARTLIST_FOREACH(s, char *, cp, tor_free(cp));
2692 smartlist_free(s);
2693 return res;
2696 #define dirvote_compute_params my_dirvote_compute_params
2698 static void
2699 test_dir_param_voting(void *arg)
2701 networkstatus_t vote1, vote2, vote3, vote4;
2702 smartlist_t *votes = smartlist_new();
2703 char *res = NULL;
2705 /* dirvote_compute_params only looks at the net_params field of the votes,
2706 so that's all we need to set.
2708 (void)arg;
2709 memset(&vote1, 0, sizeof(vote1));
2710 memset(&vote2, 0, sizeof(vote2));
2711 memset(&vote3, 0, sizeof(vote3));
2712 memset(&vote4, 0, sizeof(vote4));
2713 vote1.net_params = smartlist_new();
2714 vote2.net_params = smartlist_new();
2715 vote3.net_params = smartlist_new();
2716 vote4.net_params = smartlist_new();
2717 smartlist_split_string(vote1.net_params,
2718 "ab=90 abcd=20 cw=50 x-yz=-99", NULL, 0, 0);
2719 smartlist_split_string(vote2.net_params,
2720 "ab=27 cw=5 x-yz=88", NULL, 0, 0);
2721 smartlist_split_string(vote3.net_params,
2722 "abcd=20 c=60 cw=500 x-yz=-9 zzzzz=101", NULL, 0, 0);
2723 smartlist_split_string(vote4.net_params,
2724 "ab=900 abcd=200 c=1 cw=51 x-yz=100", NULL, 0, 0);
2725 tt_int_op(100,OP_EQ, networkstatus_get_param(&vote4, "x-yz", 50, 0, 300));
2726 tt_int_op(222,OP_EQ, networkstatus_get_param(&vote4, "foobar", 222, 0, 300));
2727 tt_int_op(80,OP_EQ, networkstatus_get_param(&vote4, "ab", 12, 0, 80));
2728 tt_int_op(-8,OP_EQ, networkstatus_get_param(&vote4, "ab", -12, -100, -8));
2729 tt_int_op(0,OP_EQ, networkstatus_get_param(&vote4, "foobar", 0, -100, 8));
2731 tt_int_op(100,OP_EQ, networkstatus_get_overridable_param(
2732 &vote4, -1, "x-yz", 50, 0, 300));
2733 tt_int_op(30,OP_EQ, networkstatus_get_overridable_param(
2734 &vote4, 30, "x-yz", 50, 0, 300));
2735 tt_int_op(0,OP_EQ, networkstatus_get_overridable_param(
2736 &vote4, -101, "foobar", 0, -100, 8));
2737 tt_int_op(-99,OP_EQ, networkstatus_get_overridable_param(
2738 &vote4, -99, "foobar", 0, -100, 8));
2740 smartlist_add(votes, &vote1);
2742 /* Do the first tests without adding all the other votes, for
2743 * networks without many dirauths. */
2745 res = dirvote_compute_params(votes, 12, 2);
2746 tt_str_op(res,OP_EQ, "");
2747 tor_free(res);
2749 res = dirvote_compute_params(votes, 12, 1);
2750 tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-99");
2751 tor_free(res);
2753 smartlist_add(votes, &vote2);
2755 res = dirvote_compute_params(votes, 12, 2);
2756 tt_str_op(res,OP_EQ, "ab=27 cw=5 x-yz=-99");
2757 tor_free(res);
2759 res = dirvote_compute_params(votes, 12, 3);
2760 tt_str_op(res,OP_EQ, "ab=27 cw=5 x-yz=-99");
2761 tor_free(res);
2763 res = dirvote_compute_params(votes, 12, 6);
2764 tt_str_op(res,OP_EQ, "");
2765 tor_free(res);
2767 smartlist_add(votes, &vote3);
2769 res = dirvote_compute_params(votes, 12, 3);
2770 tt_str_op(res,OP_EQ, "ab=27 abcd=20 cw=50 x-yz=-9");
2771 tor_free(res);
2773 res = dirvote_compute_params(votes, 12, 5);
2774 tt_str_op(res,OP_EQ, "cw=50 x-yz=-9");
2775 tor_free(res);
2777 res = dirvote_compute_params(votes, 12, 9);
2778 tt_str_op(res,OP_EQ, "cw=50 x-yz=-9");
2779 tor_free(res);
2781 smartlist_add(votes, &vote4);
2783 res = dirvote_compute_params(votes, 12, 4);
2784 tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
2785 tor_free(res);
2787 res = dirvote_compute_params(votes, 12, 5);
2788 tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
2789 tor_free(res);
2791 /* Test that the special-cased "at least three dirauths voted for
2792 * this param" logic works as expected. */
2793 res = dirvote_compute_params(votes, 12, 6);
2794 tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
2795 tor_free(res);
2797 res = dirvote_compute_params(votes, 12, 10);
2798 tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
2799 tor_free(res);
2801 done:
2802 tor_free(res);
2803 SMARTLIST_FOREACH(vote1.net_params, char *, cp, tor_free(cp));
2804 SMARTLIST_FOREACH(vote2.net_params, char *, cp, tor_free(cp));
2805 SMARTLIST_FOREACH(vote3.net_params, char *, cp, tor_free(cp));
2806 SMARTLIST_FOREACH(vote4.net_params, char *, cp, tor_free(cp));
2807 smartlist_free(vote1.net_params);
2808 smartlist_free(vote2.net_params);
2809 smartlist_free(vote3.net_params);
2810 smartlist_free(vote4.net_params);
2811 smartlist_free(votes);
2813 return;
2816 static void
2817 test_dir_param_voting_lookup(void *arg)
2819 (void)arg;
2820 smartlist_t *lst = smartlist_new();
2822 smartlist_split_string(lst,
2823 "moomin=9 moomin=10 moomintroll=5 fred "
2824 "jack= electricity=sdk opa=6z abc=9 abcd=99",
2825 NULL, 0, 0);
2827 tt_int_op(1000,
2828 OP_EQ, dirvote_get_intermediate_param_value(lst, "ab", 1000));
2829 tt_int_op(9, OP_EQ, dirvote_get_intermediate_param_value(lst, "abc", 1000));
2830 tt_int_op(99, OP_EQ,
2831 dirvote_get_intermediate_param_value(lst, "abcd", 1000));
2833 #ifndef ALL_BUGS_ARE_FATAL
2834 /* moomin appears twice. That's a bug. */
2835 tor_capture_bugs_(1);
2836 tt_int_op(-100, OP_EQ,
2837 dirvote_get_intermediate_param_value(lst, "moomin", -100));
2838 tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
2839 tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
2840 "n_found == 0");
2841 tor_end_capture_bugs_();
2842 /* There is no 'fred=', so that is treated as not existing. */
2843 tt_int_op(-100, OP_EQ,
2844 dirvote_get_intermediate_param_value(lst, "fred", -100));
2845 /* jack is truncated */
2846 tor_capture_bugs_(1);
2847 tt_int_op(-100, OP_EQ,
2848 dirvote_get_intermediate_param_value(lst, "jack", -100));
2849 tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
2850 tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
2851 "!(!ok)");
2852 tor_end_capture_bugs_();
2853 /* electricity and opa aren't integers. */
2854 tor_capture_bugs_(1);
2855 tt_int_op(-100, OP_EQ,
2856 dirvote_get_intermediate_param_value(lst, "electricity", -100));
2857 tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
2858 tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
2859 "!(!ok)");
2860 tor_end_capture_bugs_();
2862 tor_capture_bugs_(1);
2863 tt_int_op(-100, OP_EQ,
2864 dirvote_get_intermediate_param_value(lst, "opa", -100));
2865 tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
2866 tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
2867 "!(!ok)");
2868 tor_end_capture_bugs_();
2869 #endif /* !defined(ALL_BUGS_ARE_FATAL) */
2871 done:
2872 SMARTLIST_FOREACH(lst, char *, cp, tor_free(cp));
2873 smartlist_free(lst);
2874 tor_end_capture_bugs_();
2877 #undef dirvote_compute_params
2879 /** Helper: Test that two networkstatus_voter_info_t do in fact represent the
2880 * same voting authority, and that they do in fact have all the same
2881 * information. */
2882 static void
2883 test_same_voter(networkstatus_voter_info_t *v1,
2884 networkstatus_voter_info_t *v2)
2886 tt_str_op(v1->nickname,OP_EQ, v2->nickname);
2887 tt_mem_op(v1->identity_digest,OP_EQ, v2->identity_digest, DIGEST_LEN);
2888 tt_str_op(v1->address,OP_EQ, v2->address);
2889 tt_assert(tor_addr_eq(&v1->ipv4_addr, &v2->ipv4_addr));
2890 tt_int_op(v1->ipv4_dirport,OP_EQ, v2->ipv4_dirport);
2891 tt_int_op(v1->ipv4_orport,OP_EQ, v2->ipv4_orport);
2892 tt_str_op(v1->contact,OP_EQ, v2->contact);
2893 tt_mem_op(v1->vote_digest,OP_EQ, v2->vote_digest, DIGEST_LEN);
2894 done:
2898 /** Helper: get a detached signatures document for one or two
2899 * consensuses. */
2900 static char *
2901 get_detached_sigs(networkstatus_t *ns, networkstatus_t *ns2)
2903 char *r;
2904 smartlist_t *sl;
2905 tor_assert(ns && ns->flavor == FLAV_NS);
2906 sl = smartlist_new();
2907 smartlist_add(sl,ns);
2908 if (ns2)
2909 smartlist_add(sl,ns2);
2910 r = networkstatus_get_detached_signatures(sl);
2911 smartlist_free(sl);
2912 return r;
2915 /** Apply tweaks to the vote list for each voter */
2916 static int
2917 vote_tweaks_for_v3ns(networkstatus_t *v, int voter, time_t now)
2919 vote_routerstatus_t *vrs;
2920 const char *msg = NULL;
2922 tt_assert(v);
2923 (void)now;
2925 if (voter == 1) {
2926 measured_bw_line_t mbw;
2927 memset(mbw.node_id, 33, sizeof(mbw.node_id));
2928 mbw.bw_kb = 1024;
2929 tt_int_op(measured_bw_line_apply(&mbw, v->routerstatus_list), OP_EQ, 1);
2930 } else if (voter == 2 || voter == 3) {
2931 /* Monkey around with the list a bit */
2932 vrs = smartlist_get(v->routerstatus_list, 2);
2933 smartlist_del_keeporder(v->routerstatus_list, 2);
2934 vote_routerstatus_free(vrs);
2935 vrs = smartlist_get(v->routerstatus_list, 0);
2936 vrs->status.is_fast = 1;
2938 if (voter == 3) {
2939 vrs = smartlist_get(v->routerstatus_list, 0);
2940 smartlist_del_keeporder(v->routerstatus_list, 0);
2941 vote_routerstatus_free(vrs);
2942 vrs = smartlist_get(v->routerstatus_list, 0);
2943 memset(vrs->status.descriptor_digest, (int)'Z', DIGEST_LEN);
2944 tt_assert(router_add_to_routerlist(
2945 dir_common_generate_ri_from_rs(vrs), &msg,0,0) >= 0);
2949 done:
2950 return 0;
2954 * Test a parsed vote_routerstatus_t for v3_networkstatus test
2956 static void
2957 test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
2959 routerstatus_t *rs;
2960 tor_addr_t addr_ipv6;
2962 tt_assert(vrs);
2963 rs = &(vrs->status);
2964 tt_assert(rs);
2966 /* Split out by digests to test */
2967 if (tor_memeq(rs->identity_digest,
2968 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
2969 "\x3\x3\x3\x3",
2970 DIGEST_LEN) &&
2971 (voter == 1)) {
2972 /* Check the first routerstatus. */
2973 tt_str_op(vrs->version,OP_EQ, "0.1.2.14");
2974 tt_int_op(rs->published_on,OP_EQ, now-1500);
2975 tt_str_op(rs->nickname,OP_EQ, "router2");
2976 tt_mem_op(rs->identity_digest,OP_EQ,
2977 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
2978 "\x3\x3\x3\x3",
2979 DIGEST_LEN);
2980 tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
2981 tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99008801));
2982 tt_int_op(rs->ipv4_orport,OP_EQ, 443);
2983 tt_int_op(rs->ipv4_dirport,OP_EQ, 8000);
2984 /* no flags except "running" (16) and "v2dir" (64) and "valid" (128) */
2985 tt_u64_op(vrs->flags, OP_EQ, UINT64_C(0xd0));
2986 } else if (tor_memeq(rs->identity_digest,
2987 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
2988 "\x5\x5\x5\x5",
2989 DIGEST_LEN) &&
2990 (voter == 1 || voter == 2)) {
2991 tt_mem_op(rs->identity_digest,OP_EQ,
2992 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
2993 "\x5\x5\x5\x5",
2994 DIGEST_LEN);
2996 if (voter == 1) {
2997 /* Check the second routerstatus. */
2998 tt_str_op(vrs->version,OP_EQ, "0.2.0.5");
2999 tt_int_op(rs->published_on,OP_EQ, now-1000);
3000 tt_str_op(rs->nickname,OP_EQ, "router1");
3002 tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
3003 tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
3004 tt_int_op(rs->ipv4_orport,OP_EQ, 443);
3005 tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
3006 tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
3007 tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
3008 tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
3009 if (voter == 1) {
3010 /* all except "authority" (1) */
3011 tt_u64_op(vrs->flags, OP_EQ, UINT64_C(254));
3012 } else {
3013 /* 1023 - authority(1) - madeofcheese(16) - madeoftin(32) */
3014 tt_u64_op(vrs->flags, OP_EQ, UINT64_C(974));
3016 } else if (tor_memeq(rs->identity_digest,
3017 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
3018 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
3019 DIGEST_LEN) &&
3020 (voter == 1 || voter == 2)) {
3021 /* Check the measured bandwidth bits */
3022 tt_assert(vrs->has_measured_bw &&
3023 vrs->measured_bw_kb == 1024);
3024 } else {
3026 * Didn't expect this, but the old unit test only checked some of them,
3027 * so don't assert.
3029 /* tt_assert(0); */
3032 done:
3033 return;
3037 * Test a consensus for v3_networkstatus_test
3039 static void
3040 test_consensus_for_v3ns(networkstatus_t *con, time_t now)
3042 (void)now;
3044 tt_assert(con);
3045 tt_ptr_op(con->cert, OP_EQ, NULL);
3046 tt_int_op(2,OP_EQ, smartlist_len(con->routerstatus_list));
3047 /* There should be two listed routers: one with identity 3, one with
3048 * identity 5. */
3050 done:
3051 return;
3055 * Test a router list entry for v3_networkstatus test
3057 static void
3058 test_routerstatus_for_v3ns(routerstatus_t *rs, time_t now)
3060 tor_addr_t addr_ipv6;
3062 tt_assert(rs);
3064 /* There should be two listed routers: one with identity 3, one with
3065 * identity 5. */
3066 /* This one showed up in 2 digests. */
3067 if (tor_memeq(rs->identity_digest,
3068 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
3069 "\x3\x3",
3070 DIGEST_LEN)) {
3071 tt_mem_op(rs->identity_digest,OP_EQ,
3072 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
3073 DIGEST_LEN);
3074 tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
3075 tt_assert(!rs->is_authority);
3076 tt_assert(!rs->is_exit);
3077 tt_assert(!rs->is_fast);
3078 tt_assert(!rs->is_possible_guard);
3079 tt_assert(!rs->is_stable);
3080 /* (If it wasn't running it wouldn't be here) */
3081 tt_assert(rs->is_flagged_running);
3082 tt_assert(rs->is_valid);
3083 tt_assert(!rs->is_named);
3084 tt_assert(rs->is_v2_dir);
3085 /* XXXX check version */
3086 } else if (tor_memeq(rs->identity_digest,
3087 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
3088 "\x5\x5\x5\x5",
3089 DIGEST_LEN)) {
3090 /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */
3091 tt_mem_op(rs->identity_digest,OP_EQ,
3092 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
3093 DIGEST_LEN);
3094 tt_str_op(rs->nickname,OP_EQ, "router1");
3095 tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
3096 tt_int_op(rs->published_on,OP_EQ, now-1000);
3097 tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
3098 tt_int_op(rs->ipv4_orport,OP_EQ, 443);
3099 tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
3100 tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
3101 tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
3102 tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
3103 tt_assert(!rs->is_authority);
3104 tt_assert(rs->is_exit);
3105 tt_assert(rs->is_fast);
3106 tt_assert(rs->is_possible_guard);
3107 tt_assert(rs->is_stable);
3108 tt_assert(rs->is_flagged_running);
3109 tt_assert(rs->is_valid);
3110 tt_assert(rs->is_v2_dir);
3111 tt_assert(!rs->is_named);
3112 /* XXXX check version */
3113 } else {
3114 /* Weren't expecting this... */
3115 tt_abort();
3118 done:
3119 return;
3122 static void
3123 test_dir_networkstatus_compute_bw_weights_v10(void *arg)
3125 (void) arg;
3126 smartlist_t *chunks = smartlist_new();
3127 int64_t G, M, E, D, T, weight_scale;
3128 int ret;
3129 weight_scale = 10000;
3131 /* no case. one or more of the values is 0 */
3132 G = M = E = D = 0;
3133 T = G + M + E + D;
3134 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3135 weight_scale);
3136 tt_int_op(ret, OP_EQ, 0);
3137 tt_int_op(smartlist_len(chunks), OP_EQ, 0);
3139 /* case 1 */
3140 /* XXX dir-spec not followed? See #20272. If it isn't closed, then this is
3141 * testing current behavior, not spec. */
3142 G = E = 10;
3143 M = D = 1;
3144 T = G + M + E + D;
3145 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3146 weight_scale);
3147 tt_int_op(ret, OP_EQ, 1);
3148 tt_int_op(smartlist_len(chunks), OP_EQ, 1);
3149 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=3333 "
3150 "Wbe=3000 Wbg=3000 Wbm=10000 Wdb=10000 Web=10000 Wed=3333 Wee=7000 "
3151 "Weg=3333 Wem=7000 Wgb=10000 Wgd=3333 Wgg=7000 Wgm=7000 Wmb=10000 "
3152 "Wmd=3333 Wme=3000 Wmg=3000 Wmm=10000\n");
3153 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3154 smartlist_clear(chunks);
3156 /* case 2a E scarce */
3157 M = 100;
3158 G = 20;
3159 E = D = 5;
3160 T = G + M + E + D;
3161 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3162 weight_scale);
3163 tt_int_op(ret, OP_EQ, 1);
3164 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
3165 "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
3166 "Wem=10000 Wgb=10000 Wgd=0 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 Wme=0 "
3167 "Wmg=0 Wmm=10000\n");
3168 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3169 smartlist_clear(chunks);
3171 /* case 2a G scarce */
3172 M = 100;
3173 E = 20;
3174 G = D = 5;
3175 T = G + M + E + D;
3176 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3177 weight_scale);
3178 tt_int_op(ret, OP_EQ, 1);
3179 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
3180 "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=10000 Weg=0 Wem=10000 "
3181 "Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 Wme=0 Wmg=0 "
3182 "Wmm=10000\n");
3183 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3184 smartlist_clear(chunks);
3186 /* case 2b1 (Wgg=1, Wmd=Wgd) */
3187 M = 10;
3188 E = 30;
3189 G = 10;
3190 D = 100;
3191 T = G + M + E + D;
3192 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3193 weight_scale);
3194 tt_int_op(ret, OP_EQ, 1);
3195 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=4000 "
3196 "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=2000 Wee=10000 Weg=2000 "
3197 "Wem=10000 Wgb=10000 Wgd=4000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=4000 "
3198 "Wme=0 Wmg=0 Wmm=10000\n");
3199 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3200 smartlist_clear(chunks);
3202 /* case 2b2 */
3203 M = 60;
3204 E = 30;
3205 G = 10;
3206 D = 100;
3207 T = G + M + E + D;
3208 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3209 weight_scale);
3210 tt_int_op(ret, OP_EQ, 1);
3211 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=666 Wbe=0 "
3212 "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=3666 Wee=10000 Weg=3666 "
3213 "Wem=10000 Wgb=10000 Wgd=5668 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=666 "
3214 "Wme=0 Wmg=0 Wmm=10000\n");
3215 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3216 smartlist_clear(chunks);
3218 /* case 2b3 */
3219 /* XXX I can't get a combination of values that hits this case without error,
3220 * so this just tests that it fails. See #20285. Also see #20284 as 2b3 does
3221 * not follow dir-spec. */
3222 /* (E < T/3 && G < T/3) && (E+D>=G || G+D>=E) && (M > T/3) */
3223 M = 80;
3224 E = 30;
3225 G = 30;
3226 D = 30;
3227 T = G + M + E + D;
3228 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3229 weight_scale);
3230 tt_int_op(ret, OP_EQ, 0);
3231 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3232 smartlist_clear(chunks);
3234 /* case 3a G scarce */
3235 M = 10;
3236 E = 30;
3237 G = 10;
3238 D = 5;
3239 T = G + M + E + D;
3240 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3241 weight_scale);
3242 tt_int_op(ret, OP_EQ, 1);
3243 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 "
3244 "Wbe=3333 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=6667 Weg=0 "
3245 "Wem=6667 Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 "
3246 "Wme=3333 Wmg=0 Wmm=10000\n");
3247 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3248 smartlist_clear(chunks);
3250 /* case 3a E scarce */
3251 M = 10;
3252 E = 10;
3253 G = 30;
3254 D = 5;
3255 T = G + M + E + D;
3256 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3257 weight_scale);
3258 tt_int_op(ret, OP_EQ, 1);
3259 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
3260 "Wbg=3333 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
3261 "Wem=10000 Wgb=10000 Wgd=0 Wgg=6667 Wgm=6667 Wmb=10000 Wmd=0 Wme=0 "
3262 "Wmg=3333 Wmm=10000\n");
3263 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3264 smartlist_clear(chunks);
3266 /* case 3bg */
3267 M = 10;
3268 E = 30;
3269 G = 10;
3270 D = 10;
3271 T = G + M + E + D;
3272 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3273 weight_scale);
3274 tt_int_op(ret, OP_EQ, 1);
3275 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 "
3276 "Wbe=3334 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=6666 Weg=0 "
3277 "Wem=6666 Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 "
3278 "Wme=3334 Wmg=0 Wmm=10000\n");
3279 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3280 smartlist_clear(chunks);
3282 /* case 3be */
3283 M = 10;
3284 E = 10;
3285 G = 30;
3286 D = 10;
3287 T = G + M + E + D;
3288 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3289 weight_scale);
3290 tt_int_op(ret, OP_EQ, 1);
3291 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
3292 "Wbg=3334 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
3293 "Wem=10000 Wgb=10000 Wgd=0 Wgg=6666 Wgm=6666 Wmb=10000 Wmd=0 Wme=0 "
3294 "Wmg=3334 Wmm=10000\n");
3295 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3296 smartlist_clear(chunks);
3298 /* case from 21 Jul 2013 (3be) */
3299 G = 5483409;
3300 M = 1455379;
3301 E = 980834;
3302 D = 3385803;
3303 T = 11305425;
3304 tt_i64_op(G+M+E+D, OP_EQ, T);
3305 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3306 weight_scale);
3307 tt_assert(ret);
3308 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=883 Wbe=0 "
3309 "Wbg=3673 Wbm=10000 Wdb=10000 Web=10000 Wed=8233 Wee=10000 Weg=8233 "
3310 "Wem=10000 Wgb=10000 Wgd=883 Wgg=6327 Wgm=6327 Wmb=10000 Wmd=883 Wme=0 "
3311 "Wmg=3673 Wmm=10000\n");
3312 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3313 smartlist_clear(chunks);
3315 /* case from 04 Oct 2016 (3a E scarce) */
3316 G=29322240;
3317 M=4721546;
3318 E=1522058;
3319 D=9273571;
3320 T=44839415;
3321 tt_i64_op(G+M+E+D, OP_EQ, T);
3322 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3323 weight_scale);
3324 tt_assert(ret);
3325 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
3326 "Wbg=4194 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
3327 "Wem=10000 Wgb=10000 Wgd=0 Wgg=5806 Wgm=5806 Wmb=10000 Wmd=0 Wme=0 "
3328 "Wmg=4194 Wmm=10000\n");
3329 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3330 smartlist_clear(chunks);
3332 /* case from 04 Sep 2013 (2b1) */
3333 G=3091352;
3334 M=1838837;
3335 E=2109300;
3336 D=2469369;
3337 T=9508858;
3338 tt_i64_op(G+M+E+D, OP_EQ, T);
3339 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3340 weight_scale);
3341 tt_assert(ret);
3342 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=317 "
3343 "Wbe=5938 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=9366 Wee=4061 "
3344 "Weg=9366 Wem=4061 Wgb=10000 Wgd=317 Wgg=10000 Wgm=10000 Wmb=10000 "
3345 "Wmd=317 Wme=5938 Wmg=0 Wmm=10000\n");
3346 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3347 smartlist_clear(chunks);
3349 /* explicitly test initializing weights to 1*/
3350 G=1;
3351 M=1;
3352 E=1;
3353 D=1;
3354 T=4;
3355 tt_i64_op(G+M+E+D, OP_EQ, T);
3356 ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3357 weight_scale);
3358 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=3333 "
3359 "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=3333 Wee=10000 Weg=3333 "
3360 "Wem=10000 Wgb=10000 Wgd=3333 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=3333 "
3361 "Wme=0 Wmg=0 Wmm=10000\n");
3362 tt_assert(ret);
3364 done:
3365 SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3366 smartlist_free(chunks);
3369 static authority_cert_t *mock_cert;
3371 static authority_cert_t *
3372 get_my_v3_authority_cert_m(void)
3374 tor_assert(mock_cert);
3375 return mock_cert;
3378 /** Run a unit tests for generating and parsing networkstatuses, with
3379 * the supply test fns. */
3380 static void
3381 test_a_networkstatus(
3382 vote_routerstatus_t * (*vrs_gen)(int idx, time_t now),
3383 int (*vote_tweaks)(networkstatus_t *v, int voter, time_t now),
3384 void (*vrs_test)(vote_routerstatus_t *vrs, int voter, time_t now),
3385 void (*consensus_test)(networkstatus_t *con, time_t now),
3386 void (*rs_test)(routerstatus_t *rs, time_t now))
3388 authority_cert_t *cert1=NULL, *cert2=NULL, *cert3=NULL;
3389 crypto_pk_t *sign_skey_1=NULL, *sign_skey_2=NULL, *sign_skey_3=NULL;
3390 crypto_pk_t *sign_skey_leg1=NULL;
3392 * Sum the non-zero returns from vote_tweaks() we've seen; if vote_tweaks()
3393 * returns non-zero, it changed net_params and we should skip the tests for
3394 * that later as they will fail.
3396 int params_tweaked = 0;
3398 time_t now = time(NULL);
3399 networkstatus_voter_info_t *voter;
3400 document_signature_t *sig;
3401 networkstatus_t *vote=NULL, *v1=NULL, *v2=NULL, *v3=NULL, *con=NULL,
3402 *con_md=NULL;
3403 vote_routerstatus_t *vrs;
3404 routerstatus_t *rs;
3405 int idx, n_rs, n_vrs;
3406 char *consensus_text=NULL, *cp=NULL;
3407 smartlist_t *votes = smartlist_new();
3409 /* For generating the two other consensuses. */
3410 char *detached_text1=NULL, *detached_text2=NULL;
3411 char *consensus_text2=NULL, *consensus_text3=NULL;
3412 char *consensus_text_md2=NULL, *consensus_text_md3=NULL;
3413 char *consensus_text_md=NULL;
3414 networkstatus_t *con2=NULL, *con_md2=NULL, *con3=NULL, *con_md3=NULL;
3415 ns_detached_signatures_t *dsig1=NULL, *dsig2=NULL;
3417 tt_assert(vrs_gen);
3418 tt_assert(rs_test);
3419 tt_assert(vrs_test);
3421 MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
3423 /* Parse certificates and keys. */
3424 cert1 = mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1,
3425 strlen(AUTHORITY_CERT_1),
3426 NULL);
3427 tt_assert(cert1);
3428 cert2 = authority_cert_parse_from_string(AUTHORITY_CERT_2,
3429 strlen(AUTHORITY_CERT_2),
3430 NULL);
3431 tt_assert(cert2);
3432 cert3 = authority_cert_parse_from_string(AUTHORITY_CERT_3,
3433 strlen(AUTHORITY_CERT_3),
3434 NULL);
3435 tt_assert(cert3);
3436 sign_skey_1 = crypto_pk_new();
3437 sign_skey_2 = crypto_pk_new();
3438 sign_skey_3 = crypto_pk_new();
3439 sign_skey_leg1 = pk_generate(4);
3440 dirauth_sched_recalculate_timing(get_options(), now);
3441 sr_state_init(0, 0);
3443 tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_1,
3444 AUTHORITY_SIGNKEY_1, -1));
3445 tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_2,
3446 AUTHORITY_SIGNKEY_2, -1));
3447 tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_3,
3448 AUTHORITY_SIGNKEY_3, -1));
3450 tt_assert(!crypto_pk_cmp_keys(sign_skey_1, cert1->signing_key));
3451 tt_assert(!crypto_pk_cmp_keys(sign_skey_2, cert2->signing_key));
3453 tt_assert(!dir_common_construct_vote_1(&vote, cert1, sign_skey_1, vrs_gen,
3454 &v1, &n_vrs, now, 1));
3455 tt_assert(v1);
3457 /* Make sure the parsed thing was right. */
3458 tt_int_op(v1->type,OP_EQ, NS_TYPE_VOTE);
3459 tt_int_op(v1->published,OP_EQ, vote->published);
3460 tt_int_op(v1->valid_after,OP_EQ, vote->valid_after);
3461 tt_int_op(v1->fresh_until,OP_EQ, vote->fresh_until);
3462 tt_int_op(v1->valid_until,OP_EQ, vote->valid_until);
3463 tt_int_op(v1->vote_seconds,OP_EQ, vote->vote_seconds);
3464 tt_int_op(v1->dist_seconds,OP_EQ, vote->dist_seconds);
3465 tt_str_op(v1->client_versions,OP_EQ, vote->client_versions);
3466 tt_str_op(v1->server_versions,OP_EQ, vote->server_versions);
3467 tt_assert(v1->voters && smartlist_len(v1->voters));
3468 voter = smartlist_get(v1->voters, 0);
3469 tt_str_op(voter->nickname,OP_EQ, "Voter1");
3470 tt_str_op(voter->address,OP_EQ, "1.2.3.4");
3471 tt_assert(tor_addr_eq_ipv4h(&voter->ipv4_addr, 0x01020304));
3472 tt_int_op(voter->ipv4_dirport,OP_EQ, 80);
3473 tt_int_op(voter->ipv4_orport,OP_EQ, 9000);
3474 tt_str_op(voter->contact,OP_EQ, "voter@example.com");
3475 tt_assert(v1->cert);
3476 tt_assert(!crypto_pk_cmp_keys(sign_skey_1, v1->cert->signing_key));
3477 cp = smartlist_join_strings(v1->known_flags, ":", 0, NULL);
3478 tt_str_op(cp,OP_EQ, "Authority:Exit:Fast:Guard:Running:Stable:V2Dir:Valid");
3479 tor_free(cp);
3480 tt_int_op(smartlist_len(v1->routerstatus_list),OP_EQ, n_vrs);
3481 networkstatus_vote_free(vote);
3482 vote = NULL;
3484 if (vote_tweaks) params_tweaked += vote_tweaks(v1, 1, now);
3486 /* Check the routerstatuses. */
3487 for (idx = 0; idx < n_vrs; ++idx) {
3488 vrs = smartlist_get(v1->routerstatus_list, idx);
3489 tt_assert(vrs);
3490 vrs_test(vrs, 1, now);
3493 /* Generate second vote. It disagrees on some of the times,
3494 * and doesn't list versions, and knows some crazy flags.
3495 * Generate and parse v2. */
3496 tt_assert(!dir_common_construct_vote_2(&vote, cert2, sign_skey_2, vrs_gen,
3497 &v2, &n_vrs, now, 1));
3498 tt_assert(v2);
3500 if (vote_tweaks) params_tweaked += vote_tweaks(v2, 2, now);
3502 /* Check that flags come out right.*/
3503 cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
3504 tt_str_op(cp,OP_EQ, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
3505 "Running:Stable:V2Dir:Valid");
3506 tor_free(cp);
3508 /* Check the routerstatuses. */
3509 n_vrs = smartlist_len(v2->routerstatus_list);
3510 for (idx = 0; idx < n_vrs; ++idx) {
3511 vrs = smartlist_get(v2->routerstatus_list, idx);
3512 tt_assert(vrs);
3513 vrs_test(vrs, 2, now);
3515 networkstatus_vote_free(vote);
3516 vote = NULL;
3518 /* Generate the third vote with a legacy id. */
3519 tt_assert(!dir_common_construct_vote_3(&vote, cert3, sign_skey_3, vrs_gen,
3520 &v3, &n_vrs, now, 1));
3521 tt_assert(v3);
3523 if (vote_tweaks) params_tweaked += vote_tweaks(v3, 3, now);
3525 /* Compute a consensus as voter 3. */
3526 smartlist_add(votes, v3);
3527 smartlist_add(votes, v1);
3528 smartlist_add(votes, v2);
3529 consensus_text = networkstatus_compute_consensus(votes, 3,
3530 cert3->identity_key,
3531 sign_skey_3,
3532 "AAAAAAAAAAAAAAAAAAAA",
3533 sign_skey_leg1,
3534 FLAV_NS);
3535 tt_assert(consensus_text);
3536 con = networkstatus_parse_vote_from_string_(consensus_text, NULL,
3537 NS_TYPE_CONSENSUS);
3538 tt_assert(con);
3539 //log_notice(LD_GENERAL, "<<%s>>\n<<%s>>\n<<%s>>\n",
3540 // v1_text, v2_text, v3_text);
3541 consensus_text_md = networkstatus_compute_consensus(votes, 3,
3542 cert3->identity_key,
3543 sign_skey_3,
3544 "AAAAAAAAAAAAAAAAAAAA",
3545 sign_skey_leg1,
3546 FLAV_MICRODESC);
3547 tt_assert(consensus_text_md);
3548 con_md = networkstatus_parse_vote_from_string_(consensus_text_md, NULL,
3549 NS_TYPE_CONSENSUS);
3550 tt_assert(con_md);
3551 tt_int_op(con_md->flavor,OP_EQ, FLAV_MICRODESC);
3553 /* Check consensus contents. */
3554 tt_assert(con->type == NS_TYPE_CONSENSUS);
3555 tt_int_op(con->published,OP_EQ, 0); /* this field only appears in votes. */
3556 tt_int_op(con->valid_after,OP_EQ, now+1000);
3557 tt_int_op(con->fresh_until,OP_EQ, now+2003); /* median */
3558 tt_int_op(con->valid_until,OP_EQ, now+3000);
3559 tt_int_op(con->vote_seconds,OP_EQ, 100);
3560 tt_int_op(con->dist_seconds,OP_EQ, 250); /* median */
3561 tt_str_op(con->client_versions,OP_EQ, "0.1.2.14");
3562 tt_str_op(con->server_versions,OP_EQ, "0.1.2.15,0.1.2.16");
3563 cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
3564 tt_str_op(cp,OP_EQ, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
3565 "Running:Stable:V2Dir:Valid");
3566 tor_free(cp);
3567 if (!params_tweaked) {
3568 /* Skip this one if vote_tweaks() messed with the param lists */
3569 cp = smartlist_join_strings(con->net_params, ":", 0, NULL);
3570 tt_str_op(cp,OP_EQ, "circuitwindow=80:foo=660");
3571 tor_free(cp);
3574 tt_int_op(4,OP_EQ, smartlist_len(con->voters)); /*3 voters, 1 legacy key.*/
3575 /* The voter id digests should be in this order. */
3576 tt_assert(fast_memcmp(cert2->cache_info.identity_digest,
3577 cert1->cache_info.identity_digest,DIGEST_LEN)<0);
3578 tt_assert(fast_memcmp(cert1->cache_info.identity_digest,
3579 cert3->cache_info.identity_digest,DIGEST_LEN)<0);
3580 test_same_voter(smartlist_get(con->voters, 1),
3581 smartlist_get(v2->voters, 0));
3582 test_same_voter(smartlist_get(con->voters, 2),
3583 smartlist_get(v1->voters, 0));
3584 test_same_voter(smartlist_get(con->voters, 3),
3585 smartlist_get(v3->voters, 0));
3587 consensus_test(con, now);
3589 /* Check the routerstatuses. */
3590 n_rs = smartlist_len(con->routerstatus_list);
3591 tt_assert(n_rs);
3592 for (idx = 0; idx < n_rs; ++idx) {
3593 rs = smartlist_get(con->routerstatus_list, idx);
3594 tt_assert(rs);
3595 rs_test(rs, now);
3598 n_rs = smartlist_len(con_md->routerstatus_list);
3599 tt_assert(n_rs);
3600 for (idx = 0; idx < n_rs; ++idx) {
3601 rs = smartlist_get(con_md->routerstatus_list, idx);
3602 tt_assert(rs);
3605 /* Check signatures. the first voter is a pseudo-entry with a legacy key.
3606 * The second one hasn't signed. The fourth one has signed: validate it. */
3607 voter = smartlist_get(con->voters, 1);
3608 tt_int_op(smartlist_len(voter->sigs),OP_EQ, 0);
3610 voter = smartlist_get(con->voters, 3);
3611 tt_int_op(smartlist_len(voter->sigs),OP_EQ, 1);
3612 sig = smartlist_get(voter->sigs, 0);
3613 tt_assert(sig->signature);
3614 tt_assert(!sig->good_signature);
3615 tt_assert(!sig->bad_signature);
3617 tt_assert(!networkstatus_check_document_signature(con, sig, cert3));
3618 tt_assert(sig->signature);
3619 tt_assert(sig->good_signature);
3620 tt_assert(!sig->bad_signature);
3623 const char *msg=NULL;
3624 /* Compute the other two signed consensuses. */
3625 smartlist_shuffle(votes);
3626 consensus_text2 = networkstatus_compute_consensus(votes, 3,
3627 cert2->identity_key,
3628 sign_skey_2, NULL,NULL,
3629 FLAV_NS);
3630 consensus_text_md2 = networkstatus_compute_consensus(votes, 3,
3631 cert2->identity_key,
3632 sign_skey_2, NULL,NULL,
3633 FLAV_MICRODESC);
3634 smartlist_shuffle(votes);
3635 consensus_text3 = networkstatus_compute_consensus(votes, 3,
3636 cert1->identity_key,
3637 sign_skey_1, NULL,NULL,
3638 FLAV_NS);
3639 consensus_text_md3 = networkstatus_compute_consensus(votes, 3,
3640 cert1->identity_key,
3641 sign_skey_1, NULL,NULL,
3642 FLAV_MICRODESC);
3643 tt_assert(consensus_text2);
3644 tt_assert(consensus_text3);
3645 tt_assert(consensus_text_md2);
3646 tt_assert(consensus_text_md3);
3647 con2 = networkstatus_parse_vote_from_string_(consensus_text2, NULL,
3648 NS_TYPE_CONSENSUS);
3649 con3 = networkstatus_parse_vote_from_string_(consensus_text3, NULL,
3650 NS_TYPE_CONSENSUS);
3651 con_md2 = networkstatus_parse_vote_from_string_(consensus_text_md2, NULL,
3652 NS_TYPE_CONSENSUS);
3653 con_md3 = networkstatus_parse_vote_from_string_(consensus_text_md3, NULL,
3654 NS_TYPE_CONSENSUS);
3655 tt_assert(con2);
3656 tt_assert(con3);
3657 tt_assert(con_md2);
3658 tt_assert(con_md3);
3660 /* All three should have the same digest. */
3661 tt_mem_op(&con->digests,OP_EQ, &con2->digests, sizeof(common_digests_t));
3662 tt_mem_op(&con->digests,OP_EQ, &con3->digests, sizeof(common_digests_t));
3664 tt_mem_op(&con_md->digests,OP_EQ, &con_md2->digests,
3665 sizeof(common_digests_t));
3666 tt_mem_op(&con_md->digests,OP_EQ, &con_md3->digests,
3667 sizeof(common_digests_t));
3669 /* Extract a detached signature from con3. */
3670 detached_text1 = get_detached_sigs(con3, con_md3);
3671 tt_assert(detached_text1);
3672 /* Try to parse it. */
3673 dsig1 = networkstatus_parse_detached_signatures(detached_text1, NULL);
3674 tt_assert(dsig1);
3676 /* Are parsed values as expected? */
3677 tt_int_op(dsig1->valid_after,OP_EQ, con3->valid_after);
3678 tt_int_op(dsig1->fresh_until,OP_EQ, con3->fresh_until);
3679 tt_int_op(dsig1->valid_until,OP_EQ, con3->valid_until);
3681 common_digests_t *dsig_digests = strmap_get(dsig1->digests, "ns");
3682 tt_assert(dsig_digests);
3683 tt_mem_op(dsig_digests->d[DIGEST_SHA1], OP_EQ,
3684 con3->digests.d[DIGEST_SHA1], DIGEST_LEN);
3685 dsig_digests = strmap_get(dsig1->digests, "microdesc");
3686 tt_assert(dsig_digests);
3687 tt_mem_op(dsig_digests->d[DIGEST_SHA256],OP_EQ,
3688 con_md3->digests.d[DIGEST_SHA256],
3689 DIGEST256_LEN);
3692 smartlist_t *dsig_signatures = strmap_get(dsig1->signatures, "ns");
3693 tt_assert(dsig_signatures);
3694 tt_int_op(1,OP_EQ, smartlist_len(dsig_signatures));
3695 sig = smartlist_get(dsig_signatures, 0);
3696 tt_mem_op(sig->identity_digest,OP_EQ, cert1->cache_info.identity_digest,
3697 DIGEST_LEN);
3698 tt_int_op(sig->alg,OP_EQ, DIGEST_SHA1);
3700 dsig_signatures = strmap_get(dsig1->signatures, "microdesc");
3701 tt_assert(dsig_signatures);
3702 tt_int_op(1,OP_EQ, smartlist_len(dsig_signatures));
3703 sig = smartlist_get(dsig_signatures, 0);
3704 tt_mem_op(sig->identity_digest,OP_EQ, cert1->cache_info.identity_digest,
3705 DIGEST_LEN);
3706 tt_int_op(sig->alg,OP_EQ, DIGEST_SHA256);
3709 /* Try adding it to con2. */
3710 detached_text2 = get_detached_sigs(con2,con_md2);
3711 tt_int_op(1,OP_EQ, networkstatus_add_detached_signatures(con2, dsig1,
3712 "test", LOG_INFO, &msg));
3713 tor_free(detached_text2);
3714 tt_int_op(1,OP_EQ,
3715 networkstatus_add_detached_signatures(con_md2, dsig1, "test",
3716 LOG_INFO, &msg));
3717 tor_free(detached_text2);
3718 detached_text2 = get_detached_sigs(con2,con_md2);
3719 //printf("\n<%s>\n", detached_text2);
3720 dsig2 = networkstatus_parse_detached_signatures(detached_text2, NULL);
3721 tt_assert(dsig2);
3723 printf("\n");
3724 SMARTLIST_FOREACH(dsig2->signatures, networkstatus_voter_info_t *, vi, {
3725 char hd[64];
3726 base16_encode(hd, sizeof(hd), vi->identity_digest, DIGEST_LEN);
3727 printf("%s\n", hd);
3730 tt_int_op(2,OP_EQ,
3731 smartlist_len((smartlist_t*)strmap_get(dsig2->signatures, "ns")));
3732 tt_int_op(2,OP_EQ,
3733 smartlist_len((smartlist_t*)strmap_get(dsig2->signatures,
3734 "microdesc")));
3736 /* Try adding to con2 twice; verify that nothing changes. */
3737 tt_int_op(0,OP_EQ, networkstatus_add_detached_signatures(con2, dsig1,
3738 "test", LOG_INFO, &msg));
3740 /* Add to con. */
3741 tt_int_op(2,OP_EQ, networkstatus_add_detached_signatures(con, dsig2,
3742 "test", LOG_INFO, &msg));
3743 /* Check signatures */
3744 voter = smartlist_get(con->voters, 1);
3745 sig = smartlist_get(voter->sigs, 0);
3746 tt_assert(sig);
3747 tt_assert(!networkstatus_check_document_signature(con, sig, cert2));
3748 voter = smartlist_get(con->voters, 2);
3749 sig = smartlist_get(voter->sigs, 0);
3750 tt_assert(sig);
3751 tt_assert(!networkstatus_check_document_signature(con, sig, cert1));
3754 done:
3755 tor_free(cp);
3756 smartlist_free(votes);
3757 tor_free(consensus_text);
3758 tor_free(consensus_text_md);
3760 networkstatus_vote_free(vote);
3761 networkstatus_vote_free(v1);
3762 networkstatus_vote_free(v2);
3763 networkstatus_vote_free(v3);
3764 networkstatus_vote_free(con);
3765 networkstatus_vote_free(con_md);
3766 crypto_pk_free(sign_skey_1);
3767 crypto_pk_free(sign_skey_2);
3768 crypto_pk_free(sign_skey_3);
3769 crypto_pk_free(sign_skey_leg1);
3770 authority_cert_free(cert1);
3771 authority_cert_free(cert2);
3772 authority_cert_free(cert3);
3774 tor_free(consensus_text2);
3775 tor_free(consensus_text3);
3776 tor_free(consensus_text_md2);
3777 tor_free(consensus_text_md3);
3778 tor_free(detached_text1);
3779 tor_free(detached_text2);
3781 networkstatus_vote_free(con2);
3782 networkstatus_vote_free(con3);
3783 networkstatus_vote_free(con_md2);
3784 networkstatus_vote_free(con_md3);
3785 ns_detached_signatures_free(dsig1);
3786 ns_detached_signatures_free(dsig2);
3789 /** Run unit tests for generating and parsing V3 consensus networkstatus
3790 * documents. */
3791 static void
3792 test_dir_v3_networkstatus(void *arg)
3794 (void)arg;
3795 test_a_networkstatus(dir_common_gen_routerstatus_for_v3ns,
3796 vote_tweaks_for_v3ns,
3797 test_vrs_for_v3ns,
3798 test_consensus_for_v3ns,
3799 test_routerstatus_for_v3ns);
3802 static void
3803 test_dir_scale_bw(void *testdata)
3805 double v[8] = { 2.0/3,
3806 7.0,
3807 1.0,
3808 3.0,
3809 1.0/5,
3810 1.0/7,
3811 12.0,
3812 24.0 };
3813 double vals_dbl[8];
3814 uint64_t vals_u64[8];
3815 uint64_t total;
3816 int i;
3818 (void) testdata;
3820 for (i=0; i<8; ++i)
3821 vals_dbl[i] = v[i];
3823 scale_array_elements_to_u64(vals_u64, vals_dbl, 8, &total);
3825 tt_int_op((int)total, OP_EQ, 48);
3826 total = 0;
3827 for (i=0; i<8; ++i) {
3828 total += vals_u64[i];
3830 tt_assert(total >= (UINT64_C(1)<<60));
3831 tt_assert(total <= (UINT64_C(1)<<62));
3833 for (i=0; i<8; ++i) {
3834 /* vals[2].u64 is the scaled value of 1.0 */
3835 double ratio = ((double)vals_u64[i]) / vals_u64[2];
3836 tt_double_op(fabs(ratio - v[i]), OP_LT, .00001);
3839 /* test handling of no entries */
3840 total = 1;
3841 scale_array_elements_to_u64(vals_u64, vals_dbl, 0, &total);
3842 tt_assert(total == 0);
3844 /* make sure we don't read the array when we have no entries
3845 * may require compiler flags to catch NULL dereferences */
3846 total = 1;
3847 scale_array_elements_to_u64(NULL, NULL, 0, &total);
3848 tt_assert(total == 0);
3850 scale_array_elements_to_u64(NULL, NULL, 0, NULL);
3852 /* test handling of zero totals */
3853 total = 1;
3854 vals_dbl[0] = 0.0;
3855 scale_array_elements_to_u64(vals_u64, vals_dbl, 1, &total);
3856 tt_assert(total == 0);
3857 tt_assert(vals_u64[0] == 0);
3859 vals_dbl[0] = 0.0;
3860 vals_dbl[1] = 0.0;
3861 scale_array_elements_to_u64(vals_u64, vals_dbl, 2, NULL);
3862 tt_assert(vals_u64[0] == 0);
3863 tt_assert(vals_u64[1] == 0);
3865 done:
3869 static void
3870 test_dir_random_weighted(void *testdata)
3872 int histogram[10];
3873 uint64_t vals[10] = {3,1,2,4,6,0,7,5,8,9}, total=0;
3874 uint64_t inp_u64[10];
3875 int i, choice;
3876 const int n = 50000;
3877 double max_sq_error;
3878 (void) testdata;
3880 /* Try a ten-element array with values from 0 through 10. The values are
3881 * in a scrambled order to make sure we don't depend on order. */
3882 memset(histogram,0,sizeof(histogram));
3883 for (i=0; i<10; ++i) {
3884 inp_u64[i] = vals[i];
3885 total += vals[i];
3887 tt_u64_op(total, OP_EQ, 45);
3888 for (i=0; i<n; ++i) {
3889 choice = choose_array_element_by_weight(inp_u64, 10);
3890 tt_int_op(choice, OP_GE, 0);
3891 tt_int_op(choice, OP_LT, 10);
3892 histogram[choice]++;
3895 /* Now see if we chose things about frequently enough. */
3896 max_sq_error = 0;
3897 for (i=0; i<10; ++i) {
3898 int expected = (int)(n*vals[i]/total);
3899 double frac_diff = 0, sq;
3900 TT_BLATHER((" %d : %5d vs %5d\n", (int)vals[i], histogram[i], expected));
3901 if (expected)
3902 frac_diff = (histogram[i] - expected) / ((double)expected);
3903 else
3904 tt_int_op(histogram[i], OP_EQ, 0);
3906 sq = frac_diff * frac_diff;
3907 if (sq > max_sq_error)
3908 max_sq_error = sq;
3910 /* It should almost always be much much less than this. If you want to
3911 * figure out the odds, please feel free. */
3912 tt_double_op(max_sq_error, OP_LT, .05);
3914 /* Now try a singleton; do we choose it? */
3915 for (i = 0; i < 100; ++i) {
3916 choice = choose_array_element_by_weight(inp_u64, 1);
3917 tt_int_op(choice, OP_EQ, 0);
3920 /* Now try an array of zeros. We should choose randomly. */
3921 memset(histogram,0,sizeof(histogram));
3922 for (i = 0; i < 5; ++i)
3923 inp_u64[i] = 0;
3924 for (i = 0; i < n; ++i) {
3925 choice = choose_array_element_by_weight(inp_u64, 5);
3926 tt_int_op(choice, OP_GE, 0);
3927 tt_int_op(choice, OP_LT, 5);
3928 histogram[choice]++;
3930 /* Now see if we chose things about frequently enough. */
3931 max_sq_error = 0;
3932 for (i=0; i<5; ++i) {
3933 int expected = n/5;
3934 double frac_diff = 0, sq;
3935 TT_BLATHER((" %d : %5d vs %5d\n", (int)vals[i], histogram[i], expected));
3936 frac_diff = (histogram[i] - expected) / ((double)expected);
3937 sq = frac_diff * frac_diff;
3938 if (sq > max_sq_error)
3939 max_sq_error = sq;
3941 /* It should almost always be much much less than this. If you want to
3942 * figure out the odds, please feel free. */
3943 tt_double_op(max_sq_error, OP_LT, .05);
3944 done:
3948 /* Function pointers for test_dir_clip_unmeasured_bw_kb() */
3950 static uint32_t alternate_clip_bw = 0;
3953 * Generate a routerstatus for clip_unmeasured_bw_kb test; based on the
3954 * v3_networkstatus ones.
3956 static vote_routerstatus_t *
3957 gen_routerstatus_for_umbw(int idx, time_t now)
3959 vote_routerstatus_t *vrs = NULL;
3960 routerstatus_t *rs;
3961 tor_addr_t addr_ipv6;
3962 uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
3963 alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
3965 switch (idx) {
3966 case 0:
3967 /* Generate the first routerstatus. */
3968 vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
3969 rs = &vrs->status;
3970 vrs->version = tor_strdup("0.1.2.14");
3971 rs->published_on = now-1500;
3972 strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
3973 memset(rs->identity_digest, 3, DIGEST_LEN);
3974 memset(rs->descriptor_digest, 78, DIGEST_LEN);
3975 tor_addr_from_ipv4h(&rs->ipv4_addr, 0x99008801);
3976 rs->ipv4_orport = 443;
3977 rs->ipv4_dirport = 8000;
3978 /* all flags but running and valid cleared */
3979 rs->is_flagged_running = 1;
3980 rs->is_valid = 1;
3982 * This one has measured bandwidth below the clip cutoff, and
3983 * so shouldn't be clipped; we'll have to test that it isn't
3984 * later.
3986 vrs->has_measured_bw = 1;
3987 rs->has_bandwidth = 1;
3988 vrs->measured_bw_kb = rs->bandwidth_kb = max_unmeasured_bw_kb / 2;
3989 vrs->protocols = tor_strdup("Link=2 Wombat=40");
3990 break;
3991 case 1:
3992 /* Generate the second routerstatus. */
3993 vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
3994 rs = &vrs->status;
3995 vrs->version = tor_strdup("0.2.0.5");
3996 rs->published_on = now-1000;
3997 strlcpy(rs->nickname, "router1", sizeof(rs->nickname));
3998 memset(rs->identity_digest, 5, DIGEST_LEN);
3999 memset(rs->descriptor_digest, 77, DIGEST_LEN);
4000 tor_addr_from_ipv4h(&rs->ipv4_addr, 0x99009901);
4001 rs->ipv4_orport = 443;
4002 rs->ipv4_dirport = 0;
4003 tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
4004 tor_addr_copy(&rs->ipv6_addr, &addr_ipv6);
4005 rs->ipv6_orport = 4711;
4006 rs->is_exit = rs->is_stable = rs->is_fast = rs->is_flagged_running =
4007 rs->is_valid = rs->is_possible_guard = 1;
4009 * This one has measured bandwidth above the clip cutoff, and
4010 * so shouldn't be clipped; we'll have to test that it isn't
4011 * later.
4013 vrs->has_measured_bw = 1;
4014 rs->has_bandwidth = 1;
4015 vrs->measured_bw_kb = rs->bandwidth_kb = 2 * max_unmeasured_bw_kb;
4016 vrs->protocols = tor_strdup("Link=2 Wombat=40");
4017 break;
4018 case 2:
4019 /* Generate the third routerstatus. */
4020 vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
4021 rs = &vrs->status;
4022 vrs->version = tor_strdup("0.1.0.3");
4023 rs->published_on = now-1000;
4024 strlcpy(rs->nickname, "router3", sizeof(rs->nickname));
4025 memset(rs->identity_digest, 0x33, DIGEST_LEN);
4026 memset(rs->descriptor_digest, 79, DIGEST_LEN);
4027 tor_addr_from_ipv4h(&rs->ipv4_addr, 0xAA009901);
4028 rs->ipv4_orport = 400;
4029 rs->ipv4_dirport = 9999;
4030 rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
4031 rs->is_flagged_running = rs->is_valid =
4032 rs->is_possible_guard = 1;
4034 * This one has unmeasured bandwidth above the clip cutoff, and
4035 * so should be clipped; we'll have to test that it isn't
4036 * later.
4038 vrs->has_measured_bw = 0;
4039 rs->has_bandwidth = 1;
4040 vrs->measured_bw_kb = 0;
4041 rs->bandwidth_kb = 2 * max_unmeasured_bw_kb;
4042 vrs->protocols = tor_strdup("Link=2 Wombat=40");
4043 break;
4044 case 3:
4045 /* Generate a fourth routerstatus that is not running. */
4046 vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
4047 rs = &vrs->status;
4048 vrs->version = tor_strdup("0.1.6.3");
4049 rs->published_on = now-1000;
4050 strlcpy(rs->nickname, "router4", sizeof(rs->nickname));
4051 memset(rs->identity_digest, 0x34, DIGEST_LEN);
4052 memset(rs->descriptor_digest, 47, DIGEST_LEN);
4053 tor_addr_from_ipv4h(&rs->ipv4_addr, 0xC0000203);
4054 rs->ipv4_orport = 500;
4055 rs->ipv4_dirport = 1999;
4056 /* all flags but running and valid cleared */
4057 rs->is_flagged_running = 1;
4058 rs->is_valid = 1;
4060 * This one has unmeasured bandwidth below the clip cutoff, and
4061 * so shouldn't be clipped; we'll have to test that it isn't
4062 * later.
4064 vrs->has_measured_bw = 0;
4065 rs->has_bandwidth = 1;
4066 vrs->measured_bw_kb = 0;
4067 rs->bandwidth_kb = max_unmeasured_bw_kb / 2;
4068 vrs->protocols = tor_strdup("Link=2 Wombat=40");
4069 break;
4070 case 4:
4071 /* No more for this test; return NULL */
4072 vrs = NULL;
4073 break;
4074 default:
4075 /* Shouldn't happen */
4076 tt_abort();
4078 if (vrs) {
4079 vrs->microdesc = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
4080 tor_asprintf(&vrs->microdesc->microdesc_hash_line,
4081 "m 25,26,27,28 "
4082 "sha256=xyzajkldsdsajdadlsdjaslsdksdjlsdjsdaskdaaa%d\n",
4083 idx);
4086 done:
4087 return vrs;
4090 /** Apply tweaks to the vote list for each voter; for the umbw test this is
4091 * just adding the right consensus methods to let clipping happen */
4092 static int
4093 vote_tweaks_for_umbw(networkstatus_t *v, int voter, time_t now)
4095 char *maxbw_param = NULL;
4096 int rv = 0;
4098 tt_assert(v);
4099 (void)voter;
4100 (void)now;
4102 tt_assert(v->supported_methods);
4103 SMARTLIST_FOREACH(v->supported_methods, char *, c, tor_free(c));
4104 smartlist_clear(v->supported_methods);
4105 /* Method 17 is MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB */
4106 smartlist_split_string(v->supported_methods,
4107 "25 26 27 28",
4108 NULL, 0, -1);
4109 /* If we're using a non-default clip bandwidth, add it to net_params */
4110 if (alternate_clip_bw > 0) {
4111 tor_asprintf(&maxbw_param, "maxunmeasuredbw=%u", alternate_clip_bw);
4112 tt_assert(maxbw_param);
4113 if (maxbw_param) {
4114 smartlist_add(v->net_params, maxbw_param);
4115 rv = 1;
4119 done:
4120 return rv;
4124 * Test a parsed vote_routerstatus_t for umbw test.
4126 static void
4127 test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now)
4129 routerstatus_t *rs;
4130 tor_addr_t addr_ipv6;
4131 uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
4132 alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
4134 (void)voter;
4135 tt_assert(vrs);
4136 rs = &(vrs->status);
4137 tt_assert(rs);
4139 /* Split out by digests to test */
4140 if (tor_memeq(rs->identity_digest,
4141 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
4142 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
4143 DIGEST_LEN)) {
4145 * Check the first routerstatus - measured bandwidth below the clip
4146 * cutoff.
4148 tt_str_op(vrs->version,OP_EQ, "0.1.2.14");
4149 tt_int_op(rs->published_on,OP_EQ, now-1500);
4150 tt_str_op(rs->nickname,OP_EQ, "router2");
4151 tt_mem_op(rs->identity_digest,OP_EQ,
4152 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
4153 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
4154 DIGEST_LEN);
4155 tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
4156 tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99008801));
4157 tt_int_op(rs->ipv4_orport,OP_EQ, 443);
4158 tt_int_op(rs->ipv4_dirport,OP_EQ, 8000);
4159 tt_assert(rs->has_bandwidth);
4160 tt_assert(vrs->has_measured_bw);
4161 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
4162 tt_int_op(vrs->measured_bw_kb,OP_EQ, max_unmeasured_bw_kb / 2);
4163 } else if (tor_memeq(rs->identity_digest,
4164 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
4165 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
4166 DIGEST_LEN)) {
4169 * Check the second routerstatus - measured bandwidth above the clip
4170 * cutoff.
4172 tt_str_op(vrs->version,OP_EQ, "0.2.0.5");
4173 tt_int_op(rs->published_on,OP_EQ, now-1000);
4174 tt_str_op(rs->nickname,OP_EQ, "router1");
4175 tt_mem_op(rs->identity_digest,OP_EQ,
4176 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
4177 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
4178 DIGEST_LEN);
4179 tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
4180 tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
4181 tt_int_op(rs->ipv4_orport,OP_EQ, 443);
4182 tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
4183 tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
4184 tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
4185 tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
4186 tt_assert(rs->has_bandwidth);
4187 tt_assert(vrs->has_measured_bw);
4188 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb * 2);
4189 tt_int_op(vrs->measured_bw_kb,OP_EQ, max_unmeasured_bw_kb * 2);
4190 } else if (tor_memeq(rs->identity_digest,
4191 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
4192 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
4193 DIGEST_LEN)) {
4195 * Check the third routerstatus - unmeasured bandwidth above the clip
4196 * cutoff; this one should be clipped later on in the consensus, but
4197 * appears unclipped in the vote.
4199 tt_assert(rs->has_bandwidth);
4200 tt_assert(!(vrs->has_measured_bw));
4201 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb * 2);
4202 tt_int_op(vrs->measured_bw_kb,OP_EQ, 0);
4203 } else if (tor_memeq(rs->identity_digest,
4204 "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34"
4205 "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34",
4206 DIGEST_LEN)) {
4208 * Check the fourth routerstatus - unmeasured bandwidth below the clip
4209 * cutoff; this one should not be clipped.
4211 tt_assert(rs->has_bandwidth);
4212 tt_assert(!(vrs->has_measured_bw));
4213 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
4214 tt_int_op(vrs->measured_bw_kb,OP_EQ, 0);
4215 } else {
4216 tt_abort();
4219 done:
4220 return;
4224 * Test a consensus for v3_networkstatus_test
4226 static void
4227 test_consensus_for_umbw(networkstatus_t *con, time_t now)
4229 (void)now;
4231 tt_assert(con);
4232 tt_ptr_op(con->cert, OP_EQ, NULL);
4233 // tt_assert(con->consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB);
4234 tt_int_op(con->consensus_method, OP_GE, 16);
4235 tt_int_op(4,OP_EQ, smartlist_len(con->routerstatus_list));
4236 /* There should be four listed routers; all voters saw the same in this */
4238 done:
4239 return;
4243 * Test a router list entry for umbw test
4245 static void
4246 test_routerstatus_for_umbw(routerstatus_t *rs, time_t now)
4248 tor_addr_t addr_ipv6;
4249 uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
4250 alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
4252 tt_assert(rs);
4254 /* There should be four listed routers, as constructed above */
4255 if (tor_memeq(rs->identity_digest,
4256 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
4257 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
4258 DIGEST_LEN)) {
4259 tt_mem_op(rs->identity_digest,OP_EQ,
4260 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
4261 "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
4262 DIGEST_LEN);
4263 tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
4264 tt_assert(!rs->is_authority);
4265 tt_assert(!rs->is_exit);
4266 tt_assert(!rs->is_fast);
4267 tt_assert(!rs->is_possible_guard);
4268 tt_assert(!rs->is_stable);
4269 /* (If it wasn't running and valid it wouldn't be here) */
4270 tt_assert(rs->is_flagged_running);
4271 tt_assert(rs->is_valid);
4272 tt_assert(!rs->is_named);
4273 /* This one should have measured bandwidth below the clip cutoff */
4274 tt_assert(rs->has_bandwidth);
4275 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
4276 tt_assert(!(rs->bw_is_unmeasured));
4277 } else if (tor_memeq(rs->identity_digest,
4278 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
4279 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
4280 DIGEST_LEN)) {
4281 /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */
4282 tt_mem_op(rs->identity_digest,OP_EQ,
4283 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
4284 "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
4285 DIGEST_LEN);
4286 tt_str_op(rs->nickname,OP_EQ, "router1");
4287 tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
4288 tt_int_op(rs->published_on,OP_EQ, now-1000);
4289 tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
4290 tt_int_op(rs->ipv4_orport,OP_EQ, 443);
4291 tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
4292 tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
4293 tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
4294 tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
4295 tt_assert(!rs->is_authority);
4296 tt_assert(rs->is_exit);
4297 tt_assert(rs->is_fast);
4298 tt_assert(rs->is_possible_guard);
4299 tt_assert(rs->is_stable);
4300 tt_assert(rs->is_flagged_running);
4301 tt_assert(rs->is_valid);
4302 tt_assert(!rs->is_named);
4303 /* This one should have measured bandwidth above the clip cutoff */
4304 tt_assert(rs->has_bandwidth);
4305 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb * 2);
4306 tt_assert(!(rs->bw_is_unmeasured));
4307 } else if (tor_memeq(rs->identity_digest,
4308 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
4309 "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
4310 DIGEST_LEN)) {
4312 * This one should have unmeasured bandwidth above the clip cutoff,
4313 * and so should be clipped
4315 tt_assert(rs->has_bandwidth);
4316 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb);
4317 tt_assert(rs->bw_is_unmeasured);
4318 } else if (tor_memeq(rs->identity_digest,
4319 "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34"
4320 "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34",
4321 DIGEST_LEN)) {
4323 * This one should have unmeasured bandwidth below the clip cutoff,
4324 * and so should not be clipped
4326 tt_assert(rs->has_bandwidth);
4327 tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
4328 tt_assert(rs->bw_is_unmeasured);
4329 } else {
4330 /* Weren't expecting this... */
4331 tt_abort();
4334 done:
4335 return;
4339 * Compute a consensus involving clipping unmeasured bandwidth with consensus
4340 * method 17; this uses the same test_a_networkstatus() function that the
4341 * v3_networkstatus test uses.
4344 static void
4345 test_dir_clip_unmeasured_bw_kb(void *arg)
4347 /* Run the test with the default clip bandwidth */
4348 (void)arg;
4349 alternate_clip_bw = 0;
4350 test_a_networkstatus(gen_routerstatus_for_umbw,
4351 vote_tweaks_for_umbw,
4352 test_vrs_for_umbw,
4353 test_consensus_for_umbw,
4354 test_routerstatus_for_umbw);
4358 * This version of test_dir_clip_unmeasured_bw_kb() uses a non-default choice
4359 * of clip bandwidth.
4362 static void
4363 test_dir_clip_unmeasured_bw_kb_alt(void *arg)
4366 * Try a different one; this value is chosen so that the below-the-cutoff
4367 * unmeasured nodes the test uses, at alternate_clip_bw / 2, will be above
4368 * DEFAULT_MAX_UNMEASURED_BW_KB and if the consensus incorrectly uses that
4369 * cutoff it will fail the test.
4371 (void)arg;
4372 alternate_clip_bw = 3 * DEFAULT_MAX_UNMEASURED_BW_KB;
4373 test_a_networkstatus(gen_routerstatus_for_umbw,
4374 vote_tweaks_for_umbw,
4375 test_vrs_for_umbw,
4376 test_consensus_for_umbw,
4377 test_routerstatus_for_umbw);
4380 static void
4381 test_dir_fmt_control_ns(void *arg)
4383 char *s = NULL;
4384 routerstatus_t rs;
4385 (void)arg;
4387 memset(&rs, 0, sizeof(rs));
4388 rs.published_on = 1364925198;
4389 strlcpy(rs.nickname, "TetsuoMilk", sizeof(rs.nickname));
4390 memcpy(rs.identity_digest, "Stately, plump Buck ", DIGEST_LEN);
4391 memcpy(rs.descriptor_digest, "Mulligan came up fro", DIGEST_LEN);
4392 tor_addr_from_ipv4h(&rs.ipv4_addr, 0x20304050);
4393 rs.ipv4_orport = 9001;
4394 rs.ipv4_dirport = 9002;
4395 rs.is_exit = 1;
4396 rs.is_fast = 1;
4397 rs.is_flagged_running = 1;
4398 rs.has_bandwidth = 1;
4399 rs.is_v2_dir = 1;
4400 rs.bandwidth_kb = 1000;
4402 s = networkstatus_getinfo_helper_single(&rs);
4403 tt_assert(s);
4404 tt_str_op(s, OP_EQ,
4405 "r TetsuoMilk U3RhdGVseSwgcGx1bXAgQnVjayA "
4406 "TXVsbGlnYW4gY2FtZSB1cCBmcm8 2013-04-02 17:53:18 "
4407 "32.48.64.80 9001 9002\n"
4408 "s Exit Fast Running V2Dir\n"
4409 "w Bandwidth=1000\n");
4411 done:
4412 tor_free(s);
4415 static int mock_get_options_calls = 0;
4416 static or_options_t *mock_options = NULL;
4418 static void
4419 reset_options(or_options_t *options, int *get_options_calls)
4421 memset(options, 0, sizeof(or_options_t));
4422 options->TestingTorNetwork = 1;
4424 *get_options_calls = 0;
4427 static const or_options_t *
4428 mock_get_options(void)
4430 ++mock_get_options_calls;
4431 tor_assert(mock_options);
4432 return mock_options;
4436 * Test dirauth_get_b64_digest_bw_file.
4437 * This function should be near the other bwauth functions, but it needs
4438 * mock_get_options, that is only defined here.
4441 static void
4442 test_dir_bwauth_bw_file_digest256(void *arg)
4444 (void)arg;
4445 const char *content =
4446 "1541171221\n"
4447 "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 "
4448 "master_key_ed25519=YaqV4vbvPYKucElk297eVdNArDz9HtIwUoIeo0+cVIpQ "
4449 "bw=760 nick=Test time=2018-05-08T16:13:26\n";
4451 char *fname = tor_strdup(get_fname("V3BandwidthsFile"));
4452 /* Initialize to a wrong digest. */
4453 uint8_t digest[DIGEST256_LEN] = "01234567890123456789abcdefghijkl";
4455 /* Digest of an empty string. Initialize to a wrong digest. */
4456 char digest_empty_str[DIGEST256_LEN] = "01234567890123456789abcdefghijkl";
4457 crypto_digest256(digest_empty_str, "", 0, DIGEST_SHA256);
4459 /* Digest of the content. Initialize to a wrong digest. */
4460 char digest_expected[DIGEST256_LEN] = "01234567890123456789abcdefghijkl";
4461 crypto_digest256(digest_expected, content, strlen(content), DIGEST_SHA256);
4463 /* When the bandwidth file can not be found. */
4464 tt_int_op(-1, OP_EQ,
4465 dirserv_read_measured_bandwidths(fname,
4466 NULL, NULL, digest));
4467 tt_mem_op(digest, OP_EQ, digest_empty_str, DIGEST256_LEN);
4469 /* When there is a timestamp but it is too old. */
4470 write_str_to_file(fname, content, 0);
4471 tt_int_op(-1, OP_EQ,
4472 dirserv_read_measured_bandwidths(fname,
4473 NULL, NULL, digest));
4474 /* The digest will be correct. */
4475 tt_mem_op(digest, OP_EQ, digest_expected, DIGEST256_LEN);
4477 update_approx_time(1541171221);
4479 /* When there is a bandwidth file and it can be read. */
4480 tt_int_op(0, OP_EQ,
4481 dirserv_read_measured_bandwidths(fname,
4482 NULL, NULL, digest));
4483 tt_mem_op(digest, OP_EQ, digest_expected, DIGEST256_LEN);
4485 done:
4486 unlink(fname);
4487 tor_free(fname);
4488 update_approx_time(time(NULL));
4491 static void
4492 reset_routerstatus(routerstatus_t *rs,
4493 const char *hex_identity_digest,
4494 uint32_t ipv4_addr)
4496 memset(rs, 0, sizeof(routerstatus_t));
4497 base16_decode(rs->identity_digest, sizeof(rs->identity_digest),
4498 hex_identity_digest, HEX_DIGEST_LEN);
4499 /* A zero address matches everything, so the address needs to be set.
4500 * But the specific value is irrelevant. */
4501 tor_addr_from_ipv4h(&rs->ipv4_addr, ipv4_addr);
4504 #define ROUTER_A_ID_STR "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
4505 #define ROUTER_A_IPV4 0xAA008801
4506 #define ROUTER_B_ID_STR "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
4507 #define ROUTER_B_IPV4 0xBB008801
4509 #define ROUTERSET_ALL_STR "*"
4510 #define ROUTERSET_A_STR ROUTER_A_ID_STR
4511 #define ROUTERSET_NONE_STR ""
4514 * Test that dirserv_set_routerstatus_testing sets router flags correctly
4515 * Using "*" sets flags on A and B
4516 * Using "A" sets flags on A
4517 * Using "" sets flags on Neither
4518 * If the router is not included:
4519 * - if *Strict is set, the flag is set to 0,
4520 * - otherwise, the flag is not modified. */
4521 static void
4522 test_dir_dirserv_set_routerstatus_testing(void *arg)
4524 (void)arg;
4526 /* Init options */
4527 dirauth_options_t *dirauth_options =
4528 tor_malloc_zero(sizeof(dirauth_options_t));
4530 mock_options = tor_malloc(sizeof(or_options_t));
4531 reset_options(mock_options, &mock_get_options_calls);
4532 MOCK(get_options, mock_get_options);
4533 dirauth_set_options(dirauth_options);
4535 /* Init routersets */
4536 routerset_t *routerset_all = routerset_new();
4537 routerset_parse(routerset_all, ROUTERSET_ALL_STR, "All routers");
4539 routerset_t *routerset_a = routerset_new();
4540 routerset_parse(routerset_a, ROUTERSET_A_STR, "Router A only");
4542 routerset_t *routerset_none = routerset_new();
4543 /* Routersets are empty when provided by routerset_new(),
4544 * so this is not strictly necessary */
4545 routerset_parse(routerset_none, ROUTERSET_NONE_STR, "No routers");
4547 /* Init routerstatuses */
4548 routerstatus_t *rs_a = tor_malloc(sizeof(routerstatus_t));
4549 reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
4551 routerstatus_t *rs_b = tor_malloc(sizeof(routerstatus_t));
4552 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4554 /* Sanity check that routersets correspond to routerstatuses.
4555 * Return values are {2, 3, 4} */
4557 /* We want 3 ("*" means match all addresses) */
4558 tt_int_op(routerset_contains_routerstatus(routerset_all, rs_a, 0), OP_EQ, 3);
4559 tt_int_op(routerset_contains_routerstatus(routerset_all, rs_b, 0), OP_EQ, 3);
4561 /* We want 4 (match id_digest [or nickname]) */
4562 tt_int_op(routerset_contains_routerstatus(routerset_a, rs_a, 0), OP_EQ, 4);
4563 tt_int_op(routerset_contains_routerstatus(routerset_a, rs_b, 0), OP_EQ, 0);
4565 tt_int_op(routerset_contains_routerstatus(routerset_none, rs_a, 0), OP_EQ,
4567 tt_int_op(routerset_contains_routerstatus(routerset_none, rs_b, 0), OP_EQ,
4570 /* Check that "*" sets flags on all routers: Exit
4571 * Check the flags aren't being confused with each other */
4572 reset_options(mock_options, &mock_get_options_calls);
4573 memset(dirauth_options, 0, sizeof(*dirauth_options));
4574 reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
4575 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4577 dirauth_options->TestingDirAuthVoteExit = routerset_all;
4578 dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
4580 dirserv_set_routerstatus_testing(rs_a);
4581 dirserv_set_routerstatus_testing(rs_b);
4583 tt_uint_op(rs_a->is_exit, OP_EQ, 1);
4584 tt_uint_op(rs_b->is_exit, OP_EQ, 1);
4585 /* Be paranoid - check no other flags are set */
4586 tt_uint_op(rs_a->is_possible_guard, OP_EQ, 0);
4587 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
4588 tt_uint_op(rs_a->is_hs_dir, OP_EQ, 0);
4589 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
4591 /* Check that "*" sets flags on all routers: Guard & HSDir
4592 * Cover the remaining flags in one test */
4593 reset_options(mock_options, &mock_get_options_calls);
4594 memset(dirauth_options, 0, sizeof(*dirauth_options));
4595 reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
4596 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4598 dirauth_options->TestingDirAuthVoteGuard = routerset_all;
4599 dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
4600 dirauth_options->TestingDirAuthVoteHSDir = routerset_all;
4601 dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
4603 dirserv_set_routerstatus_testing(rs_a);
4604 dirserv_set_routerstatus_testing(rs_b);
4606 tt_uint_op(rs_a->is_possible_guard, OP_EQ, 1);
4607 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1);
4608 tt_uint_op(rs_a->is_hs_dir, OP_EQ, 1);
4609 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1);
4610 /* Be paranoid - check exit isn't set */
4611 tt_uint_op(rs_a->is_exit, OP_EQ, 0);
4612 tt_uint_op(rs_b->is_exit, OP_EQ, 0);
4614 /* Check routerset A sets all flags on router A,
4615 * but leaves router B unmodified */
4616 reset_options(mock_options, &mock_get_options_calls);
4617 memset(dirauth_options, 0, sizeof(*dirauth_options));
4618 reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
4619 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4621 dirauth_options->TestingDirAuthVoteExit = routerset_a;
4622 dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
4623 dirauth_options->TestingDirAuthVoteGuard = routerset_a;
4624 dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
4625 dirauth_options->TestingDirAuthVoteHSDir = routerset_a;
4626 dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
4628 dirserv_set_routerstatus_testing(rs_a);
4629 dirserv_set_routerstatus_testing(rs_b);
4631 tt_uint_op(rs_a->is_exit, OP_EQ, 1);
4632 tt_uint_op(rs_b->is_exit, OP_EQ, 0);
4633 tt_uint_op(rs_a->is_possible_guard, OP_EQ, 1);
4634 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
4635 tt_uint_op(rs_a->is_hs_dir, OP_EQ, 1);
4636 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
4638 /* Check routerset A unsets all flags on router B when Strict is set */
4639 reset_options(mock_options, &mock_get_options_calls);
4640 memset(dirauth_options, 0, sizeof(*dirauth_options));
4641 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4643 dirauth_options->TestingDirAuthVoteExit = routerset_a;
4644 dirauth_options->TestingDirAuthVoteExitIsStrict = 1;
4645 dirauth_options->TestingDirAuthVoteGuard = routerset_a;
4646 dirauth_options->TestingDirAuthVoteGuardIsStrict = 1;
4647 dirauth_options->TestingDirAuthVoteHSDir = routerset_a;
4648 dirauth_options->TestingDirAuthVoteHSDirIsStrict = 1;
4650 rs_b->is_exit = 1;
4651 rs_b->is_possible_guard = 1;
4652 rs_b->is_hs_dir = 1;
4654 dirserv_set_routerstatus_testing(rs_b);
4656 tt_uint_op(rs_b->is_exit, OP_EQ, 0);
4657 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
4658 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
4660 /* Check routerset A doesn't modify flags on router B without Strict set */
4661 reset_options(mock_options, &mock_get_options_calls);
4662 memset(dirauth_options, 0, sizeof(*dirauth_options));
4663 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4665 dirauth_options->TestingDirAuthVoteExit = routerset_a;
4666 dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
4667 dirauth_options->TestingDirAuthVoteGuard = routerset_a;
4668 dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
4669 dirauth_options->TestingDirAuthVoteHSDir = routerset_a;
4670 dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
4672 rs_b->is_exit = 1;
4673 rs_b->is_possible_guard = 1;
4674 rs_b->is_hs_dir = 1;
4676 dirserv_set_routerstatus_testing(rs_b);
4678 tt_uint_op(rs_b->is_exit, OP_EQ, 1);
4679 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1);
4680 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1);
4682 /* Check the empty routerset zeroes all flags
4683 * on routers A & B with Strict set */
4684 reset_options(mock_options, &mock_get_options_calls);
4685 memset(dirauth_options, 0, sizeof(*dirauth_options));
4686 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4688 dirauth_options->TestingDirAuthVoteExit = routerset_none;
4689 dirauth_options->TestingDirAuthVoteExitIsStrict = 1;
4690 dirauth_options->TestingDirAuthVoteGuard = routerset_none;
4691 dirauth_options->TestingDirAuthVoteGuardIsStrict = 1;
4692 dirauth_options->TestingDirAuthVoteHSDir = routerset_none;
4693 dirauth_options->TestingDirAuthVoteHSDirIsStrict = 1;
4695 rs_b->is_exit = 1;
4696 rs_b->is_possible_guard = 1;
4697 rs_b->is_hs_dir = 1;
4699 dirserv_set_routerstatus_testing(rs_b);
4701 tt_uint_op(rs_b->is_exit, OP_EQ, 0);
4702 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
4703 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
4705 /* Check the empty routerset doesn't modify any flags
4706 * on A or B without Strict set */
4707 reset_options(mock_options, &mock_get_options_calls);
4708 memset(dirauth_options, 0, sizeof(*dirauth_options));
4709 reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
4710 reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4712 dirauth_options->TestingDirAuthVoteExit = routerset_none;
4713 dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
4714 dirauth_options->TestingDirAuthVoteGuard = routerset_none;
4715 dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
4716 dirauth_options->TestingDirAuthVoteHSDir = routerset_none;
4717 dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
4719 rs_b->is_exit = 1;
4720 rs_b->is_possible_guard = 1;
4721 rs_b->is_hs_dir = 1;
4723 dirserv_set_routerstatus_testing(rs_a);
4724 dirserv_set_routerstatus_testing(rs_b);
4726 tt_uint_op(rs_a->is_exit, OP_EQ, 0);
4727 tt_uint_op(rs_a->is_possible_guard, OP_EQ, 0);
4728 tt_uint_op(rs_a->is_hs_dir, OP_EQ, 0);
4729 tt_uint_op(rs_b->is_exit, OP_EQ, 1);
4730 tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1);
4731 tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1);
4733 done:
4734 tor_free(mock_options);
4735 tor_free(dirauth_options);
4736 mock_options = NULL;
4738 UNMOCK(get_options);
4740 routerset_free(routerset_all);
4741 routerset_free(routerset_a);
4742 routerset_free(routerset_none);
4744 tor_free(rs_a);
4745 tor_free(rs_b);
4748 static void
4749 test_dir_http_handling(void *args)
4751 char *url = NULL;
4752 (void)args;
4754 /* Parse http url tests: */
4755 /* Good headers */
4756 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1\r\n"
4757 "Host: example.com\r\n"
4758 "User-Agent: Mozilla/5.0 (Windows;"
4759 " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
4760 &url),OP_EQ, 0);
4761 tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
4762 tor_free(url);
4764 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.0\r\n", &url),OP_EQ, 0);
4765 tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
4766 tor_free(url);
4768 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.600\r\n", &url),
4769 OP_EQ, 0);
4770 tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
4771 tor_free(url);
4773 /* Should prepend '/tor/' to url if required */
4774 tt_int_op(parse_http_url("GET /a/b/c.txt HTTP/1.1\r\n"
4775 "Host: example.com\r\n"
4776 "User-Agent: Mozilla/5.0 (Windows;"
4777 " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
4778 &url),OP_EQ, 0);
4779 tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
4780 tor_free(url);
4782 /* Bad headers -- no HTTP/1.x*/
4783 tt_int_op(parse_http_url("GET /a/b/c.txt\r\n"
4784 "Host: example.com\r\n"
4785 "User-Agent: Mozilla/5.0 (Windows;"
4786 " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
4787 &url),OP_EQ, -1);
4788 tt_ptr_op(url, OP_EQ, NULL);
4790 /* Bad headers */
4791 tt_int_op(parse_http_url("GET /a/b/c.txt\r\n"
4792 "Host: example.com\r\n"
4793 "User-Agent: Mozilla/5.0 (Windows;"
4794 " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
4795 &url),OP_EQ, -1);
4796 tt_ptr_op(url, OP_EQ, NULL);
4798 tt_int_op(parse_http_url("GET /tor/a/b/c.txt", &url),OP_EQ, -1);
4799 tt_ptr_op(url, OP_EQ, NULL);
4801 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1", &url),OP_EQ, -1);
4802 tt_ptr_op(url, OP_EQ, NULL);
4804 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1x\r\n", &url),
4805 OP_EQ, -1);
4806 tt_ptr_op(url, OP_EQ, NULL);
4808 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.", &url),OP_EQ, -1);
4809 tt_ptr_op(url, OP_EQ, NULL);
4811 tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.\r", &url),OP_EQ, -1);
4812 tt_ptr_op(url, OP_EQ, NULL);
4814 done:
4815 tor_free(url);
4818 static void
4819 test_dir_purpose_needs_anonymity_returns_true_by_default(void *arg)
4821 (void)arg;
4823 #ifdef ALL_BUGS_ARE_FATAL
4824 /* Coverity (and maybe clang analyser) complain that the code following
4825 * tt_skip() is unconditionally unreachable. */
4826 #if !defined(__COVERITY__) && !defined(__clang_analyzer__)
4827 tt_skip();
4828 #endif
4829 #endif /* defined(ALL_BUGS_ARE_FATAL) */
4831 tor_capture_bugs_(1);
4832 setup_full_capture_of_logs(LOG_WARN);
4833 tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, 0, NULL));
4834 tt_int_op(1, OP_EQ, smartlist_len(tor_get_captured_bug_log_()));
4835 expect_single_log_msg_containing("Called with dir_purpose=0");
4837 tor_end_capture_bugs_();
4838 done:
4839 tor_end_capture_bugs_();
4840 teardown_capture_of_logs();
4843 static void
4844 test_dir_purpose_needs_anonymity_returns_true_for_bridges(void *arg)
4846 (void)arg;
4848 tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE, NULL));
4849 tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE,
4850 "foobar"));
4851 done: ;
4854 static void
4855 test_dir_purpose_needs_anonymity_returns_false_for_own_bridge_desc(void *arg)
4857 (void)arg;
4858 tt_int_op(0, OP_EQ, purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC,
4859 ROUTER_PURPOSE_BRIDGE,
4860 "authority.z"));
4861 done: ;
4864 static void
4865 test_dir_purpose_needs_anonymity_ret_false_for_non_sensitive_conn(void *arg)
4867 (void)arg;
4869 tt_int_op(0, OP_EQ, purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_DIR,
4870 ROUTER_PURPOSE_GENERAL, NULL));
4871 tt_int_op(0, OP_EQ,
4872 purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_VOTE, 0, NULL));
4873 tt_int_op(0, OP_EQ,
4874 purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_SIGNATURES, 0, NULL));
4875 tt_int_op(0, OP_EQ,
4876 purpose_needs_anonymity(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL));
4877 tt_int_op(0, OP_EQ, purpose_needs_anonymity(
4878 DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0, NULL));
4879 tt_int_op(0, OP_EQ,
4880 purpose_needs_anonymity(DIR_PURPOSE_FETCH_CONSENSUS, 0, NULL));
4881 tt_int_op(0, OP_EQ,
4882 purpose_needs_anonymity(DIR_PURPOSE_FETCH_CERTIFICATE, 0, NULL));
4883 tt_int_op(0, OP_EQ,
4884 purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC, 0, NULL));
4885 tt_int_op(0, OP_EQ,
4886 purpose_needs_anonymity(DIR_PURPOSE_FETCH_EXTRAINFO, 0, NULL));
4887 tt_int_op(0, OP_EQ,
4888 purpose_needs_anonymity(DIR_PURPOSE_FETCH_MICRODESC, 0, NULL));
4889 done: ;
4892 static void
4893 test_dir_fetch_type(void *arg)
4895 (void)arg;
4897 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_BRIDGE,
4898 NULL), OP_EQ, EXTRAINFO_DIRINFO | BRIDGE_DIRINFO);
4899 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_GENERAL,
4900 NULL), OP_EQ, EXTRAINFO_DIRINFO | V3_DIRINFO);
4902 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_SERVERDESC, ROUTER_PURPOSE_BRIDGE,
4903 NULL), OP_EQ, BRIDGE_DIRINFO);
4904 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_SERVERDESC,
4905 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4907 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_STATUS_VOTE,
4908 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4909 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
4910 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4911 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CERTIFICATE,
4912 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4914 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CONSENSUS, ROUTER_PURPOSE_GENERAL,
4915 "microdesc"), OP_EQ, V3_DIRINFO|MICRODESC_DIRINFO);
4916 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CONSENSUS, ROUTER_PURPOSE_GENERAL,
4917 NULL), OP_EQ, V3_DIRINFO);
4919 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_MICRODESC, ROUTER_PURPOSE_GENERAL,
4920 NULL), OP_EQ, MICRODESC_DIRINFO);
4922 done:
4923 teardown_capture_of_logs();
4926 static void
4927 test_dir_packages(void *arg)
4929 smartlist_t *votes = smartlist_new();
4930 char *res = NULL;
4931 (void)arg;
4933 #define BAD(s) \
4934 tt_int_op(0, OP_EQ, validate_recommended_package_line(s));
4935 #define GOOD(s) \
4936 tt_int_op(1, OP_EQ, validate_recommended_package_line(s));
4937 GOOD("tor 0.2.6.3-alpha "
4938 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
4939 "sha256=sssdlkfjdsklfjdskfljasdklfj");
4940 GOOD("tor 0.2.6.3-alpha "
4941 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
4942 "sha256=sssdlkfjdsklfjdskfljasdklfj blake2b=fred");
4943 BAD("tor 0.2.6.3-alpha "
4944 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
4945 "sha256=sssdlkfjdsklfjdskfljasdklfj=");
4946 BAD("tor 0.2.6.3-alpha "
4947 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
4948 "sha256=sssdlkfjdsklfjdskfljasdklfj blake2b");
4949 BAD("tor 0.2.6.3-alpha "
4950 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz ");
4951 BAD("tor 0.2.6.3-alpha "
4952 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz");
4953 BAD("tor 0.2.6.3-alpha ");
4954 BAD("tor 0.2.6.3-alpha");
4955 BAD("tor ");
4956 BAD("tor");
4957 BAD("");
4958 BAD("=foobar sha256="
4959 "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
4960 BAD("= = sha256="
4961 "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
4963 BAD("sha512= sha256="
4964 "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
4966 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4967 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4968 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4969 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4970 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4971 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4972 SMARTLIST_FOREACH(votes, networkstatus_t *, ns,
4973 ns->package_lines = smartlist_new());
4975 #define ADD(i, s) \
4976 smartlist_add(((networkstatus_t*)smartlist_get(votes, (i)))->package_lines, \
4977 (void*)(s));
4979 /* Only one vote for this one. */
4980 ADD(4, "cisco 99z http://foobar.example.com/ sha256=blahblah");
4982 /* Only two matching entries for this one, but 3 voters */
4983 ADD(1, "mystic 99y http://barfoo.example.com/ sha256=blahblah");
4984 ADD(3, "mystic 99y http://foobar.example.com/ sha256=blahblah");
4985 ADD(4, "mystic 99y http://foobar.example.com/ sha256=blahblah");
4987 /* Only two matching entries for this one, but at least 4 voters */
4988 ADD(1, "mystic 99p http://barfoo.example.com/ sha256=ggggggg");
4989 ADD(3, "mystic 99p http://foobar.example.com/ sha256=blahblah");
4990 ADD(4, "mystic 99p http://foobar.example.com/ sha256=blahblah");
4991 ADD(5, "mystic 99p http://foobar.example.com/ sha256=ggggggg");
4993 /* This one has only invalid votes. */
4994 ADD(0, "haffenreffer 1.2 http://foobar.example.com/ sha256");
4995 ADD(1, "haffenreffer 1.2 http://foobar.example.com/ ");
4996 ADD(2, "haffenreffer 1.2 ");
4997 ADD(3, "haffenreffer ");
4998 ADD(4, "haffenreffer");
5000 /* Three matching votes for this; it should actually go in! */
5001 ADD(2, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
5002 ADD(3, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
5003 ADD(4, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
5004 ADD(1, "element 0.66.1 http://quum.example.com/ sha256=abcdef");
5005 ADD(0, "element 0.66.1 http://quux.example.com/ sha256=abcde");
5007 /* Three votes for A, three votes for B */
5008 ADD(0, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
5009 ADD(1, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
5010 ADD(2, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
5011 ADD(3, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
5012 ADD(4, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
5013 ADD(5, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
5015 /* Three votes for A, two votes for B */
5016 ADD(1, "clownshoes 22alpha3 http://quumble.example.com/ blake2=foob");
5017 ADD(2, "clownshoes 22alpha3 http://quumble.example.com/ blake2=foob");
5018 ADD(3, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
5019 ADD(4, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
5020 ADD(5, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
5022 /* Four votes for A, two for B. */
5023 ADD(0, "clownshoes 22alpha4 http://quumble.example.com/ blake2=foob");
5024 ADD(1, "clownshoes 22alpha4 http://quumble.example.com/ blake2=foob");
5025 ADD(2, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5026 ADD(3, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5027 ADD(4, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5028 ADD(5, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5030 /* Five votes for A ... all from the same authority. Three for B. */
5031 ADD(0, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
5032 ADD(1, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
5033 ADD(3, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
5034 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5035 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5036 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5037 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5038 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5040 /* As above but new replaces old: no two match. */
5041 ADD(0, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
5042 ADD(1, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
5043 ADD(1, "cbc 99.1.11.1.2 http://example.com/cbc/x cubehash=ahooy sha512=m");
5044 ADD(2, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
5045 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5046 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5047 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5048 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5049 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5051 res = compute_consensus_package_lines(votes);
5052 tt_assert(res);
5053 tt_str_op(res, OP_EQ,
5054 "package cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m\n"
5055 "package clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz\n"
5056 "package clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa\n"
5057 "package element 0.66.1 http://quux.example.com/ sha256=abcdef\n"
5058 "package mystic 99y http://foobar.example.com/ sha256=blahblah\n"
5061 #undef ADD
5062 #undef BAD
5063 #undef GOOD
5064 done:
5065 SMARTLIST_FOREACH(votes, networkstatus_t *, ns,
5066 { smartlist_free(ns->package_lines); tor_free(ns); });
5067 smartlist_free(votes);
5068 tor_free(res);
5071 static void
5072 download_status_random_backoff_helper(int min_delay)
5074 download_status_t dls_random =
5075 { 0, 0, 0, DL_SCHED_GENERIC, DL_WANT_AUTHORITY,
5076 DL_SCHED_INCREMENT_FAILURE, 0, 0 };
5077 int increment = -1;
5078 int old_increment = -1;
5079 time_t current_time = time(NULL);
5081 /* Check the random backoff cases */
5082 int n_attempts = 0;
5083 do {
5084 increment = download_status_schedule_get_delay(&dls_random,
5085 min_delay,
5086 current_time);
5088 log_debug(LD_DIR, "Min: %d, Inc: %d, Old Inc: %d",
5089 min_delay, increment, old_increment);
5091 /* Regression test for 20534 and friends
5092 * increment must always increase after the first */
5093 if (dls_random.last_backoff_position > 0) {
5094 /* Always increment the exponential backoff */
5095 tt_int_op(increment, OP_GE, 1);
5098 /* Test */
5099 tt_int_op(increment, OP_GE, min_delay);
5101 /* Advance */
5102 if (dls_random.n_download_attempts < IMPOSSIBLE_TO_DOWNLOAD - 1) {
5103 ++(dls_random.n_download_attempts);
5104 ++(dls_random.n_download_failures);
5107 /* Try another maybe */
5108 old_increment = increment;
5109 } while (++n_attempts < 1000);
5111 done:
5112 return;
5115 static void
5116 test_dir_download_status_random_backoff(void *arg)
5118 (void)arg;
5120 /* Do a standard test */
5121 download_status_random_backoff_helper(0);
5122 /* regression tests for 17750: initial delay */
5123 download_status_random_backoff_helper(10);
5124 download_status_random_backoff_helper(20);
5126 /* Pathological cases */
5127 download_status_random_backoff_helper(INT_MAX/2);
5130 static void
5131 test_dir_download_status_random_backoff_ranges(void *arg)
5133 (void)arg;
5134 int lo, hi;
5135 next_random_exponential_delay_range(&lo, &hi, 0, 10);
5136 tt_int_op(lo, OP_EQ, 10);
5137 tt_int_op(hi, OP_EQ, 11);
5139 next_random_exponential_delay_range(&lo, &hi, 6, 10);
5140 tt_int_op(lo, OP_EQ, 10);
5141 tt_int_op(hi, OP_EQ, 6*3);
5143 next_random_exponential_delay_range(&lo, &hi, 13, 10);
5144 tt_int_op(lo, OP_EQ, 10);
5145 tt_int_op(hi, OP_EQ, 13 * 3);
5147 next_random_exponential_delay_range(&lo, &hi, 37, 10);
5148 tt_int_op(lo, OP_EQ, 10);
5149 tt_int_op(hi, OP_EQ, 111);
5151 next_random_exponential_delay_range(&lo, &hi, 123, 10);
5152 tt_int_op(lo, OP_EQ, 10);
5153 tt_int_op(hi, OP_EQ, 369);
5155 next_random_exponential_delay_range(&lo, &hi, INT_MAX-5, 10);
5156 tt_int_op(lo, OP_EQ, 10);
5157 tt_int_op(hi, OP_EQ, INT_MAX);
5158 done:
5162 static void
5163 test_dir_download_status_increment(void *arg)
5165 (void)arg;
5166 download_status_t dls_exp = { 0, 0, 0, DL_SCHED_GENERIC,
5167 DL_WANT_ANY_DIRSERVER,
5168 DL_SCHED_INCREMENT_ATTEMPT,
5169 0, 0 };
5170 or_options_t test_options;
5171 time_t current_time = time(NULL);
5173 const int delay0 = 10;
5174 const int no_delay = 0;
5175 const int schedule = 10;
5176 const int schedule_no_initial_delay = 0;
5178 /* Put it in the options */
5179 mock_options = &test_options;
5180 reset_options(mock_options, &mock_get_options_calls);
5181 mock_options->TestingBridgeBootstrapDownloadInitialDelay = schedule;
5182 mock_options->TestingClientDownloadInitialDelay = schedule;
5184 MOCK(get_options, mock_get_options);
5186 /* Check that the initial value of the schedule is the first value used,
5187 * whether or not it was reset before being used */
5189 /* regression test for 17750: no initial delay */
5190 mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay;
5191 mock_get_options_calls = 0;
5192 /* we really want to test that it's equal to time(NULL) + delay0, but that's
5193 * an unrealiable test, because time(NULL) might change. */
5195 /* regression test for 17750: exponential, no initial delay */
5196 mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay;
5197 mock_get_options_calls = 0;
5198 /* we really want to test that it's equal to time(NULL) + delay0, but that's
5199 * an unrealiable test, because time(NULL) might change. */
5200 tt_assert(download_status_get_next_attempt_at(&dls_exp)
5201 >= current_time + no_delay);
5202 tt_assert(download_status_get_next_attempt_at(&dls_exp)
5203 != TIME_MAX);
5204 tt_int_op(download_status_get_n_failures(&dls_exp), OP_EQ, 0);
5205 tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0);
5206 tt_int_op(mock_get_options_calls, OP_GE, 1);
5208 /* regression test for 17750: exponential, initial delay */
5209 mock_options->TestingClientDownloadInitialDelay = schedule;
5210 mock_get_options_calls = 0;
5211 /* we really want to test that it's equal to time(NULL) + delay0, but that's
5212 * an unrealiable test, because time(NULL) might change. */
5213 tt_assert(download_status_get_next_attempt_at(&dls_exp)
5214 >= current_time + delay0);
5215 tt_assert(download_status_get_next_attempt_at(&dls_exp)
5216 != TIME_MAX);
5217 tt_int_op(download_status_get_n_failures(&dls_exp), OP_EQ, 0);
5218 tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0);
5219 tt_int_op(mock_get_options_calls, OP_GE, 1);
5221 done:
5222 UNMOCK(get_options);
5223 mock_options = NULL;
5224 mock_get_options_calls = 0;
5225 teardown_capture_of_logs();
5228 static void
5229 test_dir_authdir_type_to_string(void *data)
5231 (void)data;
5232 char *res;
5234 tt_str_op(res = authdir_type_to_string(NO_DIRINFO), OP_EQ,
5235 "[Not an authority]");
5236 tor_free(res);
5238 tt_str_op(res = authdir_type_to_string(EXTRAINFO_DIRINFO), OP_EQ,
5239 "[Not an authority]");
5240 tor_free(res);
5242 tt_str_op(res = authdir_type_to_string(MICRODESC_DIRINFO), OP_EQ,
5243 "[Not an authority]");
5244 tor_free(res);
5246 tt_str_op(res = authdir_type_to_string(V3_DIRINFO), OP_EQ, "V3");
5247 tor_free(res);
5249 tt_str_op(res = authdir_type_to_string(BRIDGE_DIRINFO), OP_EQ, "Bridge");
5250 tor_free(res);
5252 tt_str_op(res = authdir_type_to_string(
5253 V3_DIRINFO | BRIDGE_DIRINFO | EXTRAINFO_DIRINFO), OP_EQ,
5254 "V3, Bridge");
5255 done:
5256 tor_free(res);
5259 static void
5260 test_dir_conn_purpose_to_string(void *data)
5262 (void)data;
5264 #define EXPECT_CONN_PURPOSE(purpose, expected) \
5265 tt_str_op(dir_conn_purpose_to_string(purpose), OP_EQ, expected);
5267 EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_DIR, "server descriptor upload");
5268 EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_VOTE, "server vote upload");
5269 EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_SIGNATURES,
5270 "consensus signature upload");
5271 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_SERVERDESC, "server descriptor fetch");
5272 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_EXTRAINFO, "extra-info fetch");
5273 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_CONSENSUS,
5274 "consensus network-status fetch");
5275 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_CERTIFICATE, "authority cert fetch");
5276 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_STATUS_VOTE, "status vote fetch");
5277 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
5278 "consensus signature fetch");
5279 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_MICRODESC, "microdescriptor fetch");
5281 /* This will give a warning, because there is no purpose 1024. */
5282 setup_full_capture_of_logs(LOG_WARN);
5283 EXPECT_CONN_PURPOSE(1024, "(unknown)");
5284 expect_single_log_msg_containing("Called with unknown purpose 1024");
5286 done:
5287 teardown_capture_of_logs();
5290 static int dir_tests_public_server_mode(const or_options_t *options);
5291 ATTR_UNUSED static int dir_tests_public_server_mode_called = 0;
5293 static int
5294 dir_tests_public_server_mode(const or_options_t *options)
5296 (void)options;
5298 if (dir_tests_public_server_mode_called++ == 0) {
5299 return 1;
5302 return 0;
5305 static void
5306 test_dir_should_use_directory_guards(void *data)
5308 or_options_t *options;
5309 char *errmsg = NULL;
5310 (void)data;
5312 MOCK(public_server_mode,
5313 dir_tests_public_server_mode);
5315 options = options_new();
5316 options_init(options);
5318 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5319 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 1);
5321 options->UseEntryGuards = 1;
5322 options->DownloadExtraInfo = 0;
5323 options->FetchDirInfoEarly = 0;
5324 options->FetchDirInfoExtraEarly = 0;
5325 options->FetchUselessDescriptors = 0;
5326 tt_int_op(should_use_directory_guards(options), OP_EQ, 1);
5327 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 2);
5329 options->UseEntryGuards = 0;
5330 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5331 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 3);
5332 options->UseEntryGuards = 1;
5334 options->DownloadExtraInfo = 1;
5335 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5336 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 4);
5337 options->DownloadExtraInfo = 0;
5339 options->FetchDirInfoEarly = 1;
5340 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5341 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 5);
5342 options->FetchDirInfoEarly = 0;
5344 options->FetchDirInfoExtraEarly = 1;
5345 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5346 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 6);
5347 options->FetchDirInfoExtraEarly = 0;
5349 options->FetchUselessDescriptors = 1;
5350 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5351 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 7);
5352 options->FetchUselessDescriptors = 0;
5354 done:
5355 UNMOCK(public_server_mode);
5356 or_options_free(options);
5357 tor_free(errmsg);
5360 static void dir_tests_directory_initiate_request(directory_request_t *req);
5361 ATTR_UNUSED static int dir_tests_directory_initiate_request_called = 0;
5363 static void
5364 test_dir_should_not_init_request_to_ourselves(void *data)
5366 char digest[DIGEST_LEN];
5367 dir_server_t *ourself = NULL;
5368 crypto_pk_t *key = pk_generate(2);
5369 (void) data;
5371 MOCK(directory_initiate_request,
5372 dir_tests_directory_initiate_request);
5374 clear_dir_servers();
5375 routerlist_free_all();
5377 set_server_identity_key(key);
5378 crypto_pk_get_digest(key, (char*) &digest);
5379 ourself = trusted_dir_server_new("ourself", "127.0.0.1", 9059, 9060,
5380 NULL, digest,
5381 NULL, V3_DIRINFO, 1.0);
5383 tt_assert(ourself);
5384 dir_server_add(ourself);
5386 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
5387 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5389 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
5390 NULL);
5392 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5394 done:
5395 UNMOCK(directory_initiate_request);
5396 clear_dir_servers();
5397 routerlist_free_all();
5398 crypto_pk_free(key);
5401 static void
5402 test_dir_should_not_init_request_to_dir_auths_without_v3_info(void *data)
5404 dir_server_t *ds = NULL;
5405 dirinfo_type_t dirinfo_type = BRIDGE_DIRINFO | EXTRAINFO_DIRINFO \
5406 | MICRODESC_DIRINFO;
5407 (void) data;
5409 MOCK(directory_initiate_request,
5410 dir_tests_directory_initiate_request);
5412 clear_dir_servers();
5413 routerlist_free_all();
5415 ds = trusted_dir_server_new("ds", "10.0.0.1", 9059, 9060, NULL,
5416 "12345678901234567890", NULL, dirinfo_type, 1.0);
5417 tt_assert(ds);
5418 dir_server_add(ds);
5420 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
5421 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5423 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
5424 NULL);
5425 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5427 done:
5428 UNMOCK(directory_initiate_request);
5429 clear_dir_servers();
5430 routerlist_free_all();
5433 static void
5434 test_dir_should_init_request_to_dir_auths(void *data)
5436 dir_server_t *ds = NULL;
5437 (void) data;
5439 MOCK(directory_initiate_request,
5440 dir_tests_directory_initiate_request);
5442 clear_dir_servers();
5443 routerlist_free_all();
5445 ds = trusted_dir_server_new("ds", "10.0.0.1", 9059, 9060, NULL,
5446 "12345678901234567890", NULL, V3_DIRINFO, 1.0);
5447 tt_assert(ds);
5448 dir_server_add(ds);
5450 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
5451 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 1);
5453 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
5454 NULL);
5455 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 2);
5457 done:
5458 UNMOCK(directory_initiate_request);
5459 clear_dir_servers();
5460 routerlist_free_all();
5463 void
5464 dir_tests_directory_initiate_request(directory_request_t *req)
5466 (void)req;
5467 dir_tests_directory_initiate_request_called++;
5471 * Mock check_private_dir(), and always succeed - no need to actually
5472 * look at or create anything on the filesystem.
5475 static int
5476 mock_check_private_dir(const char *dirname, cpd_check_t check,
5477 const char *effective_user)
5479 (void)dirname;
5480 (void)check;
5481 (void)effective_user;
5483 return 0;
5487 * This really mocks options_get_datadir_fname2_suffix(), but for testing
5488 * dump_desc(), we only care about get_datadir_fname(sub1), which is defined
5489 * in config.h as:
5491 * options_get_datadir_fname2_suffix(get_options(), sub1, NULL, NULL)
5494 static char *
5495 mock_get_datadir_fname(const or_options_t *options,
5496 directory_root_t roottype,
5497 const char *sub1, const char *sub2,
5498 const char *suffix)
5500 (void) roottype;
5501 char *rv = NULL;
5504 * Assert we were called like get_datadir_fname2() or get_datadir_fname(),
5505 * since that's all we implement here.
5507 tt_ptr_op(options, OP_NE, NULL);
5508 tt_ptr_op(sub1, OP_NE, NULL);
5510 * No particular assertions about sub2, since we could be in the
5511 * get_datadir_fname() or get_datadir_fname2() case.
5513 tt_ptr_op(suffix, OP_EQ, NULL);
5515 /* Just duplicate the basename and return it for this mock */
5516 if (sub2) {
5517 /* If we have sub2, it's the basename, otherwise sub1 */
5518 rv = tor_strdup(sub2);
5519 } else {
5520 rv = tor_strdup(sub1);
5523 done:
5524 return rv;
5527 static char *last_unlinked_path = NULL;
5528 static int unlinked_count = 0;
5530 static void
5531 mock_unlink_reset(void)
5533 tor_free(last_unlinked_path);
5534 unlinked_count = 0;
5537 static int
5538 mock_unlink(const char *path)
5540 tt_ptr_op(path, OP_NE, NULL);
5542 tor_free(last_unlinked_path);
5543 last_unlinked_path = tor_strdup(path);
5544 ++unlinked_count;
5546 done:
5547 return 0;
5550 static char *last_write_str_path = NULL;
5551 static uint8_t last_write_str_hash[DIGEST256_LEN];
5552 static int write_str_count = 0;
5554 static void
5555 mock_write_str_to_file_reset(void)
5557 tor_free(last_write_str_path);
5558 write_str_count = 0;
5561 static int
5562 mock_write_str_to_file(const char *path, const char *str, int bin)
5564 size_t len;
5565 uint8_t hash[DIGEST256_LEN];
5567 (void)bin;
5569 tt_ptr_op(path, OP_NE, NULL);
5570 tt_ptr_op(str, OP_NE, NULL);
5572 len = strlen(str);
5573 crypto_digest256((char *)hash, str, len, DIGEST_SHA256);
5575 tor_free(last_write_str_path);
5576 last_write_str_path = tor_strdup(path);
5577 memcpy(last_write_str_hash, hash, sizeof(last_write_str_hash));
5578 ++write_str_count;
5580 done:
5581 return 0;
5584 static void
5585 test_dir_dump_unparseable_descriptors(void *data)
5588 * These bogus descriptors look nothing at all like real bogus descriptors
5589 * we might see, but we're only testing dump_desc() here, not the parser.
5591 const char *test_desc_type = "squamous";
5592 /* strlen(test_desc_1) = 583 bytes */
5593 const char *test_desc_1 =
5594 "The most merciful thing in the world, I think, is the inability of the "
5595 "human mind to correlate all its contents. We live on a placid island of"
5596 " ignorance in the midst of black seas of infinity, and it was not meant"
5597 " that we should voyage far. The sciences, each straining in its own dir"
5598 "ection, have hitherto harmed us little; but some day the piecing togeth"
5599 "er of dissociated knowledge will open up such terrifying vistas of real"
5600 "ity, and of our frightful position therein, that we shall either go mad"
5601 "from the revelation or flee from the light into the peace and safety of"
5602 "a new dark age.";
5603 uint8_t test_desc_1_hash[DIGEST256_LEN];
5604 char test_desc_1_hash_str[HEX_DIGEST256_LEN+1];
5605 /* strlen(test_desc_2) = 650 bytes */
5606 const char *test_desc_2 =
5607 "I think their predominant colour was a greyish-green, though they had w"
5608 "hite bellies. They were mostly shiny and slippery, but the ridges of th"
5609 "eir backs were scaly. Their forms vaguely suggested the anthropoid, whi"
5610 "le their heads were the heads of fish, with prodigious bulging eyes tha"
5611 "t never closed. At the sides of their necks were palpitating gills, and"
5612 "their long paws were webbed. They hopped irregularly, sometimes on two "
5613 "legs and sometimes on four. I was somehow glad that they had no more th"
5614 "an four limbs. Their croaking, baying voices, clearly wed tar articulat"
5615 "e speech, held all the dark shades of expression which their staring fa"
5616 "ces lacked.";
5617 uint8_t test_desc_2_hash[DIGEST256_LEN];
5618 char test_desc_2_hash_str[HEX_DIGEST256_LEN+1];
5619 /* strlen(test_desc_3) = 700 bytes */
5620 const char *test_desc_3 =
5621 "Without knowing what futurism is like, Johansen achieved something very"
5622 "close to it when he spoke of the city; for instead of describing any de"
5623 "finite structure or building, he dwells only on broad impressions of va"
5624 "st angles and stone surfaces - surfaces too great to belong to anything"
5625 "right or proper for this earth, and impious with horrible images and hi"
5626 "eroglyphs. I mention his talk about angles because it suggests somethin"
5627 "g Wilcox had told me of his awful dreams. He said that the geometry of "
5628 "the dream-place he saw was abnormal, non-Euclidean, and loathsomely red"
5629 "olent of spheres and dimensions apart from ours. Now an unlettered seam"
5630 "an felt the same thing whilst gazing at the terrible reality.";
5631 uint8_t test_desc_3_hash[DIGEST256_LEN];
5632 char test_desc_3_hash_str[HEX_DIGEST256_LEN+1];
5633 /* strlen(test_desc_3) = 604 bytes */
5634 const char *test_desc_4 =
5635 "So we glanced back simultaneously, it would appear; though no doubt the"
5636 "incipient motion of one prompted the imitation of the other. As we did "
5637 "so we flashed both torches full strength at the momentarily thinned mis"
5638 "t; either from sheer primitive anxiety to see all we could, or in a les"
5639 "s primitive but equally unconscious effort to dazzle the entity before "
5640 "we dimmed our light and dodged among the penguins of the labyrinth cent"
5641 "er ahead. Unhappy act! Not Orpheus himself, or Lot's wife, paid much mo"
5642 "re dearly for a backward glance. And again came that shocking, wide-ran"
5643 "ged piping - \"Tekeli-li! Tekeli-li!\"";
5644 uint8_t test_desc_4_hash[DIGEST256_LEN];
5645 char test_desc_4_hash_str[HEX_DIGEST256_LEN+1];
5646 (void)data;
5649 * Set up options mock so we can force a tiny FIFO size and generate
5650 * cleanups.
5652 mock_options = tor_malloc(sizeof(or_options_t));
5653 reset_options(mock_options, &mock_get_options_calls);
5654 mock_options->MaxUnparseableDescSizeToLog = 1536;
5655 MOCK(get_options, mock_get_options);
5656 MOCK(check_private_dir, mock_check_private_dir);
5657 MOCK(options_get_dir_fname2_suffix,
5658 mock_get_datadir_fname);
5661 * Set up unlink and write mocks
5663 MOCK(tor_unlink, mock_unlink);
5664 mock_unlink_reset();
5665 MOCK(write_str_to_file, mock_write_str_to_file);
5666 mock_write_str_to_file_reset();
5669 * Compute hashes we'll need to recognize which descriptor is which
5671 crypto_digest256((char *)test_desc_1_hash, test_desc_1,
5672 strlen(test_desc_1), DIGEST_SHA256);
5673 base16_encode(test_desc_1_hash_str, sizeof(test_desc_1_hash_str),
5674 (const char *)test_desc_1_hash,
5675 sizeof(test_desc_1_hash));
5676 crypto_digest256((char *)test_desc_2_hash, test_desc_2,
5677 strlen(test_desc_2), DIGEST_SHA256);
5678 base16_encode(test_desc_2_hash_str, sizeof(test_desc_2_hash_str),
5679 (const char *)test_desc_2_hash,
5680 sizeof(test_desc_2_hash));
5681 crypto_digest256((char *)test_desc_3_hash, test_desc_3,
5682 strlen(test_desc_3), DIGEST_SHA256);
5683 base16_encode(test_desc_3_hash_str, sizeof(test_desc_3_hash_str),
5684 (const char *)test_desc_3_hash,
5685 sizeof(test_desc_3_hash));
5686 crypto_digest256((char *)test_desc_4_hash, test_desc_4,
5687 strlen(test_desc_4), DIGEST_SHA256);
5688 base16_encode(test_desc_4_hash_str, sizeof(test_desc_4_hash_str),
5689 (const char *)test_desc_4_hash,
5690 sizeof(test_desc_4_hash));
5693 * Reset the FIFO and check its state
5695 dump_desc_fifo_cleanup();
5696 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5697 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5700 * (1) Fire off dump_desc() once; these descriptors should all be safely
5701 * smaller than configured FIFO size.
5704 dump_desc(test_desc_1, test_desc_type);
5707 * Assert things about the FIFO state
5709 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_1));
5710 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5713 * Assert things about the mocks
5715 tt_int_op(unlinked_count, OP_EQ, 0);
5716 tt_int_op(write_str_count, OP_EQ, 1);
5717 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
5720 * Reset the FIFO and check its state
5722 dump_desc_fifo_cleanup();
5723 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5724 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5727 * Reset the mocks and check their state
5729 mock_unlink_reset();
5730 mock_write_str_to_file_reset();
5731 tt_int_op(unlinked_count, OP_EQ, 0);
5732 tt_int_op(write_str_count, OP_EQ, 0);
5735 * (2) Fire off dump_desc() twice; this still should trigger no cleanup.
5738 /* First time */
5739 dump_desc(test_desc_2, test_desc_type);
5742 * Assert things about the FIFO state
5744 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_2));
5745 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5748 * Assert things about the mocks
5750 tt_int_op(unlinked_count, OP_EQ, 0);
5751 tt_int_op(write_str_count, OP_EQ, 1);
5752 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
5754 /* Second time */
5755 dump_desc(test_desc_3, test_desc_type);
5758 * Assert things about the FIFO state
5760 tt_u64_op(len_descs_dumped, OP_EQ,
5761 strlen(test_desc_2) + strlen(test_desc_3));
5762 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5765 * Assert things about the mocks
5767 tt_int_op(unlinked_count, OP_EQ, 0);
5768 tt_int_op(write_str_count, OP_EQ, 2);
5769 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
5772 * Reset the FIFO and check its state
5774 dump_desc_fifo_cleanup();
5775 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5776 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5779 * Reset the mocks and check their state
5781 mock_unlink_reset();
5782 mock_write_str_to_file_reset();
5783 tt_int_op(unlinked_count, OP_EQ, 0);
5784 tt_int_op(write_str_count, OP_EQ, 0);
5787 * (3) Three calls to dump_desc cause a FIFO cleanup
5790 /* First time */
5791 dump_desc(test_desc_4, test_desc_type);
5794 * Assert things about the FIFO state
5796 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_4));
5797 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5800 * Assert things about the mocks
5802 tt_int_op(unlinked_count, OP_EQ, 0);
5803 tt_int_op(write_str_count, OP_EQ, 1);
5804 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
5806 /* Second time */
5807 dump_desc(test_desc_1, test_desc_type);
5810 * Assert things about the FIFO state
5812 tt_u64_op(len_descs_dumped, OP_EQ,
5813 strlen(test_desc_4) + strlen(test_desc_1));
5814 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5817 * Assert things about the mocks
5819 tt_int_op(unlinked_count, OP_EQ, 0);
5820 tt_int_op(write_str_count, OP_EQ, 2);
5821 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
5823 /* Third time - we should unlink the dump of test_desc_4 here */
5824 dump_desc(test_desc_2, test_desc_type);
5827 * Assert things about the FIFO state
5829 tt_u64_op(len_descs_dumped, OP_EQ,
5830 strlen(test_desc_1) + strlen(test_desc_2));
5831 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5834 * Assert things about the mocks
5836 tt_int_op(unlinked_count, OP_EQ, 1);
5837 tt_int_op(write_str_count, OP_EQ, 3);
5838 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
5841 * Reset the FIFO and check its state
5843 dump_desc_fifo_cleanup();
5844 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5845 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5848 * Reset the mocks and check their state
5850 mock_unlink_reset();
5851 mock_write_str_to_file_reset();
5852 tt_int_op(unlinked_count, OP_EQ, 0);
5853 tt_int_op(write_str_count, OP_EQ, 0);
5856 * (4) But repeating one (A B B) doesn't overflow and cleanup
5859 /* First time */
5860 dump_desc(test_desc_3, test_desc_type);
5863 * Assert things about the FIFO state
5865 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_3));
5866 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5869 * Assert things about the mocks
5871 tt_int_op(unlinked_count, OP_EQ, 0);
5872 tt_int_op(write_str_count, OP_EQ, 1);
5873 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
5875 /* Second time */
5876 dump_desc(test_desc_4, test_desc_type);
5879 * Assert things about the FIFO state
5881 tt_u64_op(len_descs_dumped, OP_EQ,
5882 strlen(test_desc_3) + strlen(test_desc_4));
5883 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5886 * Assert things about the mocks
5888 tt_int_op(unlinked_count, OP_EQ, 0);
5889 tt_int_op(write_str_count, OP_EQ, 2);
5890 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
5892 /* Third time */
5893 dump_desc(test_desc_4, test_desc_type);
5896 * Assert things about the FIFO state
5898 tt_u64_op(len_descs_dumped, OP_EQ,
5899 strlen(test_desc_3) + strlen(test_desc_4));
5900 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5903 * Assert things about the mocks
5905 tt_int_op(unlinked_count, OP_EQ, 0);
5906 tt_int_op(write_str_count, OP_EQ, 2);
5907 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
5910 * Reset the FIFO and check its state
5912 dump_desc_fifo_cleanup();
5913 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5914 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5917 * Reset the mocks and check their state
5919 mock_unlink_reset();
5920 mock_write_str_to_file_reset();
5921 tt_int_op(unlinked_count, OP_EQ, 0);
5922 tt_int_op(write_str_count, OP_EQ, 0);
5925 * (5) Same for the (A B A) repetition
5928 /* First time */
5929 dump_desc(test_desc_1, test_desc_type);
5932 * Assert things about the FIFO state
5934 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_1));
5935 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5938 * Assert things about the mocks
5940 tt_int_op(unlinked_count, OP_EQ, 0);
5941 tt_int_op(write_str_count, OP_EQ, 1);
5942 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
5944 /* Second time */
5945 dump_desc(test_desc_2, test_desc_type);
5948 * Assert things about the FIFO state
5950 tt_u64_op(len_descs_dumped, OP_EQ,
5951 strlen(test_desc_1) + strlen(test_desc_2));
5952 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5955 * Assert things about the mocks
5957 tt_int_op(unlinked_count, OP_EQ, 0);
5958 tt_int_op(write_str_count, OP_EQ, 2);
5959 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
5961 /* Third time */
5962 dump_desc(test_desc_1, test_desc_type);
5965 * Assert things about the FIFO state
5967 tt_u64_op(len_descs_dumped, OP_EQ,
5968 strlen(test_desc_1) + strlen(test_desc_2));
5969 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5972 * Assert things about the mocks
5974 tt_int_op(unlinked_count, OP_EQ, 0);
5975 tt_int_op(write_str_count, OP_EQ, 2);
5976 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
5979 * Reset the FIFO and check its state
5981 dump_desc_fifo_cleanup();
5982 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5983 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5986 * Reset the mocks and check their state
5988 mock_unlink_reset();
5989 mock_write_str_to_file_reset();
5990 tt_int_op(unlinked_count, OP_EQ, 0);
5991 tt_int_op(write_str_count, OP_EQ, 0);
5994 * (6) (A B B C) triggering overflow on C causes A, not B to be unlinked
5997 /* First time */
5998 dump_desc(test_desc_3, test_desc_type);
6001 * Assert things about the FIFO state
6003 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_3));
6004 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
6007 * Assert things about the mocks
6009 tt_int_op(unlinked_count, OP_EQ, 0);
6010 tt_int_op(write_str_count, OP_EQ, 1);
6011 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
6013 /* Second time */
6014 dump_desc(test_desc_4, test_desc_type);
6017 * Assert things about the FIFO state
6019 tt_u64_op(len_descs_dumped, OP_EQ,
6020 strlen(test_desc_3) + strlen(test_desc_4));
6021 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6024 * Assert things about the mocks
6026 tt_int_op(unlinked_count, OP_EQ, 0);
6027 tt_int_op(write_str_count, OP_EQ, 2);
6028 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
6030 /* Third time */
6031 dump_desc(test_desc_4, test_desc_type);
6034 * Assert things about the FIFO state
6036 tt_u64_op(len_descs_dumped, OP_EQ,
6037 strlen(test_desc_3) + strlen(test_desc_4));
6038 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6041 * Assert things about the mocks
6043 tt_int_op(unlinked_count, OP_EQ, 0);
6044 tt_int_op(write_str_count, OP_EQ, 2);
6045 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
6047 /* Fourth time - we should unlink the dump of test_desc_3 here */
6048 dump_desc(test_desc_1, test_desc_type);
6051 * Assert things about the FIFO state
6053 tt_u64_op(len_descs_dumped, OP_EQ,
6054 strlen(test_desc_4) + strlen(test_desc_1));
6055 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6058 * Assert things about the mocks
6060 tt_int_op(unlinked_count, OP_EQ, 1);
6061 tt_int_op(write_str_count, OP_EQ, 3);
6062 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
6065 * Reset the FIFO and check its state
6067 dump_desc_fifo_cleanup();
6068 tt_u64_op(len_descs_dumped, OP_EQ, 0);
6069 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
6072 * Reset the mocks and check their state
6074 mock_unlink_reset();
6075 mock_write_str_to_file_reset();
6076 tt_int_op(unlinked_count, OP_EQ, 0);
6077 tt_int_op(write_str_count, OP_EQ, 0);
6080 * (7) (A B A C) triggering overflow on C causes B, not A to be unlinked
6083 /* First time */
6084 dump_desc(test_desc_2, test_desc_type);
6087 * Assert things about the FIFO state
6089 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_2));
6090 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
6093 * Assert things about the mocks
6095 tt_int_op(unlinked_count, OP_EQ, 0);
6096 tt_int_op(write_str_count, OP_EQ, 1);
6097 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
6099 /* Second time */
6100 dump_desc(test_desc_3, test_desc_type);
6103 * Assert things about the FIFO state
6105 tt_u64_op(len_descs_dumped, OP_EQ,
6106 strlen(test_desc_2) + strlen(test_desc_3));
6107 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6110 * Assert things about the mocks
6112 tt_int_op(unlinked_count, OP_EQ, 0);
6113 tt_int_op(write_str_count, OP_EQ, 2);
6114 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
6116 /* Third time */
6117 dump_desc(test_desc_2, test_desc_type);
6120 * Assert things about the FIFO state
6122 tt_u64_op(len_descs_dumped, OP_EQ,
6123 strlen(test_desc_2) + strlen(test_desc_3));
6124 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6127 * Assert things about the mocks
6129 tt_int_op(unlinked_count, OP_EQ, 0);
6130 tt_int_op(write_str_count, OP_EQ, 2);
6131 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
6133 /* Fourth time - we should unlink the dump of test_desc_3 here */
6134 dump_desc(test_desc_4, test_desc_type);
6137 * Assert things about the FIFO state
6139 tt_u64_op(len_descs_dumped, OP_EQ,
6140 strlen(test_desc_2) + strlen(test_desc_4));
6141 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6144 * Assert things about the mocks
6146 tt_int_op(unlinked_count, OP_EQ, 1);
6147 tt_int_op(write_str_count, OP_EQ, 3);
6148 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
6151 * Reset the FIFO and check its state
6153 dump_desc_fifo_cleanup();
6154 tt_u64_op(len_descs_dumped, OP_EQ, 0);
6155 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
6158 * Reset the mocks and check their state
6160 mock_unlink_reset();
6161 mock_write_str_to_file_reset();
6162 tt_int_op(unlinked_count, OP_EQ, 0);
6163 tt_int_op(write_str_count, OP_EQ, 0);
6165 done:
6167 /* Clean up the fifo */
6168 dump_desc_fifo_cleanup();
6170 /* Remove mocks */
6171 UNMOCK(tor_unlink);
6172 mock_unlink_reset();
6173 UNMOCK(write_str_to_file);
6174 mock_write_str_to_file_reset();
6175 UNMOCK(options_get_dir_fname2_suffix);
6176 UNMOCK(check_private_dir);
6177 UNMOCK(get_options);
6178 tor_free(mock_options);
6179 mock_options = NULL;
6181 return;
6184 /* Variables for reset_read_file_to_str_mock() */
6186 static int enforce_expected_filename = 0;
6187 static char *expected_filename = NULL;
6188 static char *file_content = NULL;
6189 static size_t file_content_len = 0;
6190 static struct stat file_stat;
6191 static int read_count = 0, read_call_count = 0;
6193 static void
6194 reset_read_file_to_str_mock(void)
6196 tor_free(expected_filename);
6197 tor_free(file_content);
6198 file_content_len = 0;
6199 memset(&file_stat, 0, sizeof(file_stat));
6200 read_count = 0;
6201 read_call_count = 0;
6204 static char *
6205 read_file_to_str_mock(const char *filename, int flags,
6206 struct stat *stat_out) {
6207 char *result = NULL;
6209 /* Insist we got a filename */
6210 tt_ptr_op(filename, OP_NE, NULL);
6212 /* We ignore flags */
6213 (void)flags;
6215 /* Bump the call count */
6216 ++read_call_count;
6218 if (enforce_expected_filename) {
6219 tt_assert(expected_filename);
6220 tt_str_op(filename, OP_EQ, expected_filename);
6223 if (expected_filename != NULL &&
6224 file_content != NULL &&
6225 strcmp(filename, expected_filename) == 0) {
6226 /* You asked for it, you got it */
6229 * This is the same behavior as the real read_file_to_str();
6230 * if there's a NUL, the real size ends up in stat_out.
6232 result = tor_malloc(file_content_len + 1);
6233 if (file_content_len > 0) {
6234 memcpy(result, file_content, file_content_len);
6236 result[file_content_len] = '\0';
6238 /* Do we need to set up stat_out? */
6239 if (stat_out != NULL) {
6240 memcpy(stat_out, &file_stat, sizeof(file_stat));
6241 /* We always return the correct length here */
6242 stat_out->st_size = file_content_len;
6245 /* Wooo, we have a return value - bump the counter */
6246 ++read_count;
6248 /* else no match, return NULL */
6250 done:
6251 return result;
6254 /* This one tests dump_desc_populate_one_file() */
6255 static void
6256 test_dir_populate_dump_desc_fifo(void *data)
6258 const char *dirname = "foo";
6259 const char *fname = NULL;
6260 dumped_desc_t *ent;
6262 (void)data;
6265 * Set up unlink and read_file_to_str mocks
6267 MOCK(tor_unlink, mock_unlink);
6268 mock_unlink_reset();
6269 MOCK(read_file_to_str, read_file_to_str_mock);
6270 reset_read_file_to_str_mock();
6272 /* Check state of unlink mock */
6273 tt_int_op(unlinked_count, OP_EQ, 0);
6275 /* Some cases that should fail before trying to read the file */
6276 ent = dump_desc_populate_one_file(dirname, "bar");
6277 tt_ptr_op(ent, OP_EQ, NULL);
6278 tt_int_op(unlinked_count, OP_EQ, 1);
6279 tt_int_op(read_count, OP_EQ, 0);
6280 tt_int_op(read_call_count, OP_EQ, 0);
6282 ent = dump_desc_populate_one_file(dirname, "unparseable-desc");
6283 tt_ptr_op(ent, OP_EQ, NULL);
6284 tt_int_op(unlinked_count, OP_EQ, 2);
6285 tt_int_op(read_count, OP_EQ, 0);
6286 tt_int_op(read_call_count, OP_EQ, 0);
6288 ent = dump_desc_populate_one_file(dirname, "unparseable-desc.baz");
6289 tt_ptr_op(ent, OP_EQ, NULL);
6290 tt_int_op(unlinked_count, OP_EQ, 3);
6291 tt_int_op(read_count, OP_EQ, 0);
6292 tt_int_op(read_call_count, OP_EQ, 0);
6294 ent = dump_desc_populate_one_file(
6295 dirname,
6296 "unparseable-desc.08AE85E90461F59E");
6297 tt_ptr_op(ent, OP_EQ, NULL);
6298 tt_int_op(unlinked_count, OP_EQ, 4);
6299 tt_int_op(read_count, OP_EQ, 0);
6300 tt_int_op(read_call_count, OP_EQ, 0);
6302 ent = dump_desc_populate_one_file(
6303 dirname,
6304 "unparseable-desc.08AE85E90461F59EDF0981323F3A70D02B55AB54B44B04F"
6305 "287D72F7B72F242E85C8CB0EDA8854A99");
6306 tt_ptr_op(ent, OP_EQ, NULL);
6307 tt_int_op(unlinked_count, OP_EQ, 5);
6308 tt_int_op(read_count, OP_EQ, 0);
6309 tt_int_op(read_call_count, OP_EQ, 0);
6311 /* This is a correct-length digest but base16_decode() will fail */
6312 ent = dump_desc_populate_one_file(
6313 dirname,
6314 "unparseable-desc.68219B8BGE64B705A6FFC728C069DC596216D60A7D7520C"
6315 "D5ECE250D912E686B");
6316 tt_ptr_op(ent, OP_EQ, NULL);
6317 tt_int_op(unlinked_count, OP_EQ, 6);
6318 tt_int_op(read_count, OP_EQ, 0);
6319 tt_int_op(read_call_count, OP_EQ, 0);
6321 /* This one has a correctly formed filename and should try reading */
6323 /* Read fails */
6324 ent = dump_desc_populate_one_file(
6325 dirname,
6326 "unparseable-desc.DF0981323F3A70D02B55AB54B44B04F287D72F7B72F242E"
6327 "85C8CB0EDA8854A99");
6328 tt_ptr_op(ent, OP_EQ, NULL);
6329 tt_int_op(unlinked_count, OP_EQ, 7);
6330 tt_int_op(read_count, OP_EQ, 0);
6331 tt_int_op(read_call_count, OP_EQ, 1);
6333 /* This read will succeed but the digest won't match the file content */
6334 fname =
6335 "unparseable-desc."
6336 "DF0981323F3A70D02B55AB54B44B04F287D72F7B72F242E85C8CB0EDA8854A99";
6337 enforce_expected_filename = 1;
6338 tor_asprintf(&expected_filename, "%s%s%s", dirname, PATH_SEPARATOR, fname);
6339 file_content = tor_strdup("hanc culpam maiorem an illam dicam?");
6340 file_content_len = strlen(file_content);
6341 file_stat.st_mtime = 123456;
6342 ent = dump_desc_populate_one_file(dirname, fname);
6343 enforce_expected_filename = 0;
6344 tt_ptr_op(ent, OP_EQ, NULL);
6345 tt_int_op(unlinked_count, OP_EQ, 8);
6346 tt_int_op(read_count, OP_EQ, 1);
6347 tt_int_op(read_call_count, OP_EQ, 2);
6348 tor_free(expected_filename);
6349 tor_free(file_content);
6351 /* This one will match */
6352 fname =
6353 "unparseable-desc."
6354 "0786C7173447B7FB033FFCA2FC47C3CF71C30DD47CA8236D3FC7FF35853271C6";
6355 tor_asprintf(&expected_filename, "%s%s%s", dirname, PATH_SEPARATOR, fname);
6356 file_content = tor_strdup("hanc culpam maiorem an illam dicam?");
6357 file_content_len = strlen(file_content);
6358 file_stat.st_mtime = 789012;
6359 ent = dump_desc_populate_one_file(dirname, fname);
6360 tt_ptr_op(ent, OP_NE, NULL);
6361 tt_int_op(unlinked_count, OP_EQ, 8);
6362 tt_int_op(read_count, OP_EQ, 2);
6363 tt_int_op(read_call_count, OP_EQ, 3);
6364 tt_str_op(ent->filename, OP_EQ, expected_filename);
6365 tt_int_op(ent->len, OP_EQ, file_content_len);
6366 tt_int_op(ent->when, OP_EQ, file_stat.st_mtime);
6367 tor_free(ent->filename);
6368 tor_free(ent);
6369 tor_free(expected_filename);
6372 * Reset the mocks and check their state
6374 mock_unlink_reset();
6375 tt_int_op(unlinked_count, OP_EQ, 0);
6376 reset_read_file_to_str_mock();
6377 tt_int_op(read_count, OP_EQ, 0);
6379 done:
6381 UNMOCK(tor_unlink);
6382 mock_unlink_reset();
6383 UNMOCK(read_file_to_str);
6384 reset_read_file_to_str_mock();
6386 tor_free(file_content);
6388 return;
6391 static smartlist_t *
6392 listdir_mock(const char *dname)
6394 smartlist_t *l;
6396 /* Ignore the name, always return this list */
6397 (void)dname;
6399 l = smartlist_new();
6400 smartlist_add_strdup(l, "foo");
6401 smartlist_add_strdup(l, "bar");
6402 smartlist_add_strdup(l, "baz");
6404 return l;
6407 static dumped_desc_t *
6408 pop_one_mock(const char *dirname, const char *f)
6410 dumped_desc_t *ent = NULL;
6412 if (dirname != NULL && strcmp(dirname, "d") == 0) {
6413 if (f != NULL && strcmp(f, "foo") == 0) {
6414 ent = tor_malloc_zero(sizeof(*ent));
6415 ent->filename = tor_strdup("d/foo");
6416 ent->len = 123;
6417 ent->digest_sha256[0] = 1;
6418 ent->when = 1024;
6419 } else if (f != NULL && strcmp(f, "bar") == 0) {
6420 ent = tor_malloc_zero(sizeof(*ent));
6421 ent->filename = tor_strdup("d/bar");
6422 ent->len = 456;
6423 ent->digest_sha256[0] = 2;
6425 * Note that the timestamps are in a different order than
6426 * listdir_mock() returns; we're testing the sort order.
6428 ent->when = 512;
6429 } else if (f != NULL && strcmp(f, "baz") == 0) {
6430 ent = tor_malloc_zero(sizeof(*ent));
6431 ent->filename = tor_strdup("d/baz");
6432 ent->len = 789;
6433 ent->digest_sha256[0] = 3;
6434 ent->when = 768;
6438 return ent;
6441 /* This one tests dump_desc_populate_fifo_from_directory() */
6442 static void
6443 test_dir_populate_dump_desc_fifo_2(void *data)
6445 dumped_desc_t *ent = NULL;
6447 (void)data;
6449 /* Set up the mocks */
6450 MOCK(tor_listdir, listdir_mock);
6451 MOCK(dump_desc_populate_one_file, pop_one_mock);
6453 /* Run dump_desc_populate_fifo_from_directory() */
6454 descs_dumped = NULL;
6455 len_descs_dumped = 0;
6456 dump_desc_populate_fifo_from_directory("d");
6457 tt_assert(descs_dumped != NULL);
6458 tt_int_op(smartlist_len(descs_dumped), OP_EQ, 3);
6459 tt_u64_op(len_descs_dumped, OP_EQ, 1368);
6460 ent = smartlist_get(descs_dumped, 0);
6461 tt_str_op(ent->filename, OP_EQ, "d/bar");
6462 tt_int_op(ent->len, OP_EQ, 456);
6463 tt_int_op(ent->when, OP_EQ, 512);
6464 ent = smartlist_get(descs_dumped, 1);
6465 tt_str_op(ent->filename, OP_EQ, "d/baz");
6466 tt_int_op(ent->len, OP_EQ, 789);
6467 tt_int_op(ent->when, OP_EQ, 768);
6468 ent = smartlist_get(descs_dumped, 2);
6469 tt_str_op(ent->filename, OP_EQ, "d/foo");
6470 tt_int_op(ent->len, OP_EQ, 123);
6471 tt_int_op(ent->when, OP_EQ, 1024);
6473 done:
6474 dump_desc_fifo_cleanup();
6476 UNMOCK(dump_desc_populate_one_file);
6477 UNMOCK(tor_listdir);
6479 return;
6482 static int mock_networkstatus_consensus_is_bootstrapping_value = 0;
6483 static int
6484 mock_networkstatus_consensus_is_bootstrapping(time_t now)
6486 (void)now;
6487 return mock_networkstatus_consensus_is_bootstrapping_value;
6490 static int mock_networkstatus_consensus_can_use_extra_fallbacks_value = 0;
6491 static int
6492 mock_networkstatus_consensus_can_use_extra_fallbacks(
6493 const or_options_t *options)
6495 (void)options;
6496 return mock_networkstatus_consensus_can_use_extra_fallbacks_value;
6499 static int mock_num_bridges_usable_value = 0;
6500 static int
6501 mock_num_bridges_usable(int use_maybe_reachable)
6503 (void)use_maybe_reachable;
6504 return mock_num_bridges_usable_value;
6507 /* data is a 3 character nul-terminated string.
6508 * If data[0] is 'b', set bootstrapping, anything else means not bootstrapping
6509 * If data[1] is 'f', set extra fallbacks, anything else means no extra
6510 * If data[2] is 'f', set running bridges, anything else means no extra
6511 * fallbacks.
6513 static void
6514 test_dir_find_dl_min_delay(void* data)
6516 const char *str = (const char *)data;
6518 tt_assert(strlen(data) == 3);
6520 if (str[0] == 'b') {
6521 mock_networkstatus_consensus_is_bootstrapping_value = 1;
6522 } else {
6523 mock_networkstatus_consensus_is_bootstrapping_value = 0;
6526 if (str[1] == 'f') {
6527 mock_networkstatus_consensus_can_use_extra_fallbacks_value = 1;
6528 } else {
6529 mock_networkstatus_consensus_can_use_extra_fallbacks_value = 0;
6532 if (str[2] == 'r') {
6533 /* Any positive, non-zero value should work */
6534 mock_num_bridges_usable_value = 2;
6535 } else {
6536 mock_num_bridges_usable_value = 0;
6539 MOCK(networkstatus_consensus_is_bootstrapping,
6540 mock_networkstatus_consensus_is_bootstrapping);
6541 MOCK(networkstatus_consensus_can_use_extra_fallbacks,
6542 mock_networkstatus_consensus_can_use_extra_fallbacks);
6543 MOCK(num_bridges_usable,
6544 mock_num_bridges_usable);
6546 download_status_t dls;
6548 const int server=10, client=20, server_cons=30, client_cons=40;
6549 const int client_boot_auth_only_cons=50, client_boot_auth_cons=60;
6550 const int client_boot_fallback_cons=70, bridge=80, bridge_bootstrap=90;
6552 mock_options = tor_malloc(sizeof(or_options_t));
6553 reset_options(mock_options, &mock_get_options_calls);
6554 MOCK(get_options, mock_get_options);
6556 mock_options->TestingServerDownloadInitialDelay = server;
6557 mock_options->TestingClientDownloadInitialDelay = client;
6558 mock_options->TestingServerConsensusDownloadInitialDelay = server_cons;
6559 mock_options->TestingClientConsensusDownloadInitialDelay = client_cons;
6560 mock_options->ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay =
6561 client_boot_auth_only_cons;
6562 mock_options->ClientBootstrapConsensusAuthorityDownloadInitialDelay =
6563 client_boot_auth_cons;
6564 mock_options->ClientBootstrapConsensusFallbackDownloadInitialDelay =
6565 client_boot_fallback_cons;
6566 mock_options->TestingBridgeDownloadInitialDelay = bridge;
6567 mock_options->TestingBridgeBootstrapDownloadInitialDelay = bridge_bootstrap;
6569 dls.schedule = DL_SCHED_GENERIC;
6570 /* client */
6571 mock_options->ClientOnly = 1;
6572 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, client);
6573 mock_options->ClientOnly = 0;
6575 /* dir mode */
6576 mock_options->DirPort_set = 1;
6577 mock_options->DirCache = 1;
6578 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server);
6579 mock_options->DirPort_set = 0;
6580 mock_options->DirCache = 0;
6582 dls.schedule = DL_SCHED_CONSENSUS;
6583 /* public server mode */
6584 mock_options->ORPort_set = 1;
6585 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server_cons);
6586 mock_options->ORPort_set = 0;
6588 /* client and bridge modes */
6589 if (networkstatus_consensus_is_bootstrapping(time(NULL))) {
6590 if (networkstatus_consensus_can_use_extra_fallbacks(mock_options)) {
6591 dls.want_authority = 1;
6592 /* client */
6593 mock_options->ClientOnly = 1;
6594 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6595 client_boot_auth_cons);
6596 mock_options->ClientOnly = 0;
6598 /* bridge relay */
6599 mock_options->ORPort_set = 1;
6600 mock_options->BridgeRelay = 1;
6601 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6602 client_boot_auth_cons);
6603 mock_options->ORPort_set = 0;
6604 mock_options->BridgeRelay = 0;
6606 dls.want_authority = 0;
6607 /* client */
6608 mock_options->ClientOnly = 1;
6609 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6610 client_boot_fallback_cons);
6611 mock_options->ClientOnly = 0;
6613 /* bridge relay */
6614 mock_options->ORPort_set = 1;
6615 mock_options->BridgeRelay = 1;
6616 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6617 client_boot_fallback_cons);
6618 mock_options->ORPort_set = 0;
6619 mock_options->BridgeRelay = 0;
6621 } else {
6622 /* dls.want_authority is ignored */
6623 /* client */
6624 mock_options->ClientOnly = 1;
6625 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6626 client_boot_auth_only_cons);
6627 mock_options->ClientOnly = 0;
6629 /* bridge relay */
6630 mock_options->ORPort_set = 1;
6631 mock_options->BridgeRelay = 1;
6632 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6633 client_boot_auth_only_cons);
6634 mock_options->ORPort_set = 0;
6635 mock_options->BridgeRelay = 0;
6637 } else {
6638 /* client */
6639 mock_options->ClientOnly = 1;
6640 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6641 client_cons);
6642 mock_options->ClientOnly = 0;
6644 /* bridge relay */
6645 mock_options->ORPort_set = 1;
6646 mock_options->BridgeRelay = 1;
6647 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6648 client_cons);
6649 mock_options->ORPort_set = 0;
6650 mock_options->BridgeRelay = 0;
6653 dls.schedule = DL_SCHED_BRIDGE;
6654 /* client */
6655 mock_options->ClientOnly = 1;
6656 mock_options->UseBridges = 1;
6657 if (num_bridges_usable(0) > 0) {
6658 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge);
6659 } else {
6660 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge_bootstrap);
6663 done:
6664 UNMOCK(networkstatus_consensus_is_bootstrapping);
6665 UNMOCK(networkstatus_consensus_can_use_extra_fallbacks);
6666 UNMOCK(num_bridges_usable);
6667 UNMOCK(get_options);
6668 tor_free(mock_options);
6669 mock_options = NULL;
6672 static void
6673 test_dir_matching_flags(void *arg)
6675 (void) arg;
6676 routerstatus_t *rs_noflags = NULL;
6677 routerstatus_t *rs = NULL;
6678 char *s = NULL;
6680 smartlist_t *tokens = smartlist_new();
6681 memarea_t *area = memarea_new();
6683 int expected_val_when_unused = 0;
6685 const char *ex_noflags =
6686 "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 "
6687 "192.168.0.1 9001 0\n"
6688 "m thisoneislongerbecauseitisa256bitmddigest33\n"
6689 "s\n"
6690 "pr Link=4\n";
6691 const char *cp = ex_noflags;
6692 rs_noflags = routerstatus_parse_entry_from_string(
6693 area, &cp,
6694 cp + strlen(cp),
6695 tokens, NULL, NULL,
6696 MAX_SUPPORTED_CONSENSUS_METHOD, FLAV_MICRODESC);
6697 tt_assert(rs_noflags);
6699 #define FLAG(string, field) STMT_BEGIN { \
6700 tor_asprintf(&s,\
6701 "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 " \
6702 "192.168.0.1 9001 0\n" \
6703 "m thisoneislongerbecauseitisa256bitmddigest33\n" \
6704 "pr Link=4\n" \
6705 "s %s\n", string); \
6706 cp = s; \
6707 rs = routerstatus_parse_entry_from_string( \
6708 area, &cp, \
6709 cp + strlen(cp), \
6710 tokens, NULL, NULL, \
6711 MAX_SUPPORTED_CONSENSUS_METHOD, FLAV_MICRODESC); \
6712 /* the field should usually be 0 when no flags are listed */ \
6713 tt_int_op(rs_noflags->field, OP_EQ, expected_val_when_unused); \
6714 /* the field should be 1 when this flags islisted */ \
6715 tt_int_op(rs->field, OP_EQ, 1); \
6716 tor_free(s); \
6717 routerstatus_free(rs); \
6718 } STMT_END
6720 FLAG("Authority", is_authority);
6721 FLAG("BadExit", is_bad_exit);
6722 FLAG("Exit", is_exit);
6723 FLAG("Fast", is_fast);
6724 FLAG("Guard", is_possible_guard);
6725 FLAG("HSDir", is_hs_dir);
6726 FLAG("Stable", is_stable);
6727 FLAG("StaleDesc", is_staledesc);
6728 FLAG("V2Dir", is_v2_dir);
6730 // These flags are assumed to be set whether they're declared or not.
6731 expected_val_when_unused = 1;
6732 FLAG("Running", is_flagged_running);
6733 FLAG("Valid", is_valid);
6734 expected_val_when_unused = 0;
6736 // These flags are no longer used, but still parsed.
6737 FLAG("Named", is_named);
6738 FLAG("Unnamed", is_unnamed);
6740 done:
6741 tor_free(s);
6742 routerstatus_free(rs);
6743 routerstatus_free(rs_noflags);
6744 memarea_drop_all(area);
6745 smartlist_free(tokens);
6748 static void
6749 test_dir_assumed_flags(void *arg)
6751 (void)arg;
6752 smartlist_t *tokens = smartlist_new();
6753 memarea_t *area = memarea_new();
6754 routerstatus_t *rs = NULL;
6756 /* We can assume that consensus method is higher than 24, so Running and
6757 * Valid are always implicitly set */
6758 const char *str1 =
6759 "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 "
6760 "192.168.0.1 9001 0\n"
6761 "m thisoneislongerbecauseitisa256bitmddigest33\n"
6762 "s Fast Guard Stable\n"
6763 "pr Link=4\n";
6764 const char *eos = str1 + strlen(str1);
6766 const char *cp = str1;
6767 rs = routerstatus_parse_entry_from_string(area, &cp, eos, tokens, NULL, NULL,
6768 24, FLAV_MICRODESC);
6769 tt_assert(rs);
6770 tt_assert(rs->is_flagged_running);
6771 tt_assert(rs->is_valid);
6772 tt_assert(! rs->is_exit);
6773 tt_assert(rs->is_fast);
6775 done:
6776 smartlist_free(tokens);
6777 memarea_drop_all(area);
6778 routerstatus_free(rs);
6781 static void
6782 test_dir_post_parsing(void *arg)
6784 (void) arg;
6786 /* Test the version parsing from an HS descriptor publish request. */
6788 const char *end;
6789 const char *prefix = "/tor/hs/";
6790 int version = parse_hs_version_from_post("/tor/hs//publish", prefix, &end);
6791 tt_int_op(version, OP_EQ, -1);
6792 tt_ptr_op(end, OP_EQ, NULL);
6793 version = parse_hs_version_from_post("/tor/hs/a/publish", prefix, &end);
6794 tt_int_op(version, OP_EQ, -1);
6795 tt_ptr_op(end, OP_EQ, NULL);
6796 version = parse_hs_version_from_post("/tor/hs/3/publish", prefix, &end);
6797 tt_int_op(version, OP_EQ, 3);
6798 tt_str_op(end, OP_EQ, "/publish");
6799 version = parse_hs_version_from_post("/tor/hs/42/publish", prefix, &end);
6800 tt_int_op(version, OP_EQ, 42);
6801 tt_str_op(end, OP_EQ, "/publish");
6802 version = parse_hs_version_from_post("/tor/hs/18163/publish",prefix, &end);
6803 tt_int_op(version, OP_EQ, 18163);
6804 tt_str_op(end, OP_EQ, "/publish");
6805 version = parse_hs_version_from_post("JUNKJUNKJUNK", prefix, &end);
6806 tt_int_op(version, OP_EQ, -1);
6807 tt_ptr_op(end, OP_EQ, NULL);
6808 version = parse_hs_version_from_post("/tor/hs/3/publish", "blah", &end);
6809 tt_int_op(version, OP_EQ, -1);
6810 tt_ptr_op(end, OP_EQ, NULL);
6811 /* Missing the '/' at the end of the prefix. */
6812 version = parse_hs_version_from_post("/tor/hs/3/publish", "/tor/hs", &end);
6813 tt_int_op(version, OP_EQ, -1);
6814 tt_ptr_op(end, OP_EQ, NULL);
6815 version = parse_hs_version_from_post("/random/blah/tor/hs/3/publish",
6816 prefix, &end);
6817 tt_int_op(version, OP_EQ, -1);
6818 tt_ptr_op(end, OP_EQ, NULL);
6819 version = parse_hs_version_from_post("/tor/hs/3/publish/random/junk",
6820 prefix, &end);
6821 tt_int_op(version, OP_EQ, 3);
6822 tt_str_op(end, OP_EQ, "/publish/random/junk");
6823 version = parse_hs_version_from_post("/tor/hs/-1/publish", prefix, &end);
6824 tt_int_op(version, OP_EQ, -1);
6825 tt_ptr_op(end, OP_EQ, NULL);
6826 /* INT_MAX */
6827 version = parse_hs_version_from_post("/tor/hs/2147483647/publish",
6828 prefix, &end);
6829 tt_int_op(version, OP_EQ, INT_MAX);
6830 tt_str_op(end, OP_EQ, "/publish");
6831 /* INT_MAX + 1*/
6832 version = parse_hs_version_from_post("/tor/hs/2147483648/publish",
6833 prefix, &end);
6834 tt_int_op(version, OP_EQ, -1);
6835 tt_ptr_op(end, OP_EQ, NULL);
6838 done:
6842 static void
6843 test_dir_platform_str(void *arg)
6845 char platform[256];
6846 (void)arg;
6847 platform[0] = 0;
6848 get_platform_str(platform, sizeof(platform));
6849 tt_int_op((int)strlen(platform), OP_GT, 0);
6850 tt_assert(!strcmpstart(platform, "Tor "));
6852 tor_version_t ver;
6853 // make sure this is a tor version, a real actual tor version.
6854 tt_int_op(tor_version_parse_platform(platform, &ver, 1), OP_EQ, 1);
6856 TT_BLATHER(("%d.%d.%d.%d", ver.major, ver.minor, ver.micro, ver.patchlevel));
6858 // Handle an example version.
6859 tt_int_op(tor_version_parse_platform(
6860 "Tor 0.3.3.3 (foo) (git-xyzzy) on a potato", &ver, 1), OP_EQ, 1);
6861 done:
6865 static void
6866 test_dir_format_versions_list(void *arg)
6868 (void)arg;
6869 char *s = NULL;
6870 config_line_t *lines = NULL;
6872 setup_capture_of_logs(LOG_WARN);
6873 s = format_recommended_version_list(lines, 1);
6874 tt_str_op(s, OP_EQ, "");
6876 tor_free(s);
6877 config_line_append(&lines, "ignored", "0.3.4.1, 0.2.9.111-alpha, 4.4.4-rc");
6878 s = format_recommended_version_list(lines, 1);
6879 tt_str_op(s, OP_EQ, "0.2.9.111-alpha,0.3.4.1,4.4.4-rc");
6881 tor_free(s);
6882 config_line_append(&lines, "ignored", "0.1.2.3,0.2.9.10 ");
6883 s = format_recommended_version_list(lines, 1);
6884 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");
6886 /* There should be no warnings so far. */
6887 expect_no_log_entry();
6889 /* Now try a line with a space in it. */
6890 tor_free(s);
6891 config_line_append(&lines, "ignored", "1.3.3.8 1.3.3.7");
6892 s = format_recommended_version_list(lines, 1);
6893 tt_str_op(s, OP_EQ, "0.1.2.3,0.2.9.10,0.2.9.111-alpha,0.3.4.1,"
6894 "1.3.3.7,1.3.3.8,4.4.4-rc");
6896 expect_single_log_msg_containing(
6897 "Unexpected space in versions list member \"1.3.3.8 1.3.3.7\"." );
6899 /* Start over, with a line containing a bogus version */
6900 config_free_lines(lines);
6901 lines = NULL;
6902 tor_free(s);
6903 mock_clean_saved_logs();
6904 config_line_append(&lines, "ignored", "0.1.2.3, alpha-complex, 0.1.1.8-rc");
6905 s = format_recommended_version_list(lines,1);
6906 tt_str_op(s, OP_EQ, "0.1.1.8-rc,0.1.2.3,alpha-complex");
6907 expect_single_log_msg_containing(
6908 "Recommended version \"alpha-complex\" does not look valid.");
6910 done:
6911 tor_free(s);
6912 config_free_lines(lines);
6913 teardown_capture_of_logs();
6916 static void
6917 test_dir_add_fingerprint(void *arg)
6919 (void)arg;
6920 authdir_config_t *list;
6921 int ret;
6922 ed25519_secret_key_t seckey;
6923 ed25519_public_key_t pubkey_good, pubkey_bad;
6925 authdir_init_fingerprint_list();
6926 list = authdir_return_fingerprint_list();
6928 setup_capture_of_logs(LOG_WARN);
6930 /* RSA test - successful */
6931 ret = add_rsa_fingerprint_to_dir("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
6932 list, 0);
6933 tt_int_op(ret, OP_EQ, 0);
6935 /* RSA test - failure */
6936 ret = add_rsa_fingerprint_to_dir("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
6937 list, 0);
6938 tt_int_op(ret, OP_EQ, -1);
6940 /* ed25519 test - successful */
6941 ed25519_secret_key_generate(&seckey, 0);
6942 ed25519_public_key_generate(&pubkey_good, &seckey);
6944 ret = add_ed25519_to_dir(&pubkey_good, list, 0);
6945 tt_int_op(ret, OP_EQ, 0);
6947 /* ed25519 test - failure */
6948 digest256_from_base64((char *) pubkey_bad.pubkey, "gibberish");
6950 ret = add_ed25519_to_dir(&pubkey_bad, list, 0);
6951 tt_int_op(ret, OP_EQ, -1);
6953 done:
6954 teardown_capture_of_logs();
6955 dirserv_free_fingerprint_list();
6958 static void
6959 test_dir_dirserv_load_fingerprint_file(void *arg)
6961 (void)arg;
6962 char *fname = tor_strdup(get_fname("approved-routers"));
6964 // Neither RSA nor ed25519
6965 const char *router_lines_invalid =
6966 "!badexit notafingerprint";
6967 const char *router_lines_too_long =
6968 "!badexit thisisareallylongstringthatislongerthanafingerprint\n";
6969 const char *router_lines_bad_fmt_str =
6970 "!badexit ABCDEFGH|%1$p|%2$p|%3$p|%4$p|%5$p|%6$p\n";
6971 const char *router_lines_valid_rsa =
6972 "!badexit AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n";
6973 const char *router_lines_invalid_rsa =
6974 "!badexit ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\n";
6975 const char *router_lines_valid_ed25519 =
6976 "!badexit wqfLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx/Q\n";
6977 const char *router_lines_invalid_ed25519 =
6978 "!badexit --fLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx--\n";
6980 // Test: Invalid Fingerprint (not RSA or ed25519)
6981 setup_capture_of_logs(LOG_NOTICE);
6982 write_str_to_file(fname, router_lines_invalid, 0);
6983 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
6984 expect_log_msg_containing("Invalid fingerprint");
6985 teardown_capture_of_logs();
6987 // Test: Very long string (longer than RSA or ed25519 key)
6988 setup_capture_of_logs(LOG_NOTICE);
6989 write_str_to_file(fname, router_lines_too_long, 0);
6990 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
6991 expect_log_msg_containing("Invalid fingerprint");
6992 teardown_capture_of_logs();
6994 // Test: Format string exploit
6995 setup_capture_of_logs(LOG_NOTICE);
6996 write_str_to_file(fname, router_lines_bad_fmt_str, 0);
6997 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
6998 expect_log_msg_containing("Invalid fingerprint");
6999 teardown_capture_of_logs();
7001 // Test: Valid RSA
7002 setup_capture_of_logs(LOG_NOTICE);
7003 write_str_to_file(fname, router_lines_valid_rsa, 0);
7004 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7005 teardown_capture_of_logs();
7007 // Test: Invalid RSA
7008 setup_capture_of_logs(LOG_NOTICE);
7009 write_str_to_file(fname, router_lines_invalid_rsa, 0);
7010 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7011 expect_log_msg_containing("Invalid fingerprint");
7012 teardown_capture_of_logs();
7014 // Test: Valid ed25519
7015 setup_capture_of_logs(LOG_NOTICE);
7016 write_str_to_file(fname, router_lines_valid_ed25519, 0);
7017 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7018 teardown_capture_of_logs();
7020 // Test: Invalid ed25519
7021 setup_capture_of_logs(LOG_NOTICE);
7022 write_str_to_file(fname, router_lines_invalid_ed25519, 0);
7023 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7024 expect_log_msg_containing("Invalid fingerprint");
7025 teardown_capture_of_logs();
7027 done:
7028 tor_free(fname);
7029 dirserv_free_fingerprint_list();
7032 #define RESET_FP_LIST(list) STMT_BEGIN \
7033 dirserv_free_fingerprint_list(); \
7034 authdir_init_fingerprint_list(); \
7035 list = authdir_return_fingerprint_list(); \
7036 STMT_END
7038 static void
7039 test_dir_dirserv_router_get_status(void *arg)
7041 authdir_config_t *list;
7042 routerinfo_t *ri = NULL;
7043 ed25519_keypair_t kp1, kp2;
7044 char d[DIGEST_LEN];
7045 char fp[HEX_DIGEST_LEN+1];
7046 int ret;
7047 const char *msg;
7048 time_t now = time(NULL);
7050 (void)arg;
7052 crypto_pk_t *pk = pk_generate(0);
7054 authdir_init_fingerprint_list();
7055 list = authdir_return_fingerprint_list();
7057 /* Set up the routerinfo */
7058 ri = tor_malloc_zero(sizeof(routerinfo_t));
7059 tor_addr_from_ipv4h(&ri->ipv4_addr, 0xc0a80001u);
7060 ri->ipv4_orport = 9001;
7061 ri->platform = tor_strdup("0.4.0.1-alpha");
7062 ri->nickname = tor_strdup("Jessica");
7063 ri->identity_pkey = crypto_pk_dup_key(pk);
7065 curve25519_keypair_t ri_onion_keypair;
7066 curve25519_keypair_generate(&ri_onion_keypair, 0);
7067 ri->onion_curve25519_pkey = tor_memdup(&ri_onion_keypair.pubkey,
7068 sizeof(curve25519_public_key_t));
7070 ed25519_secret_key_from_seed(&kp1.seckey,
7071 (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
7072 ed25519_public_key_generate(&kp1.pubkey, &kp1.seckey);
7073 ed25519_secret_key_from_seed(&kp2.seckey,
7074 (const uint8_t*)"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
7075 ed25519_public_key_generate(&kp2.pubkey, &kp2.seckey);
7076 ri->cache_info.signing_key_cert = tor_cert_create_ed25519(&kp1,
7077 CERT_TYPE_ID_SIGNING,
7078 &kp2.pubkey,
7079 now, 86400,
7080 CERT_FLAG_INCLUDE_SIGNING_KEY);
7082 crypto_pk_get_digest(ri->identity_pkey, d);
7083 base16_encode(fp, HEX_DIGEST_LEN + 1, d, DIGEST_LEN);
7085 /* Try on an empty fingerprint list */
7086 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7087 tt_int_op(ret, OP_EQ, 0);
7088 RESET_FP_LIST(list);
7090 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7091 tt_int_op(ret, OP_EQ, 0);
7092 RESET_FP_LIST(list);
7094 /* Try an accepted router */
7095 add_rsa_fingerprint_to_dir(fp, list, 0);
7096 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7097 tt_int_op(ret, OP_EQ, 0);
7098 RESET_FP_LIST(list);
7100 add_ed25519_to_dir(&kp1.pubkey, list, 0);
7101 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7102 tt_int_op(ret, OP_EQ, 0);
7103 RESET_FP_LIST(list);
7105 /* Try a rejected router */
7106 add_rsa_fingerprint_to_dir(fp, list, RTR_REJECT);
7107 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7108 tt_int_op(ret, OP_EQ, RTR_REJECT);
7109 RESET_FP_LIST(list);
7111 add_ed25519_to_dir(&kp1.pubkey, list, RTR_REJECT);
7112 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7113 tt_int_op(ret, OP_EQ, RTR_REJECT);
7114 RESET_FP_LIST(list);
7116 done:
7117 dirserv_free_fingerprint_list();
7118 routerinfo_free(ri);
7119 crypto_pk_free(pk);
7122 static void
7123 test_dir_dirserv_would_reject_router(void *arg)
7125 authdir_config_t *list;
7126 routerstatus_t rs;
7127 vote_routerstatus_t vrs;
7128 ed25519_keypair_t kp;
7129 char fp[HEX_DIGEST_LEN+1];
7131 (void)arg;
7133 authdir_init_fingerprint_list();
7134 list = authdir_return_fingerprint_list();
7136 /* Set up the routerstatus */
7137 memset(&rs, 0, sizeof(rs));
7138 tor_addr_from_ipv4h(&rs.ipv4_addr, 0xc0a80001u);
7139 rs.ipv4_orport = 9001;
7140 strlcpy(rs.nickname, "Nicole", sizeof(rs.nickname));
7141 memcpy(rs.identity_digest, "Cloud nine is great ", DIGEST_LEN);
7143 ed25519_secret_key_from_seed(&kp.seckey,
7144 (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
7145 ed25519_public_key_generate(&kp.pubkey, &kp.seckey);
7147 base16_encode(fp, HEX_DIGEST_LEN + 1, rs.identity_digest, DIGEST_LEN);
7149 /* Setup the vote_routerstatus_t. */
7150 memcpy(vrs.ed25519_id, &kp.pubkey, ED25519_PUBKEY_LEN);
7152 /* Try an empty fingerprint list */
7153 tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7154 RESET_FP_LIST(list);
7156 tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7157 RESET_FP_LIST(list);
7159 /* Try an accepted router */
7160 add_rsa_fingerprint_to_dir(fp, list, 0);
7161 tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7162 RESET_FP_LIST(list);
7164 add_ed25519_to_dir(&kp.pubkey, list, 0);
7165 tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7166 RESET_FP_LIST(list);
7168 /* Try a rejected router */
7169 add_rsa_fingerprint_to_dir(fp, list, RTR_REJECT);
7170 tt_assert(dirserv_would_reject_router(&rs, &vrs));
7171 RESET_FP_LIST(list);
7173 add_ed25519_to_dir(&kp.pubkey, list, RTR_REJECT);
7174 tt_assert(dirserv_would_reject_router(&rs, &vrs));
7175 RESET_FP_LIST(list);
7177 done:
7178 dirserv_free_fingerprint_list();
7181 static void
7182 test_dir_dirserv_add_own_fingerprint(void *arg)
7184 authdir_config_t *list;
7185 char digest[DIGEST_LEN];
7186 crypto_pk_t *pk = pk_generate(0);
7188 (void)arg;
7190 init_mock_ed_keys(pk);
7191 authdir_init_fingerprint_list();
7192 list = authdir_return_fingerprint_list();
7193 dirserv_add_own_fingerprint(pk, get_master_identity_key());
7195 /* Check if we have a RSA key. */
7196 crypto_pk_get_digest(pk, digest);
7197 tt_assert(digestmap_get(list->status_by_digest, digest));
7199 /* Check if we have a ed25519 key. */
7200 tt_assert(digest256map_get(list->status_by_digest256,
7201 get_master_identity_key()->pubkey));
7203 RESET_FP_LIST(list);
7205 done:
7206 dirserv_free_fingerprint_list();
7207 crypto_pk_free(pk);
7210 #ifndef COCCI
7211 #define DIR_LEGACY(name) \
7212 { #name, test_dir_ ## name , TT_FORK, NULL, NULL }
7214 #define DIR(name,flags) \
7215 { #name, test_dir_##name, (flags), NULL, NULL }
7217 /* where arg is a string constant */
7218 #define DIR_ARG(name,flags,arg) \
7219 { #name "_" arg, test_dir_##name, (flags), &passthrough_setup, (void*) arg }
7220 #endif /* !defined(COCCI) */
7222 struct testcase_t dir_tests[] = {
7223 DIR_LEGACY(nicknames),
7224 /* extrainfo without any stats */
7225 DIR_ARG(formats_rsa_ed25519, TT_FORK, ""),
7226 /* on a bridge */
7227 DIR_ARG(formats_rsa_ed25519, TT_FORK, "b"),
7228 /* extrainfo with basic stats */
7229 DIR_ARG(formats_rsa_ed25519, TT_FORK, "e"),
7230 DIR_ARG(formats_rsa_ed25519, TT_FORK, "be"),
7231 /* extrainfo with all stats */
7232 DIR_ARG(formats_rsa_ed25519, TT_FORK, "es"),
7233 DIR_ARG(formats_rsa_ed25519, TT_FORK, "bes"),
7234 DIR(routerinfo_parsing, 0),
7235 DIR(extrainfo_parsing, 0),
7236 DIR(parse_router_list, TT_FORK),
7237 DIR(load_routers, TT_FORK),
7238 DIR(load_extrainfo, TT_FORK),
7239 DIR(getinfo_extra, 0),
7240 DIR_LEGACY(versions),
7241 DIR_LEGACY(fp_pairs),
7242 DIR(split_fps, 0),
7243 DIR_LEGACY(measured_bw_kb),
7244 DIR_LEGACY(measured_bw_kb_line_is_after_headers),
7245 DIR_LEGACY(measured_bw_kb_cache),
7246 DIR_LEGACY(dirserv_read_measured_bandwidths),
7247 DIR(bwauth_bw_file_digest256, 0),
7248 DIR_LEGACY(param_voting),
7249 DIR(param_voting_lookup, 0),
7250 DIR_LEGACY(v3_networkstatus),
7251 DIR(random_weighted, 0),
7252 DIR(scale_bw, 0),
7253 DIR_LEGACY(clip_unmeasured_bw_kb),
7254 DIR_LEGACY(clip_unmeasured_bw_kb_alt),
7255 DIR(fmt_control_ns, 0),
7256 DIR(dirserv_set_routerstatus_testing, TT_FORK),
7257 DIR(http_handling, 0),
7258 DIR(purpose_needs_anonymity_returns_true_for_bridges, 0),
7259 DIR(purpose_needs_anonymity_returns_false_for_own_bridge_desc, 0),
7260 DIR(purpose_needs_anonymity_returns_true_by_default, 0),
7261 DIR(purpose_needs_anonymity_ret_false_for_non_sensitive_conn, 0),
7262 DIR(post_parsing, 0),
7263 DIR(fetch_type, 0),
7264 DIR(packages, 0),
7265 DIR(download_status_random_backoff, 0),
7266 DIR(download_status_random_backoff_ranges, 0),
7267 DIR(download_status_increment, TT_FORK),
7268 DIR(authdir_type_to_string, 0),
7269 DIR(conn_purpose_to_string, 0),
7270 DIR(should_use_directory_guards, 0),
7271 DIR(should_not_init_request_to_ourselves, TT_FORK),
7272 DIR(should_not_init_request_to_dir_auths_without_v3_info, 0),
7273 DIR(should_init_request_to_dir_auths, 0),
7274 DIR(dump_unparseable_descriptors, 0),
7275 DIR(populate_dump_desc_fifo, 0),
7276 DIR(populate_dump_desc_fifo_2, 0),
7277 DIR_ARG(find_dl_min_delay, TT_FORK, "bfd"),
7278 DIR_ARG(find_dl_min_delay, TT_FORK, "bad"),
7279 DIR_ARG(find_dl_min_delay, TT_FORK, "cfd"),
7280 DIR_ARG(find_dl_min_delay, TT_FORK, "cad"),
7281 DIR_ARG(find_dl_min_delay, TT_FORK, "bfr"),
7282 DIR_ARG(find_dl_min_delay, TT_FORK, "bar"),
7283 DIR_ARG(find_dl_min_delay, TT_FORK, "cfr"),
7284 DIR_ARG(find_dl_min_delay, TT_FORK, "car"),
7285 DIR(assumed_flags, 0),
7286 DIR(matching_flags, 0),
7287 DIR(networkstatus_compute_bw_weights_v10, 0),
7288 DIR(platform_str, 0),
7289 DIR(format_versions_list, TT_FORK),
7290 DIR(add_fingerprint, TT_FORK),
7291 DIR(dirserv_load_fingerprint_file, TT_FORK),
7292 DIR(dirserv_router_get_status, TT_FORK),
7293 DIR(dirserv_would_reject_router, TT_FORK),
7294 DIR(dirserv_add_own_fingerprint, TT_FORK),
7295 END_OF_TESTCASES