Loading changes/ticket31240 0 → 100644 +5 −0 Original line number Diff line number Diff line o Minor features (configuration): - The configuration code has been extended to allow splitting configuration data across multiple objects. Previously, all configuration data needed to be kept in a single object, which tended to become bloated. Closes ticket 31240. src/app/config/config.c +75 −82 Original line number Diff line number Diff line Loading @@ -843,15 +843,15 @@ 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 cleanup_protocol_warning_severity_level(void); static void set_protocol_warning_severity_level(int warning_severity); static void options_clear_cb(const config_mgr_t *mgr, void *opts); /** Magic value for or_options_t. */ #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", Loading @@ -862,8 +862,9 @@ STATIC const config_format_t options_format = { option_deprecation_notes_, option_vars_, options_validate_cb, options_free_cb, NULL options_clear_cb, NULL, offsetof(or_options_t, subconfigs_), }; /* Loading Loading @@ -895,6 +896,20 @@ 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); config_mgr_freeze(options_mgr); } return options_mgr; } /** Return the contents of our frontpage string, or NULL if not configured. */ MOCK_IMPL(const char*, get_dirportfrontpage, (void)) Loading Loading @@ -951,9 +966,6 @@ get_options_defaults(void) int set_options(or_options_t *new_val, char **msg) { int i; smartlist_t *elements; config_line_t *line; or_options_t *old_options = global_options; global_options = new_val; /* Note that we pass the *old* options below, for comparison. It Loading @@ -975,35 +987,16 @@ set_options(or_options_t *new_val, char **msg) /* Issues a CONF_CHANGED event to notify controller of the change. If Tor is * just starting up then the old_options will be undefined. */ 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 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, var_name, 1); if (line) { config_line_t *next; for (; line; line = next) { next = line->next; smartlist_t *elements = smartlist_new(); config_line_t *changes = config_get_changes(get_options_mgr(), old_options, new_val); for (config_line_t *line = changes; line; line = line->next) { smartlist_add(elements, line->key); smartlist_add(elements, line->value); tor_free(line); } } else { smartlist_add_strdup(elements, options_format.vars[i].member.name); smartlist_add(elements, NULL); } } } control_event_conf_changed(elements); SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp)); smartlist_free(elements); config_free_lines(changes); } if (old_options != global_options) { Loading @@ -1019,11 +1012,11 @@ set_options(or_options_t *new_val, char **msg) /** Release additional memory allocated in options */ STATIC void or_options_free_(or_options_t *options) static void options_clear_cb(const config_mgr_t *mgr, void *opts) { if (!options) return; (void)mgr; or_options_t *options = opts; routerset_free(options->ExcludeExitNodesUnion_); if (options->NodeFamilySets) { Loading @@ -1046,7 +1039,14 @@ 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); } /** Release all memory allocated in options */ STATIC void or_options_free_(or_options_t *options) { config_free(get_options_mgr(), options); } /** Release all memory and resources held by global configuration structures. Loading Loading @@ -1080,6 +1080,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 Loading Loading @@ -2547,7 +2549,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; Loading @@ -2573,8 +2575,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); return (var != NULL); return config_find_option_name(get_options_mgr(), key) != NULL; } /** Return the canonical name of a configuration option, or NULL Loading @@ -2582,8 +2583,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); return var ? var->member.name : NULL; return config_find_option_name(get_options_mgr(), key); } /** Return a canonical list of the options assigned for key. Loading @@ -2591,7 +2591,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 Loading @@ -2607,9 +2607,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; Loading Loading @@ -2664,25 +2664,25 @@ print_usage(void) static void list_torrc_options(void) { int i; for (i = 0; option_vars_[i].member.name; ++i) { const config_var_t *var = &option_vars_[i]; smartlist_t *vars = config_mgr_list_vars(get_options_mgr()); SMARTLIST_FOREACH_BEGIN(vars, const config_var_t *, var) { if (! config_var_is_settable(var)) { /* This variable cannot be set, or cannot be set by this name. */ continue; } printf("%s\n", var->member.name); } } SMARTLIST_FOREACH_END(var); smartlist_free(vars); } /** Print all deprecated but non-obsolete torrc options. */ static void list_deprecated_options(void) { const config_deprecation_t *d; for (d = option_deprecation_notes_; d->name; ++d) { printf("%s\n", d->name); } smartlist_t *deps = config_mgr_list_deprecated_vars(get_options_mgr()); SMARTLIST_FOREACH(deps, const char *, name, printf("%s\n", name)); smartlist_free(deps); } /** Print all compile-time modules and their enabled/disabled status. */ Loading Loading @@ -2992,7 +2992,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. Loading @@ -3000,10 +3000,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); Loading Loading @@ -3040,7 +3040,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 Loading Loading @@ -3172,13 +3172,6 @@ options_validate_cb(void *old_options, void *options, void *default_options, return rv; } /** Callback to free an or_options_t */ static void options_free_cb(void *options) { or_options_free_(options); } #define REJECT(arg) \ STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END #if defined(__GNUC__) && __GNUC__ <= 3 Loading Loading @@ -4435,7 +4428,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!"); \ Loading Loading @@ -5411,8 +5404,7 @@ options_init_from_string(const char *cf_defaults, const char *cf, oldoptions = global_options; /* get_options unfortunately asserts if this is the first time we run*/ newoptions = tor_malloc_zero(sizeof(or_options_t)); newoptions->magic_ = OR_OPTIONS_MAGIC; newoptions = options_new(); options_init(newoptions); newoptions->command = command; newoptions->command_arg = command_arg ? tor_strdup(command_arg) : NULL; Loading @@ -5431,7 +5423,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) { Loading @@ -5439,15 +5431,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; Loading Loading @@ -8133,9 +8125,8 @@ getinfo_helper_config(control_connection_t *conn, (void) errmsg; if (!strcmp(question, "config/names")) { smartlist_t *sl = smartlist_new(); int i; for (i = 0; option_vars_[i].member.name; ++i) { const config_var_t *var = &option_vars_[i]; smartlist_t *vars = config_mgr_list_vars(get_options_mgr()); SMARTLIST_FOREACH_BEGIN(vars, const config_var_t *, var) { /* don't tell controller about invisible options */ if (config_var_is_invisible(var)) continue; Loading @@ -8143,26 +8134,27 @@ getinfo_helper_config(control_connection_t *conn, if (!type) continue; smartlist_add_asprintf(sl, "%s %s\n",var->member.name,type); } } SMARTLIST_FOREACH_END(var); *answer = smartlist_join_strings(sl, "", 0, NULL); SMARTLIST_FOREACH(sl, char *, c, tor_free(c)); smartlist_free(sl); smartlist_free(vars); } else if (!strcmp(question, "config/defaults")) { smartlist_t *sl = smartlist_new(); int dirauth_lines_seen = 0, fallback_lines_seen = 0; for (int i = 0; option_vars_[i].member.name; ++i) { const config_var_t *var = &option_vars_[i]; smartlist_t *vars = config_mgr_list_vars(get_options_mgr()); SMARTLIST_FOREACH_BEGIN(vars, const config_var_t *, var) { if (var->initvalue != NULL) { if (strcmp(option_vars_[i].member.name, "DirAuthority") == 0) { if (strcmp(var->member.name, "DirAuthority") == 0) { /* * Count dirauth lines we have a default for; we'll use the * count later to decide whether to add the defaults manually */ ++dirauth_lines_seen; } if (strcmp(option_vars_[i].member.name, "FallbackDir") == 0) { if (strcmp(var->member.name, "FallbackDir") == 0) { /* * Similarly count fallback lines, so that we can decided later * Similarly count fallback lines, so that we can decide later * to add the defaults manually. */ ++fallback_lines_seen; Loading @@ -8171,7 +8163,8 @@ getinfo_helper_config(control_connection_t *conn, smartlist_add_asprintf(sl, "%s %s\n",var->member.name,val); tor_free(val); } } } SMARTLIST_FOREACH_END(var); smartlist_free(vars); if (dirauth_lines_seen == 0) { /* Loading src/app/config/config.h +2 −3 Original line number Diff line number Diff line Loading @@ -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) \ Loading src/app/config/confparse.c +589 −157 File changed.Preview size limit exceeded, changes collapsed. Show changes src/app/config/confparse.h +60 −26 Original line number Diff line number Diff line Loading @@ -39,8 +39,19 @@ typedef struct config_deprecation_t { * of arguments. */ typedef int (*validate_fn_t)(void*,void*,void*,int,char**); /** Callback to free a configuration object. */ typedef void (*free_cfg_fn_t)(void*); struct config_mgr_t; /** * Callback to clear all non-managed fields of a configuration object. * * <b>obj</b> is the configuration object whose non-managed fields should be * cleared. * * (Regular fields get cleared by config_reset(), but you might have fields * in the object that do not correspond to configuration variables. If those * fields need to be cleared or freed, this is where to do it.) */ typedef void (*clear_cfg_fn_t)(const struct config_mgr_t *mgr, void *obj); /** Information on the keys, value types, key-to-struct-member mappings, * variable descriptions, validation functions, and abbreviations for a Loading @@ -55,51 +66,70 @@ typedef struct config_format_t { * values, and where we stick them in the * structure. */ validate_fn_t validate_fn; /**< Function to validate config. */ free_cfg_fn_t free_fn; /**< Function to free the configuration. */ clear_cfg_fn_t clear_fn; /**< Function to clear the configuration. */ /** If present, extra denotes a LINELIST variable for unrecognized * lines. Otherwise, unrecognized lines are an error. */ const struct_member_t *extra; /** The position of a config_suite_t pointer within the toplevel object, * or -1 if there is no such pointer. */ int config_suite_offset; } config_format_t; /** Macro: assert that <b>cfg</b> has the right magic field for format * <b>fmt</b>. */ #define CONFIG_CHECK(fmt, cfg) STMT_BEGIN \ tor_assert(fmt); \ struct_check_magic((cfg), &fmt->magic); \ STMT_END /** * 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); int config_mgr_add_format(config_mgr_t *mgr, const config_format_t *fmt); void config_mgr_freeze(config_mgr_t *mgr); #define config_mgr_free(mgr) \ FREE_AND_NULL(config_mgr_t, config_mgr_free_, (mgr)) struct smartlist_t *config_mgr_list_vars(const config_mgr_t *mgr); struct smartlist_t *config_mgr_list_deprecated_vars(const config_mgr_t *mgr); /** A collection of managed configuration objects. */ typedef struct config_suite_t config_suite_t; #define CAL_USE_DEFAULTS (1u<<0) #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, struct config_line_t *config_get_changes(const config_mgr_t *mgr, const void *options1, const void *options2); 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 char *config_find_option_name(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); Loading @@ -119,8 +149,12 @@ bool config_var_is_dumpable(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); STATIC void *config_mgr_get_obj_mutable(const config_mgr_t *mgr, void *toplevel, int idx); STATIC const void *config_mgr_get_obj(const config_mgr_t *mgr, const void *toplevel, int idx); #endif #endif /* !defined(TOR_CONFPARSE_H) */ Loading
changes/ticket31240 0 → 100644 +5 −0 Original line number Diff line number Diff line o Minor features (configuration): - The configuration code has been extended to allow splitting configuration data across multiple objects. Previously, all configuration data needed to be kept in a single object, which tended to become bloated. Closes ticket 31240.
src/app/config/config.c +75 −82 Original line number Diff line number Diff line Loading @@ -843,15 +843,15 @@ 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 cleanup_protocol_warning_severity_level(void); static void set_protocol_warning_severity_level(int warning_severity); static void options_clear_cb(const config_mgr_t *mgr, void *opts); /** Magic value for or_options_t. */ #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", Loading @@ -862,8 +862,9 @@ STATIC const config_format_t options_format = { option_deprecation_notes_, option_vars_, options_validate_cb, options_free_cb, NULL options_clear_cb, NULL, offsetof(or_options_t, subconfigs_), }; /* Loading Loading @@ -895,6 +896,20 @@ 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); config_mgr_freeze(options_mgr); } return options_mgr; } /** Return the contents of our frontpage string, or NULL if not configured. */ MOCK_IMPL(const char*, get_dirportfrontpage, (void)) Loading Loading @@ -951,9 +966,6 @@ get_options_defaults(void) int set_options(or_options_t *new_val, char **msg) { int i; smartlist_t *elements; config_line_t *line; or_options_t *old_options = global_options; global_options = new_val; /* Note that we pass the *old* options below, for comparison. It Loading @@ -975,35 +987,16 @@ set_options(or_options_t *new_val, char **msg) /* Issues a CONF_CHANGED event to notify controller of the change. If Tor is * just starting up then the old_options will be undefined. */ 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 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, var_name, 1); if (line) { config_line_t *next; for (; line; line = next) { next = line->next; smartlist_t *elements = smartlist_new(); config_line_t *changes = config_get_changes(get_options_mgr(), old_options, new_val); for (config_line_t *line = changes; line; line = line->next) { smartlist_add(elements, line->key); smartlist_add(elements, line->value); tor_free(line); } } else { smartlist_add_strdup(elements, options_format.vars[i].member.name); smartlist_add(elements, NULL); } } } control_event_conf_changed(elements); SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp)); smartlist_free(elements); config_free_lines(changes); } if (old_options != global_options) { Loading @@ -1019,11 +1012,11 @@ set_options(or_options_t *new_val, char **msg) /** Release additional memory allocated in options */ STATIC void or_options_free_(or_options_t *options) static void options_clear_cb(const config_mgr_t *mgr, void *opts) { if (!options) return; (void)mgr; or_options_t *options = opts; routerset_free(options->ExcludeExitNodesUnion_); if (options->NodeFamilySets) { Loading @@ -1046,7 +1039,14 @@ 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); } /** Release all memory allocated in options */ STATIC void or_options_free_(or_options_t *options) { config_free(get_options_mgr(), options); } /** Release all memory and resources held by global configuration structures. Loading Loading @@ -1080,6 +1080,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 Loading Loading @@ -2547,7 +2549,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; Loading @@ -2573,8 +2575,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); return (var != NULL); return config_find_option_name(get_options_mgr(), key) != NULL; } /** Return the canonical name of a configuration option, or NULL Loading @@ -2582,8 +2583,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); return var ? var->member.name : NULL; return config_find_option_name(get_options_mgr(), key); } /** Return a canonical list of the options assigned for key. Loading @@ -2591,7 +2591,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 Loading @@ -2607,9 +2607,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; Loading Loading @@ -2664,25 +2664,25 @@ print_usage(void) static void list_torrc_options(void) { int i; for (i = 0; option_vars_[i].member.name; ++i) { const config_var_t *var = &option_vars_[i]; smartlist_t *vars = config_mgr_list_vars(get_options_mgr()); SMARTLIST_FOREACH_BEGIN(vars, const config_var_t *, var) { if (! config_var_is_settable(var)) { /* This variable cannot be set, or cannot be set by this name. */ continue; } printf("%s\n", var->member.name); } } SMARTLIST_FOREACH_END(var); smartlist_free(vars); } /** Print all deprecated but non-obsolete torrc options. */ static void list_deprecated_options(void) { const config_deprecation_t *d; for (d = option_deprecation_notes_; d->name; ++d) { printf("%s\n", d->name); } smartlist_t *deps = config_mgr_list_deprecated_vars(get_options_mgr()); SMARTLIST_FOREACH(deps, const char *, name, printf("%s\n", name)); smartlist_free(deps); } /** Print all compile-time modules and their enabled/disabled status. */ Loading Loading @@ -2992,7 +2992,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. Loading @@ -3000,10 +3000,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); Loading Loading @@ -3040,7 +3040,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 Loading Loading @@ -3172,13 +3172,6 @@ options_validate_cb(void *old_options, void *options, void *default_options, return rv; } /** Callback to free an or_options_t */ static void options_free_cb(void *options) { or_options_free_(options); } #define REJECT(arg) \ STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END #if defined(__GNUC__) && __GNUC__ <= 3 Loading Loading @@ -4435,7 +4428,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!"); \ Loading Loading @@ -5411,8 +5404,7 @@ options_init_from_string(const char *cf_defaults, const char *cf, oldoptions = global_options; /* get_options unfortunately asserts if this is the first time we run*/ newoptions = tor_malloc_zero(sizeof(or_options_t)); newoptions->magic_ = OR_OPTIONS_MAGIC; newoptions = options_new(); options_init(newoptions); newoptions->command = command; newoptions->command_arg = command_arg ? tor_strdup(command_arg) : NULL; Loading @@ -5431,7 +5423,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) { Loading @@ -5439,15 +5431,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; Loading Loading @@ -8133,9 +8125,8 @@ getinfo_helper_config(control_connection_t *conn, (void) errmsg; if (!strcmp(question, "config/names")) { smartlist_t *sl = smartlist_new(); int i; for (i = 0; option_vars_[i].member.name; ++i) { const config_var_t *var = &option_vars_[i]; smartlist_t *vars = config_mgr_list_vars(get_options_mgr()); SMARTLIST_FOREACH_BEGIN(vars, const config_var_t *, var) { /* don't tell controller about invisible options */ if (config_var_is_invisible(var)) continue; Loading @@ -8143,26 +8134,27 @@ getinfo_helper_config(control_connection_t *conn, if (!type) continue; smartlist_add_asprintf(sl, "%s %s\n",var->member.name,type); } } SMARTLIST_FOREACH_END(var); *answer = smartlist_join_strings(sl, "", 0, NULL); SMARTLIST_FOREACH(sl, char *, c, tor_free(c)); smartlist_free(sl); smartlist_free(vars); } else if (!strcmp(question, "config/defaults")) { smartlist_t *sl = smartlist_new(); int dirauth_lines_seen = 0, fallback_lines_seen = 0; for (int i = 0; option_vars_[i].member.name; ++i) { const config_var_t *var = &option_vars_[i]; smartlist_t *vars = config_mgr_list_vars(get_options_mgr()); SMARTLIST_FOREACH_BEGIN(vars, const config_var_t *, var) { if (var->initvalue != NULL) { if (strcmp(option_vars_[i].member.name, "DirAuthority") == 0) { if (strcmp(var->member.name, "DirAuthority") == 0) { /* * Count dirauth lines we have a default for; we'll use the * count later to decide whether to add the defaults manually */ ++dirauth_lines_seen; } if (strcmp(option_vars_[i].member.name, "FallbackDir") == 0) { if (strcmp(var->member.name, "FallbackDir") == 0) { /* * Similarly count fallback lines, so that we can decided later * Similarly count fallback lines, so that we can decide later * to add the defaults manually. */ ++fallback_lines_seen; Loading @@ -8171,7 +8163,8 @@ getinfo_helper_config(control_connection_t *conn, smartlist_add_asprintf(sl, "%s %s\n",var->member.name,val); tor_free(val); } } } SMARTLIST_FOREACH_END(var); smartlist_free(vars); if (dirauth_lines_seen == 0) { /* Loading
src/app/config/config.h +2 −3 Original line number Diff line number Diff line Loading @@ -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) \ Loading
src/app/config/confparse.c +589 −157 File changed.Preview size limit exceeded, changes collapsed. Show changes
src/app/config/confparse.h +60 −26 Original line number Diff line number Diff line Loading @@ -39,8 +39,19 @@ typedef struct config_deprecation_t { * of arguments. */ typedef int (*validate_fn_t)(void*,void*,void*,int,char**); /** Callback to free a configuration object. */ typedef void (*free_cfg_fn_t)(void*); struct config_mgr_t; /** * Callback to clear all non-managed fields of a configuration object. * * <b>obj</b> is the configuration object whose non-managed fields should be * cleared. * * (Regular fields get cleared by config_reset(), but you might have fields * in the object that do not correspond to configuration variables. If those * fields need to be cleared or freed, this is where to do it.) */ typedef void (*clear_cfg_fn_t)(const struct config_mgr_t *mgr, void *obj); /** Information on the keys, value types, key-to-struct-member mappings, * variable descriptions, validation functions, and abbreviations for a Loading @@ -55,51 +66,70 @@ typedef struct config_format_t { * values, and where we stick them in the * structure. */ validate_fn_t validate_fn; /**< Function to validate config. */ free_cfg_fn_t free_fn; /**< Function to free the configuration. */ clear_cfg_fn_t clear_fn; /**< Function to clear the configuration. */ /** If present, extra denotes a LINELIST variable for unrecognized * lines. Otherwise, unrecognized lines are an error. */ const struct_member_t *extra; /** The position of a config_suite_t pointer within the toplevel object, * or -1 if there is no such pointer. */ int config_suite_offset; } config_format_t; /** Macro: assert that <b>cfg</b> has the right magic field for format * <b>fmt</b>. */ #define CONFIG_CHECK(fmt, cfg) STMT_BEGIN \ tor_assert(fmt); \ struct_check_magic((cfg), &fmt->magic); \ STMT_END /** * 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); int config_mgr_add_format(config_mgr_t *mgr, const config_format_t *fmt); void config_mgr_freeze(config_mgr_t *mgr); #define config_mgr_free(mgr) \ FREE_AND_NULL(config_mgr_t, config_mgr_free_, (mgr)) struct smartlist_t *config_mgr_list_vars(const config_mgr_t *mgr); struct smartlist_t *config_mgr_list_deprecated_vars(const config_mgr_t *mgr); /** A collection of managed configuration objects. */ typedef struct config_suite_t config_suite_t; #define CAL_USE_DEFAULTS (1u<<0) #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, struct config_line_t *config_get_changes(const config_mgr_t *mgr, const void *options1, const void *options2); 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 char *config_find_option_name(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); Loading @@ -119,8 +149,12 @@ bool config_var_is_dumpable(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); STATIC void *config_mgr_get_obj_mutable(const config_mgr_t *mgr, void *toplevel, int idx); STATIC const void *config_mgr_get_obj(const config_mgr_t *mgr, const void *toplevel, int idx); #endif #endif /* !defined(TOR_CONFPARSE_H) */