Merge branch 'maint-0.4.5' into release-0.4.5
[tor.git] / src / test / test_dir.c
blobd62dd3fb9ec855bbcd1efde52ce5612a72aa96f5
1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2020, 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 tt_int_op(1, OP_EQ,
4852 purpose_needs_anonymity(DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2,
4853 ROUTER_PURPOSE_BRIDGE, NULL));
4854 done: ;
4857 static void
4858 test_dir_purpose_needs_anonymity_returns_false_for_own_bridge_desc(void *arg)
4860 (void)arg;
4861 tt_int_op(0, OP_EQ, purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC,
4862 ROUTER_PURPOSE_BRIDGE,
4863 "authority.z"));
4864 done: ;
4867 static void
4868 test_dir_purpose_needs_anonymity_returns_true_for_sensitive_purpose(void *arg)
4870 (void)arg;
4872 tt_int_op(1, OP_EQ, purpose_needs_anonymity(
4873 DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2,
4874 ROUTER_PURPOSE_GENERAL, NULL));
4875 tt_int_op(1, OP_EQ, purpose_needs_anonymity(
4876 DIR_PURPOSE_UPLOAD_RENDDESC_V2, 0, NULL));
4877 tt_int_op(1, OP_EQ, purpose_needs_anonymity(
4878 DIR_PURPOSE_FETCH_RENDDESC_V2, 0, NULL));
4879 done: ;
4882 static void
4883 test_dir_purpose_needs_anonymity_ret_false_for_non_sensitive_conn(void *arg)
4885 (void)arg;
4887 tt_int_op(0, OP_EQ, purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_DIR,
4888 ROUTER_PURPOSE_GENERAL, NULL));
4889 tt_int_op(0, OP_EQ,
4890 purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_VOTE, 0, NULL));
4891 tt_int_op(0, OP_EQ,
4892 purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_SIGNATURES, 0, NULL));
4893 tt_int_op(0, OP_EQ,
4894 purpose_needs_anonymity(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL));
4895 tt_int_op(0, OP_EQ, purpose_needs_anonymity(
4896 DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0, NULL));
4897 tt_int_op(0, OP_EQ,
4898 purpose_needs_anonymity(DIR_PURPOSE_FETCH_CONSENSUS, 0, NULL));
4899 tt_int_op(0, OP_EQ,
4900 purpose_needs_anonymity(DIR_PURPOSE_FETCH_CERTIFICATE, 0, NULL));
4901 tt_int_op(0, OP_EQ,
4902 purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC, 0, NULL));
4903 tt_int_op(0, OP_EQ,
4904 purpose_needs_anonymity(DIR_PURPOSE_FETCH_EXTRAINFO, 0, NULL));
4905 tt_int_op(0, OP_EQ,
4906 purpose_needs_anonymity(DIR_PURPOSE_FETCH_MICRODESC, 0, NULL));
4907 done: ;
4910 static void
4911 test_dir_fetch_type(void *arg)
4913 (void)arg;
4915 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_BRIDGE,
4916 NULL), OP_EQ, EXTRAINFO_DIRINFO | BRIDGE_DIRINFO);
4917 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_GENERAL,
4918 NULL), OP_EQ, EXTRAINFO_DIRINFO | V3_DIRINFO);
4920 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_SERVERDESC, ROUTER_PURPOSE_BRIDGE,
4921 NULL), OP_EQ, BRIDGE_DIRINFO);
4922 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_SERVERDESC,
4923 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4925 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_STATUS_VOTE,
4926 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4927 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
4928 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4929 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CERTIFICATE,
4930 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4932 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CONSENSUS, ROUTER_PURPOSE_GENERAL,
4933 "microdesc"), OP_EQ, V3_DIRINFO|MICRODESC_DIRINFO);
4934 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CONSENSUS, ROUTER_PURPOSE_GENERAL,
4935 NULL), OP_EQ, V3_DIRINFO);
4937 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_MICRODESC, ROUTER_PURPOSE_GENERAL,
4938 NULL), OP_EQ, MICRODESC_DIRINFO);
4940 /* This will give a warning, because this function isn't supposed to be
4941 * used for HS descriptors. */
4942 setup_full_capture_of_logs(LOG_WARN);
4943 tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_RENDDESC_V2,
4944 ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, NO_DIRINFO);
4945 expect_single_log_msg_containing("Unexpected purpose");
4946 done:
4947 teardown_capture_of_logs();
4950 static void
4951 test_dir_packages(void *arg)
4953 smartlist_t *votes = smartlist_new();
4954 char *res = NULL;
4955 (void)arg;
4957 #define BAD(s) \
4958 tt_int_op(0, OP_EQ, validate_recommended_package_line(s));
4959 #define GOOD(s) \
4960 tt_int_op(1, OP_EQ, validate_recommended_package_line(s));
4961 GOOD("tor 0.2.6.3-alpha "
4962 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
4963 "sha256=sssdlkfjdsklfjdskfljasdklfj");
4964 GOOD("tor 0.2.6.3-alpha "
4965 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
4966 "sha256=sssdlkfjdsklfjdskfljasdklfj blake2b=fred");
4967 BAD("tor 0.2.6.3-alpha "
4968 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
4969 "sha256=sssdlkfjdsklfjdskfljasdklfj=");
4970 BAD("tor 0.2.6.3-alpha "
4971 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
4972 "sha256=sssdlkfjdsklfjdskfljasdklfj blake2b");
4973 BAD("tor 0.2.6.3-alpha "
4974 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz ");
4975 BAD("tor 0.2.6.3-alpha "
4976 "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz");
4977 BAD("tor 0.2.6.3-alpha ");
4978 BAD("tor 0.2.6.3-alpha");
4979 BAD("tor ");
4980 BAD("tor");
4981 BAD("");
4982 BAD("=foobar sha256="
4983 "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
4984 BAD("= = sha256="
4985 "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
4987 BAD("sha512= sha256="
4988 "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
4990 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4991 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4992 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4993 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4994 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4995 smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4996 SMARTLIST_FOREACH(votes, networkstatus_t *, ns,
4997 ns->package_lines = smartlist_new());
4999 #define ADD(i, s) \
5000 smartlist_add(((networkstatus_t*)smartlist_get(votes, (i)))->package_lines, \
5001 (void*)(s));
5003 /* Only one vote for this one. */
5004 ADD(4, "cisco 99z http://foobar.example.com/ sha256=blahblah");
5006 /* Only two matching entries for this one, but 3 voters */
5007 ADD(1, "mystic 99y http://barfoo.example.com/ sha256=blahblah");
5008 ADD(3, "mystic 99y http://foobar.example.com/ sha256=blahblah");
5009 ADD(4, "mystic 99y http://foobar.example.com/ sha256=blahblah");
5011 /* Only two matching entries for this one, but at least 4 voters */
5012 ADD(1, "mystic 99p http://barfoo.example.com/ sha256=ggggggg");
5013 ADD(3, "mystic 99p http://foobar.example.com/ sha256=blahblah");
5014 ADD(4, "mystic 99p http://foobar.example.com/ sha256=blahblah");
5015 ADD(5, "mystic 99p http://foobar.example.com/ sha256=ggggggg");
5017 /* This one has only invalid votes. */
5018 ADD(0, "haffenreffer 1.2 http://foobar.example.com/ sha256");
5019 ADD(1, "haffenreffer 1.2 http://foobar.example.com/ ");
5020 ADD(2, "haffenreffer 1.2 ");
5021 ADD(3, "haffenreffer ");
5022 ADD(4, "haffenreffer");
5024 /* Three matching votes for this; it should actually go in! */
5025 ADD(2, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
5026 ADD(3, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
5027 ADD(4, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
5028 ADD(1, "element 0.66.1 http://quum.example.com/ sha256=abcdef");
5029 ADD(0, "element 0.66.1 http://quux.example.com/ sha256=abcde");
5031 /* Three votes for A, three votes for B */
5032 ADD(0, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
5033 ADD(1, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
5034 ADD(2, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
5035 ADD(3, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
5036 ADD(4, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
5037 ADD(5, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
5039 /* Three votes for A, two votes for B */
5040 ADD(1, "clownshoes 22alpha3 http://quumble.example.com/ blake2=foob");
5041 ADD(2, "clownshoes 22alpha3 http://quumble.example.com/ blake2=foob");
5042 ADD(3, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
5043 ADD(4, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
5044 ADD(5, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
5046 /* Four votes for A, two for B. */
5047 ADD(0, "clownshoes 22alpha4 http://quumble.example.com/ blake2=foob");
5048 ADD(1, "clownshoes 22alpha4 http://quumble.example.com/ blake2=foob");
5049 ADD(2, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5050 ADD(3, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5051 ADD(4, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5052 ADD(5, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5054 /* Five votes for A ... all from the same authority. Three for B. */
5055 ADD(0, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
5056 ADD(1, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
5057 ADD(3, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
5058 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5059 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5060 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5061 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5062 ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5064 /* As above but new replaces old: no two match. */
5065 ADD(0, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
5066 ADD(1, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
5067 ADD(1, "cbc 99.1.11.1.2 http://example.com/cbc/x cubehash=ahooy sha512=m");
5068 ADD(2, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
5069 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5070 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5071 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5072 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5073 ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5075 res = compute_consensus_package_lines(votes);
5076 tt_assert(res);
5077 tt_str_op(res, OP_EQ,
5078 "package cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m\n"
5079 "package clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz\n"
5080 "package clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa\n"
5081 "package element 0.66.1 http://quux.example.com/ sha256=abcdef\n"
5082 "package mystic 99y http://foobar.example.com/ sha256=blahblah\n"
5085 #undef ADD
5086 #undef BAD
5087 #undef GOOD
5088 done:
5089 SMARTLIST_FOREACH(votes, networkstatus_t *, ns,
5090 { smartlist_free(ns->package_lines); tor_free(ns); });
5091 smartlist_free(votes);
5092 tor_free(res);
5095 static void
5096 download_status_random_backoff_helper(int min_delay)
5098 download_status_t dls_random =
5099 { 0, 0, 0, DL_SCHED_GENERIC, DL_WANT_AUTHORITY,
5100 DL_SCHED_INCREMENT_FAILURE, 0, 0 };
5101 int increment = -1;
5102 int old_increment = -1;
5103 time_t current_time = time(NULL);
5105 /* Check the random backoff cases */
5106 int n_attempts = 0;
5107 do {
5108 increment = download_status_schedule_get_delay(&dls_random,
5109 min_delay,
5110 current_time);
5112 log_debug(LD_DIR, "Min: %d, Inc: %d, Old Inc: %d",
5113 min_delay, increment, old_increment);
5115 /* Regression test for 20534 and friends
5116 * increment must always increase after the first */
5117 if (dls_random.last_backoff_position > 0) {
5118 /* Always increment the exponential backoff */
5119 tt_int_op(increment, OP_GE, 1);
5122 /* Test */
5123 tt_int_op(increment, OP_GE, min_delay);
5125 /* Advance */
5126 if (dls_random.n_download_attempts < IMPOSSIBLE_TO_DOWNLOAD - 1) {
5127 ++(dls_random.n_download_attempts);
5128 ++(dls_random.n_download_failures);
5131 /* Try another maybe */
5132 old_increment = increment;
5133 } while (++n_attempts < 1000);
5135 done:
5136 return;
5139 static void
5140 test_dir_download_status_random_backoff(void *arg)
5142 (void)arg;
5144 /* Do a standard test */
5145 download_status_random_backoff_helper(0);
5146 /* regression tests for 17750: initial delay */
5147 download_status_random_backoff_helper(10);
5148 download_status_random_backoff_helper(20);
5150 /* Pathological cases */
5151 download_status_random_backoff_helper(INT_MAX/2);
5154 static void
5155 test_dir_download_status_random_backoff_ranges(void *arg)
5157 (void)arg;
5158 int lo, hi;
5159 next_random_exponential_delay_range(&lo, &hi, 0, 10);
5160 tt_int_op(lo, OP_EQ, 10);
5161 tt_int_op(hi, OP_EQ, 11);
5163 next_random_exponential_delay_range(&lo, &hi, 6, 10);
5164 tt_int_op(lo, OP_EQ, 10);
5165 tt_int_op(hi, OP_EQ, 6*3);
5167 next_random_exponential_delay_range(&lo, &hi, 13, 10);
5168 tt_int_op(lo, OP_EQ, 10);
5169 tt_int_op(hi, OP_EQ, 13 * 3);
5171 next_random_exponential_delay_range(&lo, &hi, 37, 10);
5172 tt_int_op(lo, OP_EQ, 10);
5173 tt_int_op(hi, OP_EQ, 111);
5175 next_random_exponential_delay_range(&lo, &hi, 123, 10);
5176 tt_int_op(lo, OP_EQ, 10);
5177 tt_int_op(hi, OP_EQ, 369);
5179 next_random_exponential_delay_range(&lo, &hi, INT_MAX-5, 10);
5180 tt_int_op(lo, OP_EQ, 10);
5181 tt_int_op(hi, OP_EQ, INT_MAX);
5182 done:
5186 static void
5187 test_dir_download_status_increment(void *arg)
5189 (void)arg;
5190 download_status_t dls_exp = { 0, 0, 0, DL_SCHED_GENERIC,
5191 DL_WANT_ANY_DIRSERVER,
5192 DL_SCHED_INCREMENT_ATTEMPT,
5193 0, 0 };
5194 or_options_t test_options;
5195 time_t current_time = time(NULL);
5197 const int delay0 = 10;
5198 const int no_delay = 0;
5199 const int schedule = 10;
5200 const int schedule_no_initial_delay = 0;
5202 /* Put it in the options */
5203 mock_options = &test_options;
5204 reset_options(mock_options, &mock_get_options_calls);
5205 mock_options->TestingBridgeBootstrapDownloadInitialDelay = schedule;
5206 mock_options->TestingClientDownloadInitialDelay = schedule;
5208 MOCK(get_options, mock_get_options);
5210 /* Check that the initial value of the schedule is the first value used,
5211 * whether or not it was reset before being used */
5213 /* regression test for 17750: no initial delay */
5214 mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay;
5215 mock_get_options_calls = 0;
5216 /* we really want to test that it's equal to time(NULL) + delay0, but that's
5217 * an unrealiable test, because time(NULL) might change. */
5219 /* regression test for 17750: exponential, no initial delay */
5220 mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay;
5221 mock_get_options_calls = 0;
5222 /* we really want to test that it's equal to time(NULL) + delay0, but that's
5223 * an unrealiable test, because time(NULL) might change. */
5224 tt_assert(download_status_get_next_attempt_at(&dls_exp)
5225 >= current_time + no_delay);
5226 tt_assert(download_status_get_next_attempt_at(&dls_exp)
5227 != TIME_MAX);
5228 tt_int_op(download_status_get_n_failures(&dls_exp), OP_EQ, 0);
5229 tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0);
5230 tt_int_op(mock_get_options_calls, OP_GE, 1);
5232 /* regression test for 17750: exponential, initial delay */
5233 mock_options->TestingClientDownloadInitialDelay = schedule;
5234 mock_get_options_calls = 0;
5235 /* we really want to test that it's equal to time(NULL) + delay0, but that's
5236 * an unrealiable test, because time(NULL) might change. */
5237 tt_assert(download_status_get_next_attempt_at(&dls_exp)
5238 >= current_time + delay0);
5239 tt_assert(download_status_get_next_attempt_at(&dls_exp)
5240 != TIME_MAX);
5241 tt_int_op(download_status_get_n_failures(&dls_exp), OP_EQ, 0);
5242 tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0);
5243 tt_int_op(mock_get_options_calls, OP_GE, 1);
5245 done:
5246 UNMOCK(get_options);
5247 mock_options = NULL;
5248 mock_get_options_calls = 0;
5249 teardown_capture_of_logs();
5252 static void
5253 test_dir_authdir_type_to_string(void *data)
5255 (void)data;
5256 char *res;
5258 tt_str_op(res = authdir_type_to_string(NO_DIRINFO), OP_EQ,
5259 "[Not an authority]");
5260 tor_free(res);
5262 tt_str_op(res = authdir_type_to_string(EXTRAINFO_DIRINFO), OP_EQ,
5263 "[Not an authority]");
5264 tor_free(res);
5266 tt_str_op(res = authdir_type_to_string(MICRODESC_DIRINFO), OP_EQ,
5267 "[Not an authority]");
5268 tor_free(res);
5270 tt_str_op(res = authdir_type_to_string(V3_DIRINFO), OP_EQ, "V3");
5271 tor_free(res);
5273 tt_str_op(res = authdir_type_to_string(BRIDGE_DIRINFO), OP_EQ, "Bridge");
5274 tor_free(res);
5276 tt_str_op(res = authdir_type_to_string(
5277 V3_DIRINFO | BRIDGE_DIRINFO | EXTRAINFO_DIRINFO), OP_EQ,
5278 "V3, Bridge");
5279 done:
5280 tor_free(res);
5283 static void
5284 test_dir_conn_purpose_to_string(void *data)
5286 (void)data;
5288 #define EXPECT_CONN_PURPOSE(purpose, expected) \
5289 tt_str_op(dir_conn_purpose_to_string(purpose), OP_EQ, expected);
5291 EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_DIR, "server descriptor upload");
5292 EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_VOTE, "server vote upload");
5293 EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_SIGNATURES,
5294 "consensus signature upload");
5295 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_SERVERDESC, "server descriptor fetch");
5296 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_EXTRAINFO, "extra-info fetch");
5297 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_CONSENSUS,
5298 "consensus network-status fetch");
5299 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_CERTIFICATE, "authority cert fetch");
5300 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_STATUS_VOTE, "status vote fetch");
5301 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
5302 "consensus signature fetch");
5303 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_RENDDESC_V2,
5304 "hidden-service v2 descriptor fetch");
5305 EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_RENDDESC_V2,
5306 "hidden-service v2 descriptor upload");
5307 EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_MICRODESC, "microdescriptor fetch");
5309 /* This will give a warning, because there is no purpose 1024. */
5310 setup_full_capture_of_logs(LOG_WARN);
5311 EXPECT_CONN_PURPOSE(1024, "(unknown)");
5312 expect_single_log_msg_containing("Called with unknown purpose 1024");
5314 done:
5315 teardown_capture_of_logs();
5318 static int dir_tests_public_server_mode(const or_options_t *options);
5319 ATTR_UNUSED static int dir_tests_public_server_mode_called = 0;
5321 static int
5322 dir_tests_public_server_mode(const or_options_t *options)
5324 (void)options;
5326 if (dir_tests_public_server_mode_called++ == 0) {
5327 return 1;
5330 return 0;
5333 static void
5334 test_dir_should_use_directory_guards(void *data)
5336 or_options_t *options;
5337 char *errmsg = NULL;
5338 (void)data;
5340 MOCK(public_server_mode,
5341 dir_tests_public_server_mode);
5343 options = options_new();
5344 options_init(options);
5346 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5347 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 1);
5349 options->UseEntryGuards = 1;
5350 options->DownloadExtraInfo = 0;
5351 options->FetchDirInfoEarly = 0;
5352 options->FetchDirInfoExtraEarly = 0;
5353 options->FetchUselessDescriptors = 0;
5354 tt_int_op(should_use_directory_guards(options), OP_EQ, 1);
5355 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 2);
5357 options->UseEntryGuards = 0;
5358 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5359 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 3);
5360 options->UseEntryGuards = 1;
5362 options->DownloadExtraInfo = 1;
5363 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5364 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 4);
5365 options->DownloadExtraInfo = 0;
5367 options->FetchDirInfoEarly = 1;
5368 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5369 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 5);
5370 options->FetchDirInfoEarly = 0;
5372 options->FetchDirInfoExtraEarly = 1;
5373 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5374 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 6);
5375 options->FetchDirInfoExtraEarly = 0;
5377 options->FetchUselessDescriptors = 1;
5378 tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5379 tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 7);
5380 options->FetchUselessDescriptors = 0;
5382 done:
5383 UNMOCK(public_server_mode);
5384 or_options_free(options);
5385 tor_free(errmsg);
5388 static void dir_tests_directory_initiate_request(directory_request_t *req);
5389 ATTR_UNUSED static int dir_tests_directory_initiate_request_called = 0;
5391 static void
5392 test_dir_should_not_init_request_to_ourselves(void *data)
5394 char digest[DIGEST_LEN];
5395 dir_server_t *ourself = NULL;
5396 crypto_pk_t *key = pk_generate(2);
5397 (void) data;
5399 MOCK(directory_initiate_request,
5400 dir_tests_directory_initiate_request);
5402 clear_dir_servers();
5403 routerlist_free_all();
5405 set_server_identity_key(key);
5406 crypto_pk_get_digest(key, (char*) &digest);
5407 ourself = trusted_dir_server_new("ourself", "127.0.0.1", 9059, 9060,
5408 NULL, digest,
5409 NULL, V3_DIRINFO, 1.0);
5411 tt_assert(ourself);
5412 dir_server_add(ourself);
5414 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
5415 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5417 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
5418 NULL);
5420 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5422 done:
5423 UNMOCK(directory_initiate_request);
5424 clear_dir_servers();
5425 routerlist_free_all();
5426 crypto_pk_free(key);
5429 static void
5430 test_dir_should_not_init_request_to_dir_auths_without_v3_info(void *data)
5432 dir_server_t *ds = NULL;
5433 dirinfo_type_t dirinfo_type = BRIDGE_DIRINFO | EXTRAINFO_DIRINFO \
5434 | MICRODESC_DIRINFO;
5435 (void) data;
5437 MOCK(directory_initiate_request,
5438 dir_tests_directory_initiate_request);
5440 clear_dir_servers();
5441 routerlist_free_all();
5443 ds = trusted_dir_server_new("ds", "10.0.0.1", 9059, 9060, NULL,
5444 "12345678901234567890", NULL, dirinfo_type, 1.0);
5445 tt_assert(ds);
5446 dir_server_add(ds);
5448 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
5449 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5451 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
5452 NULL);
5453 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5455 done:
5456 UNMOCK(directory_initiate_request);
5457 clear_dir_servers();
5458 routerlist_free_all();
5461 static void
5462 test_dir_should_init_request_to_dir_auths(void *data)
5464 dir_server_t *ds = NULL;
5465 (void) data;
5467 MOCK(directory_initiate_request,
5468 dir_tests_directory_initiate_request);
5470 clear_dir_servers();
5471 routerlist_free_all();
5473 ds = trusted_dir_server_new("ds", "10.0.0.1", 9059, 9060, NULL,
5474 "12345678901234567890", NULL, V3_DIRINFO, 1.0);
5475 tt_assert(ds);
5476 dir_server_add(ds);
5478 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
5479 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 1);
5481 directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
5482 NULL);
5483 tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 2);
5485 done:
5486 UNMOCK(directory_initiate_request);
5487 clear_dir_servers();
5488 routerlist_free_all();
5491 void
5492 dir_tests_directory_initiate_request(directory_request_t *req)
5494 (void)req;
5495 dir_tests_directory_initiate_request_called++;
5498 static void
5499 test_dir_choose_compression_level(void* data)
5501 (void)data;
5503 /* It starts under_memory_pressure */
5504 tt_int_op(have_been_under_memory_pressure(), OP_EQ, 1);
5506 tt_assert(HIGH_COMPRESSION == choose_compression_level(-1));
5507 tt_assert(LOW_COMPRESSION == choose_compression_level(1024-1));
5508 tt_assert(MEDIUM_COMPRESSION == choose_compression_level(2048-1));
5509 tt_assert(HIGH_COMPRESSION == choose_compression_level(2048));
5511 /* Reset under_memory_pressure timer */
5512 cell_queues_check_size();
5513 tt_int_op(have_been_under_memory_pressure(), OP_EQ, 0);
5515 tt_assert(HIGH_COMPRESSION == choose_compression_level(-1));
5516 tt_assert(HIGH_COMPRESSION == choose_compression_level(1024-1));
5517 tt_assert(HIGH_COMPRESSION == choose_compression_level(2048-1));
5518 tt_assert(HIGH_COMPRESSION == choose_compression_level(2048));
5520 done: ;
5524 * Mock check_private_dir(), and always succeed - no need to actually
5525 * look at or create anything on the filesystem.
5528 static int
5529 mock_check_private_dir(const char *dirname, cpd_check_t check,
5530 const char *effective_user)
5532 (void)dirname;
5533 (void)check;
5534 (void)effective_user;
5536 return 0;
5540 * This really mocks options_get_datadir_fname2_suffix(), but for testing
5541 * dump_desc(), we only care about get_datadir_fname(sub1), which is defined
5542 * in config.h as:
5544 * options_get_datadir_fname2_suffix(get_options(), sub1, NULL, NULL)
5547 static char *
5548 mock_get_datadir_fname(const or_options_t *options,
5549 directory_root_t roottype,
5550 const char *sub1, const char *sub2,
5551 const char *suffix)
5553 (void) roottype;
5554 char *rv = NULL;
5557 * Assert we were called like get_datadir_fname2() or get_datadir_fname(),
5558 * since that's all we implement here.
5560 tt_ptr_op(options, OP_NE, NULL);
5561 tt_ptr_op(sub1, OP_NE, NULL);
5563 * No particular assertions about sub2, since we could be in the
5564 * get_datadir_fname() or get_datadir_fname2() case.
5566 tt_ptr_op(suffix, OP_EQ, NULL);
5568 /* Just duplicate the basename and return it for this mock */
5569 if (sub2) {
5570 /* If we have sub2, it's the basename, otherwise sub1 */
5571 rv = tor_strdup(sub2);
5572 } else {
5573 rv = tor_strdup(sub1);
5576 done:
5577 return rv;
5580 static char *last_unlinked_path = NULL;
5581 static int unlinked_count = 0;
5583 static void
5584 mock_unlink_reset(void)
5586 tor_free(last_unlinked_path);
5587 unlinked_count = 0;
5590 static int
5591 mock_unlink(const char *path)
5593 tt_ptr_op(path, OP_NE, NULL);
5595 tor_free(last_unlinked_path);
5596 last_unlinked_path = tor_strdup(path);
5597 ++unlinked_count;
5599 done:
5600 return 0;
5603 static char *last_write_str_path = NULL;
5604 static uint8_t last_write_str_hash[DIGEST256_LEN];
5605 static int write_str_count = 0;
5607 static void
5608 mock_write_str_to_file_reset(void)
5610 tor_free(last_write_str_path);
5611 write_str_count = 0;
5614 static int
5615 mock_write_str_to_file(const char *path, const char *str, int bin)
5617 size_t len;
5618 uint8_t hash[DIGEST256_LEN];
5620 (void)bin;
5622 tt_ptr_op(path, OP_NE, NULL);
5623 tt_ptr_op(str, OP_NE, NULL);
5625 len = strlen(str);
5626 crypto_digest256((char *)hash, str, len, DIGEST_SHA256);
5628 tor_free(last_write_str_path);
5629 last_write_str_path = tor_strdup(path);
5630 memcpy(last_write_str_hash, hash, sizeof(last_write_str_hash));
5631 ++write_str_count;
5633 done:
5634 return 0;
5637 static void
5638 test_dir_dump_unparseable_descriptors(void *data)
5641 * These bogus descriptors look nothing at all like real bogus descriptors
5642 * we might see, but we're only testing dump_desc() here, not the parser.
5644 const char *test_desc_type = "squamous";
5645 /* strlen(test_desc_1) = 583 bytes */
5646 const char *test_desc_1 =
5647 "The most merciful thing in the world, I think, is the inability of the "
5648 "human mind to correlate all its contents. We live on a placid island of"
5649 " ignorance in the midst of black seas of infinity, and it was not meant"
5650 " that we should voyage far. The sciences, each straining in its own dir"
5651 "ection, have hitherto harmed us little; but some day the piecing togeth"
5652 "er of dissociated knowledge will open up such terrifying vistas of real"
5653 "ity, and of our frightful position therein, that we shall either go mad"
5654 "from the revelation or flee from the light into the peace and safety of"
5655 "a new dark age.";
5656 uint8_t test_desc_1_hash[DIGEST256_LEN];
5657 char test_desc_1_hash_str[HEX_DIGEST256_LEN+1];
5658 /* strlen(test_desc_2) = 650 bytes */
5659 const char *test_desc_2 =
5660 "I think their predominant colour was a greyish-green, though they had w"
5661 "hite bellies. They were mostly shiny and slippery, but the ridges of th"
5662 "eir backs were scaly. Their forms vaguely suggested the anthropoid, whi"
5663 "le their heads were the heads of fish, with prodigious bulging eyes tha"
5664 "t never closed. At the sides of their necks were palpitating gills, and"
5665 "their long paws were webbed. They hopped irregularly, sometimes on two "
5666 "legs and sometimes on four. I was somehow glad that they had no more th"
5667 "an four limbs. Their croaking, baying voices, clearly wed tar articulat"
5668 "e speech, held all the dark shades of expression which their staring fa"
5669 "ces lacked.";
5670 uint8_t test_desc_2_hash[DIGEST256_LEN];
5671 char test_desc_2_hash_str[HEX_DIGEST256_LEN+1];
5672 /* strlen(test_desc_3) = 700 bytes */
5673 const char *test_desc_3 =
5674 "Without knowing what futurism is like, Johansen achieved something very"
5675 "close to it when he spoke of the city; for instead of describing any de"
5676 "finite structure or building, he dwells only on broad impressions of va"
5677 "st angles and stone surfaces - surfaces too great to belong to anything"
5678 "right or proper for this earth, and impious with horrible images and hi"
5679 "eroglyphs. I mention his talk about angles because it suggests somethin"
5680 "g Wilcox had told me of his awful dreams. He said that the geometry of "
5681 "the dream-place he saw was abnormal, non-Euclidean, and loathsomely red"
5682 "olent of spheres and dimensions apart from ours. Now an unlettered seam"
5683 "an felt the same thing whilst gazing at the terrible reality.";
5684 uint8_t test_desc_3_hash[DIGEST256_LEN];
5685 char test_desc_3_hash_str[HEX_DIGEST256_LEN+1];
5686 /* strlen(test_desc_3) = 604 bytes */
5687 const char *test_desc_4 =
5688 "So we glanced back simultaneously, it would appear; though no doubt the"
5689 "incipient motion of one prompted the imitation of the other. As we did "
5690 "so we flashed both torches full strength at the momentarily thinned mis"
5691 "t; either from sheer primitive anxiety to see all we could, or in a les"
5692 "s primitive but equally unconscious effort to dazzle the entity before "
5693 "we dimmed our light and dodged among the penguins of the labyrinth cent"
5694 "er ahead. Unhappy act! Not Orpheus himself, or Lot's wife, paid much mo"
5695 "re dearly for a backward glance. And again came that shocking, wide-ran"
5696 "ged piping - \"Tekeli-li! Tekeli-li!\"";
5697 uint8_t test_desc_4_hash[DIGEST256_LEN];
5698 char test_desc_4_hash_str[HEX_DIGEST256_LEN+1];
5699 (void)data;
5702 * Set up options mock so we can force a tiny FIFO size and generate
5703 * cleanups.
5705 mock_options = tor_malloc(sizeof(or_options_t));
5706 reset_options(mock_options, &mock_get_options_calls);
5707 mock_options->MaxUnparseableDescSizeToLog = 1536;
5708 MOCK(get_options, mock_get_options);
5709 MOCK(check_private_dir, mock_check_private_dir);
5710 MOCK(options_get_dir_fname2_suffix,
5711 mock_get_datadir_fname);
5714 * Set up unlink and write mocks
5716 MOCK(tor_unlink, mock_unlink);
5717 mock_unlink_reset();
5718 MOCK(write_str_to_file, mock_write_str_to_file);
5719 mock_write_str_to_file_reset();
5722 * Compute hashes we'll need to recognize which descriptor is which
5724 crypto_digest256((char *)test_desc_1_hash, test_desc_1,
5725 strlen(test_desc_1), DIGEST_SHA256);
5726 base16_encode(test_desc_1_hash_str, sizeof(test_desc_1_hash_str),
5727 (const char *)test_desc_1_hash,
5728 sizeof(test_desc_1_hash));
5729 crypto_digest256((char *)test_desc_2_hash, test_desc_2,
5730 strlen(test_desc_2), DIGEST_SHA256);
5731 base16_encode(test_desc_2_hash_str, sizeof(test_desc_2_hash_str),
5732 (const char *)test_desc_2_hash,
5733 sizeof(test_desc_2_hash));
5734 crypto_digest256((char *)test_desc_3_hash, test_desc_3,
5735 strlen(test_desc_3), DIGEST_SHA256);
5736 base16_encode(test_desc_3_hash_str, sizeof(test_desc_3_hash_str),
5737 (const char *)test_desc_3_hash,
5738 sizeof(test_desc_3_hash));
5739 crypto_digest256((char *)test_desc_4_hash, test_desc_4,
5740 strlen(test_desc_4), DIGEST_SHA256);
5741 base16_encode(test_desc_4_hash_str, sizeof(test_desc_4_hash_str),
5742 (const char *)test_desc_4_hash,
5743 sizeof(test_desc_4_hash));
5746 * Reset the FIFO and check its state
5748 dump_desc_fifo_cleanup();
5749 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5750 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5753 * (1) Fire off dump_desc() once; these descriptors should all be safely
5754 * smaller than configured FIFO size.
5757 dump_desc(test_desc_1, test_desc_type);
5760 * Assert things about the FIFO state
5762 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_1));
5763 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5766 * Assert things about the mocks
5768 tt_int_op(unlinked_count, OP_EQ, 0);
5769 tt_int_op(write_str_count, OP_EQ, 1);
5770 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
5773 * Reset the FIFO and check its state
5775 dump_desc_fifo_cleanup();
5776 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5777 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5780 * Reset the mocks and check their state
5782 mock_unlink_reset();
5783 mock_write_str_to_file_reset();
5784 tt_int_op(unlinked_count, OP_EQ, 0);
5785 tt_int_op(write_str_count, OP_EQ, 0);
5788 * (2) Fire off dump_desc() twice; this still should trigger no cleanup.
5791 /* First time */
5792 dump_desc(test_desc_2, test_desc_type);
5795 * Assert things about the FIFO state
5797 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_2));
5798 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5801 * Assert things about the mocks
5803 tt_int_op(unlinked_count, OP_EQ, 0);
5804 tt_int_op(write_str_count, OP_EQ, 1);
5805 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
5807 /* Second time */
5808 dump_desc(test_desc_3, test_desc_type);
5811 * Assert things about the FIFO state
5813 tt_u64_op(len_descs_dumped, OP_EQ,
5814 strlen(test_desc_2) + strlen(test_desc_3));
5815 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5818 * Assert things about the mocks
5820 tt_int_op(unlinked_count, OP_EQ, 0);
5821 tt_int_op(write_str_count, OP_EQ, 2);
5822 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
5825 * Reset the FIFO and check its state
5827 dump_desc_fifo_cleanup();
5828 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5829 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5832 * Reset the mocks and check their state
5834 mock_unlink_reset();
5835 mock_write_str_to_file_reset();
5836 tt_int_op(unlinked_count, OP_EQ, 0);
5837 tt_int_op(write_str_count, OP_EQ, 0);
5840 * (3) Three calls to dump_desc cause a FIFO cleanup
5843 /* First time */
5844 dump_desc(test_desc_4, test_desc_type);
5847 * Assert things about the FIFO state
5849 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_4));
5850 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5853 * Assert things about the mocks
5855 tt_int_op(unlinked_count, OP_EQ, 0);
5856 tt_int_op(write_str_count, OP_EQ, 1);
5857 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
5859 /* Second time */
5860 dump_desc(test_desc_1, test_desc_type);
5863 * Assert things about the FIFO state
5865 tt_u64_op(len_descs_dumped, OP_EQ,
5866 strlen(test_desc_4) + strlen(test_desc_1));
5867 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5870 * Assert things about the mocks
5872 tt_int_op(unlinked_count, OP_EQ, 0);
5873 tt_int_op(write_str_count, OP_EQ, 2);
5874 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
5876 /* Third time - we should unlink the dump of test_desc_4 here */
5877 dump_desc(test_desc_2, test_desc_type);
5880 * Assert things about the FIFO state
5882 tt_u64_op(len_descs_dumped, OP_EQ,
5883 strlen(test_desc_1) + strlen(test_desc_2));
5884 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5887 * Assert things about the mocks
5889 tt_int_op(unlinked_count, OP_EQ, 1);
5890 tt_int_op(write_str_count, OP_EQ, 3);
5891 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
5894 * Reset the FIFO and check its state
5896 dump_desc_fifo_cleanup();
5897 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5898 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5901 * Reset the mocks and check their state
5903 mock_unlink_reset();
5904 mock_write_str_to_file_reset();
5905 tt_int_op(unlinked_count, OP_EQ, 0);
5906 tt_int_op(write_str_count, OP_EQ, 0);
5909 * (4) But repeating one (A B B) doesn't overflow and cleanup
5912 /* First time */
5913 dump_desc(test_desc_3, test_desc_type);
5916 * Assert things about the FIFO state
5918 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_3));
5919 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5922 * Assert things about the mocks
5924 tt_int_op(unlinked_count, OP_EQ, 0);
5925 tt_int_op(write_str_count, OP_EQ, 1);
5926 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
5928 /* Second time */
5929 dump_desc(test_desc_4, test_desc_type);
5932 * Assert things about the FIFO state
5934 tt_u64_op(len_descs_dumped, OP_EQ,
5935 strlen(test_desc_3) + strlen(test_desc_4));
5936 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5939 * Assert things about the mocks
5941 tt_int_op(unlinked_count, OP_EQ, 0);
5942 tt_int_op(write_str_count, OP_EQ, 2);
5943 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
5945 /* Third time */
5946 dump_desc(test_desc_4, test_desc_type);
5949 * Assert things about the FIFO state
5951 tt_u64_op(len_descs_dumped, OP_EQ,
5952 strlen(test_desc_3) + strlen(test_desc_4));
5953 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5956 * Assert things about the mocks
5958 tt_int_op(unlinked_count, OP_EQ, 0);
5959 tt_int_op(write_str_count, OP_EQ, 2);
5960 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
5963 * Reset the FIFO and check its state
5965 dump_desc_fifo_cleanup();
5966 tt_u64_op(len_descs_dumped, OP_EQ, 0);
5967 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5970 * Reset the mocks and check their state
5972 mock_unlink_reset();
5973 mock_write_str_to_file_reset();
5974 tt_int_op(unlinked_count, OP_EQ, 0);
5975 tt_int_op(write_str_count, OP_EQ, 0);
5978 * (5) Same for the (A B A) repetition
5981 /* First time */
5982 dump_desc(test_desc_1, test_desc_type);
5985 * Assert things about the FIFO state
5987 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_1));
5988 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5991 * Assert things about the mocks
5993 tt_int_op(unlinked_count, OP_EQ, 0);
5994 tt_int_op(write_str_count, OP_EQ, 1);
5995 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
5997 /* Second time */
5998 dump_desc(test_desc_2, test_desc_type);
6001 * Assert things about the FIFO state
6003 tt_u64_op(len_descs_dumped, OP_EQ,
6004 strlen(test_desc_1) + strlen(test_desc_2));
6005 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6008 * Assert things about the mocks
6010 tt_int_op(unlinked_count, OP_EQ, 0);
6011 tt_int_op(write_str_count, OP_EQ, 2);
6012 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
6014 /* Third time */
6015 dump_desc(test_desc_1, test_desc_type);
6018 * Assert things about the FIFO state
6020 tt_u64_op(len_descs_dumped, OP_EQ,
6021 strlen(test_desc_1) + strlen(test_desc_2));
6022 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6025 * Assert things about the mocks
6027 tt_int_op(unlinked_count, OP_EQ, 0);
6028 tt_int_op(write_str_count, OP_EQ, 2);
6029 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
6032 * Reset the FIFO and check its state
6034 dump_desc_fifo_cleanup();
6035 tt_u64_op(len_descs_dumped, OP_EQ, 0);
6036 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
6039 * Reset the mocks and check their state
6041 mock_unlink_reset();
6042 mock_write_str_to_file_reset();
6043 tt_int_op(unlinked_count, OP_EQ, 0);
6044 tt_int_op(write_str_count, OP_EQ, 0);
6047 * (6) (A B B C) triggering overflow on C causes A, not B to be unlinked
6050 /* First time */
6051 dump_desc(test_desc_3, test_desc_type);
6054 * Assert things about the FIFO state
6056 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_3));
6057 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
6060 * Assert things about the mocks
6062 tt_int_op(unlinked_count, OP_EQ, 0);
6063 tt_int_op(write_str_count, OP_EQ, 1);
6064 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
6066 /* Second time */
6067 dump_desc(test_desc_4, test_desc_type);
6070 * Assert things about the FIFO state
6072 tt_u64_op(len_descs_dumped, OP_EQ,
6073 strlen(test_desc_3) + strlen(test_desc_4));
6074 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6077 * Assert things about the mocks
6079 tt_int_op(unlinked_count, OP_EQ, 0);
6080 tt_int_op(write_str_count, OP_EQ, 2);
6081 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
6083 /* Third time */
6084 dump_desc(test_desc_4, test_desc_type);
6087 * Assert things about the FIFO state
6089 tt_u64_op(len_descs_dumped, OP_EQ,
6090 strlen(test_desc_3) + strlen(test_desc_4));
6091 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6094 * Assert things about the mocks
6096 tt_int_op(unlinked_count, OP_EQ, 0);
6097 tt_int_op(write_str_count, OP_EQ, 2);
6098 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
6100 /* Fourth time - we should unlink the dump of test_desc_3 here */
6101 dump_desc(test_desc_1, test_desc_type);
6104 * Assert things about the FIFO state
6106 tt_u64_op(len_descs_dumped, OP_EQ,
6107 strlen(test_desc_4) + strlen(test_desc_1));
6108 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6111 * Assert things about the mocks
6113 tt_int_op(unlinked_count, OP_EQ, 1);
6114 tt_int_op(write_str_count, OP_EQ, 3);
6115 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
6118 * Reset the FIFO and check its state
6120 dump_desc_fifo_cleanup();
6121 tt_u64_op(len_descs_dumped, OP_EQ, 0);
6122 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
6125 * Reset the mocks and check their state
6127 mock_unlink_reset();
6128 mock_write_str_to_file_reset();
6129 tt_int_op(unlinked_count, OP_EQ, 0);
6130 tt_int_op(write_str_count, OP_EQ, 0);
6133 * (7) (A B A C) triggering overflow on C causes B, not A to be unlinked
6136 /* First time */
6137 dump_desc(test_desc_2, test_desc_type);
6140 * Assert things about the FIFO state
6142 tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_2));
6143 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
6146 * Assert things about the mocks
6148 tt_int_op(unlinked_count, OP_EQ, 0);
6149 tt_int_op(write_str_count, OP_EQ, 1);
6150 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
6152 /* Second time */
6153 dump_desc(test_desc_3, test_desc_type);
6156 * Assert things about the FIFO state
6158 tt_u64_op(len_descs_dumped, OP_EQ,
6159 strlen(test_desc_2) + strlen(test_desc_3));
6160 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6163 * Assert things about the mocks
6165 tt_int_op(unlinked_count, OP_EQ, 0);
6166 tt_int_op(write_str_count, OP_EQ, 2);
6167 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
6169 /* Third time */
6170 dump_desc(test_desc_2, test_desc_type);
6173 * Assert things about the FIFO state
6175 tt_u64_op(len_descs_dumped, OP_EQ,
6176 strlen(test_desc_2) + strlen(test_desc_3));
6177 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6180 * Assert things about the mocks
6182 tt_int_op(unlinked_count, OP_EQ, 0);
6183 tt_int_op(write_str_count, OP_EQ, 2);
6184 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
6186 /* Fourth time - we should unlink the dump of test_desc_3 here */
6187 dump_desc(test_desc_4, test_desc_type);
6190 * Assert things about the FIFO state
6192 tt_u64_op(len_descs_dumped, OP_EQ,
6193 strlen(test_desc_2) + strlen(test_desc_4));
6194 tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6197 * Assert things about the mocks
6199 tt_int_op(unlinked_count, OP_EQ, 1);
6200 tt_int_op(write_str_count, OP_EQ, 3);
6201 tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
6204 * Reset the FIFO and check its state
6206 dump_desc_fifo_cleanup();
6207 tt_u64_op(len_descs_dumped, OP_EQ, 0);
6208 tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
6211 * Reset the mocks and check their state
6213 mock_unlink_reset();
6214 mock_write_str_to_file_reset();
6215 tt_int_op(unlinked_count, OP_EQ, 0);
6216 tt_int_op(write_str_count, OP_EQ, 0);
6218 done:
6220 /* Clean up the fifo */
6221 dump_desc_fifo_cleanup();
6223 /* Remove mocks */
6224 UNMOCK(tor_unlink);
6225 mock_unlink_reset();
6226 UNMOCK(write_str_to_file);
6227 mock_write_str_to_file_reset();
6228 UNMOCK(options_get_dir_fname2_suffix);
6229 UNMOCK(check_private_dir);
6230 UNMOCK(get_options);
6231 tor_free(mock_options);
6232 mock_options = NULL;
6234 return;
6237 /* Variables for reset_read_file_to_str_mock() */
6239 static int enforce_expected_filename = 0;
6240 static char *expected_filename = NULL;
6241 static char *file_content = NULL;
6242 static size_t file_content_len = 0;
6243 static struct stat file_stat;
6244 static int read_count = 0, read_call_count = 0;
6246 static void
6247 reset_read_file_to_str_mock(void)
6249 tor_free(expected_filename);
6250 tor_free(file_content);
6251 file_content_len = 0;
6252 memset(&file_stat, 0, sizeof(file_stat));
6253 read_count = 0;
6254 read_call_count = 0;
6257 static char *
6258 read_file_to_str_mock(const char *filename, int flags,
6259 struct stat *stat_out) {
6260 char *result = NULL;
6262 /* Insist we got a filename */
6263 tt_ptr_op(filename, OP_NE, NULL);
6265 /* We ignore flags */
6266 (void)flags;
6268 /* Bump the call count */
6269 ++read_call_count;
6271 if (enforce_expected_filename) {
6272 tt_assert(expected_filename);
6273 tt_str_op(filename, OP_EQ, expected_filename);
6276 if (expected_filename != NULL &&
6277 file_content != NULL &&
6278 strcmp(filename, expected_filename) == 0) {
6279 /* You asked for it, you got it */
6282 * This is the same behavior as the real read_file_to_str();
6283 * if there's a NUL, the real size ends up in stat_out.
6285 result = tor_malloc(file_content_len + 1);
6286 if (file_content_len > 0) {
6287 memcpy(result, file_content, file_content_len);
6289 result[file_content_len] = '\0';
6291 /* Do we need to set up stat_out? */
6292 if (stat_out != NULL) {
6293 memcpy(stat_out, &file_stat, sizeof(file_stat));
6294 /* We always return the correct length here */
6295 stat_out->st_size = file_content_len;
6298 /* Wooo, we have a return value - bump the counter */
6299 ++read_count;
6301 /* else no match, return NULL */
6303 done:
6304 return result;
6307 /* This one tests dump_desc_populate_one_file() */
6308 static void
6309 test_dir_populate_dump_desc_fifo(void *data)
6311 const char *dirname = "foo";
6312 const char *fname = NULL;
6313 dumped_desc_t *ent;
6315 (void)data;
6318 * Set up unlink and read_file_to_str mocks
6320 MOCK(tor_unlink, mock_unlink);
6321 mock_unlink_reset();
6322 MOCK(read_file_to_str, read_file_to_str_mock);
6323 reset_read_file_to_str_mock();
6325 /* Check state of unlink mock */
6326 tt_int_op(unlinked_count, OP_EQ, 0);
6328 /* Some cases that should fail before trying to read the file */
6329 ent = dump_desc_populate_one_file(dirname, "bar");
6330 tt_ptr_op(ent, OP_EQ, NULL);
6331 tt_int_op(unlinked_count, OP_EQ, 1);
6332 tt_int_op(read_count, OP_EQ, 0);
6333 tt_int_op(read_call_count, OP_EQ, 0);
6335 ent = dump_desc_populate_one_file(dirname, "unparseable-desc");
6336 tt_ptr_op(ent, OP_EQ, NULL);
6337 tt_int_op(unlinked_count, OP_EQ, 2);
6338 tt_int_op(read_count, OP_EQ, 0);
6339 tt_int_op(read_call_count, OP_EQ, 0);
6341 ent = dump_desc_populate_one_file(dirname, "unparseable-desc.baz");
6342 tt_ptr_op(ent, OP_EQ, NULL);
6343 tt_int_op(unlinked_count, OP_EQ, 3);
6344 tt_int_op(read_count, OP_EQ, 0);
6345 tt_int_op(read_call_count, OP_EQ, 0);
6347 ent = dump_desc_populate_one_file(
6348 dirname,
6349 "unparseable-desc.08AE85E90461F59E");
6350 tt_ptr_op(ent, OP_EQ, NULL);
6351 tt_int_op(unlinked_count, OP_EQ, 4);
6352 tt_int_op(read_count, OP_EQ, 0);
6353 tt_int_op(read_call_count, OP_EQ, 0);
6355 ent = dump_desc_populate_one_file(
6356 dirname,
6357 "unparseable-desc.08AE85E90461F59EDF0981323F3A70D02B55AB54B44B04F"
6358 "287D72F7B72F242E85C8CB0EDA8854A99");
6359 tt_ptr_op(ent, OP_EQ, NULL);
6360 tt_int_op(unlinked_count, OP_EQ, 5);
6361 tt_int_op(read_count, OP_EQ, 0);
6362 tt_int_op(read_call_count, OP_EQ, 0);
6364 /* This is a correct-length digest but base16_decode() will fail */
6365 ent = dump_desc_populate_one_file(
6366 dirname,
6367 "unparseable-desc.68219B8BGE64B705A6FFC728C069DC596216D60A7D7520C"
6368 "D5ECE250D912E686B");
6369 tt_ptr_op(ent, OP_EQ, NULL);
6370 tt_int_op(unlinked_count, OP_EQ, 6);
6371 tt_int_op(read_count, OP_EQ, 0);
6372 tt_int_op(read_call_count, OP_EQ, 0);
6374 /* This one has a correctly formed filename and should try reading */
6376 /* Read fails */
6377 ent = dump_desc_populate_one_file(
6378 dirname,
6379 "unparseable-desc.DF0981323F3A70D02B55AB54B44B04F287D72F7B72F242E"
6380 "85C8CB0EDA8854A99");
6381 tt_ptr_op(ent, OP_EQ, NULL);
6382 tt_int_op(unlinked_count, OP_EQ, 7);
6383 tt_int_op(read_count, OP_EQ, 0);
6384 tt_int_op(read_call_count, OP_EQ, 1);
6386 /* This read will succeed but the digest won't match the file content */
6387 fname =
6388 "unparseable-desc."
6389 "DF0981323F3A70D02B55AB54B44B04F287D72F7B72F242E85C8CB0EDA8854A99";
6390 enforce_expected_filename = 1;
6391 tor_asprintf(&expected_filename, "%s%s%s", dirname, PATH_SEPARATOR, fname);
6392 file_content = tor_strdup("hanc culpam maiorem an illam dicam?");
6393 file_content_len = strlen(file_content);
6394 file_stat.st_mtime = 123456;
6395 ent = dump_desc_populate_one_file(dirname, fname);
6396 enforce_expected_filename = 0;
6397 tt_ptr_op(ent, OP_EQ, NULL);
6398 tt_int_op(unlinked_count, OP_EQ, 8);
6399 tt_int_op(read_count, OP_EQ, 1);
6400 tt_int_op(read_call_count, OP_EQ, 2);
6401 tor_free(expected_filename);
6402 tor_free(file_content);
6404 /* This one will match */
6405 fname =
6406 "unparseable-desc."
6407 "0786C7173447B7FB033FFCA2FC47C3CF71C30DD47CA8236D3FC7FF35853271C6";
6408 tor_asprintf(&expected_filename, "%s%s%s", dirname, PATH_SEPARATOR, fname);
6409 file_content = tor_strdup("hanc culpam maiorem an illam dicam?");
6410 file_content_len = strlen(file_content);
6411 file_stat.st_mtime = 789012;
6412 ent = dump_desc_populate_one_file(dirname, fname);
6413 tt_ptr_op(ent, OP_NE, NULL);
6414 tt_int_op(unlinked_count, OP_EQ, 8);
6415 tt_int_op(read_count, OP_EQ, 2);
6416 tt_int_op(read_call_count, OP_EQ, 3);
6417 tt_str_op(ent->filename, OP_EQ, expected_filename);
6418 tt_int_op(ent->len, OP_EQ, file_content_len);
6419 tt_int_op(ent->when, OP_EQ, file_stat.st_mtime);
6420 tor_free(ent->filename);
6421 tor_free(ent);
6422 tor_free(expected_filename);
6425 * Reset the mocks and check their state
6427 mock_unlink_reset();
6428 tt_int_op(unlinked_count, OP_EQ, 0);
6429 reset_read_file_to_str_mock();
6430 tt_int_op(read_count, OP_EQ, 0);
6432 done:
6434 UNMOCK(tor_unlink);
6435 mock_unlink_reset();
6436 UNMOCK(read_file_to_str);
6437 reset_read_file_to_str_mock();
6439 tor_free(file_content);
6441 return;
6444 static smartlist_t *
6445 listdir_mock(const char *dname)
6447 smartlist_t *l;
6449 /* Ignore the name, always return this list */
6450 (void)dname;
6452 l = smartlist_new();
6453 smartlist_add_strdup(l, "foo");
6454 smartlist_add_strdup(l, "bar");
6455 smartlist_add_strdup(l, "baz");
6457 return l;
6460 static dumped_desc_t *
6461 pop_one_mock(const char *dirname, const char *f)
6463 dumped_desc_t *ent = NULL;
6465 if (dirname != NULL && strcmp(dirname, "d") == 0) {
6466 if (f != NULL && strcmp(f, "foo") == 0) {
6467 ent = tor_malloc_zero(sizeof(*ent));
6468 ent->filename = tor_strdup("d/foo");
6469 ent->len = 123;
6470 ent->digest_sha256[0] = 1;
6471 ent->when = 1024;
6472 } else if (f != NULL && strcmp(f, "bar") == 0) {
6473 ent = tor_malloc_zero(sizeof(*ent));
6474 ent->filename = tor_strdup("d/bar");
6475 ent->len = 456;
6476 ent->digest_sha256[0] = 2;
6478 * Note that the timestamps are in a different order than
6479 * listdir_mock() returns; we're testing the sort order.
6481 ent->when = 512;
6482 } else if (f != NULL && strcmp(f, "baz") == 0) {
6483 ent = tor_malloc_zero(sizeof(*ent));
6484 ent->filename = tor_strdup("d/baz");
6485 ent->len = 789;
6486 ent->digest_sha256[0] = 3;
6487 ent->when = 768;
6491 return ent;
6494 /* This one tests dump_desc_populate_fifo_from_directory() */
6495 static void
6496 test_dir_populate_dump_desc_fifo_2(void *data)
6498 dumped_desc_t *ent = NULL;
6500 (void)data;
6502 /* Set up the mocks */
6503 MOCK(tor_listdir, listdir_mock);
6504 MOCK(dump_desc_populate_one_file, pop_one_mock);
6506 /* Run dump_desc_populate_fifo_from_directory() */
6507 descs_dumped = NULL;
6508 len_descs_dumped = 0;
6509 dump_desc_populate_fifo_from_directory("d");
6510 tt_assert(descs_dumped != NULL);
6511 tt_int_op(smartlist_len(descs_dumped), OP_EQ, 3);
6512 tt_u64_op(len_descs_dumped, OP_EQ, 1368);
6513 ent = smartlist_get(descs_dumped, 0);
6514 tt_str_op(ent->filename, OP_EQ, "d/bar");
6515 tt_int_op(ent->len, OP_EQ, 456);
6516 tt_int_op(ent->when, OP_EQ, 512);
6517 ent = smartlist_get(descs_dumped, 1);
6518 tt_str_op(ent->filename, OP_EQ, "d/baz");
6519 tt_int_op(ent->len, OP_EQ, 789);
6520 tt_int_op(ent->when, OP_EQ, 768);
6521 ent = smartlist_get(descs_dumped, 2);
6522 tt_str_op(ent->filename, OP_EQ, "d/foo");
6523 tt_int_op(ent->len, OP_EQ, 123);
6524 tt_int_op(ent->when, OP_EQ, 1024);
6526 done:
6527 dump_desc_fifo_cleanup();
6529 UNMOCK(dump_desc_populate_one_file);
6530 UNMOCK(tor_listdir);
6532 return;
6535 static int mock_networkstatus_consensus_is_bootstrapping_value = 0;
6536 static int
6537 mock_networkstatus_consensus_is_bootstrapping(time_t now)
6539 (void)now;
6540 return mock_networkstatus_consensus_is_bootstrapping_value;
6543 static int mock_networkstatus_consensus_can_use_extra_fallbacks_value = 0;
6544 static int
6545 mock_networkstatus_consensus_can_use_extra_fallbacks(
6546 const or_options_t *options)
6548 (void)options;
6549 return mock_networkstatus_consensus_can_use_extra_fallbacks_value;
6552 static int mock_num_bridges_usable_value = 0;
6553 static int
6554 mock_num_bridges_usable(int use_maybe_reachable)
6556 (void)use_maybe_reachable;
6557 return mock_num_bridges_usable_value;
6560 /* data is a 3 character nul-terminated string.
6561 * If data[0] is 'b', set bootstrapping, anything else means not bootstrapping
6562 * If data[1] is 'f', set extra fallbacks, anything else means no extra
6563 * If data[2] is 'f', set running bridges, anything else means no extra
6564 * fallbacks.
6566 static void
6567 test_dir_find_dl_min_delay(void* data)
6569 const char *str = (const char *)data;
6571 tt_assert(strlen(data) == 3);
6573 if (str[0] == 'b') {
6574 mock_networkstatus_consensus_is_bootstrapping_value = 1;
6575 } else {
6576 mock_networkstatus_consensus_is_bootstrapping_value = 0;
6579 if (str[1] == 'f') {
6580 mock_networkstatus_consensus_can_use_extra_fallbacks_value = 1;
6581 } else {
6582 mock_networkstatus_consensus_can_use_extra_fallbacks_value = 0;
6585 if (str[2] == 'r') {
6586 /* Any positive, non-zero value should work */
6587 mock_num_bridges_usable_value = 2;
6588 } else {
6589 mock_num_bridges_usable_value = 0;
6592 MOCK(networkstatus_consensus_is_bootstrapping,
6593 mock_networkstatus_consensus_is_bootstrapping);
6594 MOCK(networkstatus_consensus_can_use_extra_fallbacks,
6595 mock_networkstatus_consensus_can_use_extra_fallbacks);
6596 MOCK(num_bridges_usable,
6597 mock_num_bridges_usable);
6599 download_status_t dls;
6601 const int server=10, client=20, server_cons=30, client_cons=40;
6602 const int client_boot_auth_only_cons=50, client_boot_auth_cons=60;
6603 const int client_boot_fallback_cons=70, bridge=80, bridge_bootstrap=90;
6605 mock_options = tor_malloc(sizeof(or_options_t));
6606 reset_options(mock_options, &mock_get_options_calls);
6607 MOCK(get_options, mock_get_options);
6609 mock_options->TestingServerDownloadInitialDelay = server;
6610 mock_options->TestingClientDownloadInitialDelay = client;
6611 mock_options->TestingServerConsensusDownloadInitialDelay = server_cons;
6612 mock_options->TestingClientConsensusDownloadInitialDelay = client_cons;
6613 mock_options->ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay =
6614 client_boot_auth_only_cons;
6615 mock_options->ClientBootstrapConsensusAuthorityDownloadInitialDelay =
6616 client_boot_auth_cons;
6617 mock_options->ClientBootstrapConsensusFallbackDownloadInitialDelay =
6618 client_boot_fallback_cons;
6619 mock_options->TestingBridgeDownloadInitialDelay = bridge;
6620 mock_options->TestingBridgeBootstrapDownloadInitialDelay = bridge_bootstrap;
6622 dls.schedule = DL_SCHED_GENERIC;
6623 /* client */
6624 mock_options->ClientOnly = 1;
6625 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, client);
6626 mock_options->ClientOnly = 0;
6628 /* dir mode */
6629 mock_options->DirPort_set = 1;
6630 mock_options->DirCache = 1;
6631 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server);
6632 mock_options->DirPort_set = 0;
6633 mock_options->DirCache = 0;
6635 dls.schedule = DL_SCHED_CONSENSUS;
6636 /* public server mode */
6637 mock_options->ORPort_set = 1;
6638 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server_cons);
6639 mock_options->ORPort_set = 0;
6641 /* client and bridge modes */
6642 if (networkstatus_consensus_is_bootstrapping(time(NULL))) {
6643 if (networkstatus_consensus_can_use_extra_fallbacks(mock_options)) {
6644 dls.want_authority = 1;
6645 /* client */
6646 mock_options->ClientOnly = 1;
6647 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6648 client_boot_auth_cons);
6649 mock_options->ClientOnly = 0;
6651 /* bridge relay */
6652 mock_options->ORPort_set = 1;
6653 mock_options->BridgeRelay = 1;
6654 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6655 client_boot_auth_cons);
6656 mock_options->ORPort_set = 0;
6657 mock_options->BridgeRelay = 0;
6659 dls.want_authority = 0;
6660 /* client */
6661 mock_options->ClientOnly = 1;
6662 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6663 client_boot_fallback_cons);
6664 mock_options->ClientOnly = 0;
6666 /* bridge relay */
6667 mock_options->ORPort_set = 1;
6668 mock_options->BridgeRelay = 1;
6669 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6670 client_boot_fallback_cons);
6671 mock_options->ORPort_set = 0;
6672 mock_options->BridgeRelay = 0;
6674 } else {
6675 /* dls.want_authority is ignored */
6676 /* client */
6677 mock_options->ClientOnly = 1;
6678 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6679 client_boot_auth_only_cons);
6680 mock_options->ClientOnly = 0;
6682 /* bridge relay */
6683 mock_options->ORPort_set = 1;
6684 mock_options->BridgeRelay = 1;
6685 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6686 client_boot_auth_only_cons);
6687 mock_options->ORPort_set = 0;
6688 mock_options->BridgeRelay = 0;
6690 } else {
6691 /* client */
6692 mock_options->ClientOnly = 1;
6693 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6694 client_cons);
6695 mock_options->ClientOnly = 0;
6697 /* bridge relay */
6698 mock_options->ORPort_set = 1;
6699 mock_options->BridgeRelay = 1;
6700 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6701 client_cons);
6702 mock_options->ORPort_set = 0;
6703 mock_options->BridgeRelay = 0;
6706 dls.schedule = DL_SCHED_BRIDGE;
6707 /* client */
6708 mock_options->ClientOnly = 1;
6709 mock_options->UseBridges = 1;
6710 if (num_bridges_usable(0) > 0) {
6711 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge);
6712 } else {
6713 tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge_bootstrap);
6716 done:
6717 UNMOCK(networkstatus_consensus_is_bootstrapping);
6718 UNMOCK(networkstatus_consensus_can_use_extra_fallbacks);
6719 UNMOCK(num_bridges_usable);
6720 UNMOCK(get_options);
6721 tor_free(mock_options);
6722 mock_options = NULL;
6725 static void
6726 test_dir_matching_flags(void *arg)
6728 (void) arg;
6729 routerstatus_t *rs_noflags = NULL;
6730 routerstatus_t *rs = NULL;
6731 char *s = NULL;
6733 smartlist_t *tokens = smartlist_new();
6734 memarea_t *area = memarea_new();
6736 int expected_val_when_unused = 0;
6738 const char *ex_noflags =
6739 "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 "
6740 "192.168.0.1 9001 0\n"
6741 "m thisoneislongerbecauseitisa256bitmddigest33\n"
6742 "s\n"
6743 "pr Link=4\n";
6744 const char *cp = ex_noflags;
6745 rs_noflags = routerstatus_parse_entry_from_string(
6746 area, &cp,
6747 cp + strlen(cp),
6748 tokens, NULL, NULL,
6749 MAX_SUPPORTED_CONSENSUS_METHOD, FLAV_MICRODESC);
6750 tt_assert(rs_noflags);
6752 #define FLAG(string, field) STMT_BEGIN { \
6753 tor_asprintf(&s,\
6754 "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 " \
6755 "192.168.0.1 9001 0\n" \
6756 "m thisoneislongerbecauseitisa256bitmddigest33\n" \
6757 "pr Link=4\n" \
6758 "s %s\n", string); \
6759 cp = s; \
6760 rs = routerstatus_parse_entry_from_string( \
6761 area, &cp, \
6762 cp + strlen(cp), \
6763 tokens, NULL, NULL, \
6764 MAX_SUPPORTED_CONSENSUS_METHOD, FLAV_MICRODESC); \
6765 /* the field should usually be 0 when no flags are listed */ \
6766 tt_int_op(rs_noflags->field, OP_EQ, expected_val_when_unused); \
6767 /* the field should be 1 when this flags islisted */ \
6768 tt_int_op(rs->field, OP_EQ, 1); \
6769 tor_free(s); \
6770 routerstatus_free(rs); \
6771 } STMT_END
6773 FLAG("Authority", is_authority);
6774 FLAG("BadExit", is_bad_exit);
6775 FLAG("Exit", is_exit);
6776 FLAG("Fast", is_fast);
6777 FLAG("Guard", is_possible_guard);
6778 FLAG("HSDir", is_hs_dir);
6779 FLAG("Stable", is_stable);
6780 FLAG("StaleDesc", is_staledesc);
6781 FLAG("V2Dir", is_v2_dir);
6783 // These flags are assumed to be set whether they're declared or not.
6784 expected_val_when_unused = 1;
6785 FLAG("Running", is_flagged_running);
6786 FLAG("Valid", is_valid);
6787 expected_val_when_unused = 0;
6789 // These flags are no longer used, but still parsed.
6790 FLAG("Named", is_named);
6791 FLAG("Unnamed", is_unnamed);
6793 done:
6794 tor_free(s);
6795 routerstatus_free(rs);
6796 routerstatus_free(rs_noflags);
6797 memarea_drop_all(area);
6798 smartlist_free(tokens);
6801 static void
6802 test_dir_assumed_flags(void *arg)
6804 (void)arg;
6805 smartlist_t *tokens = smartlist_new();
6806 memarea_t *area = memarea_new();
6807 routerstatus_t *rs = NULL;
6809 /* We can assume that consensus method is higher than 24, so Running and
6810 * Valid are always implicitly set */
6811 const char *str1 =
6812 "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 "
6813 "192.168.0.1 9001 0\n"
6814 "m thisoneislongerbecauseitisa256bitmddigest33\n"
6815 "s Fast Guard Stable\n"
6816 "pr Link=4\n";
6817 const char *eos = str1 + strlen(str1);
6819 const char *cp = str1;
6820 rs = routerstatus_parse_entry_from_string(area, &cp, eos, tokens, NULL, NULL,
6821 24, FLAV_MICRODESC);
6822 tt_assert(rs);
6823 tt_assert(rs->is_flagged_running);
6824 tt_assert(rs->is_valid);
6825 tt_assert(! rs->is_exit);
6826 tt_assert(rs->is_fast);
6828 done:
6829 smartlist_free(tokens);
6830 memarea_drop_all(area);
6831 routerstatus_free(rs);
6834 static void
6835 test_dir_post_parsing(void *arg)
6837 (void) arg;
6839 /* Test the version parsing from an HS descriptor publish request. */
6841 const char *end;
6842 const char *prefix = "/tor/hs/";
6843 int version = parse_hs_version_from_post("/tor/hs//publish", prefix, &end);
6844 tt_int_op(version, OP_EQ, -1);
6845 tt_ptr_op(end, OP_EQ, NULL);
6846 version = parse_hs_version_from_post("/tor/hs/a/publish", prefix, &end);
6847 tt_int_op(version, OP_EQ, -1);
6848 tt_ptr_op(end, OP_EQ, NULL);
6849 version = parse_hs_version_from_post("/tor/hs/3/publish", prefix, &end);
6850 tt_int_op(version, OP_EQ, 3);
6851 tt_str_op(end, OP_EQ, "/publish");
6852 version = parse_hs_version_from_post("/tor/hs/42/publish", prefix, &end);
6853 tt_int_op(version, OP_EQ, 42);
6854 tt_str_op(end, OP_EQ, "/publish");
6855 version = parse_hs_version_from_post("/tor/hs/18163/publish",prefix, &end);
6856 tt_int_op(version, OP_EQ, 18163);
6857 tt_str_op(end, OP_EQ, "/publish");
6858 version = parse_hs_version_from_post("JUNKJUNKJUNK", prefix, &end);
6859 tt_int_op(version, OP_EQ, -1);
6860 tt_ptr_op(end, OP_EQ, NULL);
6861 version = parse_hs_version_from_post("/tor/hs/3/publish", "blah", &end);
6862 tt_int_op(version, OP_EQ, -1);
6863 tt_ptr_op(end, OP_EQ, NULL);
6864 /* Missing the '/' at the end of the prefix. */
6865 version = parse_hs_version_from_post("/tor/hs/3/publish", "/tor/hs", &end);
6866 tt_int_op(version, OP_EQ, -1);
6867 tt_ptr_op(end, OP_EQ, NULL);
6868 version = parse_hs_version_from_post("/random/blah/tor/hs/3/publish",
6869 prefix, &end);
6870 tt_int_op(version, OP_EQ, -1);
6871 tt_ptr_op(end, OP_EQ, NULL);
6872 version = parse_hs_version_from_post("/tor/hs/3/publish/random/junk",
6873 prefix, &end);
6874 tt_int_op(version, OP_EQ, 3);
6875 tt_str_op(end, OP_EQ, "/publish/random/junk");
6876 version = parse_hs_version_from_post("/tor/hs/-1/publish", prefix, &end);
6877 tt_int_op(version, OP_EQ, -1);
6878 tt_ptr_op(end, OP_EQ, NULL);
6879 /* INT_MAX */
6880 version = parse_hs_version_from_post("/tor/hs/2147483647/publish",
6881 prefix, &end);
6882 tt_int_op(version, OP_EQ, INT_MAX);
6883 tt_str_op(end, OP_EQ, "/publish");
6884 /* INT_MAX + 1*/
6885 version = parse_hs_version_from_post("/tor/hs/2147483648/publish",
6886 prefix, &end);
6887 tt_int_op(version, OP_EQ, -1);
6888 tt_ptr_op(end, OP_EQ, NULL);
6891 done:
6895 static void
6896 test_dir_platform_str(void *arg)
6898 char platform[256];
6899 (void)arg;
6900 platform[0] = 0;
6901 get_platform_str(platform, sizeof(platform));
6902 tt_int_op((int)strlen(platform), OP_GT, 0);
6903 tt_assert(!strcmpstart(platform, "Tor "));
6905 tor_version_t ver;
6906 // make sure this is a tor version, a real actual tor version.
6907 tt_int_op(tor_version_parse_platform(platform, &ver, 1), OP_EQ, 1);
6909 TT_BLATHER(("%d.%d.%d.%d", ver.major, ver.minor, ver.micro, ver.patchlevel));
6911 // Handle an example version.
6912 tt_int_op(tor_version_parse_platform(
6913 "Tor 0.3.3.3 (foo) (git-xyzzy) on a potato", &ver, 1), OP_EQ, 1);
6914 done:
6918 static void
6919 test_dir_format_versions_list(void *arg)
6921 (void)arg;
6922 char *s = NULL;
6923 config_line_t *lines = NULL;
6925 setup_capture_of_logs(LOG_WARN);
6926 s = format_recommended_version_list(lines, 1);
6927 tt_str_op(s, OP_EQ, "");
6929 tor_free(s);
6930 config_line_append(&lines, "ignored", "0.3.4.1, 0.2.9.111-alpha, 4.4.4-rc");
6931 s = format_recommended_version_list(lines, 1);
6932 tt_str_op(s, OP_EQ, "0.2.9.111-alpha,0.3.4.1,4.4.4-rc");
6934 tor_free(s);
6935 config_line_append(&lines, "ignored", "0.1.2.3,0.2.9.10 ");
6936 s = format_recommended_version_list(lines, 1);
6937 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");
6939 /* There should be no warnings so far. */
6940 expect_no_log_entry();
6942 /* Now try a line with a space in it. */
6943 tor_free(s);
6944 config_line_append(&lines, "ignored", "1.3.3.8 1.3.3.7");
6945 s = format_recommended_version_list(lines, 1);
6946 tt_str_op(s, OP_EQ, "0.1.2.3,0.2.9.10,0.2.9.111-alpha,0.3.4.1,"
6947 "1.3.3.7,1.3.3.8,4.4.4-rc");
6949 expect_single_log_msg_containing(
6950 "Unexpected space in versions list member \"1.3.3.8 1.3.3.7\"." );
6952 /* Start over, with a line containing a bogus version */
6953 config_free_lines(lines);
6954 lines = NULL;
6955 tor_free(s);
6956 mock_clean_saved_logs();
6957 config_line_append(&lines, "ignored", "0.1.2.3, alpha-complex, 0.1.1.8-rc");
6958 s = format_recommended_version_list(lines,1);
6959 tt_str_op(s, OP_EQ, "0.1.1.8-rc,0.1.2.3,alpha-complex");
6960 expect_single_log_msg_containing(
6961 "Recommended version \"alpha-complex\" does not look valid.");
6963 done:
6964 tor_free(s);
6965 config_free_lines(lines);
6966 teardown_capture_of_logs();
6969 static void
6970 test_dir_add_fingerprint(void *arg)
6972 (void)arg;
6973 authdir_config_t *list;
6974 int ret;
6975 ed25519_secret_key_t seckey;
6976 ed25519_public_key_t pubkey_good, pubkey_bad;
6978 authdir_init_fingerprint_list();
6979 list = authdir_return_fingerprint_list();
6981 setup_capture_of_logs(LOG_WARN);
6983 /* RSA test - successful */
6984 ret = add_rsa_fingerprint_to_dir("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
6985 list, 0);
6986 tt_int_op(ret, OP_EQ, 0);
6988 /* RSA test - failure */
6989 ret = add_rsa_fingerprint_to_dir("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
6990 list, 0);
6991 tt_int_op(ret, OP_EQ, -1);
6993 /* ed25519 test - successful */
6994 ed25519_secret_key_generate(&seckey, 0);
6995 ed25519_public_key_generate(&pubkey_good, &seckey);
6997 ret = add_ed25519_to_dir(&pubkey_good, list, 0);
6998 tt_int_op(ret, OP_EQ, 0);
7000 /* ed25519 test - failure */
7001 digest256_from_base64((char *) pubkey_bad.pubkey, "gibberish");
7003 ret = add_ed25519_to_dir(&pubkey_bad, list, 0);
7004 tt_int_op(ret, OP_EQ, -1);
7006 done:
7007 teardown_capture_of_logs();
7008 dirserv_free_fingerprint_list();
7011 static void
7012 test_dir_dirserv_load_fingerprint_file(void *arg)
7014 (void)arg;
7015 char *fname = tor_strdup(get_fname("approved-routers"));
7017 // Neither RSA nor ed25519
7018 const char *router_lines_invalid =
7019 "!badexit notafingerprint";
7020 const char *router_lines_too_long =
7021 "!badexit thisisareallylongstringthatislongerthanafingerprint\n";
7022 const char *router_lines_bad_fmt_str =
7023 "!badexit ABCDEFGH|%1$p|%2$p|%3$p|%4$p|%5$p|%6$p\n";
7024 const char *router_lines_valid_rsa =
7025 "!badexit AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n";
7026 const char *router_lines_invalid_rsa =
7027 "!badexit ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\n";
7028 const char *router_lines_valid_ed25519 =
7029 "!badexit wqfLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx/Q\n";
7030 const char *router_lines_invalid_ed25519 =
7031 "!badexit --fLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx--\n";
7033 // Test: Invalid Fingerprint (not RSA or ed25519)
7034 setup_capture_of_logs(LOG_NOTICE);
7035 write_str_to_file(fname, router_lines_invalid, 0);
7036 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7037 expect_log_msg_containing("Invalid fingerprint");
7038 teardown_capture_of_logs();
7040 // Test: Very long string (longer than RSA or ed25519 key)
7041 setup_capture_of_logs(LOG_NOTICE);
7042 write_str_to_file(fname, router_lines_too_long, 0);
7043 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7044 expect_log_msg_containing("Invalid fingerprint");
7045 teardown_capture_of_logs();
7047 // Test: Format string exploit
7048 setup_capture_of_logs(LOG_NOTICE);
7049 write_str_to_file(fname, router_lines_bad_fmt_str, 0);
7050 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7051 expect_log_msg_containing("Invalid fingerprint");
7052 teardown_capture_of_logs();
7054 // Test: Valid RSA
7055 setup_capture_of_logs(LOG_NOTICE);
7056 write_str_to_file(fname, router_lines_valid_rsa, 0);
7057 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7058 teardown_capture_of_logs();
7060 // Test: Invalid RSA
7061 setup_capture_of_logs(LOG_NOTICE);
7062 write_str_to_file(fname, router_lines_invalid_rsa, 0);
7063 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7064 expect_log_msg_containing("Invalid fingerprint");
7065 teardown_capture_of_logs();
7067 // Test: Valid ed25519
7068 setup_capture_of_logs(LOG_NOTICE);
7069 write_str_to_file(fname, router_lines_valid_ed25519, 0);
7070 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7071 teardown_capture_of_logs();
7073 // Test: Invalid ed25519
7074 setup_capture_of_logs(LOG_NOTICE);
7075 write_str_to_file(fname, router_lines_invalid_ed25519, 0);
7076 tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7077 expect_log_msg_containing("Invalid fingerprint");
7078 teardown_capture_of_logs();
7080 done:
7081 tor_free(fname);
7082 dirserv_free_fingerprint_list();
7085 #define RESET_FP_LIST(list) STMT_BEGIN \
7086 dirserv_free_fingerprint_list(); \
7087 authdir_init_fingerprint_list(); \
7088 list = authdir_return_fingerprint_list(); \
7089 STMT_END
7091 static void
7092 test_dir_dirserv_router_get_status(void *arg)
7094 authdir_config_t *list;
7095 routerinfo_t *ri = NULL;
7096 ed25519_keypair_t kp1, kp2;
7097 char d[DIGEST_LEN];
7098 char fp[HEX_DIGEST_LEN+1];
7099 int ret;
7100 const char *msg;
7101 time_t now = time(NULL);
7103 (void)arg;
7105 crypto_pk_t *pk = pk_generate(0);
7107 authdir_init_fingerprint_list();
7108 list = authdir_return_fingerprint_list();
7110 /* Set up the routerinfo */
7111 ri = tor_malloc_zero(sizeof(routerinfo_t));
7112 tor_addr_from_ipv4h(&ri->ipv4_addr, 0xc0a80001u);
7113 ri->ipv4_orport = 9001;
7114 ri->platform = tor_strdup("0.4.0.1-alpha");
7115 ri->nickname = tor_strdup("Jessica");
7116 ri->identity_pkey = crypto_pk_dup_key(pk);
7118 curve25519_keypair_t ri_onion_keypair;
7119 curve25519_keypair_generate(&ri_onion_keypair, 0);
7120 ri->onion_curve25519_pkey = tor_memdup(&ri_onion_keypair.pubkey,
7121 sizeof(curve25519_public_key_t));
7123 ed25519_secret_key_from_seed(&kp1.seckey,
7124 (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
7125 ed25519_public_key_generate(&kp1.pubkey, &kp1.seckey);
7126 ed25519_secret_key_from_seed(&kp2.seckey,
7127 (const uint8_t*)"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
7128 ed25519_public_key_generate(&kp2.pubkey, &kp2.seckey);
7129 ri->cache_info.signing_key_cert = tor_cert_create_ed25519(&kp1,
7130 CERT_TYPE_ID_SIGNING,
7131 &kp2.pubkey,
7132 now, 86400,
7133 CERT_FLAG_INCLUDE_SIGNING_KEY);
7135 crypto_pk_get_digest(ri->identity_pkey, d);
7136 base16_encode(fp, HEX_DIGEST_LEN + 1, d, DIGEST_LEN);
7138 /* Try on an empty fingerprint list */
7139 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7140 tt_int_op(ret, OP_EQ, 0);
7141 RESET_FP_LIST(list);
7143 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7144 tt_int_op(ret, OP_EQ, 0);
7145 RESET_FP_LIST(list);
7147 /* Try an accepted router */
7148 add_rsa_fingerprint_to_dir(fp, list, 0);
7149 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7150 tt_int_op(ret, OP_EQ, 0);
7151 RESET_FP_LIST(list);
7153 add_ed25519_to_dir(&kp1.pubkey, list, 0);
7154 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7155 tt_int_op(ret, OP_EQ, 0);
7156 RESET_FP_LIST(list);
7158 /* Try a rejected router */
7159 add_rsa_fingerprint_to_dir(fp, list, RTR_REJECT);
7160 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7161 tt_int_op(ret, OP_EQ, RTR_REJECT);
7162 RESET_FP_LIST(list);
7164 add_ed25519_to_dir(&kp1.pubkey, list, RTR_REJECT);
7165 ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7166 tt_int_op(ret, OP_EQ, RTR_REJECT);
7167 RESET_FP_LIST(list);
7169 done:
7170 dirserv_free_fingerprint_list();
7171 routerinfo_free(ri);
7172 crypto_pk_free(pk);
7175 static void
7176 test_dir_dirserv_would_reject_router(void *arg)
7178 authdir_config_t *list;
7179 routerstatus_t rs;
7180 vote_routerstatus_t vrs;
7181 ed25519_keypair_t kp;
7182 char fp[HEX_DIGEST_LEN+1];
7184 (void)arg;
7186 authdir_init_fingerprint_list();
7187 list = authdir_return_fingerprint_list();
7189 /* Set up the routerstatus */
7190 memset(&rs, 0, sizeof(rs));
7191 tor_addr_from_ipv4h(&rs.ipv4_addr, 0xc0a80001u);
7192 rs.ipv4_orport = 9001;
7193 strlcpy(rs.nickname, "Nicole", sizeof(rs.nickname));
7194 memcpy(rs.identity_digest, "Cloud nine is great ", DIGEST_LEN);
7196 ed25519_secret_key_from_seed(&kp.seckey,
7197 (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
7198 ed25519_public_key_generate(&kp.pubkey, &kp.seckey);
7200 base16_encode(fp, HEX_DIGEST_LEN + 1, rs.identity_digest, DIGEST_LEN);
7202 /* Setup the vote_routerstatus_t. */
7203 memcpy(vrs.ed25519_id, &kp.pubkey, ED25519_PUBKEY_LEN);
7205 /* Try an empty fingerprint list */
7206 tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7207 RESET_FP_LIST(list);
7209 tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7210 RESET_FP_LIST(list);
7212 /* Try an accepted router */
7213 add_rsa_fingerprint_to_dir(fp, list, 0);
7214 tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7215 RESET_FP_LIST(list);
7217 add_ed25519_to_dir(&kp.pubkey, list, 0);
7218 tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7219 RESET_FP_LIST(list);
7221 /* Try a rejected router */
7222 add_rsa_fingerprint_to_dir(fp, list, RTR_REJECT);
7223 tt_assert(dirserv_would_reject_router(&rs, &vrs));
7224 RESET_FP_LIST(list);
7226 add_ed25519_to_dir(&kp.pubkey, list, RTR_REJECT);
7227 tt_assert(dirserv_would_reject_router(&rs, &vrs));
7228 RESET_FP_LIST(list);
7230 done:
7231 dirserv_free_fingerprint_list();
7234 static void
7235 test_dir_dirserv_add_own_fingerprint(void *arg)
7237 authdir_config_t *list;
7238 char digest[DIGEST_LEN];
7239 crypto_pk_t *pk = pk_generate(0);
7241 (void)arg;
7243 init_mock_ed_keys(pk);
7244 authdir_init_fingerprint_list();
7245 list = authdir_return_fingerprint_list();
7246 dirserv_add_own_fingerprint(pk, get_master_identity_key());
7248 /* Check if we have a RSA key. */
7249 crypto_pk_get_digest(pk, digest);
7250 tt_assert(digestmap_get(list->status_by_digest, digest));
7252 /* Check if we have a ed25519 key. */
7253 tt_assert(digest256map_get(list->status_by_digest256,
7254 get_master_identity_key()->pubkey));
7256 RESET_FP_LIST(list);
7258 done:
7259 dirserv_free_fingerprint_list();
7260 crypto_pk_free(pk);
7263 #ifndef COCCI
7264 #define DIR_LEGACY(name) \
7265 { #name, test_dir_ ## name , TT_FORK, NULL, NULL }
7267 #define DIR(name,flags) \
7268 { #name, test_dir_##name, (flags), NULL, NULL }
7270 /* where arg is a string constant */
7271 #define DIR_ARG(name,flags,arg) \
7272 { #name "_" arg, test_dir_##name, (flags), &passthrough_setup, (void*) arg }
7273 #endif /* !defined(COCCI) */
7275 struct testcase_t dir_tests[] = {
7276 DIR_LEGACY(nicknames),
7277 /* extrainfo without any stats */
7278 DIR_ARG(formats_rsa_ed25519, TT_FORK, ""),
7279 /* on a bridge */
7280 DIR_ARG(formats_rsa_ed25519, TT_FORK, "b"),
7281 /* extrainfo with basic stats */
7282 DIR_ARG(formats_rsa_ed25519, TT_FORK, "e"),
7283 DIR_ARG(formats_rsa_ed25519, TT_FORK, "be"),
7284 /* extrainfo with all stats */
7285 DIR_ARG(formats_rsa_ed25519, TT_FORK, "es"),
7286 DIR_ARG(formats_rsa_ed25519, TT_FORK, "bes"),
7287 DIR(routerinfo_parsing, 0),
7288 DIR(extrainfo_parsing, 0),
7289 DIR(parse_router_list, TT_FORK),
7290 DIR(load_routers, TT_FORK),
7291 DIR(load_extrainfo, TT_FORK),
7292 DIR(getinfo_extra, 0),
7293 DIR_LEGACY(versions),
7294 DIR_LEGACY(fp_pairs),
7295 DIR(split_fps, 0),
7296 DIR_LEGACY(measured_bw_kb),
7297 DIR_LEGACY(measured_bw_kb_line_is_after_headers),
7298 DIR_LEGACY(measured_bw_kb_cache),
7299 DIR_LEGACY(dirserv_read_measured_bandwidths),
7300 DIR(bwauth_bw_file_digest256, 0),
7301 DIR_LEGACY(param_voting),
7302 DIR(param_voting_lookup, 0),
7303 DIR_LEGACY(v3_networkstatus),
7304 DIR(random_weighted, 0),
7305 DIR(scale_bw, 0),
7306 DIR_LEGACY(clip_unmeasured_bw_kb),
7307 DIR_LEGACY(clip_unmeasured_bw_kb_alt),
7308 DIR(fmt_control_ns, 0),
7309 DIR(dirserv_set_routerstatus_testing, TT_FORK),
7310 DIR(http_handling, 0),
7311 DIR(purpose_needs_anonymity_returns_true_for_bridges, 0),
7312 DIR(purpose_needs_anonymity_returns_false_for_own_bridge_desc, 0),
7313 DIR(purpose_needs_anonymity_returns_true_by_default, 0),
7314 DIR(purpose_needs_anonymity_returns_true_for_sensitive_purpose, 0),
7315 DIR(purpose_needs_anonymity_ret_false_for_non_sensitive_conn, 0),
7316 DIR(post_parsing, 0),
7317 DIR(fetch_type, 0),
7318 DIR(packages, 0),
7319 DIR(download_status_random_backoff, 0),
7320 DIR(download_status_random_backoff_ranges, 0),
7321 DIR(download_status_increment, TT_FORK),
7322 DIR(authdir_type_to_string, 0),
7323 DIR(conn_purpose_to_string, 0),
7324 DIR(should_use_directory_guards, 0),
7325 DIR(should_not_init_request_to_ourselves, TT_FORK),
7326 DIR(should_not_init_request_to_dir_auths_without_v3_info, 0),
7327 DIR(should_init_request_to_dir_auths, 0),
7328 DIR(choose_compression_level, 0),
7329 DIR(dump_unparseable_descriptors, 0),
7330 DIR(populate_dump_desc_fifo, 0),
7331 DIR(populate_dump_desc_fifo_2, 0),
7332 DIR_ARG(find_dl_min_delay, TT_FORK, "bfd"),
7333 DIR_ARG(find_dl_min_delay, TT_FORK, "bad"),
7334 DIR_ARG(find_dl_min_delay, TT_FORK, "cfd"),
7335 DIR_ARG(find_dl_min_delay, TT_FORK, "cad"),
7336 DIR_ARG(find_dl_min_delay, TT_FORK, "bfr"),
7337 DIR_ARG(find_dl_min_delay, TT_FORK, "bar"),
7338 DIR_ARG(find_dl_min_delay, TT_FORK, "cfr"),
7339 DIR_ARG(find_dl_min_delay, TT_FORK, "car"),
7340 DIR(assumed_flags, 0),
7341 DIR(matching_flags, 0),
7342 DIR(networkstatus_compute_bw_weights_v10, 0),
7343 DIR(platform_str, 0),
7344 DIR(format_versions_list, TT_FORK),
7345 DIR(add_fingerprint, TT_FORK),
7346 DIR(dirserv_load_fingerprint_file, TT_FORK),
7347 DIR(dirserv_router_get_status, TT_FORK),
7348 DIR(dirserv_would_reject_router, TT_FORK),
7349 DIR(dirserv_add_own_fingerprint, TT_FORK),
7350 END_OF_TESTCASES