diff options
Diffstat (limited to 'src/test/test_dir.c')
-rw-r--r-- | src/test/test_dir.c | 2123 |
1 files changed, 1319 insertions, 804 deletions
diff --git a/src/test/test_dir.c b/src/test/test_dir.c index 4cdbfb4f84..37b015b72d 100644 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@ -1,12 +1,13 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2016, The Tor Project, Inc. */ + * Copyright (c) 2007-2017, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" #include <math.h> #define CONFIG_PRIVATE +#define CONTROL_PRIVATE #define DIRSERV_PRIVATE #define DIRVOTE_PRIVATE #define ROUTER_PRIVATE @@ -17,12 +18,16 @@ #define RELAY_PRIVATE #include "or.h" +#include "bridges.h" #include "confparse.h" #include "config.h" +#include "control.h" #include "crypto_ed25519.h" +#include "crypto_rand.h" #include "directory.h" #include "dirserv.h" -#include "dirvote.h" +#include "dirauth/dirvote.h" +#include "entrynodes.h" #include "hibernate.h" #include "memarea.h" #include "networkstatus.h" @@ -31,12 +36,13 @@ #include "routerlist.h" #include "routerparse.h" #include "routerset.h" -#include "shared_random_state.h" +#include "dirauth/shared_random_state.h" #include "test.h" #include "test_dir_common.h" #include "torcert.h" #include "relay.h" #include "log_test_helpers.h" +#include "voting_schedule.h" #define NS_MODULE dir @@ -272,8 +278,8 @@ test_dir_formats(void *arg) tt_int_op(rp1->bandwidthrate,OP_EQ, r1->bandwidthrate); tt_int_op(rp1->bandwidthburst,OP_EQ, r1->bandwidthburst); tt_int_op(rp1->bandwidthcapacity,OP_EQ, r1->bandwidthcapacity); - tt_assert(crypto_pk_cmp_keys(rp1->onion_pkey, pk1) == 0); - tt_assert(crypto_pk_cmp_keys(rp1->identity_pkey, pk2) == 0); + tt_int_op(crypto_pk_cmp_keys(rp1->onion_pkey, pk1), OP_EQ, 0); + tt_int_op(crypto_pk_cmp_keys(rp1->identity_pkey, pk2), OP_EQ, 0); tt_assert(rp1->supports_tunnelled_dir_requests); //tt_assert(rp1->exit_policy == NULL); tor_free(buf); @@ -291,9 +297,9 @@ test_dir_formats(void *arg) strlcat(buf2, "master-key-ed25519 ", sizeof(buf2)); { char k[ED25519_BASE64_LEN+1]; - tt_assert(ed25519_public_to_base64(k, - &r2->cache_info.signing_key_cert->signing_key) - >= 0); + tt_int_op(ed25519_public_to_base64(k, + &r2->cache_info.signing_key_cert->signing_key), + OP_GE, 0); strlcat(buf2, k, sizeof(buf2)); strlcat(buf2, "\n", sizeof(buf2)); } @@ -328,7 +334,7 @@ test_dir_formats(void *arg) ntor_cc = make_ntor_onion_key_crosscert(&r2_onion_keypair, &kp1.pubkey, r2->cache_info.published_on, - MIN_ONION_KEY_LIFETIME, + get_onion_key_lifetime(), &ntor_cc_sign); tt_assert(ntor_cc); base64_encode(cert_buf, sizeof(cert_buf), @@ -389,8 +395,8 @@ test_dir_formats(void *arg) tt_mem_op(rp2->onion_curve25519_pkey->public_key,OP_EQ, r2->onion_curve25519_pkey->public_key, CURVE25519_PUBKEY_LEN); - tt_assert(crypto_pk_cmp_keys(rp2->onion_pkey, pk2) == 0); - tt_assert(crypto_pk_cmp_keys(rp2->identity_pkey, pk1) == 0); + tt_int_op(crypto_pk_cmp_keys(rp2->onion_pkey, pk2), OP_EQ, 0); + tt_int_op(crypto_pk_cmp_keys(rp2->identity_pkey, pk1), OP_EQ, 0); tt_assert(rp2->supports_tunnelled_dir_requests); tt_int_op(smartlist_len(rp2->exit_policy),OP_EQ, 2); @@ -419,7 +425,7 @@ test_dir_formats(void *arg) add_fingerprint_to_dir(buf, fingerprint_list, 0); } -#endif +#endif /* 0 */ dirserv_free_fingerprint_list(); done: @@ -475,34 +481,34 @@ test_dir_routerinfo_parsing(void *arg) routerinfo_free(ri); ri = router_parse_entry_from_string(EX_RI_MINIMAL, NULL, 0, 0, "@purpose bridge\n", NULL); - tt_assert(ri != NULL); + tt_ptr_op(ri, OP_NE, NULL); tt_assert(ri->purpose == ROUTER_PURPOSE_BRIDGE); routerinfo_free(ri); /* bad annotations prepended. */ ri = router_parse_entry_from_string(EX_RI_MINIMAL, NULL, 0, 0, "@purpose\n", NULL); - tt_assert(ri == NULL); + tt_ptr_op(ri, OP_EQ, NULL); /* bad annotations on router. */ ri = router_parse_entry_from_string("@purpose\nrouter x\n", NULL, 0, 1, NULL, NULL); - tt_assert(ri == NULL); + tt_ptr_op(ri, OP_EQ, NULL); /* unwanted annotations on router. */ ri = router_parse_entry_from_string("@purpose foo\nrouter x\n", NULL, 0, 0, NULL, NULL); - tt_assert(ri == NULL); + tt_ptr_op(ri, OP_EQ, NULL); /* No signature. */ ri = router_parse_entry_from_string("router x\n", NULL, 0, 0, NULL, NULL); - tt_assert(ri == NULL); + tt_ptr_op(ri, OP_EQ, NULL); /* Not a router */ routerinfo_free(ri); ri = router_parse_entry_from_string("hello\n", NULL, 0, 0, NULL, NULL); - tt_assert(ri == NULL); + tt_ptr_op(ri, OP_EQ, NULL); CHECK_FAIL(EX_RI_BAD_SIG1, 1); CHECK_FAIL(EX_RI_BAD_SIG2, 1); @@ -563,7 +569,7 @@ test_dir_routerinfo_parsing(void *arg) static void routerinfo_free_wrapper_(void *arg) { - routerinfo_free(arg); + routerinfo_free_(arg); } static void @@ -629,11 +635,11 @@ test_dir_extrainfo_parsing(void *arg) ADD(EX_EI_ED_MISPLACED_SIG); CHECK_OK(EX_EI_MINIMAL); - tt_assert(!ei->pending_sig); + tt_ptr_op(ei->pending_sig, OP_EQ, NULL); CHECK_OK(EX_EI_MAXIMAL); - tt_assert(!ei->pending_sig); + tt_ptr_op(ei->pending_sig, OP_EQ, NULL); CHECK_OK(EX_EI_GOOD_ED_EI); - tt_assert(!ei->pending_sig); + tt_ptr_op(ei->pending_sig, OP_EQ, NULL); CHECK_FAIL(EX_EI_BAD_SIG1,1); CHECK_FAIL(EX_EI_BAD_SIG2,1); @@ -660,7 +666,7 @@ test_dir_extrainfo_parsing(void *arg) escaped(NULL); extrainfo_free(ei); routerinfo_free(ri); - digestmap_free((digestmap_t*)map, routerinfo_free_wrapper_); + digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_); } static void @@ -678,16 +684,16 @@ test_dir_parse_router_list(void *arg) routerinfo_t *ri = NULL; char d[DIGEST_LEN]; - smartlist_add(chunks, tor_strdup(EX_RI_MINIMAL)); // ri 0 - smartlist_add(chunks, tor_strdup(EX_RI_BAD_PORTS)); // bad ri 0 - smartlist_add(chunks, tor_strdup(EX_EI_MAXIMAL)); // ei 0 - smartlist_add(chunks, tor_strdup(EX_EI_BAD_SIG2)); // bad ei -- - smartlist_add(chunks, tor_strdup(EX_EI_BAD_NICKNAME));// bad ei 0 - smartlist_add(chunks, tor_strdup(EX_RI_BAD_SIG1)); // bad ri -- - smartlist_add(chunks, tor_strdup(EX_EI_BAD_PUBLISHED)); // bad ei 1 - smartlist_add(chunks, tor_strdup(EX_RI_MAXIMAL)); // ri 1 - smartlist_add(chunks, tor_strdup(EX_RI_BAD_FAMILY)); // bad ri 1 - smartlist_add(chunks, tor_strdup(EX_EI_MINIMAL)); // ei 1 + smartlist_add_strdup(chunks, EX_RI_MINIMAL); // ri 0 + smartlist_add_strdup(chunks, EX_RI_BAD_PORTS); // bad ri 0 + smartlist_add_strdup(chunks, EX_EI_MAXIMAL); // ei 0 + smartlist_add_strdup(chunks, EX_EI_BAD_SIG2); // bad ei -- + smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME);// bad ei 0 + smartlist_add_strdup(chunks, EX_RI_BAD_SIG1); // bad ri -- + smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED); // bad ei 1 + smartlist_add_strdup(chunks, EX_RI_MAXIMAL); // ri 1 + smartlist_add_strdup(chunks, EX_RI_BAD_FAMILY); // bad ri 1 + smartlist_add_strdup(chunks, EX_EI_MINIMAL); // ei 1 list = smartlist_join_strings(chunks, "", 0, NULL); @@ -756,7 +762,7 @@ test_dir_parse_router_list(void *arg) smartlist_free(chunks); routerinfo_free(ri); if (map) { - digestmap_free((digestmap_t*)map, routerinfo_free_wrapper_); + digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_); router_get_routerlist()->identity_map = (struct digest_ri_map_t*)digestmap_new(); } @@ -812,19 +818,19 @@ test_dir_load_routers(void *arg) #define ADD(str) \ do { \ tt_int_op(0,OP_EQ,router_get_router_hash(str, strlen(str), buf)); \ - smartlist_add(wanted, tor_strdup(hex_str(buf, DIGEST_LEN))); \ + smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN)); \ } while (0) MOCK(router_get_dl_status_by_descriptor_digest, mock_router_get_dl_status); update_approx_time(1412510400); - smartlist_add(chunks, tor_strdup(EX_RI_MINIMAL)); - smartlist_add(chunks, tor_strdup(EX_RI_BAD_FINGERPRINT)); - smartlist_add(chunks, tor_strdup(EX_RI_BAD_SIG2)); - smartlist_add(chunks, tor_strdup(EX_RI_MAXIMAL)); - smartlist_add(chunks, tor_strdup(EX_RI_BAD_PORTS)); - smartlist_add(chunks, tor_strdup(EX_RI_BAD_TOKENS)); + smartlist_add_strdup(chunks, EX_RI_MINIMAL); + smartlist_add_strdup(chunks, EX_RI_BAD_FINGERPRINT); + smartlist_add_strdup(chunks, EX_RI_BAD_SIG2); + smartlist_add_strdup(chunks, EX_RI_MAXIMAL); + smartlist_add_strdup(chunks, EX_RI_BAD_PORTS); + smartlist_add_strdup(chunks, EX_RI_BAD_TOKENS); /* not ADDing MINIMIAL */ ADD(EX_RI_MAXIMAL); @@ -909,6 +915,23 @@ mock_get_by_ei_desc_digest(const char *d) } } +static signed_descriptor_t * +mock_ei_get_by_ei_digest(const char *d) +{ + char hex[HEX_DIGEST_LEN+1]; + base16_encode(hex, sizeof(hex), d, DIGEST_LEN); + signed_descriptor_t *sd = &sd_ei_minimal; + + if (!strcmp(hex, "11E0EDF526950739F7769810FCACAB8C882FAEEE")) { + sd->signed_descriptor_body = (char *)EX_EI_MINIMAL; + sd->signed_descriptor_len = sizeof(EX_EI_MINIMAL); + sd->annotations_len = 0; + sd->saved_location = SAVED_NOWHERE; + return sd; + } + return NULL; +} + static smartlist_t *mock_ei_insert_list = NULL; static was_router_added_t mock_ei_insert(routerlist_t *rl, extrainfo_t *ei, int warn_if_incompatible) @@ -932,18 +955,18 @@ test_dir_load_extrainfo(void *arg) #define ADD(str) \ do { \ tt_int_op(0,OP_EQ,router_get_extrainfo_hash(str, strlen(str), buf)); \ - smartlist_add(wanted, tor_strdup(hex_str(buf, DIGEST_LEN))); \ + smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN)); \ } while (0) mock_ei_insert_list = smartlist_new(); MOCK(router_get_by_extrainfo_digest, mock_get_by_ei_desc_digest); MOCK(extrainfo_insert, mock_ei_insert); - smartlist_add(chunks, tor_strdup(EX_EI_MINIMAL)); - smartlist_add(chunks, tor_strdup(EX_EI_BAD_NICKNAME)); - smartlist_add(chunks, tor_strdup(EX_EI_MAXIMAL)); - smartlist_add(chunks, tor_strdup(EX_EI_BAD_PUBLISHED)); - smartlist_add(chunks, tor_strdup(EX_EI_BAD_TOKENS)); + smartlist_add_strdup(chunks, EX_EI_MINIMAL); + smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME); + smartlist_add_strdup(chunks, EX_EI_MAXIMAL); + smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED); + smartlist_add_strdup(chunks, EX_EI_BAD_TOKENS); /* not ADDing MINIMIAL */ ADD(EX_EI_MAXIMAL); @@ -998,6 +1021,37 @@ test_dir_load_extrainfo(void *arg) } static void +test_dir_getinfo_extra(void *arg) +{ + int r; + char *answer = NULL; + const char *errmsg = NULL; + + (void)arg; + MOCK(extrainfo_get_by_descriptor_digest, mock_ei_get_by_ei_digest); + r = getinfo_helper_dir(NULL, "extra-info/digest/" + "11E0EDF526950739F7769810FCACAB8C882FAEEE", &answer, + &errmsg); + tt_int_op(0, OP_EQ, r); + tt_ptr_op(NULL, OP_EQ, errmsg); + tt_str_op(answer, OP_EQ, EX_EI_MINIMAL); + tor_free(answer); + + answer = NULL; + r = getinfo_helper_dir(NULL, "extra-info/digest/" + "NOTAVALIDHEXSTRINGNOTAVALIDHEXSTRINGNOTA", &answer, + &errmsg); + tt_int_op(0, OP_EQ, r); + /* getinfo_helper_dir() should maybe return an error here but doesn't */ + tt_ptr_op(NULL, OP_EQ, errmsg); + /* In any case, there should be no answer for an invalid hex string. */ + tt_ptr_op(NULL, OP_EQ, answer); + + done: + UNMOCK(extrainfo_get_by_descriptor_digest); +} + +static void test_dir_versions(void *arg) { tor_version_t ver1; @@ -1064,6 +1118,7 @@ test_dir_versions(void *arg) tt_int_op(0, OP_EQ, ver1.patchlevel); tt_int_op(VER_RELEASE, OP_EQ, ver1.status); tt_str_op("alpha", OP_EQ, ver1.status_tag); + /* Go through the full set of status tags */ tt_int_op(0, OP_EQ, tor_version_parse("2.1.700-alpha", &ver1)); tt_int_op(2, OP_EQ, ver1.major); tt_int_op(1, OP_EQ, ver1.minor); @@ -1078,6 +1133,60 @@ test_dir_versions(void *arg) tt_int_op(0, OP_EQ, ver1.patchlevel); tt_int_op(VER_RELEASE, OP_EQ, ver1.status); tt_str_op("alpha-dev", OP_EQ, ver1.status_tag); + tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.5-rc", &ver1)); + tt_int_op(0, OP_EQ, ver1.major); + tt_int_op(2, OP_EQ, ver1.minor); + tt_int_op(9, OP_EQ, ver1.micro); + tt_int_op(5, OP_EQ, ver1.patchlevel); + tt_int_op(VER_RELEASE, OP_EQ, ver1.status); + tt_str_op("rc", OP_EQ, ver1.status_tag); + tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.6-rc-dev", &ver1)); + tt_int_op(0, OP_EQ, ver1.major); + tt_int_op(2, OP_EQ, ver1.minor); + tt_int_op(9, OP_EQ, ver1.micro); + tt_int_op(6, OP_EQ, ver1.patchlevel); + tt_int_op(VER_RELEASE, OP_EQ, ver1.status); + tt_str_op("rc-dev", OP_EQ, ver1.status_tag); + tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.8", &ver1)); + tt_int_op(0, OP_EQ, ver1.major); + tt_int_op(2, OP_EQ, ver1.minor); + tt_int_op(9, OP_EQ, ver1.micro); + tt_int_op(8, OP_EQ, ver1.patchlevel); + tt_int_op(VER_RELEASE, OP_EQ, ver1.status); + tt_str_op("", OP_EQ, ver1.status_tag); + tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.9-dev", &ver1)); + tt_int_op(0, OP_EQ, ver1.major); + tt_int_op(2, OP_EQ, ver1.minor); + tt_int_op(9, OP_EQ, ver1.micro); + tt_int_op(9, OP_EQ, ver1.patchlevel); + tt_int_op(VER_RELEASE, OP_EQ, ver1.status); + tt_str_op("dev", OP_EQ, ver1.status_tag); + /* In #21450, we fixed an inconsistency in parsing versions > INT32_MAX + * between i386 and x86_64, as we used tor_parse_long, and then cast to int + */ + tt_int_op(0, OP_EQ, tor_version_parse("0.2147483647.0", &ver1)); + tt_int_op(0, OP_EQ, ver1.major); + tt_int_op(2147483647, OP_EQ, ver1.minor); + tt_int_op(0, OP_EQ, ver1.micro); + tt_int_op(0, OP_EQ, ver1.patchlevel); + tt_int_op(VER_RELEASE, OP_EQ, ver1.status); + tt_str_op("", OP_EQ, ver1.status_tag); + tt_int_op(-1, OP_EQ, tor_version_parse("0.2147483648.0", &ver1)); + tt_int_op(-1, OP_EQ, tor_version_parse("0.4294967295.0", &ver1)); + /* In #21278, we reject negative version components */ + tt_int_op(-1, OP_EQ, tor_version_parse("0.-1.0", &ver1)); + tt_int_op(-1, OP_EQ, tor_version_parse("0.-2147483648.0", &ver1)); + tt_int_op(-1, OP_EQ, tor_version_parse("0.-4294967295.0", &ver1)); + /* In #21507, we reject version components with non-numeric prefixes */ + tt_int_op(-1, OP_EQ, tor_version_parse("0.-0.0", &ver1)); + tt_int_op(-1, OP_EQ, tor_version_parse("+1.0.0", &ver1)); + /* use the list in isspace() */ + tt_int_op(-1, OP_EQ, tor_version_parse("0.\t0.0", &ver1)); + tt_int_op(-1, OP_EQ, tor_version_parse("0.\n0.0", &ver1)); + tt_int_op(-1, OP_EQ, tor_version_parse("0.\v0.0", &ver1)); + tt_int_op(-1, OP_EQ, tor_version_parse("0.\f0.0", &ver1)); + tt_int_op(-1, OP_EQ, tor_version_parse("0.\r0.0", &ver1)); + tt_int_op(-1, OP_EQ, tor_version_parse("0. 0.0", &ver1)); #define tt_versionstatus_op(vs1, op, vs2) \ tt_assert_test_type(vs1,vs2,#vs1" "#op" "#vs2,version_status_t, \ @@ -1097,6 +1206,7 @@ test_dir_versions(void *arg) test_v_i_o(VS_RECOMMENDED, "0.0.7rc2", "0.0.7,Tor 0.0.7rc2,Tor 0.0.8"); test_v_i_o(VS_OLD, "0.0.5.0", "0.0.5.1-cvs"); test_v_i_o(VS_NEW_IN_SERIES, "0.0.5.1-cvs", "0.0.5, 0.0.6"); + test_v_i_o(VS_NEW, "0.2.9.9-dev", "0.2.9.9"); /* Not on list, but newer than any in same series. */ test_v_i_o(VS_NEW_IN_SERIES, "0.1.0.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0"); @@ -1135,6 +1245,70 @@ test_dir_versions(void *arg) "Tor 0.2.1.0-dev (r99)")); tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.1", "Tor 0.2.1.0-dev (r99)")); + /* And git revisions */ + tt_int_op(1,OP_EQ, tor_version_as_new_as( + "Tor 0.2.9.9 (git-56788a2489127072)", + "Tor 0.2.9.9 (git-56788a2489127072)")); + /* a git revision is newer than no git revision */ + tt_int_op(1,OP_EQ, tor_version_as_new_as( + "Tor 0.2.9.9 (git-56788a2489127072)", + "Tor 0.2.9.9")); + /* a longer git revision is newer than a shorter git revision + * this should be true if they prefix-match, but if they don't, they are + * incomparable, because hashes aren't ordered (but we compare their bytes + * anyway) */ + tt_int_op(1,OP_EQ, tor_version_as_new_as( + "Tor 0.2.9.9 (git-56788a2489127072d513cf4baf35a8ff475f3c7b)", + "Tor 0.2.9.9 (git-56788a2489127072)")); + tt_int_op(1,OP_EQ, tor_version_as_new_as( + "Tor 0.2.9.9 (git-0102)", + "Tor 0.2.9.9 (git-03)")); + tt_int_op(1,OP_EQ, tor_version_as_new_as( + "Tor 0.2.9.9 (git-0102)", + "Tor 0.2.9.9 (git-00)")); + tt_int_op(1,OP_EQ, tor_version_as_new_as( + "Tor 0.2.9.9 (git-01)", + "Tor 0.2.9.9 (git-00)")); + tt_int_op(0,OP_EQ, tor_version_as_new_as( + "Tor 0.2.9.9 (git-00)", + "Tor 0.2.9.9 (git-01)")); + /* In #21278, we compare without integer overflows. + * But since #21450 limits version components to [0, INT32_MAX], it is no + * longer possible to cause an integer overflow in tor_version_compare() */ + tt_int_op(0,OP_EQ, tor_version_as_new_as( + "Tor 0.0.0.0", + "Tor 2147483647.0.0.0")); + tt_int_op(1,OP_EQ, tor_version_as_new_as( + "Tor 2147483647.0.0.0", + "Tor 0.0.0.0")); + /* These versions used to cause an overflow, now they don't parse + * (and authorities reject their descriptors), and log a BUG message */ + setup_full_capture_of_logs(LOG_WARN); + tt_int_op(0,OP_EQ, tor_version_as_new_as( + "Tor 0.0.0.0", + "Tor 0.-2147483648.0.0")); + expect_single_log_msg_containing("unparseable"); + mock_clean_saved_logs(); + tt_int_op(0,OP_EQ, tor_version_as_new_as( + "Tor 0.2147483647.0.0", + "Tor 0.-1.0.0")); + expect_single_log_msg_containing("unparseable"); + mock_clean_saved_logs(); + tt_int_op(0,OP_EQ, tor_version_as_new_as( + "Tor 0.2147483647.0.0", + "Tor 0.-2147483648.0.0")); + expect_single_log_msg_containing("unparseable"); + mock_clean_saved_logs(); + tt_int_op(1,OP_EQ, tor_version_as_new_as( + "Tor 4294967295.0.0.0", + "Tor 0.0.0.0")); + expect_no_log_entry(); + tt_int_op(0,OP_EQ, tor_version_as_new_as( + "Tor 0.4294967295.0.0", + "Tor 0.-4294967295.0.0")); + expect_single_log_msg_containing("unparseable"); + mock_clean_saved_logs(); + teardown_capture_of_logs(); /* Now try git revisions */ tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00ff)", &ver1)); @@ -1144,11 +1318,24 @@ test_dir_versions(void *arg) tt_int_op(7,OP_EQ, ver1.patchlevel); tt_int_op(3,OP_EQ, ver1.git_tag_len); tt_mem_op(ver1.git_tag,OP_EQ, "\xff\x00\xff", 3); + /* reject bad hex digits */ tt_int_op(-1,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00xx)", &ver1)); + /* reject odd hex digit count */ tt_int_op(-1,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00fff)", &ver1)); + /* ignore "git " */ tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git ff00fff)", &ver1)); + /* standard length is 16 hex digits */ + tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git-0010203040506070)", + &ver1)); + /* length limit is 40 hex digits */ + tt_int_op(0,OP_EQ, tor_version_parse( + "0.5.6.7 (git-000102030405060708090a0b0c0d0e0f10111213)", + &ver1)); + tt_int_op(-1,OP_EQ, tor_version_parse( + "0.5.6.7 (git-000102030405060708090a0b0c0d0e0f1011121314)", + &ver1)); done: - ; + teardown_capture_of_logs(); } /** Run unit tests for directory fp_pair functions. */ @@ -1314,6 +1501,13 @@ test_dir_measured_bw_kb(void *arg) "bw=1024 junk=007\n", "misc=junk node_id=$557365204145532d32353620696e73746561642e " "bw=1024 junk=007\n", + /* check whether node_id can be at the end */ + "bw=1024 node_id=$557365204145532d32353620696e73746561642e\n", + /* check whether node_id can be at the end and bw has something in front*/ + "foo=bar bw=1024 node_id=$557365204145532d32353620696e73746561642e\n", + /* check whether node_id can be at the end and something in the + * in the middle of bw and node_id */ + "bw=1024 foo=bar node_id=$557365204145532d32353620696e73746561642e\n", "end" }; const char *lines_fail[] = { @@ -1353,12 +1547,18 @@ test_dir_measured_bw_kb(void *arg) (void)arg; for (i = 0; strcmp(lines_fail[i], "end"); i++) { //fprintf(stderr, "Testing: %s\n", lines_fail[i]); - tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i]) == -1); + /* Testing only with line_is_after_headers = 1. Tests with + * line_is_after_headers = 0 in + * test_dir_measured_bw_kb_line_is_after_headers */ + tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 1) == -1); } for (i = 0; strcmp(lines_pass[i], "end"); i++) { //fprintf(stderr, "Testing: %s %d\n", lines_pass[i], TOR_ISSPACE('\n')); - tt_assert(measured_bw_line_parse(&mbwl, lines_pass[i]) == 0); + /* Testing only with line_is_after_headers = 1. Tests with + * line_is_after_headers = 0 in + * test_dir_measured_bw_kb_line_is_after_headers */ + tt_assert(measured_bw_line_parse(&mbwl, lines_pass[i], 1) == 0); tt_assert(mbwl.bw_kb == 1024); tt_assert(strcmp(mbwl.node_hex, "557365204145532d32353620696e73746561642e") == 0); @@ -1370,7 +1570,7 @@ test_dir_measured_bw_kb(void *arg) /* Test dirserv_read_measured_bandwidths */ static void -test_dir_dirserv_read_measured_bandwidths(void *arg) +test_dir_dirserv_read_measured_bandwidths_empty(void *arg) { char *fname=NULL; (void)arg; @@ -1387,6 +1587,129 @@ test_dir_dirserv_read_measured_bandwidths(void *arg) teardown_capture_of_logs(); } +/* Unit tests for measured_bw_line_parse using line_is_after_headers flag. + * When the end of the header is detected (a first complete bw line is parsed), + * incomplete lines fail and give warnings, but do not give warnings if + * the header is not ended, allowing to ignore additional header lines. */ +static void +test_dir_measured_bw_kb_line_is_after_headers(void *arg) +{ + (void)arg; + measured_bw_line_t mbwl; + const char *line_pass = \ + "node_id=$557365204145532d32353620696e73746561642e bw=1024\n"; + int i; + const char *lines_fail[] = { + "node_id=$557365204145532d32353620696e73746561642e \n", + "bw=1024\n", + "rtt=300\n", + "end" + }; + + setup_capture_of_logs(LOG_DEBUG); + + /* Test bw lines when header has ended */ + for (i = 0; strcmp(lines_fail[i], "end"); i++) { + tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 1) == -1); + expect_log_msg_containing("Incomplete line in bandwidth file:"); + mock_clean_saved_logs(); + } + + tt_assert(measured_bw_line_parse(&mbwl, line_pass, 1) == 0); + + /* Test bw lines when header has not ended */ + for (i = 0; strcmp(lines_fail[i], "end"); i++) { + tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 0) == -1); + expect_log_msg_containing("Missing bw or node_id in bandwidth file line:"); + mock_clean_saved_logs(); + } + + tt_assert(measured_bw_line_parse(&mbwl, line_pass, 0) == 0); + + done: + teardown_capture_of_logs(); +} + +/* Test dirserv_read_measured_bandwidths with whole files. */ +static void +test_dir_dirserv_read_measured_bandwidths(void *arg) +{ + (void)arg; + char *content = NULL; + time_t timestamp = time(NULL); + char *fname = tor_strdup(get_fname("V3BandwidthsFile")); + + /* Test Torflow file only with timestamp*/ + tor_asprintf(&content, "%ld", (long)timestamp); + write_str_to_file(fname, content, 0); + tor_free(content); + tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL)); + + /* Test Torflow file with timestamp followed by '\n' */ + tor_asprintf(&content, "%ld\n", (long)timestamp); + write_str_to_file(fname, content, 0); + tor_free(content); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL)); + + /* Test Torflow complete file*/ + const char *torflow_relay_lines= + "node_id=$557365204145532d32353620696e73746561642e bw=1024 " + "nick=Test measured_at=1523911725 updated_at=1523911725 " + "pid_error=4.11374090719 pid_error_sum=4.11374090719 " + "pid_bw=57136645 pid_delta=2.12168374577 circ_fail=0.2 " + "scanner=/filepath\n"; + + tor_asprintf(&content, "%ld\n%s", (long)timestamp, torflow_relay_lines); + write_str_to_file(fname, content, 0); + tor_free(content); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL)); + + /* Test Torflow complete file including v1.1.0 headers */ + const char *v110_header_lines= + "version=1.1.0\n" + "software=sbws\n" + "software_version=0.1.0\n" + "generator_started=2018-05-08T16:13:25\n" + "earliest_bandwidth=2018-05-08T16:13:26\n" + "====\n"; + + tor_asprintf(&content, "%ld\n%s%s", (long)timestamp, v110_header_lines, + torflow_relay_lines); + write_str_to_file(fname, content, 0); + tor_free(content); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL)); + + /* Test Torflow with additional headers afer a correct bw line */ + tor_asprintf(&content, "%ld\n%s%s", (long)timestamp, torflow_relay_lines, + v110_header_lines); + write_str_to_file(fname, content, 0); + tor_free(content); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL)); + + /* Test Torflow with additional headers afer a correct bw line and more + * bw lines after the headers. */ + tor_asprintf(&content, "%ld\n%s%s%s", (long)timestamp, torflow_relay_lines, + v110_header_lines, torflow_relay_lines); + write_str_to_file(fname, content, 0); + tor_free(content); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL)); + + /* Test sbws file */ + const char *sbws_relay_lines= + "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 " + "master_key_ed25519=YaqV4vbvPYKucElk297eVdNArDz9HtIwUoIeo0+cVIpQ " + "bw=760 nick=Test rtt=380 time=2018-05-08T16:13:26\n"; + + tor_asprintf(&content, "%ld\n%s%s", (long)timestamp, v110_header_lines, + sbws_relay_lines); + write_str_to_file(fname, content, 0); + tor_free(content); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL)); + + done: + tor_free(fname); +} + #define MBWC_INIT_TIME 1000 /** Do the measured bandwidth cache unit test */ @@ -1512,6 +1835,15 @@ test_dir_param_voting(void *arg) tt_int_op(-8,OP_EQ, networkstatus_get_param(&vote4, "ab", -12, -100, -8)); tt_int_op(0,OP_EQ, networkstatus_get_param(&vote4, "foobar", 0, -100, 8)); + tt_int_op(100,OP_EQ, networkstatus_get_overridable_param( + &vote4, -1, "x-yz", 50, 0, 300)); + tt_int_op(30,OP_EQ, networkstatus_get_overridable_param( + &vote4, 30, "x-yz", 50, 0, 300)); + tt_int_op(0,OP_EQ, networkstatus_get_overridable_param( + &vote4, -101, "foobar", 0, -100, 8)); + tt_int_op(-99,OP_EQ, networkstatus_get_overridable_param( + &vote4, -99, "foobar", 0, -100, 8)); + smartlist_add(votes, &vote1); /* Do the first tests without adding all the other votes, for @@ -1611,7 +1943,7 @@ test_dir_param_voting_lookup(void *arg) dirvote_get_intermediate_param_value(lst, "moomin", -100)); tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1); tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ, - "!(n_found > 1)"); + "n_found == 0"); tor_end_capture_bugs_(); /* There is no 'fred=', so that is treated as not existing. */ tt_int_op(-100, OP_EQ, @@ -1699,8 +2031,7 @@ vote_tweaks_for_v3ns(networkstatus_t *v, int voter, time_t now) measured_bw_line_t mbw; memset(mbw.node_id, 33, sizeof(mbw.node_id)); mbw.bw_kb = 1024; - tt_assert(measured_bw_line_apply(&mbw, - v->routerstatus_list) == 1); + tt_int_op(measured_bw_line_apply(&mbw, v->routerstatus_list), OP_EQ, 1); } else if (voter == 2 || voter == 3) { /* Monkey around with the list a bit */ vrs = smartlist_get(v->routerstatus_list, 2); @@ -1816,7 +2147,7 @@ test_consensus_for_v3ns(networkstatus_t *con, time_t now) (void)now; tt_assert(con); - tt_assert(!con->cert); + tt_ptr_op(con->cert, OP_EQ, NULL); tt_int_op(2,OP_EQ, smartlist_len(con->routerstatus_list)); /* There should be two listed routers: one with identity 3, one with * identity 5. */ @@ -1886,13 +2217,260 @@ test_routerstatus_for_v3ns(routerstatus_t *rs, time_t now) /* XXXX check version */ } else { /* Weren't expecting this... */ - tt_assert(0); + tt_abort(); } done: return; } +static void +test_dir_networkstatus_compute_bw_weights_v10(void *arg) +{ + (void) arg; + smartlist_t *chunks = smartlist_new(); + int64_t G, M, E, D, T, weight_scale; + int ret; + weight_scale = 10000; + + /* no case. one or more of the values is 0 */ + G = M = E = D = 0; + T = G + M + E + D; + ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T, + weight_scale); + tt_int_op(ret, OP_EQ, 0); + tt_int_op(smartlist_len(chunks), OP_EQ, 0); + + /* case 1 */ + /* XXX dir-spec not followed? See #20272. If it isn't closed, then this is + * testing current behavior, not spec. */ + G = E = 10; + M = D = 1; + T = G + M + E + D; + ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T, + weight_scale); + tt_int_op(ret, OP_EQ, 1); + tt_int_op(smartlist_len(chunks), OP_EQ, 1); + tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=3333 " + "Wbe=3000 Wbg=3000 Wbm=10000 Wdb=10000 Web=10000 Wed=3333 Wee=7000 " + "Weg=3333 Wem=7000 Wgb=10000 Wgd=3333 Wgg=7000 Wgm=7000 Wmb=10000 " + "Wmd=3333 Wme=3000 Wmg=3000 Wmm=10000\n"); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_clear(chunks); + + /* case 2a E scarce */ + M = 100; + G = 20; + E = D = 5; + T = G + M + E + D; + ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T, + weight_scale); + tt_int_op(ret, OP_EQ, 1); + tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 " + "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 " + "Wem=10000 Wgb=10000 Wgd=0 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 Wme=0 " + "Wmg=0 Wmm=10000\n"); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_clear(chunks); + + /* case 2a G scarce */ + M = 100; + E = 20; + G = D = 5; + T = G + M + E + D; + ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T, + weight_scale); + tt_int_op(ret, OP_EQ, 1); + tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 " + "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=10000 Weg=0 Wem=10000 " + "Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 Wme=0 Wmg=0 " + "Wmm=10000\n"); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_clear(chunks); + + /* case 2b1 (Wgg=1, Wmd=Wgd) */ + M = 10; + E = 30; + G = 10; + D = 100; + T = G + M + E + D; + ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T, + weight_scale); + tt_int_op(ret, OP_EQ, 1); + tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=4000 " + "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=2000 Wee=10000 Weg=2000 " + "Wem=10000 Wgb=10000 Wgd=4000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=4000 " + "Wme=0 Wmg=0 Wmm=10000\n"); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_clear(chunks); + + /* case 2b2 */ + M = 60; + E = 30; + G = 10; + D = 100; + T = G + M + E + D; + ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T, + weight_scale); + tt_int_op(ret, OP_EQ, 1); + tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=666 Wbe=0 " + "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=3666 Wee=10000 Weg=3666 " + "Wem=10000 Wgb=10000 Wgd=5668 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=666 " + "Wme=0 Wmg=0 Wmm=10000\n"); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_clear(chunks); + + /* case 2b3 */ + /* XXX I can't get a combination of values that hits this case without error, + * so this just tests that it fails. See #20285. Also see #20284 as 2b3 does + * not follow dir-spec. */ + /* (E < T/3 && G < T/3) && (E+D>=G || G+D>=E) && (M > T/3) */ + M = 80; + E = 30; + G = 30; + D = 30; + T = G + M + E + D; + ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T, + weight_scale); + tt_int_op(ret, OP_EQ, 0); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_clear(chunks); + + /* case 3a G scarce */ + M = 10; + E = 30; + G = 10; + D = 5; + T = G + M + E + D; + ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T, + weight_scale); + tt_int_op(ret, OP_EQ, 1); + tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 " + "Wbe=3333 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=6667 Weg=0 " + "Wem=6667 Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 " + "Wme=3333 Wmg=0 Wmm=10000\n"); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_clear(chunks); + + /* case 3a E scarce */ + M = 10; + E = 10; + G = 30; + D = 5; + T = G + M + E + D; + ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T, + weight_scale); + tt_int_op(ret, OP_EQ, 1); + tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 " + "Wbg=3333 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 " + "Wem=10000 Wgb=10000 Wgd=0 Wgg=6667 Wgm=6667 Wmb=10000 Wmd=0 Wme=0 " + "Wmg=3333 Wmm=10000\n"); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_clear(chunks); + + /* case 3bg */ + M = 10; + E = 30; + G = 10; + D = 10; + T = G + M + E + D; + ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T, + weight_scale); + tt_int_op(ret, OP_EQ, 1); + tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 " + "Wbe=3334 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=6666 Weg=0 " + "Wem=6666 Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 " + "Wme=3334 Wmg=0 Wmm=10000\n"); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_clear(chunks); + + /* case 3be */ + M = 10; + E = 10; + G = 30; + D = 10; + T = G + M + E + D; + ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T, + weight_scale); + tt_int_op(ret, OP_EQ, 1); + tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 " + "Wbg=3334 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 " + "Wem=10000 Wgb=10000 Wgd=0 Wgg=6666 Wgm=6666 Wmb=10000 Wmd=0 Wme=0 " + "Wmg=3334 Wmm=10000\n"); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_clear(chunks); + + /* case from 21 Jul 2013 (3be) */ + G = 5483409; + M = 1455379; + E = 980834; + D = 3385803; + T = 11305425; + tt_i64_op(G+M+E+D, OP_EQ, T); + ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T, + weight_scale); + tt_assert(ret); + tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=883 Wbe=0 " + "Wbg=3673 Wbm=10000 Wdb=10000 Web=10000 Wed=8233 Wee=10000 Weg=8233 " + "Wem=10000 Wgb=10000 Wgd=883 Wgg=6327 Wgm=6327 Wmb=10000 Wmd=883 Wme=0 " + "Wmg=3673 Wmm=10000\n"); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_clear(chunks); + + /* case from 04 Oct 2016 (3a E scarce) */ + G=29322240; + M=4721546; + E=1522058; + D=9273571; + T=44839415; + tt_i64_op(G+M+E+D, OP_EQ, T); + ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T, + weight_scale); + tt_assert(ret); + tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 " + "Wbg=4194 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 " + "Wem=10000 Wgb=10000 Wgd=0 Wgg=5806 Wgm=5806 Wmb=10000 Wmd=0 Wme=0 " + "Wmg=4194 Wmm=10000\n"); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_clear(chunks); + + /* case from 04 Sep 2013 (2b1) */ + G=3091352; + M=1838837; + E=2109300; + D=2469369; + T=9508858; + tt_i64_op(G+M+E+D, OP_EQ, T); + ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T, + weight_scale); + tt_assert(ret); + tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=317 " + "Wbe=5938 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=9366 Wee=4061 " + "Weg=9366 Wem=4061 Wgb=10000 Wgd=317 Wgg=10000 Wgm=10000 Wmb=10000 " + "Wmd=317 Wme=5938 Wmg=0 Wmm=10000\n"); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_clear(chunks); + + /* explicitly test initializing weights to 1*/ + G=1; + M=1; + E=1; + D=1; + T=4; + tt_i64_op(G+M+E+D, OP_EQ, T); + ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T, + weight_scale); + tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=3333 " + "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=3333 Wee=10000 Weg=3333 " + "Wem=10000 Wgb=10000 Wgd=3333 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=3333 " + "Wme=0 Wmg=0 Wmm=10000\n"); + tt_assert(ret); + + done: + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_free(chunks); +} + static authority_cert_t *mock_cert; static authority_cert_t * @@ -1958,6 +2536,7 @@ test_a_networkstatus( sign_skey_2 = crypto_pk_new(); sign_skey_3 = crypto_pk_new(); sign_skey_leg1 = pk_generate(4); + voting_schedule_recalculate_timing(get_options(), now); sr_state_init(0, 0); tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_1, @@ -2495,8 +3074,9 @@ gen_routerstatus_for_umbw(int idx, time_t now) rs->addr = 0x99008801; rs->or_port = 443; rs->dir_port = 8000; - /* all flags but running cleared */ + /* all flags but running and valid cleared */ rs->is_flagged_running = 1; + rs->is_valid = 1; /* * This one has measured bandwidth below the clip cutoff, and * so shouldn't be clipped; we'll have to test that it isn't @@ -2569,8 +3149,9 @@ gen_routerstatus_for_umbw(int idx, time_t now) rs->addr = 0xC0000203; rs->or_port = 500; rs->dir_port = 1999; - /* all flags but running cleared */ + /* all flags but running and valid cleared */ rs->is_flagged_running = 1; + rs->is_valid = 1; /* * This one has unmeasured bandwidth below the clip cutoff, and * so shouldn't be clipped; we'll have to test that it isn't @@ -2587,12 +3168,12 @@ gen_routerstatus_for_umbw(int idx, time_t now) break; default: /* Shouldn't happen */ - tt_assert(0); + tt_abort(); } if (vrs) { vrs->microdesc = tor_malloc_zero(sizeof(vote_microdesc_hash_t)); tor_asprintf(&vrs->microdesc->microdesc_hash_line, - "m 9,10,11,12,13,14,15,16,17 " + "m 25,26,27,28 " "sha256=xyzajkldsdsajdadlsdjaslsdksdjlsdjsdaskdaaa%d\n", idx); } @@ -2618,7 +3199,7 @@ vote_tweaks_for_umbw(networkstatus_t *v, int voter, time_t now) smartlist_clear(v->supported_methods); /* Method 17 is MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB */ smartlist_split_string(v->supported_methods, - "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17", + "25 26 27 28", NULL, 0, -1); /* If we're using a non-default clip bandwidth, add it to net_params */ if (alternate_clip_bw > 0) { @@ -2727,7 +3308,7 @@ test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now) tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2); tt_int_op(vrs->measured_bw_kb,OP_EQ, 0); } else { - tt_assert(0); + tt_abort(); } done: @@ -2743,9 +3324,9 @@ test_consensus_for_umbw(networkstatus_t *con, time_t now) (void)now; tt_assert(con); - tt_assert(!con->cert); + tt_ptr_op(con->cert, OP_EQ, NULL); // tt_assert(con->consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB); - tt_assert(con->consensus_method >= 16); + tt_int_op(con->consensus_method, OP_GE, 16); tt_int_op(4,OP_EQ, smartlist_len(con->routerstatus_list)); /* There should be four listed routers; all voters saw the same in this */ @@ -2780,9 +3361,9 @@ test_routerstatus_for_umbw(routerstatus_t *rs, time_t now) tt_assert(!rs->is_fast); tt_assert(!rs->is_possible_guard); tt_assert(!rs->is_stable); - /* (If it wasn't running it wouldn't be here) */ + /* (If it wasn't running and valid it wouldn't be here) */ tt_assert(rs->is_flagged_running); - tt_assert(!rs->is_valid); + tt_assert(rs->is_valid); tt_assert(!rs->is_named); /* This one should have measured bandwidth below the clip cutoff */ tt_assert(rs->has_bandwidth); @@ -2842,7 +3423,7 @@ test_routerstatus_for_umbw(routerstatus_t *rs, time_t now) tt_assert(rs->bw_is_unmeasured); } else { /* Weren't expecting this... */ - tt_assert(0); + tt_abort(); } done: @@ -2949,7 +3530,7 @@ mock_get_options(void) static void reset_routerstatus(routerstatus_t *rs, const char *hex_identity_digest, - int32_t ipv4_addr) + uint32_t ipv4_addr) { memset(rs, 0, sizeof(routerstatus_t)); base16_decode(rs->identity_digest, sizeof(rs->identity_digest), @@ -3010,15 +3591,17 @@ test_dir_dirserv_set_routerstatus_testing(void *arg) * Return values are {2, 3, 4} */ /* We want 3 ("*" means match all addresses) */ - tt_assert(routerset_contains_routerstatus(routerset_all, rs_a, 0) == 3); - tt_assert(routerset_contains_routerstatus(routerset_all, rs_b, 0) == 3); + tt_int_op(routerset_contains_routerstatus(routerset_all, rs_a, 0), OP_EQ, 3); + tt_int_op(routerset_contains_routerstatus(routerset_all, rs_b, 0), OP_EQ, 3); /* We want 4 (match id_digest [or nickname]) */ - tt_assert(routerset_contains_routerstatus(routerset_a, rs_a, 0) == 4); - tt_assert(routerset_contains_routerstatus(routerset_a, rs_b, 0) == 0); + tt_int_op(routerset_contains_routerstatus(routerset_a, rs_a, 0), OP_EQ, 4); + tt_int_op(routerset_contains_routerstatus(routerset_a, rs_b, 0), OP_EQ, 0); - tt_assert(routerset_contains_routerstatus(routerset_none, rs_a, 0) == 0); - tt_assert(routerset_contains_routerstatus(routerset_none, rs_b, 0) == 0); + tt_int_op(routerset_contains_routerstatus(routerset_none, rs_a, 0), OP_EQ, + 0); + tt_int_op(routerset_contains_routerstatus(routerset_none, rs_b, 0), OP_EQ, + 0); /* Check that "*" sets flags on all routers: Exit * Check the flags aren't being confused with each other */ @@ -3030,17 +3613,17 @@ test_dir_dirserv_set_routerstatus_testing(void *arg) mock_options->TestingDirAuthVoteExitIsStrict = 0; dirserv_set_routerstatus_testing(rs_a); - tt_assert(mock_get_options_calls == 1); + tt_int_op(mock_get_options_calls, OP_EQ, 1); dirserv_set_routerstatus_testing(rs_b); - tt_assert(mock_get_options_calls == 2); + tt_int_op(mock_get_options_calls, OP_EQ, 2); - tt_assert(rs_a->is_exit == 1); - tt_assert(rs_b->is_exit == 1); + tt_uint_op(rs_a->is_exit, OP_EQ, 1); + tt_uint_op(rs_b->is_exit, OP_EQ, 1); /* Be paranoid - check no other flags are set */ - tt_assert(rs_a->is_possible_guard == 0); - tt_assert(rs_b->is_possible_guard == 0); - tt_assert(rs_a->is_hs_dir == 0); - tt_assert(rs_b->is_hs_dir == 0); + tt_uint_op(rs_a->is_possible_guard, OP_EQ, 0); + tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0); + tt_uint_op(rs_a->is_hs_dir, OP_EQ, 0); + tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0); /* Check that "*" sets flags on all routers: Guard & HSDir * Cover the remaining flags in one test */ @@ -3054,17 +3637,17 @@ test_dir_dirserv_set_routerstatus_testing(void *arg) mock_options->TestingDirAuthVoteHSDirIsStrict = 0; dirserv_set_routerstatus_testing(rs_a); - tt_assert(mock_get_options_calls == 1); + tt_int_op(mock_get_options_calls, OP_EQ, 1); dirserv_set_routerstatus_testing(rs_b); - tt_assert(mock_get_options_calls == 2); + tt_int_op(mock_get_options_calls, OP_EQ, 2); - tt_assert(rs_a->is_possible_guard == 1); - tt_assert(rs_b->is_possible_guard == 1); - tt_assert(rs_a->is_hs_dir == 1); - tt_assert(rs_b->is_hs_dir == 1); + tt_uint_op(rs_a->is_possible_guard, OP_EQ, 1); + tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1); + tt_uint_op(rs_a->is_hs_dir, OP_EQ, 1); + tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1); /* Be paranoid - check exit isn't set */ - tt_assert(rs_a->is_exit == 0); - tt_assert(rs_b->is_exit == 0); + tt_uint_op(rs_a->is_exit, OP_EQ, 0); + tt_uint_op(rs_b->is_exit, OP_EQ, 0); /* Check routerset A sets all flags on router A, * but leaves router B unmodified */ @@ -3080,16 +3663,16 @@ test_dir_dirserv_set_routerstatus_testing(void *arg) mock_options->TestingDirAuthVoteHSDirIsStrict = 0; dirserv_set_routerstatus_testing(rs_a); - tt_assert(mock_get_options_calls == 1); + tt_int_op(mock_get_options_calls, OP_EQ, 1); dirserv_set_routerstatus_testing(rs_b); - tt_assert(mock_get_options_calls == 2); + tt_int_op(mock_get_options_calls, OP_EQ, 2); - tt_assert(rs_a->is_exit == 1); - tt_assert(rs_b->is_exit == 0); - tt_assert(rs_a->is_possible_guard == 1); - tt_assert(rs_b->is_possible_guard == 0); - tt_assert(rs_a->is_hs_dir == 1); - tt_assert(rs_b->is_hs_dir == 0); + tt_uint_op(rs_a->is_exit, OP_EQ, 1); + tt_uint_op(rs_b->is_exit, OP_EQ, 0); + tt_uint_op(rs_a->is_possible_guard, OP_EQ, 1); + tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0); + tt_uint_op(rs_a->is_hs_dir, OP_EQ, 1); + tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0); /* Check routerset A unsets all flags on router B when Strict is set */ reset_options(mock_options, &mock_get_options_calls); @@ -3107,11 +3690,11 @@ test_dir_dirserv_set_routerstatus_testing(void *arg) rs_b->is_hs_dir = 1; dirserv_set_routerstatus_testing(rs_b); - tt_assert(mock_get_options_calls == 1); + tt_int_op(mock_get_options_calls, OP_EQ, 1); - tt_assert(rs_b->is_exit == 0); - tt_assert(rs_b->is_possible_guard == 0); - tt_assert(rs_b->is_hs_dir == 0); + tt_uint_op(rs_b->is_exit, OP_EQ, 0); + tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0); + tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0); /* Check routerset A doesn't modify flags on router B without Strict set */ reset_options(mock_options, &mock_get_options_calls); @@ -3129,11 +3712,11 @@ test_dir_dirserv_set_routerstatus_testing(void *arg) rs_b->is_hs_dir = 1; dirserv_set_routerstatus_testing(rs_b); - tt_assert(mock_get_options_calls == 1); + tt_int_op(mock_get_options_calls, OP_EQ, 1); - tt_assert(rs_b->is_exit == 1); - tt_assert(rs_b->is_possible_guard == 1); - tt_assert(rs_b->is_hs_dir == 1); + tt_uint_op(rs_b->is_exit, OP_EQ, 1); + tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1); + tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1); /* Check the empty routerset zeroes all flags * on routers A & B with Strict set */ @@ -3152,11 +3735,11 @@ test_dir_dirserv_set_routerstatus_testing(void *arg) rs_b->is_hs_dir = 1; dirserv_set_routerstatus_testing(rs_b); - tt_assert(mock_get_options_calls == 1); + tt_int_op(mock_get_options_calls, OP_EQ, 1); - tt_assert(rs_b->is_exit == 0); - tt_assert(rs_b->is_possible_guard == 0); - tt_assert(rs_b->is_hs_dir == 0); + tt_uint_op(rs_b->is_exit, OP_EQ, 0); + tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0); + tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0); /* Check the empty routerset doesn't modify any flags * on A or B without Strict set */ @@ -3176,16 +3759,16 @@ test_dir_dirserv_set_routerstatus_testing(void *arg) rs_b->is_hs_dir = 1; dirserv_set_routerstatus_testing(rs_a); - tt_assert(mock_get_options_calls == 1); + tt_int_op(mock_get_options_calls, OP_EQ, 1); dirserv_set_routerstatus_testing(rs_b); - tt_assert(mock_get_options_calls == 2); + tt_int_op(mock_get_options_calls, OP_EQ, 2); - tt_assert(rs_a->is_exit == 0); - tt_assert(rs_a->is_possible_guard == 0); - tt_assert(rs_a->is_hs_dir == 0); - tt_assert(rs_b->is_exit == 1); - tt_assert(rs_b->is_possible_guard == 1); - tt_assert(rs_b->is_hs_dir == 1); + tt_uint_op(rs_a->is_exit, OP_EQ, 0); + tt_uint_op(rs_a->is_possible_guard, OP_EQ, 0); + tt_uint_op(rs_a->is_hs_dir, OP_EQ, 0); + tt_uint_op(rs_b->is_exit, OP_EQ, 1); + tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1); + tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1); done: tor_free(mock_options); @@ -3241,7 +3824,7 @@ test_dir_http_handling(void *args) "User-Agent: Mozilla/5.0 (Windows;" " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n", &url),OP_EQ, -1); - tt_assert(!url); + tt_ptr_op(url, OP_EQ, NULL); /* Bad headers */ tt_int_op(parse_http_url("GET /a/b/c.txt\r\n" @@ -3249,40 +3832,113 @@ test_dir_http_handling(void *args) "User-Agent: Mozilla/5.0 (Windows;" " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n", &url),OP_EQ, -1); - tt_assert(!url); + tt_ptr_op(url, OP_EQ, NULL); tt_int_op(parse_http_url("GET /tor/a/b/c.txt", &url),OP_EQ, -1); - tt_assert(!url); + tt_ptr_op(url, OP_EQ, NULL); tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1", &url),OP_EQ, -1); - tt_assert(!url); + tt_ptr_op(url, OP_EQ, NULL); tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1x\r\n", &url), OP_EQ, -1); - tt_assert(!url); + tt_ptr_op(url, OP_EQ, NULL); tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.", &url),OP_EQ, -1); - tt_assert(!url); + tt_ptr_op(url, OP_EQ, NULL); tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.\r", &url),OP_EQ, -1); - tt_assert(!url); + tt_ptr_op(url, OP_EQ, NULL); done: tor_free(url); } static void -test_dir_purpose_needs_anonymity(void *arg) +test_dir_purpose_needs_anonymity_returns_true_by_default(void *arg) +{ + (void)arg; + + tor_capture_bugs_(1); + setup_full_capture_of_logs(LOG_WARN); + tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, 0, NULL)); + tt_int_op(1, OP_EQ, smartlist_len(tor_get_captured_bug_log_())); + expect_single_log_msg_containing("Called with dir_purpose=0"); + + tor_end_capture_bugs_(); + done: + tor_end_capture_bugs_(); + teardown_capture_of_logs(); +} + +static void +test_dir_purpose_needs_anonymity_returns_true_for_bridges(void *arg) { (void)arg; - tt_int_op(1, ==, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE)); - tt_int_op(1, ==, purpose_needs_anonymity(0, ROUTER_PURPOSE_GENERAL)); - tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_FETCH_MICRODESC, - ROUTER_PURPOSE_GENERAL)); + + tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE, NULL)); + tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE, + "foobar")); + tt_int_op(1, OP_EQ, + purpose_needs_anonymity(DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2, + ROUTER_PURPOSE_BRIDGE, NULL)); done: ; } static void +test_dir_purpose_needs_anonymity_returns_false_for_own_bridge_desc(void *arg) +{ + (void)arg; + tt_int_op(0, OP_EQ, purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC, + ROUTER_PURPOSE_BRIDGE, + "authority.z")); + done: ; +} + +static void +test_dir_purpose_needs_anonymity_returns_true_for_sensitive_purpose(void *arg) +{ + (void)arg; + + tt_int_op(1, OP_EQ, purpose_needs_anonymity( + DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2, + ROUTER_PURPOSE_GENERAL, NULL)); + tt_int_op(1, OP_EQ, purpose_needs_anonymity( + DIR_PURPOSE_UPLOAD_RENDDESC_V2, 0, NULL)); + tt_int_op(1, OP_EQ, purpose_needs_anonymity( + DIR_PURPOSE_FETCH_RENDDESC_V2, 0, NULL)); + done: ; +} + +static void +test_dir_purpose_needs_anonymity_ret_false_for_non_sensitive_conn(void *arg) +{ + (void)arg; + + tt_int_op(0, OP_EQ, purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_DIR, + ROUTER_PURPOSE_GENERAL, NULL)); + tt_int_op(0, OP_EQ, + purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_VOTE, 0, NULL)); + tt_int_op(0, OP_EQ, + purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_SIGNATURES, 0, NULL)); + tt_int_op(0, OP_EQ, + purpose_needs_anonymity(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL)); + tt_int_op(0, OP_EQ, purpose_needs_anonymity( + DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0, NULL)); + tt_int_op(0, OP_EQ, + purpose_needs_anonymity(DIR_PURPOSE_FETCH_CONSENSUS, 0, NULL)); + tt_int_op(0, OP_EQ, + purpose_needs_anonymity(DIR_PURPOSE_FETCH_CERTIFICATE, 0, NULL)); + tt_int_op(0, OP_EQ, + purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC, 0, NULL)); + tt_int_op(0, OP_EQ, + purpose_needs_anonymity(DIR_PURPOSE_FETCH_EXTRAINFO, 0, NULL)); + tt_int_op(0, OP_EQ, + purpose_needs_anonymity(DIR_PURPOSE_FETCH_MICRODESC, 0, NULL)); + done: ; +} + +static void test_dir_fetch_type(void *arg) { (void)arg; @@ -3330,9 +3986,9 @@ test_dir_packages(void *arg) (void)arg; #define BAD(s) \ - tt_int_op(0, ==, validate_recommended_package_line(s)); + tt_int_op(0, OP_EQ, validate_recommended_package_line(s)); #define GOOD(s) \ - tt_int_op(1, ==, validate_recommended_package_line(s)); + tt_int_op(1, OP_EQ, validate_recommended_package_line(s)); GOOD("tor 0.2.6.3-alpha " "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz " "sha256=sssdlkfjdsklfjdskfljasdklfj"); @@ -3449,7 +4105,7 @@ test_dir_packages(void *arg) res = compute_consensus_package_lines(votes); tt_assert(res); - tt_str_op(res, ==, + tt_str_op(res, OP_EQ, "package cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m\n" "package clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz\n" "package clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa\n" @@ -3468,490 +4124,156 @@ test_dir_packages(void *arg) } static void -test_dir_download_status_schedule(void *arg) -{ - (void)arg; - download_status_t dls_failure = { 0, 0, 0, DL_SCHED_GENERIC, - DL_WANT_AUTHORITY, - DL_SCHED_INCREMENT_FAILURE, - DL_SCHED_DETERMINISTIC, 0, 0 }; - download_status_t dls_attempt = { 0, 0, 0, DL_SCHED_CONSENSUS, - DL_WANT_ANY_DIRSERVER, - DL_SCHED_INCREMENT_ATTEMPT, - DL_SCHED_DETERMINISTIC, 0, 0 }; - download_status_t dls_bridge = { 0, 0, 0, DL_SCHED_BRIDGE, - DL_WANT_AUTHORITY, - DL_SCHED_INCREMENT_FAILURE, - DL_SCHED_DETERMINISTIC, 0, 0 }; - int increment = -1; - int expected_increment = -1; - time_t current_time = time(NULL); - int delay1 = -1; - int delay2 = -1; - smartlist_t *schedule = smartlist_new(); - - /* Make a dummy schedule */ - smartlist_add(schedule, (void *)&delay1); - smartlist_add(schedule, (void *)&delay2); - - /* check a range of values */ - delay1 = 1000; - increment = download_status_schedule_get_delay(&dls_failure, - schedule, - 0, INT_MAX, - TIME_MIN); - expected_increment = delay1; - tt_assert(increment == expected_increment); - tt_assert(dls_failure.next_attempt_at == TIME_MIN + expected_increment); - - delay1 = INT_MAX; - increment = download_status_schedule_get_delay(&dls_failure, - schedule, - 0, INT_MAX, - -1); - expected_increment = delay1; - tt_assert(increment == expected_increment); - tt_assert(dls_failure.next_attempt_at == TIME_MAX); - - delay1 = 0; - increment = download_status_schedule_get_delay(&dls_attempt, - schedule, - 0, INT_MAX, - 0); - expected_increment = delay1; - tt_assert(increment == expected_increment); - tt_assert(dls_attempt.next_attempt_at == 0 + expected_increment); - - delay1 = 1000; - increment = download_status_schedule_get_delay(&dls_attempt, - schedule, - 0, INT_MAX, - 1); - expected_increment = delay1; - tt_assert(increment == expected_increment); - tt_assert(dls_attempt.next_attempt_at == 1 + expected_increment); - - delay1 = INT_MAX; - increment = download_status_schedule_get_delay(&dls_bridge, - schedule, - 0, INT_MAX, - current_time); - expected_increment = delay1; - tt_assert(increment == expected_increment); - tt_assert(dls_bridge.next_attempt_at == TIME_MAX); - - delay1 = 1; - increment = download_status_schedule_get_delay(&dls_bridge, - schedule, - 0, INT_MAX, - TIME_MAX); - expected_increment = delay1; - tt_assert(increment == expected_increment); - tt_assert(dls_bridge.next_attempt_at == TIME_MAX); - - /* see what happens when we reach the end */ - dls_attempt.n_download_attempts++; - dls_bridge.n_download_failures++; - - delay2 = 100; - increment = download_status_schedule_get_delay(&dls_attempt, - schedule, - 0, INT_MAX, - current_time); - expected_increment = delay2; - tt_assert(increment == expected_increment); - tt_assert(dls_attempt.next_attempt_at == current_time + delay2); - - delay2 = 1; - increment = download_status_schedule_get_delay(&dls_bridge, - schedule, - 0, INT_MAX, - current_time); - expected_increment = delay2; - tt_assert(increment == expected_increment); - tt_assert(dls_bridge.next_attempt_at == current_time + delay2); - - /* see what happens when we try to go off the end */ - dls_attempt.n_download_attempts++; - dls_bridge.n_download_failures++; - - delay2 = 5; - increment = download_status_schedule_get_delay(&dls_attempt, - schedule, - 0, INT_MAX, - current_time); - expected_increment = delay2; - tt_assert(increment == expected_increment); - tt_assert(dls_attempt.next_attempt_at == current_time + delay2); - - delay2 = 17; - increment = download_status_schedule_get_delay(&dls_bridge, - schedule, - 0, INT_MAX, - current_time); - expected_increment = delay2; - tt_assert(increment == expected_increment); - tt_assert(dls_bridge.next_attempt_at == current_time + delay2); - - /* see what happens when we reach IMPOSSIBLE_TO_DOWNLOAD */ - dls_attempt.n_download_attempts = IMPOSSIBLE_TO_DOWNLOAD; - dls_bridge.n_download_failures = IMPOSSIBLE_TO_DOWNLOAD; - - delay2 = 35; - increment = download_status_schedule_get_delay(&dls_attempt, - schedule, - 0, INT_MAX, - current_time); - expected_increment = INT_MAX; - tt_assert(increment == expected_increment); - tt_assert(dls_attempt.next_attempt_at == TIME_MAX); - - delay2 = 99; - increment = download_status_schedule_get_delay(&dls_bridge, - schedule, - 0, INT_MAX, - current_time); - expected_increment = INT_MAX; - tt_assert(increment == expected_increment); - tt_assert(dls_bridge.next_attempt_at == TIME_MAX); - - done: - /* the pointers in schedule are allocated on the stack */ - smartlist_free(schedule); -} - -static void -test_dir_download_status_random_backoff(void *arg) +download_status_random_backoff_helper(int min_delay) { download_status_t dls_random = { 0, 0, 0, DL_SCHED_GENERIC, DL_WANT_AUTHORITY, - DL_SCHED_INCREMENT_FAILURE, DL_SCHED_RANDOM_EXPONENTIAL, 0, 0 }; + DL_SCHED_INCREMENT_FAILURE, 0, 0 }; int increment = -1; - int old_increment; + int old_increment = -1; time_t current_time = time(NULL); - const int min_delay = 0; - const int max_delay = 1000000; - - (void)arg; /* Check the random backoff cases */ - old_increment = 0; + int n_attempts = 0; do { increment = download_status_schedule_get_delay(&dls_random, - NULL, - min_delay, max_delay, + min_delay, current_time); + + log_debug(LD_DIR, "Min: %d, Inc: %d, Old Inc: %d", + min_delay, increment, old_increment); + + /* Regression test for 20534 and friends + * increment must always increase after the first */ + if (dls_random.last_backoff_position > 0) { + /* Always increment the exponential backoff */ + tt_int_op(increment, OP_GE, 1); + } + /* Test */ tt_int_op(increment, OP_GE, min_delay); - tt_int_op(increment, OP_LE, max_delay); - tt_int_op(increment, OP_GE, old_increment); - /* We at most quadruple, and maybe add one */ - tt_int_op(increment, OP_LE, 4 * old_increment + 1); /* Advance */ - current_time += increment; - ++(dls_random.n_download_attempts); - ++(dls_random.n_download_failures); + if (dls_random.n_download_attempts < IMPOSSIBLE_TO_DOWNLOAD - 1) { + ++(dls_random.n_download_attempts); + ++(dls_random.n_download_failures); + } /* Try another maybe */ old_increment = increment; - } while (increment < max_delay); + } while (++n_attempts < 1000); done: return; } static void +test_dir_download_status_random_backoff(void *arg) +{ + (void)arg; + + /* Do a standard test */ + download_status_random_backoff_helper(0); + /* regression tests for 17750: initial delay */ + download_status_random_backoff_helper(10); + download_status_random_backoff_helper(20); + + /* Pathological cases */ + download_status_random_backoff_helper(INT_MAX/2); +} + +static void +test_dir_download_status_random_backoff_ranges(void *arg) +{ + (void)arg; + int lo, hi; + next_random_exponential_delay_range(&lo, &hi, 0, 10); + tt_int_op(lo, OP_EQ, 10); + tt_int_op(hi, OP_EQ, 11); + + next_random_exponential_delay_range(&lo, &hi, 6, 10); + tt_int_op(lo, OP_EQ, 10); + tt_int_op(hi, OP_EQ, 6*3); + + next_random_exponential_delay_range(&lo, &hi, 13, 10); + tt_int_op(lo, OP_EQ, 10); + tt_int_op(hi, OP_EQ, 13 * 3); + + next_random_exponential_delay_range(&lo, &hi, 37, 10); + tt_int_op(lo, OP_EQ, 10); + tt_int_op(hi, OP_EQ, 111); + + next_random_exponential_delay_range(&lo, &hi, 123, 10); + tt_int_op(lo, OP_EQ, 10); + tt_int_op(hi, OP_EQ, 369); + + next_random_exponential_delay_range(&lo, &hi, INT_MAX-5, 10); + tt_int_op(lo, OP_EQ, 10); + tt_int_op(hi, OP_EQ, INT_MAX); + done: + ; +} + +static void test_dir_download_status_increment(void *arg) { (void)arg; - download_status_t dls_failure = { 0, 0, 0, DL_SCHED_GENERIC, - DL_WANT_AUTHORITY, - DL_SCHED_INCREMENT_FAILURE, - DL_SCHED_DETERMINISTIC, 0, 0 }; - download_status_t dls_attempt = { 0, 0, 0, DL_SCHED_BRIDGE, + download_status_t dls_exp = { 0, 0, 0, DL_SCHED_GENERIC, DL_WANT_ANY_DIRSERVER, DL_SCHED_INCREMENT_ATTEMPT, - DL_SCHED_DETERMINISTIC, 0, 0 }; - int delay0 = -1; - int delay1 = -1; - int delay2 = -1; - smartlist_t *schedule = smartlist_new(); + 0, 0 }; or_options_t test_options; - time_t next_at = TIME_MAX; time_t current_time = time(NULL); - /* Provide some values for the schedule */ - delay0 = 10; - delay1 = 99; - delay2 = 20; - - /* Make the schedule */ - smartlist_add(schedule, (void *)&delay0); - smartlist_add(schedule, (void *)&delay1); - smartlist_add(schedule, (void *)&delay2); + const int delay0 = 10; + const int no_delay = 0; + const int schedule = 10; + const int schedule_no_initial_delay = 0; /* Put it in the options */ mock_options = &test_options; reset_options(mock_options, &mock_get_options_calls); - mock_options->TestingClientDownloadSchedule = schedule; - mock_options->TestingBridgeDownloadSchedule = schedule; + mock_options->TestingBridgeBootstrapDownloadInitialDelay = schedule; + mock_options->TestingClientDownloadInitialDelay = schedule; MOCK(get_options, mock_get_options); - /* Check that a failure reset works */ - mock_get_options_calls = 0; - download_status_reset(&dls_failure); - /* we really want to test that it's equal to time(NULL) + delay0, but that's - * an unrealiable test, because time(NULL) might change. */ - tt_assert(download_status_get_next_attempt_at(&dls_failure) - >= current_time + delay0); - tt_assert(download_status_get_next_attempt_at(&dls_failure) - != TIME_MAX); - tt_assert(download_status_get_n_failures(&dls_failure) == 0); - tt_assert(download_status_get_n_attempts(&dls_failure) == 0); - tt_assert(mock_get_options_calls >= 1); - - /* avoid timing inconsistencies */ - dls_failure.next_attempt_at = current_time + delay0; - - /* check that a reset schedule becomes ready at the right time */ - tt_assert(download_status_is_ready(&dls_failure, - current_time + delay0 - 1, - 1) == 0); - tt_assert(download_status_is_ready(&dls_failure, - current_time + delay0, - 1) == 1); - tt_assert(download_status_is_ready(&dls_failure, - current_time + delay0 + 1, - 1) == 1); - - /* Check that a failure increment works */ - mock_get_options_calls = 0; - next_at = download_status_increment_failure(&dls_failure, 404, "test", 0, - current_time); - tt_assert(next_at == current_time + delay1); - tt_assert(download_status_get_n_failures(&dls_failure) == 1); - tt_assert(download_status_get_n_attempts(&dls_failure) == 1); - tt_assert(mock_get_options_calls >= 1); - - /* check that an incremented schedule becomes ready at the right time */ - tt_assert(download_status_is_ready(&dls_failure, - current_time + delay1 - 1, - 1) == 0); - tt_assert(download_status_is_ready(&dls_failure, - current_time + delay1, - 1) == 1); - tt_assert(download_status_is_ready(&dls_failure, - current_time + delay1 + 1, - 1) == 1); - - /* check that a schedule isn't ready if it's had too many failures */ - tt_assert(download_status_is_ready(&dls_failure, - current_time + delay1 + 10, - 0) == 0); - - /* Check that failure increments do happen on 503 for clients, and - * attempt increments do too. */ - mock_get_options_calls = 0; - next_at = download_status_increment_failure(&dls_failure, 503, "test", 0, - current_time); - tt_i64_op(next_at, ==, current_time + delay2); - tt_int_op(download_status_get_n_failures(&dls_failure), ==, 2); - tt_int_op(download_status_get_n_attempts(&dls_failure), ==, 2); - tt_assert(mock_get_options_calls >= 1); - - /* Check that failure increments do happen on 503 for servers */ - mock_get_options_calls = 0; - next_at = download_status_increment_failure(&dls_failure, 503, "test", 1, - current_time); - tt_assert(next_at == current_time + delay2); - tt_assert(download_status_get_n_failures(&dls_failure) == 3); - tt_assert(download_status_get_n_attempts(&dls_failure) == 3); - tt_assert(mock_get_options_calls >= 1); - - /* Check what happens when we run off the end of the schedule */ - mock_get_options_calls = 0; - next_at = download_status_increment_failure(&dls_failure, 404, "test", 0, - current_time); - tt_assert(next_at == current_time + delay2); - tt_assert(download_status_get_n_failures(&dls_failure) == 4); - tt_assert(download_status_get_n_attempts(&dls_failure) == 4); - tt_assert(mock_get_options_calls >= 1); - - /* Check what happens when we hit the failure limit */ - mock_get_options_calls = 0; - download_status_mark_impossible(&dls_failure); - next_at = download_status_increment_failure(&dls_failure, 404, "test", 0, - current_time); - tt_assert(next_at == TIME_MAX); - tt_assert(download_status_get_n_failures(&dls_failure) - == IMPOSSIBLE_TO_DOWNLOAD); - tt_assert(download_status_get_n_attempts(&dls_failure) - == IMPOSSIBLE_TO_DOWNLOAD); - tt_assert(mock_get_options_calls >= 1); - - /* Check that a failure reset doesn't reset at the limit */ - mock_get_options_calls = 0; - download_status_reset(&dls_failure); - tt_assert(download_status_get_next_attempt_at(&dls_failure) - == TIME_MAX); - tt_assert(download_status_get_n_failures(&dls_failure) - == IMPOSSIBLE_TO_DOWNLOAD); - tt_assert(download_status_get_n_attempts(&dls_failure) - == IMPOSSIBLE_TO_DOWNLOAD); - tt_assert(mock_get_options_calls == 0); - - /* Check that a failure reset resets just before the limit */ + /* Check that the initial value of the schedule is the first value used, + * whether or not it was reset before being used */ + + /* regression test for 17750: no initial delay */ + mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay; mock_get_options_calls = 0; - dls_failure.n_download_failures = IMPOSSIBLE_TO_DOWNLOAD - 1; - dls_failure.n_download_attempts = IMPOSSIBLE_TO_DOWNLOAD - 1; - download_status_reset(&dls_failure); /* we really want to test that it's equal to time(NULL) + delay0, but that's * an unrealiable test, because time(NULL) might change. */ - tt_assert(download_status_get_next_attempt_at(&dls_failure) - >= current_time + delay0); - tt_assert(download_status_get_next_attempt_at(&dls_failure) - != TIME_MAX); - tt_assert(download_status_get_n_failures(&dls_failure) == 0); - tt_assert(download_status_get_n_attempts(&dls_failure) == 0); - tt_assert(mock_get_options_calls >= 1); - /* Check that failure increments do happen on attempt-based schedules, - * but that the retry is set at the end of time */ - mock_get_options_calls = 0; - next_at = download_status_increment_failure(&dls_attempt, 404, "test", 0, - current_time); - tt_assert(next_at == TIME_MAX); - tt_assert(download_status_get_n_failures(&dls_attempt) == 1); - tt_assert(download_status_get_n_attempts(&dls_attempt) == 0); - tt_assert(mock_get_options_calls == 0); - - /* Check that an attempt reset works */ + /* regression test for 17750: exponential, no initial delay */ + mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay; mock_get_options_calls = 0; - download_status_reset(&dls_attempt); /* we really want to test that it's equal to time(NULL) + delay0, but that's * an unrealiable test, because time(NULL) might change. */ - tt_assert(download_status_get_next_attempt_at(&dls_attempt) - >= current_time + delay0); - tt_assert(download_status_get_next_attempt_at(&dls_attempt) + tt_assert(download_status_get_next_attempt_at(&dls_exp) + >= current_time + no_delay); + tt_assert(download_status_get_next_attempt_at(&dls_exp) != TIME_MAX); - tt_assert(download_status_get_n_failures(&dls_attempt) == 0); - tt_assert(download_status_get_n_attempts(&dls_attempt) == 0); - tt_assert(mock_get_options_calls >= 1); - - /* avoid timing inconsistencies */ - dls_attempt.next_attempt_at = current_time + delay0; - - /* check that a reset schedule becomes ready at the right time */ - tt_assert(download_status_is_ready(&dls_attempt, - current_time + delay0 - 1, - 1) == 0); - tt_assert(download_status_is_ready(&dls_attempt, - current_time + delay0, - 1) == 1); - tt_assert(download_status_is_ready(&dls_attempt, - current_time + delay0 + 1, - 1) == 1); - - /* Check that an attempt increment works */ - mock_get_options_calls = 0; - next_at = download_status_increment_attempt(&dls_attempt, "test", - current_time); - tt_assert(next_at == current_time + delay1); - tt_assert(download_status_get_n_failures(&dls_attempt) == 0); - tt_assert(download_status_get_n_attempts(&dls_attempt) == 1); - tt_assert(mock_get_options_calls >= 1); - - /* check that an incremented schedule becomes ready at the right time */ - tt_assert(download_status_is_ready(&dls_attempt, - current_time + delay1 - 1, - 1) == 0); - tt_assert(download_status_is_ready(&dls_attempt, - current_time + delay1, - 1) == 1); - tt_assert(download_status_is_ready(&dls_attempt, - current_time + delay1 + 1, - 1) == 1); - - /* check that a schedule isn't ready if it's had too many attempts */ - tt_assert(download_status_is_ready(&dls_attempt, - current_time + delay1 + 10, - 0) == 0); - - /* Check what happens when we reach then run off the end of the schedule */ - mock_get_options_calls = 0; - next_at = download_status_increment_attempt(&dls_attempt, "test", - current_time); - tt_assert(next_at == current_time + delay2); - tt_assert(download_status_get_n_failures(&dls_attempt) == 0); - tt_assert(download_status_get_n_attempts(&dls_attempt) == 2); - tt_assert(mock_get_options_calls >= 1); + tt_int_op(download_status_get_n_failures(&dls_exp), OP_EQ, 0); + tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0); + tt_int_op(mock_get_options_calls, OP_GE, 1); + /* regression test for 17750: exponential, initial delay */ + mock_options->TestingClientDownloadInitialDelay = schedule; mock_get_options_calls = 0; - next_at = download_status_increment_attempt(&dls_attempt, "test", - current_time); - tt_assert(next_at == current_time + delay2); - tt_assert(download_status_get_n_failures(&dls_attempt) == 0); - tt_assert(download_status_get_n_attempts(&dls_attempt) == 3); - tt_assert(mock_get_options_calls >= 1); - - /* Check what happens when we hit the attempt limit */ - mock_get_options_calls = 0; - download_status_mark_impossible(&dls_attempt); - next_at = download_status_increment_attempt(&dls_attempt, "test", - current_time); - tt_assert(next_at == TIME_MAX); - tt_assert(download_status_get_n_failures(&dls_attempt) - == IMPOSSIBLE_TO_DOWNLOAD); - tt_assert(download_status_get_n_attempts(&dls_attempt) - == IMPOSSIBLE_TO_DOWNLOAD); - tt_assert(mock_get_options_calls >= 1); - - /* Check that an attempt reset doesn't reset at the limit */ - mock_get_options_calls = 0; - download_status_reset(&dls_attempt); - tt_assert(download_status_get_next_attempt_at(&dls_attempt) - == TIME_MAX); - tt_assert(download_status_get_n_failures(&dls_attempt) - == IMPOSSIBLE_TO_DOWNLOAD); - tt_assert(download_status_get_n_attempts(&dls_attempt) - == IMPOSSIBLE_TO_DOWNLOAD); - tt_assert(mock_get_options_calls == 0); - - /* Check that an attempt reset resets just before the limit */ - mock_get_options_calls = 0; - dls_attempt.n_download_failures = IMPOSSIBLE_TO_DOWNLOAD - 1; - dls_attempt.n_download_attempts = IMPOSSIBLE_TO_DOWNLOAD - 1; - download_status_reset(&dls_attempt); /* we really want to test that it's equal to time(NULL) + delay0, but that's * an unrealiable test, because time(NULL) might change. */ - tt_assert(download_status_get_next_attempt_at(&dls_attempt) + tt_assert(download_status_get_next_attempt_at(&dls_exp) >= current_time + delay0); - tt_assert(download_status_get_next_attempt_at(&dls_attempt) + tt_assert(download_status_get_next_attempt_at(&dls_exp) != TIME_MAX); - tt_assert(download_status_get_n_failures(&dls_attempt) == 0); - tt_assert(download_status_get_n_attempts(&dls_attempt) == 0); - tt_assert(mock_get_options_calls >= 1); - - /* Check that attempt increments don't happen on failure-based schedules, - * and that the attempt is set at the end of time */ - mock_get_options_calls = 0; - setup_full_capture_of_logs(LOG_WARN); - next_at = download_status_increment_attempt(&dls_failure, "test", - current_time); - expect_single_log_msg_containing( - "Tried to launch an attempt-based connection on a failure-based " - "schedule."); - teardown_capture_of_logs(); - tt_assert(next_at == TIME_MAX); - tt_assert(download_status_get_n_failures(&dls_failure) == 0); - tt_assert(download_status_get_n_attempts(&dls_failure) == 0); - tt_assert(mock_get_options_calls == 0); + tt_int_op(download_status_get_n_failures(&dls_exp), OP_EQ, 0); + tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0); + tt_int_op(mock_get_options_calls, OP_GE, 1); done: - /* the pointers in schedule are allocated on the stack */ - smartlist_free(schedule); UNMOCK(get_options); mock_options = NULL; mock_get_options_calls = 0; @@ -4054,7 +4376,6 @@ test_dir_should_use_directory_guards(void *data) tt_int_op(should_use_directory_guards(options), OP_EQ, 0); tt_int_op(CALLED(public_server_mode), OP_EQ, 1); - options->UseEntryGuardsAsDirGuards = 1; options->UseEntryGuards = 1; options->DownloadExtraInfo = 0; options->FetchDirInfoEarly = 0; @@ -4068,29 +4389,24 @@ test_dir_should_use_directory_guards(void *data) tt_int_op(CALLED(public_server_mode), OP_EQ, 3); options->UseEntryGuards = 1; - options->UseEntryGuardsAsDirGuards = 0; - tt_int_op(should_use_directory_guards(options), OP_EQ, 0); - tt_int_op(CALLED(public_server_mode), OP_EQ, 4); - options->UseEntryGuardsAsDirGuards = 1; - options->DownloadExtraInfo = 1; tt_int_op(should_use_directory_guards(options), OP_EQ, 0); - tt_int_op(CALLED(public_server_mode), OP_EQ, 5); + tt_int_op(CALLED(public_server_mode), OP_EQ, 4); options->DownloadExtraInfo = 0; options->FetchDirInfoEarly = 1; tt_int_op(should_use_directory_guards(options), OP_EQ, 0); - tt_int_op(CALLED(public_server_mode), OP_EQ, 6); + tt_int_op(CALLED(public_server_mode), OP_EQ, 5); options->FetchDirInfoEarly = 0; options->FetchDirInfoExtraEarly = 1; tt_int_op(should_use_directory_guards(options), OP_EQ, 0); - tt_int_op(CALLED(public_server_mode), OP_EQ, 7); + tt_int_op(CALLED(public_server_mode), OP_EQ, 6); options->FetchDirInfoExtraEarly = 0; options->FetchUselessDescriptors = 1; tt_int_op(should_use_directory_guards(options), OP_EQ, 0); - tt_int_op(CALLED(public_server_mode), OP_EQ, 8); + tt_int_op(CALLED(public_server_mode), OP_EQ, 7); options->FetchUselessDescriptors = 0; done: @@ -4100,14 +4416,7 @@ test_dir_should_use_directory_guards(void *data) } NS_DECL(void, -directory_initiate_command_routerstatus, (const routerstatus_t *status, - uint8_t dir_purpose, - uint8_t router_purpose, - dir_indirection_t indirection, - const char *resource, - const char *payload, - size_t payload_len, - time_t if_modified_since)); +directory_initiate_request, (directory_request_t *req)); static void test_dir_should_not_init_request_to_ourselves(void *data) @@ -4117,7 +4426,7 @@ test_dir_should_not_init_request_to_ourselves(void *data) crypto_pk_t *key = pk_generate(2); (void) data; - NS_MOCK(directory_initiate_command_routerstatus); + NS_MOCK(directory_initiate_request); clear_dir_servers(); routerlist_free_all(); @@ -4132,15 +4441,15 @@ test_dir_should_not_init_request_to_ourselves(void *data) dir_server_add(ourself); directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL); - tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 0); + tt_int_op(CALLED(directory_initiate_request), OP_EQ, 0); directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0, NULL); - tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 0); + tt_int_op(CALLED(directory_initiate_request), OP_EQ, 0); done: - NS_UNMOCK(directory_initiate_command_routerstatus); + NS_UNMOCK(directory_initiate_request); clear_dir_servers(); routerlist_free_all(); crypto_pk_free(key); @@ -4154,7 +4463,7 @@ test_dir_should_not_init_request_to_dir_auths_without_v3_info(void *data) | MICRODESC_DIRINFO; (void) data; - NS_MOCK(directory_initiate_command_routerstatus); + NS_MOCK(directory_initiate_request); clear_dir_servers(); routerlist_free_all(); @@ -4165,14 +4474,14 @@ test_dir_should_not_init_request_to_dir_auths_without_v3_info(void *data) dir_server_add(ds); directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL); - tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 0); + tt_int_op(CALLED(directory_initiate_request), OP_EQ, 0); directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0, NULL); - tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 0); + tt_int_op(CALLED(directory_initiate_request), OP_EQ, 0); done: - NS_UNMOCK(directory_initiate_command_routerstatus); + NS_UNMOCK(directory_initiate_request); clear_dir_servers(); routerlist_free_all(); } @@ -4183,7 +4492,7 @@ test_dir_should_init_request_to_dir_auths(void *data) dir_server_t *ds = NULL; (void) data; - NS_MOCK(directory_initiate_command_routerstatus); + NS_MOCK(directory_initiate_request); clear_dir_servers(); routerlist_free_all(); @@ -4194,37 +4503,23 @@ test_dir_should_init_request_to_dir_auths(void *data) dir_server_add(ds); directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL); - tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 1); + tt_int_op(CALLED(directory_initiate_request), OP_EQ, 1); directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0, NULL); - tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 2); + tt_int_op(CALLED(directory_initiate_request), OP_EQ, 2); done: - NS_UNMOCK(directory_initiate_command_routerstatus); + NS_UNMOCK(directory_initiate_request); clear_dir_servers(); routerlist_free_all(); } void -NS(directory_initiate_command_routerstatus)(const routerstatus_t *status, - uint8_t dir_purpose, - uint8_t router_purpose, - dir_indirection_t indirection, - const char *resource, - const char *payload, - size_t payload_len, - time_t if_modified_since) +NS(directory_initiate_request)(directory_request_t *req) { - (void)status; - (void)dir_purpose; - (void)router_purpose; - (void)indirection; - (void)resource; - (void)payload; - (void)payload_len; - (void)if_modified_since; - CALLED(directory_initiate_command_routerstatus)++; + (void)req; + CALLED(directory_initiate_request)++; } static void @@ -4278,22 +4573,24 @@ mock_check_private_dir(const char *dirname, cpd_check_t check, static char * mock_get_datadir_fname(const or_options_t *options, + directory_root_t roottype, const char *sub1, const char *sub2, const char *suffix) { + (void) roottype; char *rv = NULL; /* * Assert we were called like get_datadir_fname2() or get_datadir_fname(), * since that's all we implement here. */ - tt_assert(options != NULL); - tt_assert(sub1 != NULL); + tt_ptr_op(options, OP_NE, NULL); + tt_ptr_op(sub1, OP_NE, NULL); /* * No particular assertions about sub2, since we could be in the * get_datadir_fname() or get_datadir_fname2() case. */ - tt_assert(suffix == NULL); + tt_ptr_op(suffix, OP_EQ, NULL); /* Just duplicate the basename and return it for this mock */ if (sub2) { @@ -4320,7 +4617,7 @@ mock_unlink_reset(void) static int mock_unlink(const char *path) { - tt_assert(path != NULL); + tt_ptr_op(path, OP_NE, NULL); tor_free(last_unlinked_path); last_unlinked_path = tor_strdup(path); @@ -4349,8 +4646,8 @@ mock_write_str_to_file(const char *path, const char *str, int bin) (void)bin; - tt_assert(path != NULL); - tt_assert(str != NULL); + tt_ptr_op(path, OP_NE, NULL); + tt_ptr_op(str, OP_NE, NULL); len = strlen(str); crypto_digest256((char *)hash, str, len, DIGEST_SHA256); @@ -4437,7 +4734,7 @@ test_dir_dump_unparseable_descriptors(void *data) mock_options->MaxUnparseableDescSizeToLog = 1536; MOCK(get_options, mock_get_options); MOCK(check_private_dir, mock_check_private_dir); - MOCK(options_get_datadir_fname2_suffix, + MOCK(options_get_dir_fname2_suffix, mock_get_datadir_fname); /* @@ -4476,7 +4773,7 @@ test_dir_dump_unparseable_descriptors(void *data) * Reset the FIFO and check its state */ dump_desc_fifo_cleanup(); - tt_u64_op(len_descs_dumped, ==, 0); + tt_u64_op(len_descs_dumped, OP_EQ, 0); tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0); /* @@ -4489,21 +4786,21 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_1)); + tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_1)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 1); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 1); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256); /* * Reset the FIFO and check its state */ dump_desc_fifo_cleanup(); - tt_u64_op(len_descs_dumped, ==, 0); + tt_u64_op(len_descs_dumped, OP_EQ, 0); tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0); /* @@ -4511,8 +4808,8 @@ test_dir_dump_unparseable_descriptors(void *data) */ mock_unlink_reset(); mock_write_str_to_file_reset(); - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 0); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 0); /* * (2) Fire off dump_desc() twice; this still should trigger no cleanup. @@ -4524,14 +4821,14 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_2)); + tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_2)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 1); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 1); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256); /* Second time */ @@ -4540,21 +4837,22 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_2) + strlen(test_desc_3)); + tt_u64_op(len_descs_dumped, OP_EQ, + strlen(test_desc_2) + strlen(test_desc_3)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 2); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 2); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256); /* * Reset the FIFO and check its state */ dump_desc_fifo_cleanup(); - tt_u64_op(len_descs_dumped, ==, 0); + tt_u64_op(len_descs_dumped, OP_EQ, 0); tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0); /* @@ -4562,8 +4860,8 @@ test_dir_dump_unparseable_descriptors(void *data) */ mock_unlink_reset(); mock_write_str_to_file_reset(); - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 0); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 0); /* * (3) Three calls to dump_desc cause a FIFO cleanup @@ -4575,14 +4873,14 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_4)); + tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_4)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 1); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 1); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256); /* Second time */ @@ -4591,14 +4889,15 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_4) + strlen(test_desc_1)); + tt_u64_op(len_descs_dumped, OP_EQ, + strlen(test_desc_4) + strlen(test_desc_1)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 2); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 2); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256); /* Third time - we should unlink the dump of test_desc_4 here */ @@ -4607,21 +4906,22 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_1) + strlen(test_desc_2)); + tt_u64_op(len_descs_dumped, OP_EQ, + strlen(test_desc_1) + strlen(test_desc_2)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 1); - tt_int_op(write_str_count, ==, 3); + tt_int_op(unlinked_count, OP_EQ, 1); + tt_int_op(write_str_count, OP_EQ, 3); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256); /* * Reset the FIFO and check its state */ dump_desc_fifo_cleanup(); - tt_u64_op(len_descs_dumped, ==, 0); + tt_u64_op(len_descs_dumped, OP_EQ, 0); tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0); /* @@ -4629,8 +4929,8 @@ test_dir_dump_unparseable_descriptors(void *data) */ mock_unlink_reset(); mock_write_str_to_file_reset(); - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 0); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 0); /* * (4) But repeating one (A B B) doesn't overflow and cleanup @@ -4642,14 +4942,14 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_3)); + tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_3)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 1); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 1); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256); /* Second time */ @@ -4658,14 +4958,15 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_3) + strlen(test_desc_4)); + tt_u64_op(len_descs_dumped, OP_EQ, + strlen(test_desc_3) + strlen(test_desc_4)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 2); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 2); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256); /* Third time */ @@ -4674,21 +4975,22 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_3) + strlen(test_desc_4)); + tt_u64_op(len_descs_dumped, OP_EQ, + strlen(test_desc_3) + strlen(test_desc_4)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 2); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 2); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256); /* * Reset the FIFO and check its state */ dump_desc_fifo_cleanup(); - tt_u64_op(len_descs_dumped, ==, 0); + tt_u64_op(len_descs_dumped, OP_EQ, 0); tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0); /* @@ -4696,8 +4998,8 @@ test_dir_dump_unparseable_descriptors(void *data) */ mock_unlink_reset(); mock_write_str_to_file_reset(); - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 0); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 0); /* * (5) Same for the (A B A) repetition @@ -4709,14 +5011,14 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_1)); + tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_1)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 1); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 1); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256); /* Second time */ @@ -4725,14 +5027,15 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_1) + strlen(test_desc_2)); + tt_u64_op(len_descs_dumped, OP_EQ, + strlen(test_desc_1) + strlen(test_desc_2)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 2); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 2); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256); /* Third time */ @@ -4741,21 +5044,22 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_1) + strlen(test_desc_2)); + tt_u64_op(len_descs_dumped, OP_EQ, + strlen(test_desc_1) + strlen(test_desc_2)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 2); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 2); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256); /* * Reset the FIFO and check its state */ dump_desc_fifo_cleanup(); - tt_u64_op(len_descs_dumped, ==, 0); + tt_u64_op(len_descs_dumped, OP_EQ, 0); tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0); /* @@ -4763,8 +5067,8 @@ test_dir_dump_unparseable_descriptors(void *data) */ mock_unlink_reset(); mock_write_str_to_file_reset(); - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 0); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 0); /* * (6) (A B B C) triggering overflow on C causes A, not B to be unlinked @@ -4776,14 +5080,14 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_3)); + tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_3)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 1); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 1); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256); /* Second time */ @@ -4792,14 +5096,15 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_3) + strlen(test_desc_4)); + tt_u64_op(len_descs_dumped, OP_EQ, + strlen(test_desc_3) + strlen(test_desc_4)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 2); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 2); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256); /* Third time */ @@ -4808,14 +5113,15 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_3) + strlen(test_desc_4)); + tt_u64_op(len_descs_dumped, OP_EQ, + strlen(test_desc_3) + strlen(test_desc_4)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 2); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 2); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256); /* Fourth time - we should unlink the dump of test_desc_3 here */ @@ -4824,21 +5130,22 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_4) + strlen(test_desc_1)); + tt_u64_op(len_descs_dumped, OP_EQ, + strlen(test_desc_4) + strlen(test_desc_1)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 1); - tt_int_op(write_str_count, ==, 3); + tt_int_op(unlinked_count, OP_EQ, 1); + tt_int_op(write_str_count, OP_EQ, 3); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256); /* * Reset the FIFO and check its state */ dump_desc_fifo_cleanup(); - tt_u64_op(len_descs_dumped, ==, 0); + tt_u64_op(len_descs_dumped, OP_EQ, 0); tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0); /* @@ -4846,8 +5153,8 @@ test_dir_dump_unparseable_descriptors(void *data) */ mock_unlink_reset(); mock_write_str_to_file_reset(); - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 0); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 0); /* * (7) (A B A C) triggering overflow on C causes B, not A to be unlinked @@ -4859,14 +5166,14 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_2)); + tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_2)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 1); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 1); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256); /* Second time */ @@ -4875,14 +5182,15 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_2) + strlen(test_desc_3)); + tt_u64_op(len_descs_dumped, OP_EQ, + strlen(test_desc_2) + strlen(test_desc_3)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 2); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 2); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256); /* Third time */ @@ -4891,14 +5199,15 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_2) + strlen(test_desc_3)); + tt_u64_op(len_descs_dumped, OP_EQ, + strlen(test_desc_2) + strlen(test_desc_3)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 2); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 2); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256); /* Fourth time - we should unlink the dump of test_desc_3 here */ @@ -4907,21 +5216,22 @@ test_dir_dump_unparseable_descriptors(void *data) /* * Assert things about the FIFO state */ - tt_u64_op(len_descs_dumped, ==, strlen(test_desc_2) + strlen(test_desc_4)); + tt_u64_op(len_descs_dumped, OP_EQ, + strlen(test_desc_2) + strlen(test_desc_4)); tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2); /* * Assert things about the mocks */ - tt_int_op(unlinked_count, ==, 1); - tt_int_op(write_str_count, ==, 3); + tt_int_op(unlinked_count, OP_EQ, 1); + tt_int_op(write_str_count, OP_EQ, 3); tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256); /* * Reset the FIFO and check its state */ dump_desc_fifo_cleanup(); - tt_u64_op(len_descs_dumped, ==, 0); + tt_u64_op(len_descs_dumped, OP_EQ, 0); tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0); /* @@ -4929,8 +5239,8 @@ test_dir_dump_unparseable_descriptors(void *data) */ mock_unlink_reset(); mock_write_str_to_file_reset(); - tt_int_op(unlinked_count, ==, 0); - tt_int_op(write_str_count, ==, 0); + tt_int_op(unlinked_count, OP_EQ, 0); + tt_int_op(write_str_count, OP_EQ, 0); done: @@ -4942,7 +5252,7 @@ test_dir_dump_unparseable_descriptors(void *data) mock_unlink_reset(); UNMOCK(write_str_to_file); mock_write_str_to_file_reset(); - UNMOCK(options_get_datadir_fname2_suffix); + UNMOCK(options_get_dir_fname2_suffix); UNMOCK(check_private_dir); UNMOCK(get_options); tor_free(mock_options); @@ -4977,7 +5287,7 @@ read_file_to_str_mock(const char *filename, int flags, char *result = NULL; /* Insist we got a filename */ - tt_assert(filename != NULL); + tt_ptr_op(filename, OP_NE, NULL); /* We ignore flags */ (void)flags; @@ -5040,53 +5350,53 @@ test_dir_populate_dump_desc_fifo(void *data) reset_read_file_to_str_mock(); /* Check state of unlink mock */ - tt_int_op(unlinked_count, ==, 0); + tt_int_op(unlinked_count, OP_EQ, 0); /* Some cases that should fail before trying to read the file */ ent = dump_desc_populate_one_file(dirname, "bar"); - tt_assert(ent == NULL); - tt_int_op(unlinked_count, ==, 1); - tt_int_op(read_count, ==, 0); - tt_int_op(read_call_count, ==, 0); + tt_ptr_op(ent, OP_EQ, NULL); + tt_int_op(unlinked_count, OP_EQ, 1); + tt_int_op(read_count, OP_EQ, 0); + tt_int_op(read_call_count, OP_EQ, 0); ent = dump_desc_populate_one_file(dirname, "unparseable-desc"); - tt_assert(ent == NULL); - tt_int_op(unlinked_count, ==, 2); - tt_int_op(read_count, ==, 0); - tt_int_op(read_call_count, ==, 0); + tt_ptr_op(ent, OP_EQ, NULL); + tt_int_op(unlinked_count, OP_EQ, 2); + tt_int_op(read_count, OP_EQ, 0); + tt_int_op(read_call_count, OP_EQ, 0); ent = dump_desc_populate_one_file(dirname, "unparseable-desc.baz"); - tt_assert(ent == NULL); - tt_int_op(unlinked_count, ==, 3); - tt_int_op(read_count, ==, 0); - tt_int_op(read_call_count, ==, 0); + tt_ptr_op(ent, OP_EQ, NULL); + tt_int_op(unlinked_count, OP_EQ, 3); + tt_int_op(read_count, OP_EQ, 0); + tt_int_op(read_call_count, OP_EQ, 0); ent = dump_desc_populate_one_file( dirname, "unparseable-desc.08AE85E90461F59E"); - tt_assert(ent == NULL); - tt_int_op(unlinked_count, ==, 4); - tt_int_op(read_count, ==, 0); - tt_int_op(read_call_count, ==, 0); + tt_ptr_op(ent, OP_EQ, NULL); + tt_int_op(unlinked_count, OP_EQ, 4); + tt_int_op(read_count, OP_EQ, 0); + tt_int_op(read_call_count, OP_EQ, 0); ent = dump_desc_populate_one_file( dirname, "unparseable-desc.08AE85E90461F59EDF0981323F3A70D02B55AB54B44B04F" "287D72F7B72F242E85C8CB0EDA8854A99"); - tt_assert(ent == NULL); - tt_int_op(unlinked_count, ==, 5); - tt_int_op(read_count, ==, 0); - tt_int_op(read_call_count, ==, 0); + tt_ptr_op(ent, OP_EQ, NULL); + tt_int_op(unlinked_count, OP_EQ, 5); + tt_int_op(read_count, OP_EQ, 0); + tt_int_op(read_call_count, OP_EQ, 0); /* This is a correct-length digest but base16_decode() will fail */ ent = dump_desc_populate_one_file( dirname, "unparseable-desc.68219B8BGE64B705A6FFC728C069DC596216D60A7D7520C" "D5ECE250D912E686B"); - tt_assert(ent == NULL); - tt_int_op(unlinked_count, ==, 6); - tt_int_op(read_count, ==, 0); - tt_int_op(read_call_count, ==, 0); + tt_ptr_op(ent, OP_EQ, NULL); + tt_int_op(unlinked_count, OP_EQ, 6); + tt_int_op(read_count, OP_EQ, 0); + tt_int_op(read_call_count, OP_EQ, 0); /* This one has a correctly formed filename and should try reading */ @@ -5095,10 +5405,10 @@ test_dir_populate_dump_desc_fifo(void *data) dirname, "unparseable-desc.DF0981323F3A70D02B55AB54B44B04F287D72F7B72F242E" "85C8CB0EDA8854A99"); - tt_assert(ent == NULL); - tt_int_op(unlinked_count, ==, 7); - tt_int_op(read_count, ==, 0); - tt_int_op(read_call_count, ==, 1); + tt_ptr_op(ent, OP_EQ, NULL); + tt_int_op(unlinked_count, OP_EQ, 7); + tt_int_op(read_count, OP_EQ, 0); + tt_int_op(read_call_count, OP_EQ, 1); /* This read will succeed but the digest won't match the file content */ fname = @@ -5111,10 +5421,10 @@ test_dir_populate_dump_desc_fifo(void *data) file_stat.st_mtime = 123456; ent = dump_desc_populate_one_file(dirname, fname); enforce_expected_filename = 0; - tt_assert(ent == NULL); - tt_int_op(unlinked_count, ==, 8); - tt_int_op(read_count, ==, 1); - tt_int_op(read_call_count, ==, 2); + tt_ptr_op(ent, OP_EQ, NULL); + tt_int_op(unlinked_count, OP_EQ, 8); + tt_int_op(read_count, OP_EQ, 1); + tt_int_op(read_call_count, OP_EQ, 2); tor_free(expected_filename); tor_free(file_content); @@ -5127,13 +5437,13 @@ test_dir_populate_dump_desc_fifo(void *data) file_content_len = strlen(file_content); file_stat.st_mtime = 789012; ent = dump_desc_populate_one_file(dirname, fname); - tt_assert(ent != NULL); - tt_int_op(unlinked_count, ==, 8); - tt_int_op(read_count, ==, 2); - tt_int_op(read_call_count, ==, 3); + tt_ptr_op(ent, OP_NE, NULL); + tt_int_op(unlinked_count, OP_EQ, 8); + tt_int_op(read_count, OP_EQ, 2); + tt_int_op(read_call_count, OP_EQ, 3); tt_str_op(ent->filename, OP_EQ, expected_filename); - tt_int_op(ent->len, ==, file_content_len); - tt_int_op(ent->when, ==, file_stat.st_mtime); + tt_int_op(ent->len, OP_EQ, file_content_len); + tt_int_op(ent->when, OP_EQ, file_stat.st_mtime); tor_free(ent->filename); tor_free(ent); tor_free(expected_filename); @@ -5142,9 +5452,9 @@ test_dir_populate_dump_desc_fifo(void *data) * Reset the mocks and check their state */ mock_unlink_reset(); - tt_int_op(unlinked_count, ==, 0); + tt_int_op(unlinked_count, OP_EQ, 0); reset_read_file_to_str_mock(); - tt_int_op(read_count, ==, 0); + tt_int_op(read_count, OP_EQ, 0); done: @@ -5167,9 +5477,9 @@ listdir_mock(const char *dname) (void)dname; l = smartlist_new(); - smartlist_add(l, tor_strdup("foo")); - smartlist_add(l, tor_strdup("bar")); - smartlist_add(l, tor_strdup("baz")); + smartlist_add_strdup(l, "foo"); + smartlist_add_strdup(l, "bar"); + smartlist_add_strdup(l, "baz"); return l; } @@ -5266,17 +5576,26 @@ mock_networkstatus_consensus_can_use_extra_fallbacks( return mock_networkstatus_consensus_can_use_extra_fallbacks_value; } -/* data is a 2 character nul-terminated string. +static int mock_num_bridges_usable_value = 0; +static int +mock_num_bridges_usable(int use_maybe_reachable) +{ + (void)use_maybe_reachable; + return mock_num_bridges_usable_value; +} + +/* data is a 3 character nul-terminated string. * If data[0] is 'b', set bootstrapping, anything else means not bootstrapping * If data[1] is 'f', set extra fallbacks, anything else means no extra + * If data[2] is 'f', set running bridges, anything else means no extra * fallbacks. */ static void -test_dir_find_dl_schedule(void* data) +test_dir_find_dl_min_delay(void* data) { const char *str = (const char *)data; - tt_assert(strlen(data) == 2); + tt_assert(strlen(data) == 3); if (str[0] == 'b') { mock_networkstatus_consensus_is_bootstrapping_value = 1; @@ -5290,49 +5609,60 @@ test_dir_find_dl_schedule(void* data) mock_networkstatus_consensus_can_use_extra_fallbacks_value = 0; } + if (str[2] == 'r') { + /* Any positive, non-zero value should work */ + mock_num_bridges_usable_value = 2; + } else { + mock_num_bridges_usable_value = 0; + } + MOCK(networkstatus_consensus_is_bootstrapping, mock_networkstatus_consensus_is_bootstrapping); MOCK(networkstatus_consensus_can_use_extra_fallbacks, mock_networkstatus_consensus_can_use_extra_fallbacks); + MOCK(num_bridges_usable, + mock_num_bridges_usable); download_status_t dls; - smartlist_t server, client, server_cons, client_cons; - smartlist_t client_boot_auth_only_cons, client_boot_auth_cons; - smartlist_t client_boot_fallback_cons, bridge; + + const int server=10, client=20, server_cons=30, client_cons=40; + const int client_boot_auth_only_cons=50, client_boot_auth_cons=60; + const int client_boot_fallback_cons=70, bridge=80, bridge_bootstrap=90; mock_options = tor_malloc(sizeof(or_options_t)); reset_options(mock_options, &mock_get_options_calls); MOCK(get_options, mock_get_options); - mock_options->TestingServerDownloadSchedule = &server; - mock_options->TestingClientDownloadSchedule = &client; - mock_options->TestingServerConsensusDownloadSchedule = &server_cons; - mock_options->TestingClientConsensusDownloadSchedule = &client_cons; - mock_options->ClientBootstrapConsensusAuthorityOnlyDownloadSchedule = - &client_boot_auth_only_cons; - mock_options->ClientBootstrapConsensusAuthorityDownloadSchedule = - &client_boot_auth_cons; - mock_options->ClientBootstrapConsensusFallbackDownloadSchedule = - &client_boot_fallback_cons; - mock_options->TestingBridgeDownloadSchedule = &bridge; + mock_options->TestingServerDownloadInitialDelay = server; + mock_options->TestingClientDownloadInitialDelay = client; + mock_options->TestingServerConsensusDownloadInitialDelay = server_cons; + mock_options->TestingClientConsensusDownloadInitialDelay = client_cons; + mock_options->ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay = + client_boot_auth_only_cons; + mock_options->ClientBootstrapConsensusAuthorityDownloadInitialDelay = + client_boot_auth_cons; + mock_options->ClientBootstrapConsensusFallbackDownloadInitialDelay = + client_boot_fallback_cons; + mock_options->TestingBridgeDownloadInitialDelay = bridge; + mock_options->TestingBridgeBootstrapDownloadInitialDelay = bridge_bootstrap; dls.schedule = DL_SCHED_GENERIC; /* client */ mock_options->ClientOnly = 1; - tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &client); + tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, client); mock_options->ClientOnly = 0; /* dir mode */ mock_options->DirPort_set = 1; mock_options->DirCache = 1; - tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &server); + tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server); mock_options->DirPort_set = 0; mock_options->DirCache = 0; dls.schedule = DL_SCHED_CONSENSUS; /* public server mode */ mock_options->ORPort_set = 1; - tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &server_cons); + tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server_cons); mock_options->ORPort_set = 0; /* client and bridge modes */ @@ -5341,30 +5671,30 @@ test_dir_find_dl_schedule(void* data) dls.want_authority = 1; /* client */ mock_options->ClientOnly = 1; - tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, - &client_boot_auth_cons); + tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, + client_boot_auth_cons); mock_options->ClientOnly = 0; /* bridge relay */ mock_options->ORPort_set = 1; mock_options->BridgeRelay = 1; - tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, - &client_boot_auth_cons); + tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, + client_boot_auth_cons); mock_options->ORPort_set = 0; mock_options->BridgeRelay = 0; dls.want_authority = 0; /* client */ mock_options->ClientOnly = 1; - tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, - &client_boot_fallback_cons); + tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, + client_boot_fallback_cons); mock_options->ClientOnly = 0; /* bridge relay */ mock_options->ORPort_set = 1; mock_options->BridgeRelay = 1; - tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, - &client_boot_fallback_cons); + tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, + client_boot_fallback_cons); mock_options->ORPort_set = 0; mock_options->BridgeRelay = 0; @@ -5372,30 +5702,30 @@ test_dir_find_dl_schedule(void* data) /* dls.want_authority is ignored */ /* client */ mock_options->ClientOnly = 1; - tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, - &client_boot_auth_only_cons); + tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, + client_boot_auth_only_cons); mock_options->ClientOnly = 0; /* bridge relay */ mock_options->ORPort_set = 1; mock_options->BridgeRelay = 1; - tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, - &client_boot_auth_only_cons); + tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, + client_boot_auth_only_cons); mock_options->ORPort_set = 0; mock_options->BridgeRelay = 0; } } else { /* client */ mock_options->ClientOnly = 1; - tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, - &client_cons); + tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, + client_cons); mock_options->ClientOnly = 0; /* bridge relay */ mock_options->ORPort_set = 1; mock_options->BridgeRelay = 1; - tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, - &client_cons); + tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, + client_cons); mock_options->ORPort_set = 0; mock_options->BridgeRelay = 0; } @@ -5403,11 +5733,17 @@ test_dir_find_dl_schedule(void* data) dls.schedule = DL_SCHED_BRIDGE; /* client */ mock_options->ClientOnly = 1; - tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &bridge); + mock_options->UseBridges = 1; + if (num_bridges_usable(0) > 0) { + tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge); + } else { + tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge_bootstrap); + } done: UNMOCK(networkstatus_consensus_is_bootstrapping); UNMOCK(networkstatus_consensus_can_use_extra_fallbacks); + UNMOCK(num_bridges_usable); UNMOCK(get_options); tor_free(mock_options); mock_options = NULL; @@ -5421,9 +5757,8 @@ test_dir_assumed_flags(void *arg) memarea_t *area = memarea_new(); routerstatus_t *rs = NULL; - /* First, we should always assume that the Running flag is set, even - * when it isn't listed, since the consensus method is always - * higher than 4. */ + /* We can assume that consensus method is higher than 24, so Running and + * Valid are always implicitly set */ const char *str1 = "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 " "192.168.0.1 9001 0\n" @@ -5432,17 +5767,6 @@ test_dir_assumed_flags(void *arg) const char *cp = str1; rs = routerstatus_parse_entry_from_string(area, &cp, tokens, NULL, NULL, - 23, FLAV_MICRODESC); - tt_assert(rs); - tt_assert(rs->is_flagged_running); - tt_assert(! rs->is_valid); - tt_assert(! rs->is_exit); - tt_assert(rs->is_fast); - routerstatus_free(rs); - - /* With method 24 or later, we can assume "valid" is set. */ - cp = str1; - rs = routerstatus_parse_entry_from_string(area, &cp, tokens, NULL, NULL, 24, FLAV_MICRODESC); tt_assert(rs); tt_assert(rs->is_flagged_running); @@ -5457,6 +5781,182 @@ test_dir_assumed_flags(void *arg) } static void +test_dir_post_parsing(void *arg) +{ + (void) arg; + + /* Test the version parsing from an HS descriptor publish request. */ + { + const char *end; + const char *prefix = "/tor/hs/"; + int version = parse_hs_version_from_post("/tor/hs//publish", prefix, &end); + tt_int_op(version, OP_EQ, -1); + tt_ptr_op(end, OP_EQ, NULL); + version = parse_hs_version_from_post("/tor/hs/a/publish", prefix, &end); + tt_int_op(version, OP_EQ, -1); + tt_ptr_op(end, OP_EQ, NULL); + version = parse_hs_version_from_post("/tor/hs/3/publish", prefix, &end); + tt_int_op(version, OP_EQ, 3); + tt_str_op(end, OP_EQ, "/publish"); + version = parse_hs_version_from_post("/tor/hs/42/publish", prefix, &end); + tt_int_op(version, OP_EQ, 42); + tt_str_op(end, OP_EQ, "/publish"); + version = parse_hs_version_from_post("/tor/hs/18163/publish",prefix, &end); + tt_int_op(version, OP_EQ, 18163); + tt_str_op(end, OP_EQ, "/publish"); + version = parse_hs_version_from_post("JUNKJUNKJUNK", prefix, &end); + tt_int_op(version, OP_EQ, -1); + tt_ptr_op(end, OP_EQ, NULL); + version = parse_hs_version_from_post("/tor/hs/3/publish", "blah", &end); + tt_int_op(version, OP_EQ, -1); + tt_ptr_op(end, OP_EQ, NULL); + /* Missing the '/' at the end of the prefix. */ + version = parse_hs_version_from_post("/tor/hs/3/publish", "/tor/hs", &end); + tt_int_op(version, OP_EQ, -1); + tt_ptr_op(end, OP_EQ, NULL); + version = parse_hs_version_from_post("/random/blah/tor/hs/3/publish", + prefix, &end); + tt_int_op(version, OP_EQ, -1); + tt_ptr_op(end, OP_EQ, NULL); + version = parse_hs_version_from_post("/tor/hs/3/publish/random/junk", + prefix, &end); + tt_int_op(version, OP_EQ, 3); + tt_str_op(end, OP_EQ, "/publish/random/junk"); + version = parse_hs_version_from_post("/tor/hs/-1/publish", prefix, &end); + tt_int_op(version, OP_EQ, -1); + tt_ptr_op(end, OP_EQ, NULL); + /* INT_MAX */ + version = parse_hs_version_from_post("/tor/hs/2147483647/publish", + prefix, &end); + tt_int_op(version, OP_EQ, INT_MAX); + tt_str_op(end, OP_EQ, "/publish"); + /* INT_MAX + 1*/ + version = parse_hs_version_from_post("/tor/hs/2147483648/publish", + prefix, &end); + tt_int_op(version, OP_EQ, -1); + tt_ptr_op(end, OP_EQ, NULL); + } + + done: + ; +} + +static void +test_dir_platform_str(void *arg) +{ + char platform[256]; + (void)arg; + platform[0] = 0; + get_platform_str(platform, sizeof(platform)); + tt_int_op((int)strlen(platform), OP_GT, 0); + tt_assert(!strcmpstart(platform, "Tor ")); + + tor_version_t ver; + // make sure this is a tor version, a real actual tor version. + tt_int_op(tor_version_parse_platform(platform, &ver, 1), OP_EQ, 1); + + TT_BLATHER(("%d.%d.%d.%d", ver.major, ver.minor, ver.micro, ver.patchlevel)); + + // Handle an example version. + tt_int_op(tor_version_parse_platform( + "Tor 0.3.3.3 (foo) (git-xyzzy) on a potato", &ver, 1), OP_EQ, 1); + done: + ; +} + +static networkstatus_t *mock_networkstatus; + +static networkstatus_t * +mock_networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f) +{ + (void)f; + return mock_networkstatus; +} + +static void +test_dir_networkstatus_consensus_has_ipv6(void *arg) +{ + (void)arg; + + int has_ipv6 = 0; + + /* Init options and networkstatus */ + or_options_t our_options; + mock_options = &our_options; + reset_options(mock_options, &mock_get_options_calls); + MOCK(get_options, mock_get_options); + + networkstatus_t our_networkstatus; + mock_networkstatus = &our_networkstatus; + memset(mock_networkstatus, 0, sizeof(*mock_networkstatus)); + MOCK(networkstatus_get_latest_consensus_by_flavor, + mock_networkstatus_get_latest_consensus_by_flavor); + + /* A live consensus */ + mock_networkstatus->valid_after = time(NULL) - 3600; + mock_networkstatus->valid_until = time(NULL) + 3600; + + /* Test the bounds for A lines in the NS consensus */ + mock_options->UseMicrodescriptors = 0; + + mock_networkstatus->consensus_method = MIN_SUPPORTED_CONSENSUS_METHOD; + has_ipv6 = networkstatus_consensus_has_ipv6(get_options()); + tt_assert(has_ipv6); + + /* Test the bounds for A lines in the microdesc consensus */ + mock_options->UseMicrodescriptors = 1; + + mock_networkstatus->consensus_method = + MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS; + has_ipv6 = networkstatus_consensus_has_ipv6(get_options()); + tt_assert(has_ipv6); + + mock_networkstatus->consensus_method = MAX_SUPPORTED_CONSENSUS_METHOD + 20; + has_ipv6 = networkstatus_consensus_has_ipv6(get_options()); + tt_assert(has_ipv6); + + mock_networkstatus->consensus_method = + MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS + 1; + has_ipv6 = networkstatus_consensus_has_ipv6(get_options()); + tt_assert(has_ipv6); + + mock_networkstatus->consensus_method = + MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS + 20; + has_ipv6 = networkstatus_consensus_has_ipv6(get_options()); + tt_assert(has_ipv6); + + mock_networkstatus->consensus_method = + MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS - 1; + has_ipv6 = networkstatus_consensus_has_ipv6(get_options()); + tt_assert(!has_ipv6); + + /* Test the edge cases */ + mock_options->UseMicrodescriptors = 1; + mock_networkstatus->consensus_method = + MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS; + + /* Reasonably live */ + mock_networkstatus->valid_until = approx_time() - 60; + has_ipv6 = networkstatus_consensus_has_ipv6(get_options()); + tt_assert(has_ipv6); + + /* Not reasonably live */ + mock_networkstatus->valid_after = approx_time() - 24*60*60 - 3600; + mock_networkstatus->valid_until = approx_time() - 24*60*60 - 60; + has_ipv6 = networkstatus_consensus_has_ipv6(get_options()); + tt_assert(!has_ipv6); + + /* NULL consensus */ + mock_networkstatus = NULL; + has_ipv6 = networkstatus_consensus_has_ipv6(get_options()); + tt_assert(!has_ipv6); + + done: + UNMOCK(get_options); + UNMOCK(networkstatus_get_latest_consensus_by_flavor); +} + +static void test_dir_format_versions_list(void *arg) { (void)arg; @@ -5525,12 +6025,15 @@ struct testcase_t dir_tests[] = { DIR(parse_router_list, TT_FORK), DIR(load_routers, TT_FORK), DIR(load_extrainfo, TT_FORK), + DIR(getinfo_extra, 0), DIR_LEGACY(versions), DIR_LEGACY(fp_pairs), DIR(split_fps, 0), - DIR_LEGACY(dirserv_read_measured_bandwidths), + DIR_LEGACY(dirserv_read_measured_bandwidths_empty), DIR_LEGACY(measured_bw_kb), + DIR_LEGACY(measured_bw_kb_line_is_after_headers), DIR_LEGACY(measured_bw_kb_cache), + DIR_LEGACY(dirserv_read_measured_bandwidths), DIR_LEGACY(param_voting), DIR(param_voting_lookup, 0), DIR_LEGACY(v3_networkstatus), @@ -5541,12 +6044,17 @@ struct testcase_t dir_tests[] = { DIR(fmt_control_ns, 0), DIR(dirserv_set_routerstatus_testing, 0), DIR(http_handling, 0), - DIR(purpose_needs_anonymity, 0), + DIR(purpose_needs_anonymity_returns_true_for_bridges, 0), + DIR(purpose_needs_anonymity_returns_false_for_own_bridge_desc, 0), + DIR(purpose_needs_anonymity_returns_true_by_default, 0), + DIR(purpose_needs_anonymity_returns_true_for_sensitive_purpose, 0), + DIR(purpose_needs_anonymity_ret_false_for_non_sensitive_conn, 0), + DIR(post_parsing, 0), DIR(fetch_type, 0), DIR(packages, 0), - DIR(download_status_schedule, 0), DIR(download_status_random_backoff, 0), - DIR(download_status_increment, 0), + DIR(download_status_random_backoff_ranges, 0), + DIR(download_status_increment, TT_FORK), DIR(authdir_type_to_string, 0), DIR(conn_purpose_to_string, 0), DIR(should_use_directory_guards, 0), @@ -5557,11 +6065,18 @@ struct testcase_t dir_tests[] = { DIR(dump_unparseable_descriptors, 0), DIR(populate_dump_desc_fifo, 0), DIR(populate_dump_desc_fifo_2, 0), - DIR_ARG(find_dl_schedule, TT_FORK, "bf"), - DIR_ARG(find_dl_schedule, TT_FORK, "ba"), - DIR_ARG(find_dl_schedule, TT_FORK, "cf"), - DIR_ARG(find_dl_schedule, TT_FORK, "ca"), + DIR_ARG(find_dl_min_delay, TT_FORK, "bfd"), + DIR_ARG(find_dl_min_delay, TT_FORK, "bad"), + DIR_ARG(find_dl_min_delay, TT_FORK, "cfd"), + DIR_ARG(find_dl_min_delay, TT_FORK, "cad"), + DIR_ARG(find_dl_min_delay, TT_FORK, "bfr"), + DIR_ARG(find_dl_min_delay, TT_FORK, "bar"), + DIR_ARG(find_dl_min_delay, TT_FORK, "cfr"), + DIR_ARG(find_dl_min_delay, TT_FORK, "car"), DIR(assumed_flags, 0), + DIR(networkstatus_compute_bw_weights_v10, 0), + DIR(platform_str, 0), + DIR(networkstatus_consensus_has_ipv6, TT_FORK), DIR(format_versions_list, TT_FORK), END_OF_TESTCASES }; |