diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/app/config/config.c | 60 | ||||
-rw-r--r-- | src/app/config/config.h | 5 | ||||
-rw-r--r-- | src/app/config/confparse.c | 145 | ||||
-rw-r--r-- | src/app/config/confparse.h | 47 | ||||
-rw-r--r-- | src/app/config/statefile.c | 33 | ||||
-rw-r--r-- | src/feature/dirauth/shared_random_state.c | 27 | ||||
-rw-r--r-- | src/test/test_confparse.c | 183 | ||||
-rw-r--r-- | src/test/test_helpers.c | 2 | ||||
-rw-r--r-- | src/test/test_options.c | 14 |
9 files changed, 327 insertions, 189 deletions
diff --git a/src/app/config/config.c b/src/app/config/config.c index 4bc807a6fb..76feed0005 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -843,7 +843,7 @@ static void config_maybe_load_geoip_files_(const or_options_t *options, static int options_validate_cb(void *old_options, void *options, void *default_options, int from_setconf, char **msg); -static void options_free_cb(void *options); +static void options_free_cb(const config_mgr_t *, void *options); static void cleanup_protocol_warning_severity_level(void); static void set_protocol_warning_severity_level(int warning_severity); @@ -851,7 +851,7 @@ static void set_protocol_warning_severity_level(int warning_severity); #define OR_OPTIONS_MAGIC 9090909 /** Configuration format for or_options_t. */ -STATIC const config_format_t options_format = { +static const config_format_t options_format = { sizeof(or_options_t), { "or_options_t", @@ -895,6 +895,19 @@ static int in_option_validation = 0; /* True iff we've initialized libevent */ static int libevent_initialized = 0; +/* A global configuration manager to handle all configuration objects. */ +static config_mgr_t *options_mgr = NULL; + +/** Return the global configuration manager object for torrc options. */ +STATIC const config_mgr_t * +get_options_mgr(void) +{ + if (PREDICT_UNLIKELY(options_mgr == NULL)) { + options_mgr = config_mgr_new(&options_format); + } + return options_mgr; +} + /** Return the contents of our frontpage string, or NULL if not configured. */ MOCK_IMPL(const char*, get_dirportfrontpage, (void)) @@ -977,14 +990,14 @@ set_options(or_options_t *new_val, char **msg) if (old_options && old_options != global_options) { elements = smartlist_new(); for (i=0; options_format.vars[i].member.name; ++i) { - const config_var_t *var = &options_format.vars[i]; + const config_var_t *var = &options_format.vars[i]; // XXXX 29211 const char *var_name = var->member.name; if (config_var_is_contained(var)) { /* something else will check this var, or it doesn't need checking */ continue; } - if (!config_is_same(&options_format, new_val, old_options, var_name)) { - line = config_get_assigned_option(&options_format, new_val, + if (!config_is_same(get_options_mgr(), new_val, old_options, var_name)) { + line = config_get_assigned_option(get_options_mgr(), new_val, var_name, 1); if (line) { @@ -1046,7 +1059,7 @@ or_options_free_(or_options_t *options) tor_free(options->command_arg); tor_free(options->master_key_fname); config_free_lines(options->MyFamily); - config_free(&options_format, options); + config_free(get_options_mgr(), options); } /** Release all memory and resources held by global configuration structures. @@ -1080,6 +1093,8 @@ config_free_all(void) have_parsed_cmdline = 0; libevent_initialized = 0; + + config_mgr_free(options_mgr); } /** Make <b>address</b> -- a piece of information related to our operation as @@ -2547,7 +2562,7 @@ config_parse_commandline(int argc, char **argv, int ignore_errors, param = tor_malloc_zero(sizeof(config_line_t)); param->key = is_cmdline ? tor_strdup(argv[i]) : - tor_strdup(config_expand_abbrev(&options_format, s, 1, 1)); + tor_strdup(config_expand_abbrev(get_options_mgr(), s, 1, 1)); param->value = arg; param->command = command; param->next = NULL; @@ -2573,7 +2588,7 @@ config_parse_commandline(int argc, char **argv, int ignore_errors, int option_is_recognized(const char *key) { - const config_var_t *var = config_find_option(&options_format, key); + const config_var_t *var = config_find_option(get_options_mgr(), key); return (var != NULL); } @@ -2582,7 +2597,7 @@ option_is_recognized(const char *key) const char * option_get_canonical_name(const char *key) { - const config_var_t *var = config_find_option(&options_format, key); + const config_var_t *var = config_find_option(get_options_mgr(), key); return var ? var->member.name : NULL; } @@ -2591,7 +2606,7 @@ option_get_canonical_name(const char *key) config_line_t * option_get_assignment(const or_options_t *options, const char *key) { - return config_get_assigned_option(&options_format, options, key, 1); + return config_get_assigned_option(get_options_mgr(), options, key, 1); } /** Try assigning <b>list</b> to the global options. You do this by duping @@ -2607,9 +2622,9 @@ setopt_err_t options_trial_assign(config_line_t *list, unsigned flags, char **msg) { int r; - or_options_t *trial_options = config_dup(&options_format, get_options()); + or_options_t *trial_options = config_dup(get_options_mgr(), get_options()); - if ((r=config_assign(&options_format, trial_options, + if ((r=config_assign(get_options_mgr(), trial_options, list, flags, msg)) < 0) { or_options_free(trial_options); return r; @@ -2992,7 +3007,7 @@ is_local_addr, (const tor_addr_t *addr)) or_options_t * options_new(void) { - return config_new(&options_format); + return config_new(get_options_mgr()); } /** Set <b>options</b> to hold reasonable defaults for most options. @@ -3000,10 +3015,10 @@ options_new(void) void options_init(or_options_t *options) { - config_init(&options_format, options); + config_init(get_options_mgr(), options); config_line_t *dflts = get_options_defaults(); char *msg=NULL; - if (config_assign(&options_format, options, dflts, + if (config_assign(get_options_mgr(), options, dflts, CAL_WARN_DEPRECATIONS, &msg)<0) { log_err(LD_BUG, "Unable to set default options: %s", msg); tor_free(msg); @@ -3040,7 +3055,7 @@ options_dump(const or_options_t *options, int how_to_dump) return NULL; } - return config_dump(&options_format, use_defaults, options, minimal, 0); + return config_dump(get_options_mgr(), use_defaults, options, minimal, 0); } /** Return 0 if every element of sl is a string holding a decimal @@ -3174,8 +3189,9 @@ options_validate_cb(void *old_options, void *options, void *default_options, /** Callback to free an or_options_t */ static void -options_free_cb(void *options) +options_free_cb(const config_mgr_t *mgr, void *options) { + (void)mgr; or_options_free_(options); } @@ -4435,7 +4451,7 @@ options_validate(or_options_t *old_options, or_options_t *options, STMT_BEGIN \ if (!options->TestingTorNetwork && \ !options->UsingTestNetworkDefaults_ && \ - !config_is_same(&options_format,options, \ + !config_is_same(get_options_mgr(),options, \ default_options,#arg)) { \ REJECT(#arg " may only be changed in testing Tor " \ "networks!"); \ @@ -5431,7 +5447,7 @@ options_init_from_string(const char *cf_defaults, const char *cf, err = SETOPT_ERR_PARSE; goto err; } - retval = config_assign(&options_format, newoptions, cl, + retval = config_assign(get_options_mgr(), newoptions, cl, CAL_WARN_DEPRECATIONS, msg); config_free_lines(cl); if (retval < 0) { @@ -5439,15 +5455,15 @@ options_init_from_string(const char *cf_defaults, const char *cf, goto err; } if (i==0) - newdefaultoptions = config_dup(&options_format, newoptions); + newdefaultoptions = config_dup(get_options_mgr(), newoptions); } if (newdefaultoptions == NULL) { - newdefaultoptions = config_dup(&options_format, global_default_options); + newdefaultoptions = config_dup(get_options_mgr(), global_default_options); } /* Go through command-line variables too */ - retval = config_assign(&options_format, newoptions, + retval = config_assign(get_options_mgr(), newoptions, global_cmdline_options, CAL_WARN_DEPRECATIONS, msg); if (retval < 0) { err = SETOPT_ERR_PARSE; diff --git a/src/app/config/config.h b/src/app/config/config.h index c6feb89fe7..44f09e5ee9 100644 --- a/src/app/config/config.h +++ b/src/app/config/config.h @@ -247,9 +247,8 @@ int options_any_client_port_set(const or_options_t *options); #define CL_PORT_DFLT_GROUP_WRITABLE (1u<<7) STATIC int options_act(const or_options_t *old_options); -#ifdef TOR_UNIT_TESTS -extern const struct config_format_t options_format; -#endif +struct config_mgr_t; +STATIC const struct config_mgr_t *get_options_mgr(void); STATIC port_cfg_t *port_cfg_new(size_t namelen); #define port_cfg_free(port) \ diff --git a/src/app/config/confparse.c b/src/app/config/confparse.c index 699fc0e3dd..9c4c6a2778 100644 --- a/src/app/config/confparse.c +++ b/src/app/config/confparse.c @@ -37,13 +37,44 @@ #include "lib/string/printf.h" #include "lib/string/util_string.h" -static void config_reset(const config_format_t *fmt, void *options, +static void config_reset(const config_mgr_t *fmt, void *options, const config_var_t *var, int use_defaults); +struct config_mgr_t { + /** The 'top-level' configuration format. This one is used for legacy + * options that have not yet been assigned to different sub-modules. + * + * (NOTE: for now, this is the only config_format_t that a config_mgr_t + * contains. A subsequent commit will add more. XXXX) + */ + const config_format_t *toplevel; +}; + +/** Create a new config_mgr_t to manage a set of configuration objects to be + * wrapped under <b>toplevel_fmt</b>. */ +config_mgr_t * +config_mgr_new(const config_format_t *toplevel_fmt) +{ + config_mgr_t *mgr = tor_malloc_zero(sizeof(config_mgr_t)); + mgr->toplevel = toplevel_fmt; + return mgr; +} + +/** Release all storage held in <b>mgr</b> */ +void +config_mgr_free_(config_mgr_t *mgr) +{ + if (!mgr) + return; + memset(mgr, 0, sizeof(*mgr)); + tor_free(mgr); +} + /** Allocate an empty configuration object of a given format type. */ void * -config_new(const config_format_t *fmt) +config_new(const config_mgr_t *mgr) { + const config_format_t *fmt = mgr->toplevel; void *opts = tor_malloc_zero(fmt->size); struct_set_magic(opts, &fmt->magic); CONFIG_CHECK(fmt, opts); @@ -60,9 +91,10 @@ config_new(const config_format_t *fmt) * apply abbreviations that work for the config file and the command line. * If <b>warn_obsolete</b> is set, warn about deprecated names. */ const char * -config_expand_abbrev(const config_format_t *fmt, const char *option, +config_expand_abbrev(const config_mgr_t *mgr, const char *option, int command_line, int warn_obsolete) { + const config_format_t *fmt = mgr->toplevel; int i; if (! fmt->abbrevs) return option; @@ -90,8 +122,9 @@ config_expand_abbrev(const config_format_t *fmt, const char *option, * explaining why it is deprecated (which may be an empty string). Return NULL * if it is not deprecated. The <b>key</b> field must be fully expanded. */ const char * -config_find_deprecation(const config_format_t *fmt, const char *key) +config_find_deprecation(const config_mgr_t *mgr, const char *key) { + const config_format_t *fmt = mgr->toplevel; if (BUG(fmt == NULL) || BUG(key == NULL)) return NULL; // LCOV_EXCL_LINE if (fmt->deprecations == NULL) @@ -112,8 +145,9 @@ config_find_deprecation(const config_format_t *fmt, const char *key) * NULL. */ const config_var_t * -config_find_option(const config_format_t *fmt, const char *key) +config_find_option(const config_mgr_t *mgr, const char *key) { + const config_format_t *fmt = mgr->toplevel; int i; size_t keylen = strlen(key); if (!keylen) @@ -139,8 +173,9 @@ config_find_option(const config_format_t *fmt, const char *key) /** Return the number of option entries in <b>fmt</b>. */ static int -config_count_options(const config_format_t *fmt) +config_count_options(const config_mgr_t *mgr) { + const config_format_t *fmt = mgr->toplevel; int i; for (i=0; fmt->vars[i].member.name; ++i) ; @@ -175,14 +210,15 @@ config_var_is_contained(const config_var_t *var) * Called from config_assign_line() and option_reset(). */ static int -config_assign_value(const config_format_t *fmt, void *options, +config_assign_value(const config_mgr_t *mgr, void *options, config_line_t *c, char **msg) { const config_var_t *var; + const config_format_t *fmt = mgr->toplevel; CONFIG_CHECK(fmt, options); - var = config_find_option(fmt, c->key); + var = config_find_option(mgr, c->key); tor_assert(var); tor_assert(!strcmp(c->key, var->member.name)); @@ -192,9 +228,11 @@ config_assign_value(const config_format_t *fmt, void *options, /** Mark every linelist in <b>options</b> "fragile", so that fresh assignments * to it will replace old ones. */ static void -config_mark_lists_fragile(const config_format_t *fmt, void *options) +config_mark_lists_fragile(const config_mgr_t *mgr, void *options) { int i; + const config_format_t *fmt = mgr->toplevel; + tor_assert(fmt); tor_assert(options); @@ -224,10 +262,11 @@ warn_deprecated_option(const char *what, const char *why) * Called from config_assign(). */ static int -config_assign_line(const config_format_t *fmt, void *options, +config_assign_line(const config_mgr_t *mgr, void *options, config_line_t *c, unsigned flags, bitarray_t *options_seen, char **msg) { + const config_format_t *fmt = mgr->toplevel; const unsigned use_defaults = flags & CAL_USE_DEFAULTS; const unsigned clear_first = flags & CAL_CLEAR_FIRST; const unsigned warn_deprecations = flags & CAL_WARN_DEPRECATIONS; @@ -235,7 +274,7 @@ config_assign_line(const config_format_t *fmt, void *options, CONFIG_CHECK(fmt, options); - var = config_find_option(fmt, c->key); + var = config_find_option(mgr, c->key); if (!var) { if (fmt->extra) { void *lvalue = STRUCT_VAR_P(options, fmt->extra->offset); @@ -258,7 +297,7 @@ config_assign_line(const config_format_t *fmt, void *options, const char *deprecation_msg; if (warn_deprecations && - (deprecation_msg = config_find_deprecation(fmt, var->member.name))) { + (deprecation_msg = config_find_deprecation(mgr, var->member.name))) { warn_deprecated_option(var->member.name, deprecation_msg); } @@ -271,14 +310,14 @@ config_assign_line(const config_format_t *fmt, void *options, log_warn(LD_CONFIG, "Linelist option '%s' has no value. Skipping.", c->key); } else { /* not already cleared */ - config_reset(fmt, options, var, use_defaults); + config_reset(mgr, options, var, use_defaults); } } return 0; } else if (c->command == CONFIG_LINE_CLEAR && !clear_first) { // XXXX This is unreachable, since a CLEAR line always has an // XXXX empty value. - config_reset(fmt, options, var, use_defaults); // LCOV_EXCL_LINE + config_reset(mgr, options, var, use_defaults); // LCOV_EXCL_LINE } if (options_seen && ! config_var_is_cumulative(var)) { @@ -292,7 +331,7 @@ config_assign_line(const config_format_t *fmt, void *options, bitarray_set(options_seen, var_index); } - if (config_assign_value(fmt, options, c, msg) < 0) + if (config_assign_value(mgr, options, c, msg) < 0) return -2; return 0; } @@ -300,18 +339,19 @@ config_assign_line(const config_format_t *fmt, void *options, /** Restore the option named <b>key</b> in options to its default value. * Called from config_assign(). */ STATIC void -config_reset_line(const config_format_t *fmt, void *options, +config_reset_line(const config_mgr_t *mgr, void *options, const char *key, int use_defaults) { + const config_format_t *fmt = mgr->toplevel; const config_var_t *var; CONFIG_CHECK(fmt, options); - var = config_find_option(fmt, key); + var = config_find_option(mgr, key); if (!var) return; /* give error on next pass. */ - config_reset(fmt, options, var, use_defaults); + config_reset(mgr, options, var, use_defaults); } /** Return true iff value needs to be quoted and escaped to be used in @@ -345,16 +385,18 @@ config_value_needs_escape(const char *value) * value needs to be quoted before it's put in a config file, quote and * escape that value. Return NULL if no such key exists. */ config_line_t * -config_get_assigned_option(const config_format_t *fmt, const void *options, +config_get_assigned_option(const config_mgr_t *mgr, const void *options, const char *key, int escape_val) { const config_var_t *var; config_line_t *result; + const config_format_t *fmt = mgr->toplevel; + tor_assert(options && key); CONFIG_CHECK(fmt, options); - var = config_find_option(fmt, key); + var = config_find_option(mgr, key); if (!var) { log_warn(LD_CONFIG, "Unknown option '%s'. Failing.", key); return NULL; @@ -432,12 +474,13 @@ options_trial_assign() calls config_assign(1, 1) returns. */ int -config_assign(const config_format_t *fmt, void *options, config_line_t *list, +config_assign(const config_mgr_t *mgr, void *options, config_line_t *list, unsigned config_assign_flags, char **msg) { config_line_t *p; bitarray_t *options_seen; - const int n_options = config_count_options(fmt); + const config_format_t *fmt = mgr->toplevel; + const int n_options = config_count_options(mgr); const unsigned clear_first = config_assign_flags & CAL_CLEAR_FIRST; const unsigned use_defaults = config_assign_flags & CAL_USE_DEFAULTS; @@ -445,7 +488,7 @@ config_assign(const config_format_t *fmt, void *options, config_line_t *list, /* pass 1: normalize keys */ for (p = list; p; p = p->next) { - const char *full = config_expand_abbrev(fmt, p->key, 0, 1); + const char *full = config_expand_abbrev(mgr, p->key, 0, 1); if (strcmp(full,p->key)) { tor_free(p->key); p->key = tor_strdup(full); @@ -456,14 +499,14 @@ config_assign(const config_format_t *fmt, void *options, config_line_t *list, * mentioned config options, and maybe set to their defaults. */ if (clear_first) { for (p = list; p; p = p->next) - config_reset_line(fmt, options, p->key, use_defaults); + config_reset_line(mgr, options, p->key, use_defaults); } options_seen = bitarray_init_zero(n_options); /* pass 3: assign. */ while (list) { int r; - if ((r=config_assign_line(fmt, options, list, config_assign_flags, + if ((r=config_assign_line(mgr, options, list, config_assign_flags, options_seen, msg))) { bitarray_free(options_seen); return r; @@ -475,7 +518,7 @@ config_assign(const config_format_t *fmt, void *options, config_line_t *list, /** Now we're done assigning a group of options to the configuration. * Subsequent group assignments should _replace_ linelists, not extend * them. */ - config_mark_lists_fragile(fmt, options); + config_mark_lists_fragile(mgr, options); return 0; } @@ -483,12 +526,9 @@ config_assign(const config_format_t *fmt, void *options, config_line_t *list, /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent. * Called from config_reset() and config_free(). */ static void -config_clear(const config_format_t *fmt, void *options, +config_clear(void *options, const config_var_t *var) { - - (void)fmt; /* unused */ - struct_var_free(options, &var->member); } @@ -496,20 +536,21 @@ config_clear(const config_format_t *fmt, void *options, * <b>use_defaults</b>, set it to its default value. * Called by config_init() and option_reset_line() and option_assign_line(). */ static void -config_reset(const config_format_t *fmt, void *options, +config_reset(const config_mgr_t *mgr, void *options, const config_var_t *var, int use_defaults) { + const config_format_t *fmt = mgr->toplevel; config_line_t *c; char *msg = NULL; CONFIG_CHECK(fmt, options); - config_clear(fmt, options, var); /* clear it first */ + config_clear(options, var); /* clear it first */ if (!use_defaults) return; /* all done */ if (var->initvalue) { c = tor_malloc_zero(sizeof(config_line_t)); c->key = tor_strdup(var->member.name); c->value = tor_strdup(var->initvalue); - if (config_assign_value(fmt, options, c, &msg) < 0) { + if (config_assign_value(mgr, options, c, &msg) < 0) { // LCOV_EXCL_START log_warn(LD_BUG, "Failed to assign default: %s", msg); tor_free(msg); /* if this happens it's a bug */ @@ -521,9 +562,10 @@ config_reset(const config_format_t *fmt, void *options, /** Release storage held by <b>options</b>. */ void -config_free_(const config_format_t *fmt, void *options) +config_free_(const config_mgr_t *mgr, void *options) { int i; + const config_format_t *fmt = mgr->toplevel; if (!options) return; @@ -531,7 +573,7 @@ config_free_(const config_format_t *fmt, void *options) tor_assert(fmt); for (i=0; fmt->vars[i].member.name; ++i) - config_clear(fmt, options, &(fmt->vars[i])); + config_clear(options, &(fmt->vars[i])); if (fmt->extra) { config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->offset); @@ -545,14 +587,15 @@ config_free_(const config_format_t *fmt, void *options) * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options. */ int -config_is_same(const config_format_t *fmt, +config_is_same(const config_mgr_t *mgr, const void *o1, const void *o2, const char *name) { + const config_format_t *fmt = mgr->toplevel; CONFIG_CHECK(fmt, o1); CONFIG_CHECK(fmt, o2); - const config_var_t *var = config_find_option(fmt, name); + const config_var_t *var = config_find_option(mgr, name); if (!var) { return true; } @@ -562,12 +605,13 @@ config_is_same(const config_format_t *fmt, /** Copy storage held by <b>old</b> into a new or_options_t and return it. */ void * -config_dup(const config_format_t *fmt, const void *old) +config_dup(const config_mgr_t *mgr, const void *old) { + const config_format_t *fmt = mgr->toplevel; void *newopts; int i; - newopts = config_new(fmt); + newopts = config_new(mgr); for (i=0; fmt->vars[i].member.name; ++i) { if (config_var_is_contained(&fmt->vars[i])) { // Something else will copy this option, or it doesn't need copying. @@ -586,9 +630,10 @@ config_dup(const config_format_t *fmt, const void *old) /** Set all vars in the configuration object <b>options</b> to their default * values. */ void -config_init(const config_format_t *fmt, void *options) +config_init(const config_mgr_t *mgr, void *options) { int i; + const config_format_t *fmt = mgr->toplevel; const config_var_t *var; CONFIG_CHECK(fmt, options); @@ -596,7 +641,7 @@ config_init(const config_format_t *fmt, void *options) var = &fmt->vars[i]; if (!var->initvalue) continue; /* defaults to NULL or 0 */ - config_reset(fmt, options, var, 1); + config_reset(mgr, options, var, 1); } } @@ -605,11 +650,12 @@ config_init(const config_format_t *fmt, void *options) * Else, if comment_defaults, write default values as comments. */ char * -config_dump(const config_format_t *fmt, const void *default_options, +config_dump(const config_mgr_t *mgr, const void *default_options, const void *options, int minimal, int comment_defaults) { smartlist_t *elements; + const config_format_t *fmt = mgr->toplevel; const void *defaults = default_options; void *defaults_tmp = NULL; config_line_t *line, *assigned; @@ -618,8 +664,8 @@ config_dump(const config_format_t *fmt, const void *default_options, char *msg = NULL; if (defaults == NULL) { - defaults = defaults_tmp = config_new(fmt); - config_init(fmt, defaults_tmp); + defaults = defaults_tmp = config_new(mgr); + config_init(mgr, defaults_tmp); } /* XXX use a 1 here so we don't add a new log line while dumping */ @@ -643,15 +689,15 @@ config_dump(const config_format_t *fmt, const void *default_options, /* Don't save 'hidden' control variables. */ if (fmt->vars[i].flags & CVFLAG_NODUMP) continue; - if (minimal && config_is_same(fmt, options, defaults, + if (minimal && config_is_same(mgr, options, defaults, fmt->vars[i].member.name)) continue; else if (comment_defaults && - config_is_same(fmt, options, defaults, fmt->vars[i].member.name)) + config_is_same(mgr, options, defaults, fmt->vars[i].member.name)) comment_option = 1; line = assigned = - config_get_assigned_option(fmt, options, fmt->vars[i].member.name, 1); + config_get_assigned_option(mgr, options, fmt->vars[i].member.name, 1); for (; line; line = line->next) { if (!strcmpstart(line->key, "__")) { @@ -677,7 +723,7 @@ config_dump(const config_format_t *fmt, const void *default_options, SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp)); smartlist_free(elements); if (defaults_tmp) { - fmt->free_fn(defaults_tmp); + fmt->free_fn(mgr, defaults_tmp); } return result; } @@ -687,8 +733,9 @@ config_dump(const config_format_t *fmt, const void *default_options, * Return false otherwise. Log errors at level <b>severity</b>. */ bool -config_check_ok(const config_format_t *fmt, const void *options, int severity) +config_check_ok(const config_mgr_t *mgr, const void *options, int severity) { + const config_format_t *fmt = mgr->toplevel; bool all_ok = true; for (int i=0; fmt->vars[i].member.name; ++i) { if (!struct_var_ok(options, &fmt->vars[i].member)) { diff --git a/src/app/config/confparse.h b/src/app/config/confparse.h index 3633c2a80b..a6a2450aee 100644 --- a/src/app/config/confparse.h +++ b/src/app/config/confparse.h @@ -39,8 +39,10 @@ typedef struct config_deprecation_t { * of arguments. */ typedef int (*validate_fn_t)(void*,void*,void*,int,char**); +struct config_mgr_t; + /** Callback to free a configuration object. */ -typedef void (*free_cfg_fn_t)(void*); +typedef void (*free_cfg_fn_t)(const struct config_mgr_t *mgr, void*); /** Information on the keys, value types, key-to-struct-member mappings, * variable descriptions, validation functions, and abbreviations for a @@ -61,6 +63,19 @@ typedef struct config_format_t { const struct_member_t *extra; } config_format_t; +/** + * A collection of config_format_t objects to describe several objects + * that are all configured with the same configuration file. + * + * (NOTE: for now, this only handles a single config_format_t.) + **/ +typedef struct config_mgr_t config_mgr_t; + +config_mgr_t *config_mgr_new(const config_format_t *toplevel_fmt); +void config_mgr_free_(config_mgr_t *mgr); +#define config_mgr_free(mgr) \ + FREE_AND_NULL(config_mgr_t, config_mgr_free_, (mgr)) + /** Macro: assert that <b>cfg</b> has the right magic field for format * <b>fmt</b>. */ #define CONFIG_CHECK(fmt, cfg) STMT_BEGIN \ @@ -72,34 +87,34 @@ typedef struct config_format_t { #define CAL_CLEAR_FIRST (1u<<1) #define CAL_WARN_DEPRECATIONS (1u<<2) -void *config_new(const config_format_t *fmt); -void config_free_(const config_format_t *fmt, void *options); -#define config_free(fmt, options) do { \ - config_free_((fmt), (options)); \ +void *config_new(const config_mgr_t *fmt); +void config_free_(const config_mgr_t *fmt, void *options); +#define config_free(mgr, options) do { \ + config_free_((mgr), (options)); \ (options) = NULL; \ } while (0) -struct config_line_t *config_get_assigned_option(const config_format_t *fmt, +struct config_line_t *config_get_assigned_option(const config_mgr_t *mgr, const void *options, const char *key, int escape_val); -int config_is_same(const config_format_t *fmt, +int config_is_same(const config_mgr_t *fmt, const void *o1, const void *o2, const char *name); -void config_init(const config_format_t *fmt, void *options); -void *config_dup(const config_format_t *fmt, const void *old); -char *config_dump(const config_format_t *fmt, const void *default_options, +void config_init(const config_mgr_t *mgr, void *options); +void *config_dup(const config_mgr_t *mgr, const void *old); +char *config_dump(const config_mgr_t *mgr, const void *default_options, const void *options, int minimal, int comment_defaults); -bool config_check_ok(const config_format_t *fmt, const void *options, +bool config_check_ok(const config_mgr_t *mgr, const void *options, int severity); -int config_assign(const config_format_t *fmt, void *options, +int config_assign(const config_mgr_t *mgr, void *options, struct config_line_t *list, unsigned flags, char **msg); -const char *config_find_deprecation(const config_format_t *fmt, +const char *config_find_deprecation(const config_mgr_t *mgr, const char *key); -const config_var_t *config_find_option(const config_format_t *fmt, +const config_var_t *config_find_option(const config_mgr_t *mgr, const char *key); -const char *config_expand_abbrev(const config_format_t *fmt, +const char *config_expand_abbrev(const config_mgr_t *mgr, const char *option, int command_line, int warn_obsolete); void warn_deprecated_option(const char *what, const char *why); @@ -117,7 +132,7 @@ bool config_var_is_contained(const config_var_t *var); #define CFG_EQ_ROUTERSET(a,b,opt) routerset_equal((a)->opt, (b)->opt) #ifdef CONFPARSE_PRIVATE -STATIC void config_reset_line(const config_format_t *fmt, void *options, +STATIC void config_reset_line(const config_mgr_t *mgr, void *options, const char *key, int use_defaults); #endif diff --git a/src/app/config/statefile.c b/src/app/config/statefile.c index d997d3932e..a44bcf6fb5 100644 --- a/src/app/config/statefile.c +++ b/src/app/config/statefile.c @@ -145,7 +145,7 @@ static int or_state_validate_cb(void *old_options, void *options, void *default_options, int from_setconf, char **msg); -static void or_state_free_cb(void *state); +static void or_state_free_cb(const config_mgr_t *mgr, void *state); /** Magic value for or_state_t. */ #define OR_STATE_MAGIC 0x57A73f57 @@ -174,6 +174,19 @@ static const config_format_t state_format = { &state_extra_var, }; +/* A global configuration manager for state-file objects */ +static config_mgr_t *state_mgr = NULL; + +/** Return the configuration manager for state-file objects. */ +static const config_mgr_t * +get_state_mgr(void) +{ + if (PREDICT_UNLIKELY(state_mgr == NULL)) { + state_mgr = config_mgr_new(&state_format); + } + return state_mgr; +} + /** Persistent serialized state. */ static or_state_t *global_state = NULL; @@ -269,8 +282,9 @@ or_state_validate_cb(void *old_state, void *state, void *default_state, } static void -or_state_free_cb(void *state) +or_state_free_cb(const config_mgr_t *mgr, void *state) { + (void)mgr; or_state_free_(state); } @@ -298,7 +312,7 @@ or_state_set(or_state_t *new_state) char *err = NULL; int ret = 0; tor_assert(new_state); - config_free(&state_format, global_state); + config_free(get_state_mgr(), global_state); global_state = new_state; if (entry_guards_parse_state(global_state, 1, &err)<0) { log_warn(LD_GENERAL,"%s",err); @@ -363,7 +377,7 @@ or_state_new(void) { or_state_t *new_state = tor_malloc_zero(sizeof(or_state_t)); new_state->magic_ = OR_STATE_MAGIC; - config_init(&state_format, new_state); + config_init(get_state_mgr(), new_state); return new_state; } @@ -404,7 +418,7 @@ or_state_load(void) int assign_retval; if (config_get_lines(contents, &lines, 0)<0) goto done; - assign_retval = config_assign(&state_format, new_state, + assign_retval = config_assign(get_state_mgr(), new_state, lines, 0, &errmsg); config_free_lines(lines); if (assign_retval<0) @@ -431,7 +445,7 @@ or_state_load(void) or_state_save_broken(fname); tor_free(contents); - config_free(&state_format, new_state); + config_free(get_state_mgr(), new_state); new_state = or_state_new(); } else if (contents) { @@ -464,7 +478,7 @@ or_state_load(void) tor_free(fname); tor_free(contents); if (new_state) - config_free(&state_format, new_state); + config_free(get_state_mgr(), new_state); return r; } @@ -517,7 +531,7 @@ or_state_save(time_t now) tor_free(global_state->TorVersion); tor_asprintf(&global_state->TorVersion, "Tor %s", get_version()); - state = config_dump(&state_format, NULL, global_state, 1, 0); + state = config_dump(get_state_mgr(), NULL, global_state, 1, 0); format_local_iso_time(tbuf, now); tor_asprintf(&contents, "# Tor state file last generated on %s local time\n" @@ -727,7 +741,7 @@ or_state_free_(or_state_t *state) if (!state) return; - config_free(&state_format, state); + config_free(get_state_mgr(), state); } void @@ -735,4 +749,5 @@ or_state_free_all(void) { or_state_free(global_state); global_state = NULL; + config_mgr_free(state_mgr); } diff --git a/src/feature/dirauth/shared_random_state.c b/src/feature/dirauth/shared_random_state.c index c2ad3e7cca..a552e621ca 100644 --- a/src/feature/dirauth/shared_random_state.c +++ b/src/feature/dirauth/shared_random_state.c @@ -62,7 +62,7 @@ DUMMY_TYPECHECK_INSTANCE(sr_disk_state_t); static int disk_state_validate_cb(void *old_state, void *state, void *default_state, int from_setconf, char **msg); -static void disk_state_free_cb(void *); +static void disk_state_free_cb(const config_mgr_t *mgr, void *); /* Array of variables that are saved to disk as a persistent state. */ static const config_var_t state_vars[] = { @@ -103,6 +103,19 @@ static const config_format_t state_format = { &state_extra_var, }; +/* Global configuration manager for the shared-random state file */ +static config_mgr_t *shared_random_state_mgr = NULL; + +/** Return the configuration manager for the shared-random state file. */ +static const config_mgr_t * +get_srs_mgr(void) +{ + if (PREDICT_UNLIKELY(shared_random_state_mgr == NULL)) { + shared_random_state_mgr = config_mgr_new(&state_format); + } + return shared_random_state_mgr; +} + static void state_query_del_(sr_state_object_t obj_type, void *data); /* Return a string representation of a protocol phase. */ @@ -264,7 +277,7 @@ disk_state_free_(sr_disk_state_t *state) if (state == NULL) { return; } - config_free(&state_format, state); + config_free(get_srs_mgr(), state); } /* Allocate a new disk state, initialize it and return it. */ @@ -280,7 +293,7 @@ disk_state_new(time_t now) new_state->ValidAfter = now; /* Init config format. */ - config_init(&state_format, new_state); + config_init(get_srs_mgr(), new_state); return new_state; } @@ -349,8 +362,9 @@ disk_state_validate_cb(void *old_state, void *state, void *default_state, } static void -disk_state_free_cb(void *state) +disk_state_free_cb(const config_mgr_t *mgr, void *state) { + (void)mgr; disk_state_free_(state); } @@ -683,7 +697,7 @@ disk_state_load_from_disk_impl(const char *fname) } disk_state = disk_state_new(time(NULL)); - config_assign(&state_format, disk_state, lines, 0, &errmsg); + config_assign(get_srs_mgr(), disk_state, lines, 0, &errmsg); config_free_lines(lines); if (errmsg) { log_warn(LD_DIR, "SR: Reading state error: %s", errmsg); @@ -736,7 +750,7 @@ disk_state_save_to_disk(void) /* Make sure that our disk state is up to date with our memory state * before saving it to disk. */ disk_state_update(); - state = config_dump(&state_format, NULL, sr_disk_state, 0, 0); + state = config_dump(get_srs_mgr(), NULL, sr_disk_state, 0, 0); format_local_iso_time(tbuf, now); tor_asprintf(&content, "# Tor shared random state file last generated on %s " @@ -1278,6 +1292,7 @@ sr_state_free_all(void) /* Nullify our global state. */ sr_state = NULL; sr_disk_state = NULL; + config_mgr_free(shared_random_state_mgr); } /* Save our current state in memory to disk. */ diff --git a/src/test/test_confparse.c b/src/test/test_confparse.c index ec018f0c52..8a921531fa 100644 --- a/src/test/test_confparse.c +++ b/src/test/test_confparse.c @@ -119,7 +119,7 @@ test_validate_cb(void *old_options, void *options, void *default_options, return 0; } -static void test_free_cb(void *options); +static void test_free_cb(const config_mgr_t *mgr, void *options); #define TEST_MAGIC 0x1337 @@ -139,12 +139,12 @@ static const config_format_t test_fmt = { }; static void -test_free_cb(void *options) +test_free_cb(const config_mgr_t *mgr, void *options) { if (!options) return; - config_free(&test_fmt, options); + config_free(mgr, options); } /* Make sure that config_init sets everything to the right defaults. */ @@ -152,8 +152,9 @@ static void test_confparse_init(void *arg) { (void)arg; - test_struct_t *tst = config_new(&test_fmt); - config_init(&test_fmt, tst); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + test_struct_t *tst = config_new(mgr); + config_init(mgr, tst); // Make sure that options are initialized right. */ tt_uint_op(tst->magic, OP_EQ, TEST_MAGIC); @@ -178,7 +179,8 @@ test_confparse_init(void *arg) tt_int_op(tst->hidden_int, OP_EQ, 0); done: - config_free(&test_fmt, tst); + config_free(mgr, tst); + config_mgr_free(mgr); } static const char simple_settings[] = @@ -207,18 +209,18 @@ static const char simple_settings[] = /* Return a configuration object set up from simple_settings above. */ static test_struct_t * -get_simple_config(void) +get_simple_config(const config_mgr_t *mgr) { test_struct_t *result = NULL; - test_struct_t *tst = config_new(&test_fmt); + test_struct_t *tst = config_new(mgr); config_line_t *lines = NULL; char *msg = NULL; - config_init(&test_fmt, tst); + config_init(mgr, tst); int r = config_get_lines(simple_settings, &lines, 0); tt_int_op(r, OP_EQ, 0); - r = config_assign(&test_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); @@ -227,7 +229,7 @@ get_simple_config(void) done: tor_free(msg); config_free_lines(lines); - config_free(&test_fmt, tst); + config_free(mgr, tst); return result; } @@ -236,7 +238,8 @@ static void test_confparse_assign_simple(void *arg) { (void)arg; - test_struct_t *tst = get_simple_config(); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + test_struct_t *tst = get_simple_config(mgr); tt_str_op(tst->s, OP_EQ, "this is a"); tt_str_op(tst->fn, OP_EQ, "/simple/test of the"); @@ -284,10 +287,11 @@ test_confparse_assign_simple(void *arg) tt_str_op(tst->mixed_hidden_lines->next->value, OP_EQ, "ABC"); tt_assert(!tst->mixed_hidden_lines->next->next); - tt_assert(config_check_ok(&test_fmt, tst, LOG_ERR)); + tt_assert(config_check_ok(mgr, tst, LOG_ERR)); done: - config_free(&test_fmt, tst); + config_free(mgr, tst); + config_mgr_free(mgr); } /* Try to assign to an obsolete option, and make sure we get a warning. */ @@ -295,26 +299,28 @@ static void test_confparse_assign_obsolete(void *arg) { (void)arg; - test_struct_t *tst = config_new(&test_fmt); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL; - config_init(&test_fmt, tst); + config_init(mgr, tst); int r = config_get_lines("obsolete option here", &lines, 0); tt_int_op(r, OP_EQ, 0); setup_capture_of_logs(LOG_WARN); - r = config_assign(&test_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); expect_single_log_msg_containing("Skipping obsolete configuration option"); done: teardown_capture_of_logs(); - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); + config_mgr_free(mgr); } /* Try to assign to an deprecated option, and make sure we get a warning @@ -323,30 +329,32 @@ static void test_confparse_assign_deprecated(void *arg) { (void)arg; - test_struct_t *tst = config_new(&test_fmt); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL; - config_init(&test_fmt, tst); + config_init(mgr, tst); int r = config_get_lines("deprecated_int 7", &lines, 0); tt_int_op(r, OP_EQ, 0); setup_capture_of_logs(LOG_WARN); - r = config_assign(&test_fmt, tst, lines, CAL_WARN_DEPRECATIONS, &msg); + r = config_assign(mgr, tst, lines, CAL_WARN_DEPRECATIONS, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); expect_single_log_msg_containing("This integer is deprecated."); tt_int_op(tst->deprecated_int, OP_EQ, 7); - tt_assert(config_check_ok(&test_fmt, tst, LOG_ERR)); + tt_assert(config_check_ok(mgr, tst, LOG_ERR)); done: teardown_capture_of_logs(); - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); + config_mgr_free(mgr); } /* Try to re-assign an option name that has been depreacted in favor of @@ -355,16 +363,17 @@ static void test_confparse_assign_replaced(void *arg) { (void)arg; - test_struct_t *tst = config_new(&test_fmt); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL; - config_init(&test_fmt, tst); + config_init(mgr, tst); int r = config_get_lines("float 1000\n", &lines, 0); tt_int_op(r, OP_EQ, 0); setup_capture_of_logs(LOG_WARN); - r = config_assign(&test_fmt, tst, lines, CAL_WARN_DEPRECATIONS, &msg); + r = config_assign(mgr, tst, lines, CAL_WARN_DEPRECATIONS, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); expect_single_log_msg_containing("use 'dbl' instead."); @@ -374,9 +383,10 @@ test_confparse_assign_replaced(void *arg) done: teardown_capture_of_logs(); - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); + config_mgr_free(mgr); } /* Try to set a linelist value with no option. */ @@ -384,25 +394,27 @@ static void test_confparse_assign_emptystring(void *arg) { (void)arg; - test_struct_t *tst = config_new(&test_fmt); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL; - config_init(&test_fmt, tst); + config_init(mgr, tst); int r = config_get_lines("lines\n", &lines, 0); tt_int_op(r, OP_EQ, 0); setup_capture_of_logs(LOG_WARN); - r = config_assign(&test_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); expect_single_log_msg_containing("has no value"); done: teardown_capture_of_logs(); - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); + config_mgr_free(mgr); } /* Try to set a the same option twice; make sure we get a warning. */ @@ -410,26 +422,28 @@ static void test_confparse_assign_twice(void *arg) { (void)arg; - test_struct_t *tst = config_new(&test_fmt); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL; - config_init(&test_fmt, tst); + config_init(mgr, tst); int r = config_get_lines("pos 10\n" "pos 99\n", &lines, 0); tt_int_op(r, OP_EQ, 0); setup_capture_of_logs(LOG_WARN); - r = config_assign(&test_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); expect_single_log_msg_containing("used more than once"); done: teardown_capture_of_logs(); - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); + config_mgr_free(mgr); } typedef struct badval_test_t { @@ -443,16 +457,17 @@ static void test_confparse_assign_badval(void *arg) { const badval_test_t *bt = arg; - test_struct_t *tst = config_new(&test_fmt); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL; - config_init(&test_fmt, tst); + config_init(mgr, tst); int r = config_get_lines(bt->cfg, &lines, 0); tt_int_op(r, OP_EQ, 0); setup_capture_of_logs(LOG_WARN); - r = config_assign(&test_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_LT, 0); tt_ptr_op(msg, OP_NE, NULL); if (! strstr(msg, bt->expect_msg)) { @@ -461,9 +476,10 @@ test_confparse_assign_badval(void *arg) done: teardown_capture_of_logs(); - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); + config_mgr_free(mgr); } /* Various arguments for badval test. @@ -495,11 +511,12 @@ static void test_confparse_dump(void *arg) { (void)arg; - test_struct_t *tst = get_simple_config(); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + test_struct_t *tst = get_simple_config(mgr); char *dumped = NULL; /* Minimal version. */ - dumped = config_dump(&test_fmt, NULL, tst, 1, 0); + dumped = config_dump(mgr, NULL, tst, 1, 0); tt_str_op(dumped, OP_EQ, "s this is a\n" "fn /simple/test of the\n" @@ -524,7 +541,7 @@ test_confparse_dump(void *arg) /* Maximal */ tor_free(dumped); - dumped = config_dump(&test_fmt, NULL, tst, 0, 0); + dumped = config_dump(mgr, NULL, tst, 0, 0); tt_str_op(dumped, OP_EQ, "s this is a\n" "fn /simple/test of the\n" @@ -550,7 +567,7 @@ test_confparse_dump(void *arg) /* commented */ tor_free(dumped); - dumped = config_dump(&test_fmt, NULL, tst, 0, 1); + dumped = config_dump(mgr, NULL, tst, 0, 1); tt_str_op(dumped, OP_EQ, "s this is a\n" "fn /simple/test of the\n" @@ -575,8 +592,9 @@ test_confparse_dump(void *arg) "VisibleLineB ABC\n"); done: - config_free(&test_fmt, tst); + config_free(mgr, tst); tor_free(dumped); + config_mgr_free(mgr); } /* Try confparse_reset_line(), and make sure it behaves correctly */ @@ -584,16 +602,18 @@ static void test_confparse_reset(void *arg) { (void)arg; - test_struct_t *tst = get_simple_config(); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + test_struct_t *tst = get_simple_config(mgr); - config_reset_line(&test_fmt, tst, "interval", 0); + config_reset_line(mgr, tst, "interval", 0); tt_int_op(tst->interval, OP_EQ, 0); - config_reset_line(&test_fmt, tst, "interval", 1); + config_reset_line(mgr, tst, "interval", 1); tt_int_op(tst->interval, OP_EQ, 10); done: - config_free(&test_fmt, tst); + config_free(mgr, tst); + config_mgr_free(mgr); } /* Try setting options a second time on a config object, and make sure @@ -602,7 +622,8 @@ static void test_confparse_reassign(void *arg) { (void)arg; - test_struct_t *tst = get_simple_config(); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL, *rs = NULL; @@ -613,7 +634,7 @@ test_confparse_reassign(void *arg) "csv 14,15\n" "routerset 127.0.0.1\n", &lines, 0); - r = config_assign(&test_fmt, tst,lines, 0, &msg); + r = config_assign(mgr, tst,lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); @@ -633,7 +654,7 @@ test_confparse_reassign(void *arg) tt_str_op(rs, OP_EQ, "127.0.0.1"); // Try again with the CLEAR_FIRST and USE_DEFAULTS flags - r = config_assign(&test_fmt, tst, lines, + r = config_assign(mgr, tst, lines, CAL_CLEAR_FIRST|CAL_USE_DEFAULTS, &msg); tt_int_op(r, OP_EQ, 0); @@ -644,10 +665,11 @@ test_confparse_reassign(void *arg) tt_int_op(tst->i, OP_EQ, 12); done: - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); tor_free(rs); + config_mgr_free(mgr); } /* Try setting options a second time on a config object, using the +foo @@ -656,7 +678,8 @@ static void test_confparse_reassign_extend(void *arg) { (void)arg; - test_struct_t *tst = get_simple_config(); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL; @@ -664,7 +687,7 @@ test_confparse_reassign_extend(void *arg) "+lines 13\n", &lines, 1); // allow extended format. tt_int_op(r, OP_EQ, 0); - r = config_assign(&test_fmt, tst,lines, 0, &msg); + r = config_assign(mgr, tst,lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); @@ -684,27 +707,28 @@ test_confparse_reassign_extend(void *arg) "/lines\n", &lines, 1); // allow extended format. tt_int_op(r, OP_EQ, 0); - r = config_assign(&test_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); tt_assert(tst->lines == NULL); config_free_lines(lines); - config_free(&test_fmt, tst); - tst = get_simple_config(); + config_free(mgr, tst); + tst = get_simple_config(mgr); r = config_get_lines( "/lines away!\n", &lines, 1); // allow extended format. tt_int_op(r, OP_EQ, 0); - r = config_assign(&test_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); tt_assert(tst->lines == NULL); done: - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); + config_mgr_free(mgr); } /* Test out confparse_get_assigned(). */ @@ -712,30 +736,32 @@ static void test_confparse_get_assigned(void *arg) { (void)arg; - test_struct_t *tst = get_simple_config(); + + config_mgr_t *mgr = config_mgr_new(&test_fmt); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; - lines = config_get_assigned_option(&test_fmt, tst, "I", 1); + lines = config_get_assigned_option(mgr, tst, "I", 1); tt_assert(lines); tt_str_op(lines->key, OP_EQ, "i"); tt_str_op(lines->value, OP_EQ, "3"); tt_assert(lines->next == NULL); config_free_lines(lines); - lines = config_get_assigned_option(&test_fmt, tst, "s", 1); + lines = config_get_assigned_option(mgr, tst, "s", 1); tt_assert(lines); tt_str_op(lines->key, OP_EQ, "s"); tt_str_op(lines->value, OP_EQ, "this is a"); tt_assert(lines->next == NULL); config_free_lines(lines); - lines = config_get_assigned_option(&test_fmt, tst, "obsolete", 1); + lines = config_get_assigned_option(mgr, tst, "obsolete", 1); tt_assert(!lines); - lines = config_get_assigned_option(&test_fmt, tst, "nonesuch", 1); + lines = config_get_assigned_option(mgr, tst, "nonesuch", 1); tt_assert(!lines); - lines = config_get_assigned_option(&test_fmt, tst, "mixedlines", 1); + lines = config_get_assigned_option(mgr, tst, "mixedlines", 1); tt_assert(lines); tt_str_op(lines->key, OP_EQ, "LineTypeA"); tt_str_op(lines->value, OP_EQ, "i d"); @@ -745,7 +771,7 @@ test_confparse_get_assigned(void *arg) tt_assert(lines->next->next == NULL); config_free_lines(lines); - lines = config_get_assigned_option(&test_fmt, tst, "linetypeb", 1); + lines = config_get_assigned_option(mgr, tst, "linetypeb", 1); tt_assert(lines); tt_str_op(lines->key, OP_EQ, "LineTypeB"); tt_str_op(lines->value, OP_EQ, "i c"); @@ -754,7 +780,7 @@ test_confparse_get_assigned(void *arg) tor_free(tst->s); tst->s = tor_strdup("Hello\nWorld"); - lines = config_get_assigned_option(&test_fmt, tst, "s", 1); + lines = config_get_assigned_option(mgr, tst, "s", 1); tt_assert(lines); tt_str_op(lines->key, OP_EQ, "s"); tt_str_op(lines->value, OP_EQ, "\"Hello\\nWorld\""); @@ -762,8 +788,9 @@ test_confparse_get_assigned(void *arg) config_free_lines(lines); done: - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); + config_mgr_free(mgr); } /* Another variant, which accepts and stores unrecognized lines.*/ @@ -796,24 +823,25 @@ static void test_confparse_extra_lines(void *arg) { (void)arg; - test_struct_t *tst = config_new(&etest_fmt); + config_mgr_t *mgr = config_mgr_new(&etest_fmt); + test_struct_t *tst = config_new(mgr); config_line_t *lines = NULL; char *msg = NULL, *dump = NULL; - config_init(&etest_fmt, tst); + config_init(mgr, tst); int r = config_get_lines( "unknotty addita\n" "pos 99\n" "wombat knish\n", &lines, 0); tt_int_op(r, OP_EQ, 0); - r = config_assign(&etest_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); tt_assert(tst->extra_lines); - dump = config_dump(&etest_fmt, NULL, tst, 1, 0); + dump = config_dump(mgr, NULL, tst, 1, 0); tt_str_op(dump, OP_EQ, "pos 99\n" "unknotty addita\n" @@ -823,7 +851,8 @@ test_confparse_extra_lines(void *arg) tor_free(msg); tor_free(dump); config_free_lines(lines); - config_free(&etest_fmt, tst); + config_free(mgr, tst); + config_mgr_free(mgr); } static void @@ -889,12 +918,14 @@ static void test_confparse_check_ok_fail(void *arg) { (void)arg; - test_struct_t *tst = config_new(&test_fmt); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + test_struct_t *tst = config_new(mgr); tst->pos = -10; - tt_assert(! config_check_ok(&test_fmt, tst, LOG_INFO)); + tt_assert(! config_check_ok(mgr, tst, LOG_INFO)); done: - config_free(&test_fmt, tst); + config_free(mgr, tst); + config_mgr_free(mgr); } #define CONFPARSE_TEST(name, flags) \ diff --git a/src/test/test_helpers.c b/src/test/test_helpers.c index b4389f2d17..31a6540efc 100644 --- a/src/test/test_helpers.c +++ b/src/test/test_helpers.c @@ -295,7 +295,7 @@ helper_parse_options(const char *conf) if (ret != 0) { goto done; } - ret = config_assign(&options_format, opt, line, 0, &msg); + ret = config_assign(get_options_mgr(), opt, line, 0, &msg); if (ret != 0) { goto done; } diff --git a/src/test/test_options.c b/src/test/test_options.c index b39cd4f1e4..b6ab97b4ae 100644 --- a/src/test/test_options.c +++ b/src/test/test_options.c @@ -96,7 +96,7 @@ clear_log_messages(void) opt->command = CMD_RUN_TOR; \ options_init(opt); \ \ - dflt = config_dup(&options_format, opt); \ + dflt = config_dup(get_options_mgr(), opt); \ clear_log_messages(); \ } while (0) @@ -196,7 +196,7 @@ test_options_validate_impl(const char *configuration, if (r) goto done; - r = config_assign(&options_format, opt, cl, 0, &msg); + r = config_assign(get_options_mgr(), opt, cl, 0, &msg); if (phase == PH_ASSIGN) { if (test_options_checkmsgs(configuration, expect_errmsg, expect_log_severity, @@ -304,7 +304,7 @@ test_have_enough_mem_for_dircache(void *arg) r = config_get_lines(configuration, &cl, 1); tt_int_op(r, OP_EQ, 0); - r = config_assign(&options_format, opt, cl, 0, &msg); + r = config_assign(get_options_mgr(), opt, cl, 0, &msg); tt_int_op(r, OP_EQ, 0); /* 300 MB RAM available, DirCache enabled */ @@ -327,7 +327,7 @@ test_have_enough_mem_for_dircache(void *arg) r = config_get_lines(configuration, &cl, 1); tt_int_op(r, OP_EQ, 0); - r = config_assign(&options_format, opt, cl, 0, &msg); + r = config_assign(get_options_mgr(), opt, cl, 0, &msg); tt_int_op(r, OP_EQ, 0); /* 300 MB RAM available, DirCache enabled, Bridge */ @@ -350,7 +350,7 @@ test_have_enough_mem_for_dircache(void *arg) r = config_get_lines(configuration, &cl, 1); tt_int_op(r, OP_EQ, 0); - r = config_assign(&options_format, opt, cl, 0, &msg); + r = config_assign(get_options_mgr(), opt, cl, 0, &msg); tt_int_op(r, OP_EQ, 0); /* 200 MB RAM available, DirCache disabled */ @@ -438,7 +438,7 @@ get_options_test_data(const char *conf) rv = config_get_lines(conf, &cl, 1); tt_int_op(rv, OP_EQ, 0); - rv = config_assign(&options_format, result->opt, cl, 0, &msg); + rv = config_assign(get_options_mgr(), result->opt, cl, 0, &msg); if (msg) { /* Display the parse error message by comparing it with an empty string */ tt_str_op(msg, OP_EQ, ""); @@ -449,7 +449,7 @@ get_options_test_data(const char *conf) result->opt->TokenBucketRefillInterval = 1; rv = config_get_lines(TEST_OPTIONS_OLD_VALUES, &cl, 1); tt_int_op(rv, OP_EQ, 0); - rv = config_assign(&options_format, result->def_opt, cl, 0, &msg); + rv = config_assign(get_options_mgr(), result->def_opt, cl, 0, &msg); if (msg) { /* Display the parse error message by comparing it with an empty string */ tt_str_op(msg, OP_EQ, ""); |