Add UseDefaultFallbackDirs for hard-coded directory mirrors

UseDefaultFallbackDirs enables any hard-coded fallback
directory mirrors. Default is 1, set it to 0 to disable fallbacks.

Implements ticket 17576.
Patch by "teor".
This commit is contained in:
teor (Tim Wilson-Brown) 2015-11-25 08:53:29 +11:00 committed by Nick Mathewson
parent 6cdd024c94
commit 080ae03ee4
5 changed files with 77 additions and 20 deletions

View File

@ -0,0 +1,4 @@
o Minor feature (fallback directories):
- Add UseDefaultFallbackDirs, which enables any hard-coded fallback
directory mirrors. Default is 1, set it to 0 to disable fallbacks.
Implements ticket 17576. Patch by "teor".

View File

@ -356,7 +356,13 @@ GENERAL OPTIONS
[[FallbackDir]] **FallbackDir** __address__:__port__ orport=__port__ id=__fingerprint__ [weight=__num__]::
When we're unable to connect to any directory cache for directory info
(usually because we don't know about any yet) we try a FallbackDir.
By default, the directory authorities are also FallbackDirs.
By default, the directory authorities are also FallbackDirs. Specifying a
FallbackDir replaces Tor's default hard-coded FallbackDirs (if any).
[[UseDefaultFallbackDirs]] **UseDefaultFallbackDirs** **0**|**1**::
Use Tor's default hard-coded FallbackDirs (if any). (When a
FallbackDir line is present, it replaces the hard-coded FallbackDirs,
regardless of the value of UseDefaultFallbackDirs.) (Default: 1)
[[DirAuthority]] **DirAuthority** [__nickname__] [**flags**] __address__:__port__ __fingerprint__::
Use a nonstandard authoritative directory server at the provided address

View File

@ -251,6 +251,7 @@ static config_var_t option_vars_[] = {
V(ExtORPortCookieAuthFileGroupReadable, BOOL, "0"),
V(ExtraInfoStatistics, BOOL, "1"),
V(FallbackDir, LINELIST, NULL),
V(UseDefaultFallbackDirs, BOOL, "1"),
OBSOLETE("FallbackNetworkstatusFile"),
V(FascistFirewall, BOOL, "0"),
@ -990,6 +991,7 @@ consider_adding_dir_servers(const or_options_t *options,
!smartlist_len(router_get_fallback_dir_servers()) || !old_options ||
!config_lines_eq(options->DirAuthorities, old_options->DirAuthorities) ||
!config_lines_eq(options->FallbackDir, old_options->FallbackDir) ||
(options->UseDefaultFallbackDirs != old_options->UseDefaultFallbackDirs) ||
!config_lines_eq(options->AlternateBridgeAuthority,
old_options->AlternateBridgeAuthority) ||
!config_lines_eq(options->AlternateDirAuthority,
@ -1018,8 +1020,8 @@ consider_adding_dir_servers(const or_options_t *options,
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) {
* are set to their defaults, and when UseDefaultFallbackDirs is 1. */
if (!options->FallbackDir && options->UseDefaultFallbackDirs) {
add_default_fallback_dir_servers();
}
}
@ -3532,6 +3534,13 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (validate_addr_policies(options, msg) < 0)
return -1;
/* If FallbackDir is set, we don't UseDefaultFallbackDirs */
if (options->UseDefaultFallbackDirs && options->FallbackDir) {
log_info(LD_CONFIG, "You have set UseDefaultFallbackDirs 1 and "
"FallbackDir(s). Ignoring UseDefaultFallbackDirs, and "
"using the FallbackDir(s) you have set.");
}
if (validate_dir_servers(options, old_options) < 0)
REJECT("Directory authority/fallback line did not parse. See logs "
"for details.");

View File

@ -3757,6 +3757,8 @@ typedef struct {
/** List of fallback directory servers */
config_line_t *FallbackDir;
/** Whether to use the default hard-coded FallbackDirs */
int UseDefaultFallbackDirs;
/** Weight to apply to all directory authority rates if considering them
* along with fallbackdirs */

View File

@ -1471,6 +1471,7 @@ add_default_fallback_dir_servers_known_default(void)
n_add_default_fallback_dir_servers_known_default++;
}
/* Test all the different combinations of adding dir servers */
static void
test_config_adding_dir_servers(void *arg)
{
@ -1529,7 +1530,7 @@ test_config_adding_dir_servers(void *arg)
/* There are 16 different cases, covering each combination of set/NULL for:
* DirAuthorities, AlternateBridgeAuthority, AlternateDirAuthority &
* FallbackDir.
* FallbackDir. (We always set UseDefaultFallbackDirs to 1.)
* But validate_dir_servers() ensures that:
* "You cannot set both DirAuthority and Alternate*Authority."
* This reduces the number of cases to 10.
@ -1543,8 +1544,6 @@ test_config_adding_dir_servers(void *arg)
* 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
@ -1581,20 +1580,6 @@ test_config_adding_dir_servers(void *arg)
* 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.
*/
/*
@ -1628,6 +1613,7 @@ test_config_adding_dir_servers(void *arg)
options->AlternateBridgeAuthority = NULL;
options->AlternateDirAuthority = NULL;
options->FallbackDir = NULL;
options->UseDefaultFallbackDirs = 1;
/* parse options - ensure we always update by passing NULL old_options */
consider_adding_dir_servers(options, NULL);
@ -1703,6 +1689,7 @@ test_config_adding_dir_servers(void *arg)
options->AlternateBridgeAuthority = NULL;
options->AlternateDirAuthority = NULL;
options->FallbackDir = test_fallback_directory;
options->UseDefaultFallbackDirs = 1;
/* parse options - ensure we always update by passing NULL old_options */
consider_adding_dir_servers(options, NULL);
@ -1840,6 +1827,7 @@ test_config_adding_dir_servers(void *arg)
options->AlternateBridgeAuthority = NULL;
options->AlternateDirAuthority = NULL;
options->FallbackDir = NULL;
options->UseDefaultFallbackDirs = 1;
/* parse options - ensure we always update by passing NULL old_options */
consider_adding_dir_servers(options, NULL);
@ -1977,6 +1965,7 @@ test_config_adding_dir_servers(void *arg)
options->AlternateBridgeAuthority = test_alt_bridge_authority;
options->AlternateDirAuthority = test_alt_dir_authority;
options->FallbackDir = test_fallback_directory;
options->UseDefaultFallbackDirs = 1;
/* parse options - ensure we always update by passing NULL old_options */
consider_adding_dir_servers(options, NULL);
@ -2115,6 +2104,7 @@ test_config_adding_dir_servers(void *arg)
options->AlternateBridgeAuthority = test_alt_bridge_authority;
options->AlternateDirAuthority = test_alt_dir_authority;
options->FallbackDir = NULL;
options->UseDefaultFallbackDirs = 1;
/* parse options - ensure we always update by passing NULL old_options */
consider_adding_dir_servers(options, NULL);
@ -2263,6 +2253,7 @@ test_config_adding_dir_servers(void *arg)
options->AlternateBridgeAuthority = test_alt_bridge_authority;
options->AlternateDirAuthority = NULL;
options->FallbackDir = test_fallback_directory;
options->UseDefaultFallbackDirs = 1;
/* parse options - ensure we always update by passing NULL old_options */
consider_adding_dir_servers(options, NULL);
@ -2413,6 +2404,7 @@ test_config_adding_dir_servers(void *arg)
options->AlternateBridgeAuthority = test_alt_bridge_authority;
options->AlternateDirAuthority = NULL;
options->FallbackDir = NULL;
options->UseDefaultFallbackDirs = 1;
/* parse options - ensure we always update by passing NULL old_options */
consider_adding_dir_servers(options, NULL);
@ -2572,6 +2564,7 @@ test_config_adding_dir_servers(void *arg)
options->AlternateBridgeAuthority = NULL;
options->AlternateDirAuthority = test_alt_dir_authority;
options->FallbackDir = test_fallback_directory;
options->UseDefaultFallbackDirs = 1;
/* parse options - ensure we always update by passing NULL old_options */
consider_adding_dir_servers(options, NULL);
@ -2725,6 +2718,7 @@ test_config_adding_dir_servers(void *arg)
options->AlternateBridgeAuthority = NULL;
options->AlternateDirAuthority = test_alt_dir_authority;
options->FallbackDir = NULL;
options->UseDefaultFallbackDirs = 1;
/* parse options - ensure we always update by passing NULL old_options */
consider_adding_dir_servers(options, NULL);
@ -2887,6 +2881,7 @@ test_config_adding_dir_servers(void *arg)
options->AlternateBridgeAuthority = NULL;
options->AlternateDirAuthority = NULL;
options->FallbackDir = test_fallback_directory;
options->UseDefaultFallbackDirs = 1;
/* parse options - ensure we always update by passing NULL old_options */
consider_adding_dir_servers(options, NULL);
@ -3046,6 +3041,7 @@ test_config_adding_dir_servers(void *arg)
options->AlternateBridgeAuthority = NULL;
options->AlternateDirAuthority = NULL;
options->FallbackDir = NULL;
options->UseDefaultFallbackDirs = 1;
/* parse options - ensure we always update by passing NULL old_options */
consider_adding_dir_servers(options, NULL);
@ -3209,11 +3205,51 @@ test_config_adding_dir_servers(void *arg)
UNMOCK(add_default_fallback_dir_servers);
}
static void
test_config_default_dir_servers(void *arg)
{
or_options_t *opts = NULL;
(void)arg;
int trusted_count = 0;
int fallback_count = 0;
opts = tor_malloc_zero(sizeof(or_options_t));
opts->UseDefaultFallbackDirs = 0;
consider_adding_dir_servers(opts, opts);
trusted_count = smartlist_len(router_get_trusted_dir_servers());
fallback_count = smartlist_len(router_get_fallback_dir_servers());
or_options_free(opts);
opts = NULL;
/* assume a release will never go out with less than 7 authorities */
tt_assert(trusted_count >= 7);
/* if we disable the default fallbacks, there must not be any extra */
tt_assert(fallback_count == trusted_count);
opts = tor_malloc_zero(sizeof(or_options_t));
opts->UseDefaultFallbackDirs = 1;
consider_adding_dir_servers(opts, opts);
trusted_count = smartlist_len(router_get_trusted_dir_servers());
fallback_count = smartlist_len(router_get_fallback_dir_servers());
or_options_free(opts);
opts = NULL;
/* assume a release will never go out with less than 7 authorities */
tt_assert(trusted_count >= 7);
/* XX/teor - allow for default fallbacks to be added without breaking
* the unit tests. Set a minimum fallback count once the list is stable. */
tt_assert(fallback_count >= trusted_count);
done:
or_options_free(opts);
}
#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(default_dir_servers, TT_FORK),
CONFIG_TEST(resolve_my_address, TT_FORK),
CONFIG_TEST(addressmap, 0),
CONFIG_TEST(parse_bridge_line, 0),