From 027f73f70ef49859d5c6b7dc2a231b3f78dafd10 Mon Sep 17 00:00:00 2001 From: teor Date: Thu, 9 Apr 2015 16:37:33 +1000 Subject: [PATCH 1/2] Disable default fallback directories when other directories are set Only add the default fallback directories when the DirAuthorities, AlternateDirAuthority, and FallbackDir directory config options are set to their defaults. The default fallback directory list is currently empty, this fix will only change tor's behaviour when it has default fallback directories. Fixes bug 15642; bugfix on 90f6071d8dc0 in 0.2.4.7-alpha. Patch by "teor". --- changes/bug-15642-default-fallback-default-dirs | 8 ++++++++ src/or/config.c | 13 +++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 changes/bug-15642-default-fallback-default-dirs diff --git a/changes/bug-15642-default-fallback-default-dirs b/changes/bug-15642-default-fallback-default-dirs new file mode 100644 index 0000000000..3864cf373c --- /dev/null +++ b/changes/bug-15642-default-fallback-default-dirs @@ -0,0 +1,8 @@ + o Minor bugfixes (configuration): + - Only add the default fallback directories when the DirAuthorities, + AlternateDirAuthority, and FallbackDir directory config options + are set to their defaults. + The default fallback directory list is empty, this fix will only + change tor's behaviour when it has default fallback directories. + Fixes bug 15642; bugfix on 90f6071d8dc0 in 0.2.4.7-alpha. + Patch by "teor". diff --git a/src/or/config.c b/src/or/config.c index d7444d52f6..d48d57f733 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -985,17 +985,22 @@ consider_adding_dir_servers(const or_options_t *options, if (!options->DirAuthorities) { /* then we may want some of the defaults */ dirinfo_type_t type = NO_DIRINFO; - if (!options->AlternateBridgeAuthority) + if (!options->AlternateBridgeAuthority) { type |= BRIDGE_DIRINFO; - if (!options->AlternateDirAuthority) + } + if (!options->AlternateDirAuthority) { type |= V3_DIRINFO | EXTRAINFO_DIRINFO | MICRODESC_DIRINFO; + /* Only add the default fallback directories when the DirAuthorities, + * AlternateDirAuthority, and FallbackDir directory config options + * are set to their defaults. */ + if (!options->FallbackDir) + add_default_fallback_dir_servers(); + } /* if type == NO_DIRINFO, we don't want to add any of the * default authorities, because we've replaced them all */ if (type != NO_DIRINFO) add_default_trusted_dir_authorities(type); } - if (!options->FallbackDir) - add_default_fallback_dir_servers(); for (cl = options->DirAuthorities; cl; cl = cl->next) if (parse_dir_authority_line(cl->value, NO_DIRINFO, 0)<0) From d68bbb0a2939927eef221d8f9543a016f2c88245 Mon Sep 17 00:00:00 2001 From: teor Date: Wed, 15 Apr 2015 19:02:29 +1000 Subject: [PATCH 2/2] Unit tests for consider_adding_dir_servers() as modified in #15642 Unit tests for the 10 valid combinations of set/NULL config options DirAuthorities, AlternateBridgeAuthority, AlternateDirAuthority, and FallbackDir. Add assertion in consider_adding_dir_servers() for checks in validate_dir_servers(): "You cannot set both DirAuthority and Alternate*Authority." --- .../bug-15642-default-fallback-default-dirs | 8 +- src/or/config.c | 20 +- src/or/config.h | 6 + src/test/test_config.c | 1771 ++++++++++++++++- 4 files changed, 1793 insertions(+), 12 deletions(-) diff --git a/changes/bug-15642-default-fallback-default-dirs b/changes/bug-15642-default-fallback-default-dirs index 3864cf373c..a1e194bf1e 100644 --- a/changes/bug-15642-default-fallback-default-dirs +++ b/changes/bug-15642-default-fallback-default-dirs @@ -1,8 +1,10 @@ - o Minor bugfixes (configuration): + o Minor bugfixes (configuration, unit tests): - Only add the default fallback directories when the DirAuthorities, AlternateDirAuthority, and FallbackDir directory config options are set to their defaults. - The default fallback directory list is empty, this fix will only - change tor's behaviour when it has default fallback directories. + The default fallback directory list is currently empty, this fix + will only change tor's behaviour when it has default fallback + directories. + Includes unit tests for consider_adding_dir_servers(). Fixes bug 15642; bugfix on 90f6071d8dc0 in 0.2.4.7-alpha. Patch by "teor". diff --git a/src/or/config.c b/src/or/config.c index d48d57f733..85917e1bca 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -545,8 +545,6 @@ static char *get_bindaddr_from_transport_listen_line(const char *line, static int parse_dir_authority_line(const char *line, dirinfo_type_t required_type, int validate_only); -static int parse_dir_fallback_line(const char *line, - int validate_only); static void port_cfg_free(port_cfg_t *port); static int parse_ports(or_options_t *options, int validate_only, char **msg_out, int *n_ports_out); @@ -891,8 +889,8 @@ add_default_trusted_dir_authorities(dirinfo_type_t type) /** Add the default fallback directory servers into the fallback directory * server list. */ -static void -add_default_fallback_dir_servers(void) +MOCK_IMPL(void, +add_default_fallback_dir_servers,(void)) { int i; const char *fallback[] = { @@ -961,7 +959,7 @@ validate_dir_servers(or_options_t *options, or_options_t *old_options) /** Look at all the config options and assign new dir authorities * as appropriate. */ -static int +int consider_adding_dir_servers(const or_options_t *options, const or_options_t *old_options) { @@ -979,6 +977,13 @@ consider_adding_dir_servers(const or_options_t *options, if (!need_to_update) return 0; /* all done */ + /* "You cannot set both DirAuthority and Alternate*Authority." + * Checking that this restriction holds allows us to simplify + * the unit tests. */ + tor_assert(!(options->DirAuthorities && + (options->AlternateDirAuthority + || options->AlternateBridgeAuthority))); + /* Start from a clean slate. */ clear_dir_servers(); @@ -993,8 +998,9 @@ consider_adding_dir_servers(const or_options_t *options, /* Only add the default fallback directories when the DirAuthorities, * AlternateDirAuthority, and FallbackDir directory config options * are set to their defaults. */ - if (!options->FallbackDir) + if (!options->FallbackDir) { add_default_fallback_dir_servers(); + } } /* if type == NO_DIRINFO, we don't want to add any of the * default authorities, because we've replaced them all */ @@ -5500,7 +5506,7 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type, * validate_only is 0, and the line is well-formed, then add the * dirserver described in the line as a fallback directory. Return 0 on * success, or -1 if the line isn't well-formed or if we can't add it. */ -static int +int parse_dir_fallback_line(const char *line, int validate_only) { diff --git a/src/or/config.h b/src/or/config.h index b0b23bcfbd..74b28f45ca 100644 --- a/src/or/config.h +++ b/src/or/config.h @@ -144,6 +144,12 @@ STATIC int options_validate(or_options_t *old_options, STATIC int parse_transport_line(const or_options_t *options, const char *line, int validate_only, int server); +STATIC int consider_adding_dir_servers(const or_options_t *options, + const or_options_t *old_options); +MOCK_DECL(STATIC void, add_default_fallback_dir_servers, (void)); +STATIC int +parse_dir_fallback_line(const char *line, + int validate_only); #endif #endif diff --git a/src/test/test_config.c b/src/test/test_config.c index 0444062722..28e9fa0f32 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -17,6 +17,7 @@ #include "address.h" #include "entrynodes.h" #include "transports.h" +#include "routerlist.h" static void test_config_addressmap(void *arg) @@ -1036,7 +1037,7 @@ static int n_get_interface_address6_failure = 0; /** * This mock function is meant to replace get_interface_addres6(). - * It will pretent to fail by return -1. + * It will pretend to fail by return -1. * n_get_interface_address6_failure is incremented by one * every time this function is called and last_address6_family * is assigned the value of family argument. @@ -1405,7 +1406,7 @@ test_config_resolve_my_address(void *arg) /* CASE 12: * Suppose the following happens: - * 1. options->Address is NULL AND options->DirAuthorities is 1. + * 1. options->Address is NULL AND options->DirAuthorities is non-NULL * 2. tor_gethostname() succeeds in getting hostname of a machine ... * 3. ... which is successfully parsed by tor_inet_aton() ... * 4. into IPv4 address that tor_addr_is_inernal() considers to be @@ -1443,10 +1444,1776 @@ test_config_resolve_my_address(void *arg) UNMOCK(tor_gethostname); } +static int n_add_default_fallback_dir_servers_known_default = 0; + +/** + * This mock function is meant to replace add_default_fallback_dir_servers(). + * It will parse and add one known default fallback dir server, + * which has a dir_port of 99. + * n_add_default_fallback_dir_servers_known_default is incremented by + * one every time this function is called. + */ +static void +add_default_fallback_dir_servers_known_default(void) +{ + int i; + const char *fallback[] = { + "127.0.0.1:60099 orport=9009 " + "id=0923456789012345678901234567890123456789", + NULL + }; + for (i=0; fallback[i]; i++) { + if (parse_dir_fallback_line(fallback[i], 0)<0) { + log_err(LD_BUG, "Couldn't parse internal FallbackDir line %s", + fallback[i]); + } + } + n_add_default_fallback_dir_servers_known_default++; +} + +static void +test_config_adding_dir_servers(void *arg) +{ + (void)arg; + + /* allocate options */ + or_options_t *options = tor_malloc(sizeof(or_options_t)); + + /* Allocate and populate configuration lines: + * + * Use the same format as the hard-coded directories in + * add_default_trusted_dir_authorities(). + * Zeroing the structure has the same effect as initialising to: + * { NULL, NULL, NULL, CONFIG_LINE_NORMAL, 0}; + */ + config_line_t *test_dir_authority = tor_malloc(sizeof(config_line_t)); + memset(test_dir_authority, 0, sizeof(config_line_t)); + test_dir_authority->key = tor_strdup("DirAuthority"); + test_dir_authority->value = tor_strdup( + "D0 orport=9000 " + "v3ident=0023456789012345678901234567890123456789 " + "127.0.0.1:60090 0123 4567 8901 2345 6789 0123 4567 8901 2345 6789" + ); + + config_line_t *test_alt_bridge_authority = tor_malloc(sizeof(config_line_t)); + memset(test_alt_bridge_authority, 0, sizeof(config_line_t)); + test_alt_bridge_authority->key = tor_strdup("AlternateBridgeAuthority"); + test_alt_bridge_authority->value = tor_strdup( + "B1 orport=9001 bridge " + "127.0.0.1:60091 1123 4567 8901 2345 6789 0123 4567 8901 2345 6789" + ); + + config_line_t *test_alt_dir_authority = tor_malloc(sizeof(config_line_t)); + memset(test_alt_dir_authority, 0, sizeof(config_line_t)); + test_alt_dir_authority->key = tor_strdup("AlternateDirAuthority"); + test_alt_dir_authority->value = tor_strdup( + "A2 orport=9002 " + "v3ident=0223456789012345678901234567890123456789 " + "127.0.0.1:60092 2123 4567 8901 2345 6789 0123 4567 8901 2345 6789" + ); + + /* Use the format specified in the manual page */ + config_line_t *test_fallback_directory = tor_malloc(sizeof(config_line_t)); + memset(test_fallback_directory, 0, sizeof(config_line_t)); + test_fallback_directory->key = tor_strdup("FallbackDir"); + test_fallback_directory->value = tor_strdup( + "127.0.0.1:60093 orport=9003 id=0323456789012345678901234567890123456789" + ); + + /* We need to know if add_default_fallback_dir_servers is called, + * so we use a version of add_default_fallback_dir_servers that adds + * one known default fallback directory. + * There doesn't appear to be any need to test it unmocked. */ + MOCK(add_default_fallback_dir_servers, + add_default_fallback_dir_servers_known_default); + + /* There are 16 different cases, covering each combination of set/NULL for: + * DirAuthorities, AlternateBridgeAuthority, AlternateDirAuthority & + * FallbackDir. + * But validate_dir_servers() ensures that: + * "You cannot set both DirAuthority and Alternate*Authority." + * This reduces the number of cases to 10. + * + * Let's count these cases using binary, with 1 meaning set & 0 meaning NULL + * So 1001 or case 9 is: + * DirAuthorities set, + * AlternateBridgeAuthority NULL, + * AlternateDirAuthority NULL + * FallbackDir set + * The valid cases are cases 0-9 counting using this method, as every case + * greater than or equal to 10 = 1010 is invalid. + * + * After #15642 - Disable default fallback dirs when any custom dirs set + * + * 1. Outcome: Use Set Directory Authorities + * - No Default Authorities + * - Use AlternateBridgeAuthority, AlternateDirAuthority, and FallbackDir + * if they are set + * Cases expected to yield this outcome: + * 8 & 9 (the 2 valid cases where DirAuthorities is set) + * 6 & 7 (the 2 cases where DirAuthorities is NULL, and + * AlternateBridgeAuthority and AlternateDirAuthority are both set) + * + * 2. Outcome: Use Set Bridge Authority + * - Use Default Non-Bridge Directory Authorities + * - Use FallbackDir if it is set, otherwise use default FallbackDir + * Cases expected to yield this outcome: + * 4 & 5 (the 2 cases where DirAuthorities is NULL, + * AlternateBridgeAuthority is set, and + * AlternateDirAuthority is NULL) + * + * 3. Outcome: Use Set Alternate Directory Authority + * - Use Default Bridge Authorities + * - Use FallbackDir if it is set, otherwise No Default Fallback Directories + * Cases expected to yield this outcome: + * 2 & 3 (the 2 cases where DirAuthorities and AlternateBridgeAuthority + * are both NULL, but AlternateDirAuthority is set) + * + * 4. Outcome: Use Set Custom Fallback Directory + * - Use Default Bridge & Directory Authorities + * Cases expected to yield this outcome: + * 1 (DirAuthorities, AlternateBridgeAuthority and AlternateDirAuthority + * are all NULL, but FallbackDir is set) + * + * 5. Outcome: Use All Defaults + * - Use Default Bridge & Directory Authorities, and + * Default Fallback Directories + * Cases expected to yield this outcome: + * 0 (DirAuthorities, AlternateBridgeAuthority, AlternateDirAuthority + * and FallbackDir are all NULL) + * + * Before #15642 but after #13163 - Stop using default authorities when both + * Alternate Dir and Bridge Authority are set + * (#13163 was committed in 0.2.6 as c1dd43d823c7) + * + * The behaviour is different in the following cases + * where FallbackDir is NULL: + * 2, 6, 8 + * + * In these cases, the Default Fallback Directories are applied, even when + * DirAuthorities or AlternateDirAuthority are set. + * + * However, as the list of default fallback directories is currently empty, + * this change doesn't modify any user-visible behaviour. + */ + + /* + * Find out how many default Bridge, Non-Bridge and Fallback Directories + * are hard-coded into this build. + * This code makes some assumptions about the implementation. + * If they are wrong, one or more of cases 0-5 could fail. + */ + int n_default_alt_bridge_authority = 0; + int n_default_alt_dir_authority = 0; + int n_default_fallback_dir = 0; +#define n_default_authorities ((n_default_alt_bridge_authority) \ + + (n_default_alt_dir_authority)) + + /* Pre-Count Number of Authorities of Each Type + * Use 0000: No Directory Authorities or Fallback Directories Set + */ + { + /* clear fallback dirs counter */ + n_add_default_fallback_dir_servers_known_default = 0; + + /* clear options*/ + memset(options, 0, sizeof(or_options_t)); + + /* clear any previous dir servers: + consider_adding_dir_servers() should do this anyway */ + clear_dir_servers(); + + /* assign options: 0000 */ + options->DirAuthorities = NULL; + options->AlternateBridgeAuthority = NULL; + options->AlternateDirAuthority = NULL; + options->FallbackDir = NULL; + + /* parse options - ensure we always update by passing NULL old_options */ + consider_adding_dir_servers(options, NULL); + + /* check outcome */ + + /* we must have added the default fallback dirs */ + tt_assert(n_add_default_fallback_dir_servers_known_default == 1); + + { + /* fallback_dir_servers */ + const smartlist_t *fallback_servers = router_get_fallback_dir_servers(); + + /* Count Bridge Authorities */ + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if it's a bridge auth */ + n_default_alt_bridge_authority += + ((ds->is_authority && (ds->type & BRIDGE_DIRINFO)) ? + 1 : 0) + ); + /* If we have no default bridge authority, something has gone wrong */ + tt_assert(n_default_alt_bridge_authority >= 1); + + /* Count v3 Authorities */ + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment found counter if it's a v3 auth */ + n_default_alt_dir_authority += + ((ds->is_authority && (ds->type & V3_DIRINFO)) ? + 1 : 0) + ); + /* If we have no default authorities, something has gone really wrong */ + tt_assert(n_default_alt_dir_authority >= 1); + + /* Calculate Fallback Directory Count */ + n_default_fallback_dir = (smartlist_len(fallback_servers) - + n_default_alt_bridge_authority - + n_default_alt_dir_authority); + /* If we have a negative count, something has gone really wrong */ + tt_assert(n_default_fallback_dir >= 0); + } + } + + /* + * 1. Outcome: Use Set Directory Authorities + * - No Default Authorities + * - Use AlternateBridgeAuthority, AlternateDirAuthority, and FallbackDir + * if they are set + * Cases expected to yield this outcome: + * 8 & 9 (the 2 valid cases where DirAuthorities is set) + * 6 & 7 (the 2 cases where DirAuthorities is NULL, and + * AlternateBridgeAuthority and AlternateDirAuthority are both set) + */ + + /* Case 9: 1001 - DirAuthorities Set, AlternateBridgeAuthority Not Set, + AlternateDirAuthority Not Set, FallbackDir Set */ + { + /* clear fallback dirs counter */ + n_add_default_fallback_dir_servers_known_default = 0; + + /* clear options*/ + memset(options, 0, sizeof(or_options_t)); + + /* clear any previous dir servers: + consider_adding_dir_servers() should do this anyway */ + clear_dir_servers(); + + /* assign options: 1001 */ + options->DirAuthorities = test_dir_authority; + options->AlternateBridgeAuthority = NULL; + options->AlternateDirAuthority = NULL; + options->FallbackDir = test_fallback_directory; + + /* parse options - ensure we always update by passing NULL old_options */ + consider_adding_dir_servers(options, NULL); + + /* check outcome */ + + /* we must not have added the default fallback dirs */ + tt_assert(n_add_default_fallback_dir_servers_known_default == 0); + + { + /* trusted_dir_servers */ + const smartlist_t *dir_servers = router_get_trusted_dir_servers(); + /* D0, (No B1), (No A2) */ + tt_assert(smartlist_len(dir_servers) == 1); + + /* DirAuthority - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 1); + + /* (No AlternateBridgeAuthority) - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 0); + + /* (No AlternateDirAuthority) - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 0); + } + + { + /* fallback_dir_servers */ + const smartlist_t *fallback_servers = router_get_fallback_dir_servers(); + /* D0, (No B1), (No A2), Custom Fallback */ + tt_assert(smartlist_len(fallback_servers) == 2); + + /* DirAuthority - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 1); + + /* (No AlternateBridgeAuthority) - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 0); + + /* (No AlternateDirAuthority) - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 0); + + /* Custom FallbackDir - No Nickname - dir_port: 60093 */ + int found_non_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_non_default_fallback += + (ds->dir_port == 60093 ? + 1 : 0) + ); + tt_assert(found_non_default_fallback == 1); + + /* (No Default FallbackDir) - No Nickname - dir_port: 60099 */ + int found_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_default_fallback += + (ds->dir_port == 60099 ? + 1 : 0) + ); + tt_assert(found_default_fallback == 0); + } + } + + /* Case 8: 1000 - DirAuthorities Set, Others Not Set */ + { + /* clear fallback dirs counter */ + n_add_default_fallback_dir_servers_known_default = 0; + + /* clear options*/ + memset(options, 0, sizeof(or_options_t)); + + /* clear any previous dir servers: + consider_adding_dir_servers() should do this anyway */ + clear_dir_servers(); + + /* assign options: 1000 */ + options->DirAuthorities = test_dir_authority; + options->AlternateBridgeAuthority = NULL; + options->AlternateDirAuthority = NULL; + options->FallbackDir = NULL; + + /* parse options - ensure we always update by passing NULL old_options */ + consider_adding_dir_servers(options, NULL); + + /* check outcome */ + + /* we must not have added the default fallback dirs */ + tt_assert(n_add_default_fallback_dir_servers_known_default == 0); + + { + /* trusted_dir_servers */ + const smartlist_t *dir_servers = router_get_trusted_dir_servers(); + /* D0, (No B1), (No A2) */ + tt_assert(smartlist_len(dir_servers) == 1); + + /* DirAuthority - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 1); + + /* (No AlternateBridgeAuthority) - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 0); + + /* (No AlternateDirAuthority) - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 0); + } + + { + /* fallback_dir_servers */ + const smartlist_t *fallback_servers = router_get_fallback_dir_servers(); + /* D0, (No B1), (No A2), (No Fallback) */ + tt_assert(smartlist_len(fallback_servers) == 1); + + /* DirAuthority - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 1); + + /* (No AlternateBridgeAuthority) - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 0); + + /* (No AlternateDirAuthority) - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 0); + + /* (No Custom FallbackDir) - No Nickname - dir_port: 60093 */ + int found_non_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_non_default_fallback += + (ds->dir_port == 60093 ? + 1 : 0) + ); + tt_assert(found_non_default_fallback == 0); + + /* (No Default FallbackDir) - No Nickname - dir_port: 60099 */ + int found_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_default_fallback += + (ds->dir_port == 60099 ? + 1 : 0) + ); + tt_assert(found_default_fallback == 0); + } + } + + /* Case 7: 0111 - DirAuthorities Not Set, Others Set */ + { + /* clear fallback dirs counter */ + n_add_default_fallback_dir_servers_known_default = 0; + + /* clear options*/ + memset(options, 0, sizeof(or_options_t)); + + /* clear any previous dir servers: + consider_adding_dir_servers() should do this anyway */ + clear_dir_servers(); + + /* assign options: 0111 */ + options->DirAuthorities = NULL; + options->AlternateBridgeAuthority = test_alt_bridge_authority; + options->AlternateDirAuthority = test_alt_dir_authority; + options->FallbackDir = test_fallback_directory; + + /* parse options - ensure we always update by passing NULL old_options */ + consider_adding_dir_servers(options, NULL); + + /* check outcome */ + + /* we must not have added the default fallback dirs */ + tt_assert(n_add_default_fallback_dir_servers_known_default == 0); + + { + /* trusted_dir_servers */ + const smartlist_t *dir_servers = router_get_trusted_dir_servers(); + /* (No D0), B1, A2 */ + tt_assert(smartlist_len(dir_servers) == 2); + + /* (No DirAuthority) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* AlternateBridgeAuthority - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 1); + + /* AlternateDirAuthority - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 1); + } + + { + /* fallback_dir_servers */ + const smartlist_t *fallback_servers = router_get_fallback_dir_servers(); + /* (No D0), B1, A2, Custom Fallback */ + tt_assert(smartlist_len(fallback_servers) == 3); + + /* (No DirAuthority) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* AlternateBridgeAuthority - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 1); + + /* AlternateDirAuthority - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 1); + + /* Custom FallbackDir - No Nickname - dir_port: 60093 */ + int found_non_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_non_default_fallback += + (ds->dir_port == 60093 ? + 1 : 0) + ); + tt_assert(found_non_default_fallback == 1); + + /* (No Default FallbackDir) - No Nickname - dir_port: 60099 */ + int found_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_default_fallback += + (ds->dir_port == 60099 ? + 1 : 0) + ); + tt_assert(found_default_fallback == 0); + } + } + + /* Case 6: 0110 - DirAuthorities Not Set, AlternateBridgeAuthority & + AlternateDirAuthority Set, FallbackDir Not Set */ + { + /* clear fallback dirs counter */ + n_add_default_fallback_dir_servers_known_default = 0; + + /* clear options*/ + memset(options, 0, sizeof(or_options_t)); + + /* clear any previous dir servers: + consider_adding_dir_servers() should do this anyway */ + clear_dir_servers(); + + /* assign options: 0110 */ + options->DirAuthorities = NULL; + options->AlternateBridgeAuthority = test_alt_bridge_authority; + options->AlternateDirAuthority = test_alt_dir_authority; + options->FallbackDir = NULL; + + /* parse options - ensure we always update by passing NULL old_options */ + consider_adding_dir_servers(options, NULL); + + /* check outcome */ + + /* we must not have added the default fallback dirs */ + tt_assert(n_add_default_fallback_dir_servers_known_default == 0); + + { + /* trusted_dir_servers */ + const smartlist_t *dir_servers = router_get_trusted_dir_servers(); + /* (No D0), B1, A2 */ + tt_assert(smartlist_len(dir_servers) == 2); + + /* (No DirAuthority) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* AlternateBridgeAuthority - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 1); + + /* AlternateDirAuthority - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 1); + } + + { + /* fallback_dir_servers */ + const smartlist_t *fallback_servers = router_get_fallback_dir_servers(); + /* (No D0), B1, A2, (No Fallback) */ + tt_assert(smartlist_len(fallback_servers) == 2); + + /* (No DirAuthority) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* AlternateBridgeAuthority - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 1); + + /* AlternateDirAuthority - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 1); + + /* (No Custom FallbackDir) - No Nickname - dir_port: 60093 */ + int found_non_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_non_default_fallback += + (ds->dir_port == 60093 ? + 1 : 0) + ); + tt_assert(found_non_default_fallback == 0); + + /* (No Default FallbackDir) - No Nickname - dir_port: 60099 */ + int found_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_default_fallback += + (ds->dir_port == 60099 ? + 1 : 0) + ); + tt_assert(found_default_fallback == 0); + } + } + + /* + 2. Outcome: Use Set Bridge Authority + - Use Default Non-Bridge Directory Authorities + - Use FallbackDir if it is set, otherwise use default FallbackDir + Cases expected to yield this outcome: + 4 & 5 (the 2 cases where DirAuthorities is NULL, + AlternateBridgeAuthority is set, and + AlternateDirAuthority is NULL) + */ + + /* Case 5: 0101 - DirAuthorities Not Set, AlternateBridgeAuthority Set, + AlternateDirAuthority Not Set, FallbackDir Set */ + { + /* clear fallback dirs counter */ + n_add_default_fallback_dir_servers_known_default = 0; + + /* clear options*/ + memset(options, 0, sizeof(or_options_t)); + + /* clear any previous dir servers: + consider_adding_dir_servers() should do this anyway */ + clear_dir_servers(); + + /* assign options: 0101 */ + options->DirAuthorities = NULL; + options->AlternateBridgeAuthority = test_alt_bridge_authority; + options->AlternateDirAuthority = NULL; + options->FallbackDir = test_fallback_directory; + + /* parse options - ensure we always update by passing NULL old_options */ + consider_adding_dir_servers(options, NULL); + + /* check outcome */ + + /* we must not have added the default fallback dirs */ + tt_assert(n_add_default_fallback_dir_servers_known_default == 0); + + { + /* trusted_dir_servers */ + const smartlist_t *dir_servers = router_get_trusted_dir_servers(); + /* (No D0), B1, (No A2), Default v3 Non-Bridge Authorities */ + tt_assert(smartlist_len(dir_servers) == 1 + n_default_alt_dir_authority); + + /* (No DirAuthorities) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* AlternateBridgeAuthority - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 1); + + /* (No AlternateDirAuthority) - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 0); + + /* There's no easy way of checking that we have included all the + * default v3 non-Bridge directory authorities, so let's assume that + * if the total count above is correct, we have the right ones. + */ + } + + { + /* fallback_dir_servers */ + const smartlist_t *fallback_servers = router_get_fallback_dir_servers(); + /* (No D0), B1, (No A2), Default v3 Non-Bridge Authorities, + * Custom Fallback */ + tt_assert(smartlist_len(fallback_servers) == + 2 + n_default_alt_dir_authority); + + /* (No DirAuthorities) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* AlternateBridgeAuthority - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 1); + + /* (No AlternateDirAuthority) - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 0); + + /* Custom FallbackDir - No Nickname - dir_port: 60093 */ + int found_non_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_non_default_fallback += + (ds->dir_port == 60093 ? + 1 : 0) + ); + tt_assert(found_non_default_fallback == 1); + + /* (No Default FallbackDir) - No Nickname - dir_port: 60099 */ + int found_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_default_fallback += + (ds->dir_port == 60099 ? + 1 : 0) + ); + tt_assert(found_default_fallback == 0); + + /* There's no easy way of checking that we have included all the + * default v3 non-Bridge directory authorities, so let's assume that + * if the total count above is correct, we have the right ones. + */ + } + } + + /* Case 4: 0100 - DirAuthorities Not Set, AlternateBridgeAuthority Set, + AlternateDirAuthority & FallbackDir Not Set */ + { + /* clear fallback dirs counter */ + n_add_default_fallback_dir_servers_known_default = 0; + + /* clear options*/ + memset(options, 0, sizeof(or_options_t)); + + /* clear any previous dir servers: + consider_adding_dir_servers() should do this anyway */ + clear_dir_servers(); + + /* assign options: 0100 */ + options->DirAuthorities = NULL; + options->AlternateBridgeAuthority = test_alt_bridge_authority; + options->AlternateDirAuthority = NULL; + options->FallbackDir = NULL; + + /* parse options - ensure we always update by passing NULL old_options */ + consider_adding_dir_servers(options, NULL); + + /* check outcome */ + + /* we must have added the default fallback dirs */ + tt_assert(n_add_default_fallback_dir_servers_known_default == 1); + + { + /* trusted_dir_servers */ + const smartlist_t *dir_servers = router_get_trusted_dir_servers(); + /* (No D0), B1, (No A2), Default v3 Non-Bridge Authorities */ + tt_assert(smartlist_len(dir_servers) == 1 + n_default_alt_dir_authority); + + /* (No DirAuthorities) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* AlternateBridgeAuthority - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 1); + + /* (No AlternateDirAuthority) - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 0); + + /* There's no easy way of checking that we have included all the + * default v3 non-Bridge directory authorities, so let's assume that + * if the total count above is correct, we have the right ones. + */ + } + + { + /* fallback_dir_servers */ + const smartlist_t *fallback_servers = router_get_fallback_dir_servers(); + /* (No D0), B1, (No A2), Default v3 Non-Bridge Authorities, + * Default Fallback */ + tt_assert(smartlist_len(fallback_servers) == + 2 + n_default_alt_dir_authority); + + /* (No DirAuthorities) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* AlternateBridgeAuthority - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 1); + + /* (No AlternateDirAuthority) - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 0); + + /* (No Custom FallbackDir) - No Nickname - dir_port: 60093 */ + int found_non_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_non_default_fallback += + (ds->dir_port == 60093 ? + 1 : 0) + ); + tt_assert(found_non_default_fallback == 0); + + /* Default FallbackDir - No Nickname - dir_port: 60099 */ + int found_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_default_fallback += + (ds->dir_port == 60099 ? + 1 : 0) + ); + tt_assert(found_default_fallback == 1); + + /* There's no easy way of checking that we have included all the + * default v3 non-Bridge directory authorities, so let's assume that + * if the total count above is correct, we have the right ones. + */ + } + } + + /* + 3. Outcome: Use Set Alternate Directory Authority + - Use Default Bridge Authorities + - Use FallbackDir if it is set, otherwise No Default Fallback Directories + Cases expected to yield this outcome: + 2 & 3 (the 2 cases where DirAuthorities and AlternateBridgeAuthority + are both NULL, but AlternateDirAuthority is set) + */ + + /* Case 3: 0011 - DirAuthorities & AlternateBridgeAuthority Not Set, + AlternateDirAuthority & FallbackDir Set */ + { + /* clear fallback dirs counter */ + n_add_default_fallback_dir_servers_known_default = 0; + + /* clear options*/ + memset(options, 0, sizeof(or_options_t)); + + /* clear any previous dir servers: + consider_adding_dir_servers() should do this anyway */ + clear_dir_servers(); + + /* assign options: 0011 */ + options->DirAuthorities = NULL; + options->AlternateBridgeAuthority = NULL; + options->AlternateDirAuthority = test_alt_dir_authority; + options->FallbackDir = test_fallback_directory; + + /* parse options - ensure we always update by passing NULL old_options */ + consider_adding_dir_servers(options, NULL); + + /* check outcome */ + + /* we must not have added the default fallback dirs */ + tt_assert(n_add_default_fallback_dir_servers_known_default == 0); + + { + /* trusted_dir_servers */ + const smartlist_t *dir_servers = router_get_trusted_dir_servers(); + /* (No D0), (No B1), Default Bridge Authorities, A2 */ + tt_assert(smartlist_len(dir_servers) == + 1 + n_default_alt_bridge_authority); + + /* (No DirAuthorities) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* (No AlternateBridgeAuthority) - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 0); + + /* AlternateDirAuthority - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 1); + + /* There's no easy way of checking that we have included all the + * default Bridge authorities (except for hard-coding tonga's details), + * so let's assume that if the total count above is correct, + * we have the right ones. + */ + } + + { + /* fallback_dir_servers */ + const smartlist_t *fallback_servers = router_get_fallback_dir_servers(); + /* (No D0), (No B1), Default Bridge Authorities, A2, + * Custom Fallback Directory, (No Default Fallback Directories) */ + tt_assert(smartlist_len(fallback_servers) == + 2 + n_default_alt_bridge_authority); + + /* (No DirAuthorities) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* (No AlternateBridgeAuthority) - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 0); + + /* AlternateDirAuthority - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 1); + + /* Custom FallbackDir - No Nickname - dir_port: 60093 */ + int found_non_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_non_default_fallback += + (ds->dir_port == 60093 ? + 1 : 0) + ); + tt_assert(found_non_default_fallback == 1); + + /* (No Default FallbackDir) - No Nickname - dir_port: 60099 */ + int found_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_default_fallback += + (ds->dir_port == 60099 ? + 1 : 0) + ); + tt_assert(found_default_fallback == 0); + + /* There's no easy way of checking that we have included all the + * default Bridge authorities (except for hard-coding tonga's details), + * so let's assume that if the total count above is correct, + * we have the right ones. + */ + } + } + + /* Case 2: 0010 - DirAuthorities & AlternateBridgeAuthority Not Set, + AlternateDirAuthority Set, FallbackDir Not Set */ + { + /* clear fallback dirs counter */ + n_add_default_fallback_dir_servers_known_default = 0; + + /* clear options*/ + memset(options, 0, sizeof(or_options_t)); + + /* clear any previous dir servers: + consider_adding_dir_servers() should do this anyway */ + clear_dir_servers(); + + /* assign options: 0010 */ + options->DirAuthorities = NULL; + options->AlternateBridgeAuthority = NULL; + options->AlternateDirAuthority = test_alt_dir_authority; + options->FallbackDir = NULL; + + /* parse options - ensure we always update by passing NULL old_options */ + consider_adding_dir_servers(options, NULL); + + /* check outcome */ + + /* we must not have added the default fallback dirs */ + tt_assert(n_add_default_fallback_dir_servers_known_default == 0); + + { + /* trusted_dir_servers */ + const smartlist_t *dir_servers = router_get_trusted_dir_servers(); + /* (No D0), (No B1), Default Bridge Authorities, A2, + * No Default or Custom Fallback Directories */ + tt_assert(smartlist_len(dir_servers) == + 1 + n_default_alt_bridge_authority); + + /* (No DirAuthorities) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* (No AlternateBridgeAuthority) - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 0); + + /* AlternateDirAuthority - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 1); + + /* There's no easy way of checking that we have included all the + * default Bridge authorities (except for hard-coding tonga's details), + * so let's assume that if the total count above is correct, + * we have the right ones. + */ + } + + { + /* fallback_dir_servers */ + const smartlist_t *fallback_servers = router_get_fallback_dir_servers(); + /* (No D0), (No B1), Default Bridge Authorities, A2, + * No Custom or Default Fallback Directories */ + tt_assert(smartlist_len(fallback_servers) == + 1 + n_default_alt_bridge_authority); + + /* (No DirAuthorities) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* (No AlternateBridgeAuthority) - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 0); + + /* AlternateDirAuthority - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 1); + + /* (No Custom FallbackDir) - No Nickname - dir_port: 60093 */ + int found_non_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_non_default_fallback += + (ds->dir_port == 60093 ? + 1 : 0) + ); + tt_assert(found_non_default_fallback == 0); + + /* (No Default FallbackDir) - No Nickname - dir_port: 60099 */ + int found_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_default_fallback += + (ds->dir_port == 60099 ? + 1 : 0) + ); + tt_assert(found_default_fallback == 0); + + /* There's no easy way of checking that we have included all the + * default Bridge authorities (except for hard-coding tonga's details), + * so let's assume that if the total count above is correct, + * we have the right ones. + */ + } + } + + /* + 4. Outcome: Use Set Custom Fallback Directory + - Use Default Bridge & Directory Authorities + Cases expected to yield this outcome: + 1 (DirAuthorities, AlternateBridgeAuthority and AlternateDirAuthority + are all NULL, but FallbackDir is set) + */ + + /* Case 1: 0001 - DirAuthorities, AlternateBridgeAuthority + & AlternateDirAuthority Not Set, FallbackDir Set */ + { + /* clear fallback dirs counter */ + n_add_default_fallback_dir_servers_known_default = 0; + + /* clear options*/ + memset(options, 0, sizeof(or_options_t)); + + /* clear any previous dir servers: + consider_adding_dir_servers() should do this anyway */ + clear_dir_servers(); + + /* assign options: 0001 */ + options->DirAuthorities = NULL; + options->AlternateBridgeAuthority = NULL; + options->AlternateDirAuthority = NULL; + options->FallbackDir = test_fallback_directory; + + /* parse options - ensure we always update by passing NULL old_options */ + consider_adding_dir_servers(options, NULL); + + /* check outcome */ + + /* we must not have added the default fallback dirs */ + tt_assert(n_add_default_fallback_dir_servers_known_default == 0); + + { + /* trusted_dir_servers */ + const smartlist_t *dir_servers = router_get_trusted_dir_servers(); + /* (No D0), (No B1), Default Bridge Authorities, + * (No A2), Default v3 Directory Authorities */ + tt_assert(smartlist_len(dir_servers) == n_default_authorities); + + /* (No DirAuthorities) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* (No AlternateBridgeAuthority) - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 0); + + /* (No AlternateDirAuthority) - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 0); + + /* There's no easy way of checking that we have included all the + * default Bridge & V3 Directory authorities, so let's assume that + * if the total count above is correct, we have the right ones. + */ + } + + { + /* fallback_dir_servers */ + const smartlist_t *fallback_servers = router_get_fallback_dir_servers(); + /* (No D0), (No B1), Default Bridge Authorities, + * (No A2), Default v3 Directory Authorities, + * Custom Fallback Directory, (No Default Fallback Directories) */ + tt_assert(smartlist_len(fallback_servers) == + 1 + n_default_authorities); + + /* (No DirAuthorities) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* (No AlternateBridgeAuthority) - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 0); + + /* (No AlternateDirAuthority) - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 0); + + /* Custom FallbackDir - No Nickname - dir_port: 60093 */ + int found_non_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_non_default_fallback += + (ds->dir_port == 60093 ? + 1 : 0) + ); + tt_assert(found_non_default_fallback == 1); + + /* (No Default FallbackDir) - No Nickname - dir_port: 60099 */ + int found_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_default_fallback += + (ds->dir_port == 60099 ? + 1 : 0) + ); + tt_assert(found_default_fallback == 0); + + /* There's no easy way of checking that we have included all the + * default Bridge & V3 Directory authorities, so let's assume that + * if the total count above is correct, we have the right ones. + */ + } + } + + /* + 5. Outcome: Use All Defaults + - Use Default Bridge & Directory Authorities, Default Fallback Directories + Cases expected to yield this outcome: + 0 (DirAuthorities, AlternateBridgeAuthority, AlternateDirAuthority + and FallbackDir are all NULL) + */ + + /* Case 0: 0000 - All Not Set */ + { + /* clear fallback dirs counter */ + n_add_default_fallback_dir_servers_known_default = 0; + + /* clear options*/ + memset(options, 0, sizeof(or_options_t)); + + /* clear any previous dir servers: + consider_adding_dir_servers() should do this anyway */ + clear_dir_servers(); + + /* assign options: 0001 */ + options->DirAuthorities = NULL; + options->AlternateBridgeAuthority = NULL; + options->AlternateDirAuthority = NULL; + options->FallbackDir = NULL; + + /* parse options - ensure we always update by passing NULL old_options */ + consider_adding_dir_servers(options, NULL); + + /* check outcome */ + + /* we must have added the default fallback dirs */ + tt_assert(n_add_default_fallback_dir_servers_known_default == 1); + + { + /* trusted_dir_servers */ + const smartlist_t *dir_servers = router_get_trusted_dir_servers(); + /* (No D0), (No B1), Default Bridge Authorities, + * (No A2), Default v3 Directory Authorities */ + tt_assert(smartlist_len(dir_servers) == n_default_authorities); + + /* (No DirAuthorities) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* (No AlternateBridgeAuthority) - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 0); + + /* (No AlternateDirAuthority) - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(dir_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 0); + + /* There's no easy way of checking that we have included all the + * default Bridge & V3 Directory authorities, so let's assume that + * if the total count above is correct, we have the right ones. + */ + } + + { + /* fallback_dir_servers */ + const smartlist_t *fallback_servers = router_get_fallback_dir_servers(); + /* (No D0), (No B1), Default Bridge Authorities, + * (No A2), Default v3 Directory Authorities, + * (No Custom Fallback Directory), Default Fallback Directories */ + tt_assert(smartlist_len(fallback_servers) == + n_default_authorities + n_default_fallback_dir); + + /* (No DirAuthorities) - D0 - dir_port: 60090 */ + int found_D0 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_D0 += + (ds->dir_port == 60090 ? + 1 : 0) + ); + tt_assert(found_D0 == 0); + + /* (No AlternateBridgeAuthority) - B1 - dir_port: 60091 */ + int found_B1 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_B1 += + (ds->dir_port == 60091 ? + 1 : 0) + ); + tt_assert(found_B1 == 0); + + /* (No AlternateDirAuthority) - A2 - dir_port: 60092 */ + int found_A2 = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_A2 += + (ds->dir_port == 60092 ? + 1 : 0) + ); + tt_assert(found_A2 == 0); + + /* Custom FallbackDir - No Nickname - dir_port: 60093 */ + int found_non_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_non_default_fallback += + (ds->dir_port == 60093 ? + 1 : 0) + ); + tt_assert(found_non_default_fallback == 0); + + /* (No Default FallbackDir) - No Nickname - dir_port: 60099 */ + int found_default_fallback = 0; + SMARTLIST_FOREACH(fallback_servers, + dir_server_t *, + ds, + /* increment the found counter if dir_port matches */ + found_default_fallback += + (ds->dir_port == 60099 ? + 1 : 0) + ); + tt_assert(found_default_fallback == 1); + + /* There's no easy way of checking that we have included all the + * default Bridge & V3 Directory authorities, and the default + * Fallback Directories, so let's assume that if the total count + * above is correct, we have the right ones. + */ + } + } + + done: + clear_dir_servers(); + + tor_free(test_dir_authority->key); + tor_free(test_dir_authority->value); + tor_free(test_dir_authority); + + tor_free(test_alt_dir_authority->key); + tor_free(test_alt_dir_authority->value); + tor_free(test_alt_dir_authority); + + tor_free(test_alt_bridge_authority->key); + tor_free(test_alt_bridge_authority->value); + tor_free(test_alt_bridge_authority); + + tor_free(test_fallback_directory->key); + tor_free(test_fallback_directory->value); + tor_free(test_fallback_directory); + + options->DirAuthorities = NULL; + options->AlternateBridgeAuthority = NULL; + options->AlternateDirAuthority = NULL; + options->FallbackDir = NULL; + or_options_free(options); + + UNMOCK(add_default_fallback_dir_servers); +} + #define CONFIG_TEST(name, flags) \ { #name, test_config_ ## name, flags, NULL, NULL } struct testcase_t config_tests[] = { + CONFIG_TEST(adding_dir_servers, TT_FORK), CONFIG_TEST(resolve_my_address, TT_FORK), CONFIG_TEST(addressmap, 0), CONFIG_TEST(parse_bridge_line, 0),