Refactor handling of TestingTorNetwork

Previously, when TestingTorNetwork was set, we would manually adjust
the initvalue members of a bunch of other config_var_t, and then
re-run the early parts or parsing the options.

Now we treat the initvalue fields as immutable, but instead assign
to them in options_init(), as early as possible.  Rather than
re-running the early parts of options, we just re-call the
options_init_from_string() function.

This patch de-kludges some of our code pretty handily.  I think it
could later handle authorities and fallbacks, but for now I think we
should leave those alone.
This commit is contained in:
Nick Mathewson 2019-06-21 11:11:48 -04:00
parent f3330d2be3
commit f306d12b58
4 changed files with 104 additions and 124 deletions

View File

@ -30,7 +30,7 @@
# Remember: It is better to fix the problem than to add a new exception!
problem file-size /src/app/config/config.c 8518
problem include-count /src/app/config/config.c 88
problem include-count /src/app/config/config.c 89
problem function-size /src/app/config/config.c:options_act_reversible() 296
problem function-size /src/app/config/config.c:options_act() 589
problem function-size /src/app/config/config.c:resolve_my_address() 192

View File

@ -758,46 +758,28 @@ static config_var_t option_vars_[] = {
END_OF_CONFIG_VARS
};
/** List of default directory authorities */
static const char *default_authorities[] = {
#include "auth_dirs.inc"
NULL
};
/** List of fallback directory authorities. The list is generated by opt-in of
* relays that meet certain stability criteria.
*/
static const char *default_fallbacks[] = {
#include "fallback_dirs.inc"
NULL
};
/** Override default values with these if the user sets the TestingTorNetwork
* option. */
static const config_var_t testing_tor_network_defaults[] = {
V(DirAllowPrivateAddresses, BOOL, "1"),
V(EnforceDistinctSubnets, BOOL, "0"),
V(AssumeReachable, BOOL, "1"),
V(AuthDirMaxServersPerAddr, POSINT, "0"),
V(ClientBootstrapConsensusAuthorityDownloadInitialDelay, CSV_INTERVAL, "0"),
V(ClientBootstrapConsensusFallbackDownloadInitialDelay, CSV_INTERVAL, "0"),
V(ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay, CSV_INTERVAL,
"0"),
V(ClientDNSRejectInternalAddresses, BOOL,"0"),
V(ClientRejectInternalAddresses, BOOL, "0"),
V(CountPrivateBandwidth, BOOL, "1"),
V(ExitPolicyRejectPrivate, BOOL, "0"),
V(ExtendAllowPrivateAddresses, BOOL, "1"),
V(V3AuthVotingInterval, INTERVAL, "5 minutes"),
V(V3AuthVoteDelay, INTERVAL, "20 seconds"),
V(V3AuthDistDelay, INTERVAL, "20 seconds"),
V(TestingV3AuthInitialVotingInterval, INTERVAL, "150 seconds"),
V(TestingV3AuthInitialVoteDelay, INTERVAL, "20 seconds"),
V(TestingV3AuthInitialDistDelay, INTERVAL, "20 seconds"),
V(TestingAuthDirTimeToLearnReachability, INTERVAL, "0 minutes"),
V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "0 minutes"),
V(MinUptimeHidServDirectoryV2, INTERVAL, "0 minutes"),
V(TestingServerDownloadInitialDelay, CSV_INTERVAL, "0"),
V(TestingClientDownloadInitialDelay, CSV_INTERVAL, "0"),
V(TestingServerConsensusDownloadInitialDelay, CSV_INTERVAL, "0"),
V(TestingClientConsensusDownloadInitialDelay, CSV_INTERVAL, "0"),
V(TestingBridgeDownloadInitialDelay, CSV_INTERVAL, "10"),
V(TestingBridgeBootstrapDownloadInitialDelay, CSV_INTERVAL, "0"),
V(TestingClientMaxIntervalWithoutRequest, INTERVAL, "5 seconds"),
V(TestingDirConnectionMaxStall, INTERVAL, "30 seconds"),
V(TestingEnableConnBwEvent, BOOL, "1"),
V(TestingEnableCellStatsEvent, BOOL, "1"),
VAR_INVIS("___UsingTestNetworkDefaults", BOOL, UsingTestNetworkDefaults_,
"1"),
V(RendPostPeriod, INTERVAL, "2 minutes"),
END_OF_CONFIG_VARS
static const struct {
const char *k;
const char *v;
} testing_tor_network_defaults[] = {
#include "testnet.inc"
{ NULL, NULL }
};
#undef VAR
@ -936,6 +918,32 @@ get_options,(void))
return get_options_mutable();
}
/**
* True iff we have noticed that this is a testing tor network, and we
* should use the corresponding defaults.
**/
static bool testing_network_configured = false;
/** Return a set of lines for any default options that we want to override
* from those set in our config_var_t values. */
static config_line_t *
get_options_defaults(void)
{
int i;
config_line_t *result = NULL, **next = &result;
if (testing_network_configured) {
for (i = 0; testing_tor_network_defaults[i].k; ++i) {
config_line_append(next,
testing_tor_network_defaults[i].k,
testing_tor_network_defaults[i].v);
next = &(*next)->next;
}
}
return result;
}
/** Change the current global options to contain <b>new_val</b> instead of
* their current value; take action based on the new value; free the old value
* as necessary. Returns 0 on success, -1 on failure.
@ -1185,21 +1193,6 @@ cleanup_protocol_warning_severity_level(void)
atomic_counter_destroy(&protocol_warning_severity_level);
}
/** List of default directory authorities */
static const char *default_authorities[] = {
#include "auth_dirs.inc"
NULL
};
/** List of fallback directory authorities. The list is generated by opt-in of
* relays that meet certain stability criteria.
*/
static const char *default_fallbacks[] = {
#include "fallback_dirs.inc"
NULL
};
/** Add the default directory authorities directly into the trusted dir list,
* but only add them insofar as they share bits with <b>type</b>.
* Each authority's bits are restricted to the bits shared with <b>type</b>.
@ -3008,6 +3001,16 @@ void
options_init(or_options_t *options)
{
config_init(&options_format, options);
config_line_t *dflts = get_options_defaults();
char *msg=NULL;
if (config_assign(&options_format, options, dflts,
CAL_WARN_DEPRECATIONS, &msg)<0) {
log_err(LD_BUG, "Unable to set default options: %s", msg);
tor_free(msg);
tor_assert_unreached();
}
config_free_lines(dflts);
tor_free(msg);
}
/** Return a string containing a possible configuration file that would give
@ -5397,6 +5400,7 @@ options_init_from_string(const char *cf_defaults, const char *cf,
int command, const char *command_arg,
char **msg)
{
bool retry = false;
or_options_t *oldoptions, *newoptions, *newdefaultoptions=NULL;
config_line_t *cl;
int retval;
@ -5454,73 +5458,12 @@ options_init_from_string(const char *cf_defaults, const char *cf,
newoptions->FilesOpenedByIncludes = opened_files;
/* If this is a testing network configuration, change defaults
* for a list of dependent config options, re-initialize newoptions
* with the new defaults, and assign all options to it second time. */
if (newoptions->TestingTorNetwork) {
/* XXXX this is a bit of a kludge. perhaps there's a better way to do
* this? We could, for example, make the parsing algorithm do two passes
* over the configuration. If it finds any "suite" options like
* TestingTorNetwork, it could change the defaults before its second pass.
* Not urgent so long as this seems to work, but at any sign of trouble,
* let's clean it up. -NM */
/* Change defaults. */
for (int i = 0; testing_tor_network_defaults[i].member.name; ++i) {
const config_var_t *new_var = &testing_tor_network_defaults[i];
config_var_t *old_var =
config_find_option_mutable(&options_format, new_var->member.name);
tor_assert(new_var);
tor_assert(old_var);
old_var->initvalue = new_var->initvalue;
if ((config_find_deprecation(&options_format, new_var->member.name))) {
log_warn(LD_GENERAL, "Testing options override the deprecated "
"option %s. Is that intentional?",
new_var->member.name);
}
}
/* Clear newoptions and re-initialize them with new defaults. */
or_options_free(newoptions);
or_options_free(newdefaultoptions);
newdefaultoptions = NULL;
newoptions = tor_malloc_zero(sizeof(or_options_t));
newoptions->magic_ = OR_OPTIONS_MAGIC;
options_init(newoptions);
newoptions->command = command;
newoptions->command_arg = command_arg ? tor_strdup(command_arg) : NULL;
/* Assign all options a second time. */
opened_files = smartlist_new();
for (int i = 0; i < 2; ++i) {
const char *body = i==0 ? cf_defaults : cf;
if (!body)
continue;
/* get config lines, assign them */
retval = config_get_lines_include(body, &cl, 1,
body == cf ? &cf_has_include : NULL,
opened_files);
if (retval < 0) {
err = SETOPT_ERR_PARSE;
goto err;
}
retval = config_assign(&options_format, newoptions, cl, 0, msg);
config_free_lines(cl);
if (retval < 0) {
err = SETOPT_ERR_PARSE;
goto err;
}
if (i==0)
newdefaultoptions = config_dup(&options_format, newoptions);
}
/* Assign command-line variables a second time too */
retval = config_assign(&options_format, newoptions,
global_cmdline_options, 0, msg);
if (retval < 0) {
err = SETOPT_ERR_PARSE;
goto err;
}
* for a list of dependent config options, and try this function again. */
if (newoptions->TestingTorNetwork && ! testing_network_configured) {
// retry with the testing defaults.
testing_network_configured = true;
retry = true;
goto err;
}
newoptions->IncludeUsed = cf_has_include;
@ -5565,6 +5508,9 @@ options_init_from_string(const char *cf_defaults, const char *cf,
tor_asprintf(msg, "Failed to parse/validate config: %s", old_msg);
tor_free(old_msg);
}
if (retry)
return options_init_from_string(cf_defaults, cf, command, command_arg,
msg);
return err;
}

View File

@ -0,0 +1,33 @@
{ "DirAllowPrivateAddresses", "1" },
{ "EnforceDistinctSubnets", "0" },
{ "AssumeReachable", "1" },
{ "AuthDirMaxServersPerAddr", "0" },
{ "ClientBootstrapConsensusAuthorityDownloadInitialDelay", "0" },
{ "ClientBootstrapConsensusFallbackDownloadInitialDelay", "0" },
{ "ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay", "0" },
{ "ClientDNSRejectInternalAddresses", "0" },
{ "ClientRejectInternalAddresses", "0" },
{ "CountPrivateBandwidth", "1" },
{ "ExitPolicyRejectPrivate", "0" },
{ "ExtendAllowPrivateAddresses", "1" },
{ "V3AuthVotingInterval", "5 minutes" },
{ "V3AuthVoteDelay", "20 seconds" },
{ "V3AuthDistDelay", "20 seconds" },
{ "TestingV3AuthInitialVotingInterval", "150 seconds" },
{ "TestingV3AuthInitialVoteDelay", "20 seconds" },
{ "TestingV3AuthInitialDistDelay", "20 seconds" },
{ "TestingAuthDirTimeToLearnReachability", "0 minutes" },
{ "TestingEstimatedDescriptorPropagationTime", "0 minutes" },
{ "MinUptimeHidServDirectoryV2", "0 minutes" },
{ "TestingServerDownloadInitialDelay", "0" },
{ "TestingClientDownloadInitialDelay", "0" },
{ "TestingServerConsensusDownloadInitialDelay", "0" },
{ "TestingClientConsensusDownloadInitialDelay", "0" },
{ "TestingBridgeDownloadInitialDelay", "10" },
{ "TestingBridgeBootstrapDownloadInitialDelay", "0" },
{ "TestingClientMaxIntervalWithoutRequest", "5 seconds" },
{ "TestingDirConnectionMaxStall", "30 seconds" },
{ "TestingEnableConnBwEvent", "1" },
{ "TestingEnableCellStatsEvent", "1" },
{ "RendPostPeriod", "2 minutes" },
{ "___UsingTestNetworkDefaults", "1" },

View File

@ -435,9 +435,10 @@ noinst_HEADERS += \
src/feature/stats/rephist.h \
src/feature/stats/predict_ports.h
noinst_HEADERS += \
src/app/config/auth_dirs.inc \
src/app/config/fallback_dirs.inc
noinst_HEADERS += \
src/app/config/auth_dirs.inc \
src/app/config/fallback_dirs.inc \
src/app/config/testnet.inc
# This may someday want to be an installed file?
noinst_HEADERS += src/feature/api/tor_api.h