/* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** * @file conftypes.h * @brief Types used to specify configurable options. * * This header defines the types that different modules will use in order to * declare their configuration and state variables, and tell the configuration * management code about those variables. From the individual module's point * of view, its configuration and state are simply data structures. * * For defining new variable types, see var_type_def_st.h. * * For the code that manipulates variables defined via this module, see * lib/confmgt/, especially typedvar.h and (later) structvar.h. The * configuration manager is responsible for encoding, decoding, and * maintaining the configuration structures used by the various modules. * * STATUS NOTE: This is a work in process refactoring. It is not yet possible * for modules to define their own variables, and much of the configuration * management code is still in src/app/config/. **/ #ifndef TOR_SRC_LIB_CONF_CONFTYPES_H #define TOR_SRC_LIB_CONF_CONFTYPES_H #include "lib/cc/torint.h" #ifdef TOR_UNIT_TESTS #include "lib/conf/conftesting.h" #endif #include /** Enumeration of types which option values can take */ typedef enum config_type_t { CONFIG_TYPE_STRING = 0, /**< An arbitrary string. */ CONFIG_TYPE_FILENAME, /**< A filename: some prefixes get expanded. */ CONFIG_TYPE_POSINT, /**< A non-negative integer less than MAX_INT */ CONFIG_TYPE_INT, /**< Any integer. */ CONFIG_TYPE_UINT64, /**< A value in range 0..UINT64_MAX */ CONFIG_TYPE_INTERVAL, /**< A number of seconds, with optional units*/ CONFIG_TYPE_MSEC_INTERVAL,/**< A number of milliseconds, with optional * units */ CONFIG_TYPE_MEMUNIT, /**< A number of bytes, with optional units*/ CONFIG_TYPE_DOUBLE, /**< A floating-point value */ CONFIG_TYPE_BOOL, /**< A boolean value, expressed as 0 or 1. */ CONFIG_TYPE_AUTOBOOL, /**< A boolean+auto value, expressed 0 for false, * 1 for true, and -1 for auto */ CONFIG_TYPE_ISOTIME, /**< An ISO-formatted time relative to UTC. */ CONFIG_TYPE_CSV, /**< A list of strings, separated by commas and * optional whitespace. */ CONFIG_TYPE_CSV_INTERVAL, /**< A list of strings, separated by commas and * optional whitespace, representing intervals in * seconds, with optional units. We allow * multiple values here for legacy reasons, but * ignore every value after the first. */ CONFIG_TYPE_LINELIST, /**< Uninterpreted config lines */ CONFIG_TYPE_LINELIST_S, /**< Uninterpreted, context-sensitive config lines, * mixed with other keywords. */ CONFIG_TYPE_LINELIST_V, /**< Catch-all "virtual" option to summarize * context-sensitive config lines when fetching. */ /** Ignored (obsolete) option. Uses no storage. * * Reported as "obsolete" when its type is queried. */ CONFIG_TYPE_OBSOLETE, /** Ignored option. Uses no storage. * * Reported as "ignored" when its type is queried. For use with options used * by disabled modules. **/ CONFIG_TYPE_IGNORE, /** * Extended type: definition appears in the type_def pointer * of the corresponding struct_member_t. * * For some types, we cannot define them as particular values of this * enumeration, since those types are abstractions defined at a higher level * than this module. (For example, parsing a routerset_t is higher-level * than this module.) To handle this, we use CONFIG_TYPE_EXTENDED for those * types, and give a definition for them in the struct_member_t.type_def. **/ CONFIG_TYPE_EXTENDED, } config_type_t; /* Forward delcaration for var_type_def_t, for extended types. */ struct var_type_def_t; /** Structure to specify a named, typed member within a structure. */ typedef struct struct_member_t { /** Name of the field. */ const char *name; /** * Type of the field, according to the config_type_t enumeration. * * For any type not otherwise listed in config_type_t, this field's value * should be CONFIG_TYPE_EXTENDED. When it is, the type_def pointer * must be set. **/ /* * NOTE: In future refactoring, we might remove this field entirely, along * with its corresponding enumeration. In that case, we will require that * type_def be set in all cases. If we do, we will also need a new mechanism * to enforce consistency between configuration variable types and their * corresponding structures, since our current design in * lib/conf/conftesting.h won't work any more. */ config_type_t type; /** * Pointer to a type definition for the type of this field. Overrides * type if it is not NULL. Must be set when type is * CONFIG_TYPE_EXTENDED. **/ const struct var_type_def_t *type_def; /** * Offset of this field within the structure. Compute this with * offsetof(structure, fieldname). **/ ptrdiff_t offset; } struct_member_t; /** * Structure to describe the location and preferred value of a "magic number" * field within a structure. * * These 'magic numbers' are 32-bit values used to tag objects to make sure * that they have the correct type. * * If all fields in this structure are zero or 0, the magic-number check is * not performed. */ typedef struct struct_magic_decl_t { /** The name of the structure */ const char *typename; /** A value used to recognize instances of this structure. */ uint32_t magic_val; /** The location within the structure at which we expect to find * magic_val. */ ptrdiff_t magic_offset; } struct_magic_decl_t; /** * Flag to indicate that an option or type is "undumpable". An * undumpable option is never saved to disk. * * For historical reasons its name is usually is prefixed with __. **/ #define CFLG_NODUMP (1u<<0) /** * Flag to indicate that an option or type is "unlisted". * * We don't tell the controller about unlisted options when it asks for a * list of them. **/ #define CFLG_NOLIST (1u<<1) /** * Flag to indicate that an option or type is "unsettable". * * An unsettable option can never be set directly by name. **/ #define CFLG_NOSET (1u<<2) /** * Flag to indicate that an option or type does not need to be copied when * copying the structure that contains it. * * (Usually, if an option does not need to be copied, then either it contains * no data, or the data that it does contain is completely contained within * another option.) **/ #define CFLG_NOCOPY (1u<<3) /** * Flag to indicate that an option or type does not need to be compared * when telling the controller about the differences between two * configurations. * * (Usually, if an option does not need to be compared, then either it * contains no data, or the data that it does contain is completely contained * within another option.) **/ #define CFLG_NOCMP (1u<<4) /** * Flag to indicate that an option or type should not be replaced when setting * it. * * For most options, setting them replaces their old value. For some options, * however, setting them appends to their old value. */ #define CFLG_NOREPLACE (1u<<5) /** * Flag to indicate that an option or type cannot be changed while Tor is * running. **/ #define CFLG_IMMUTABLE (1u<<6) /** * Flag to indicate that we should warn that an option or type is obsolete * whenever the user tries to use it. **/ #define CFLG_WARN_OBSOLETE (1u<<7) /** * Flag to indicate that we should warn that an option applies only to * a disabled module, whenever the user tries to use it. **/ #define CFLG_WARN_DISABLED (1u<<8) /** * A group of flags that should be set on all obsolete options and types. **/ #define CFLG_GROUP_OBSOLETE \ (CFLG_NOCOPY|CFLG_NOCMP|CFLG_NODUMP|CFLG_NOSET|CFLG_NOLIST|\ CFLG_WARN_OBSOLETE) /** * A group of fflags that should be set on all disabled options. **/ #define CFLG_GROUP_DISABLED \ (CFLG_NOCOPY|CFLG_NOCMP|CFLG_NODUMP|CFLG_NOSET|CFLG_NOLIST|\ CFLG_WARN_DISABLED) /** A variable allowed in the configuration file or on the command line. */ typedef struct config_var_t { struct_member_t member; /** A struct member corresponding to this * variable. */ const char *initvalue; /**< String (or null) describing initial value. */ uint32_t flags; /**< One or more flags describing special handling for this * variable */ #ifdef TOR_UNIT_TESTS /** Used for compiler-magic to typecheck the corresponding field in the * corresponding struct. Only used in unit test mode, at compile-time. */ confparse_dummy_values_t var_ptr_dummy; #endif } config_var_t; /** * An abbreviation or alias for a configuration option. **/ typedef struct config_abbrev_t { /** The option name as abbreviated. Not case-sensitive. */ const char *abbreviated; /** The full name of the option. Not case-sensitive. */ const char *full; /** True if this abbreviation should only be allowed on the command line. */ int commandline_only; /** True if we should warn whenever this abbreviation is used. */ int warn; } config_abbrev_t; /** * A note that a configuration option is deprecated, with an explanation why. */ typedef struct config_deprecation_t { /** The option that is deprecated. */ const char *name; /** A user-facing string explaining why the option is deprecated. */ const char *why_deprecated; } config_deprecation_t; #ifndef COCCI /** * Handy macro for declaring "In the config file or on the command line, you * can abbreviate toks as tok". Used inside an array of * config_abbrev_t. * * For example, to declare "NumCpu" as an abbreviation for "NumCPUs", * you can say PLURAL(NumCpu). **/ #define PLURAL(tok) { (#tok), (#tok "s"), 0, 0 } #endif /* !defined(COCCI) */ /** * Validation function: verify whether a configuation object is well-formed * and consistent. * * On success, return 0. On failure, set msg_out to a newly allocated * string containing an error message, and return -1. */ typedef int (*validate_fn_t)(const void *value, char **msg_out); /** * Validation function: verify whether a configuration object (`value`) is an * allowable value given the previous configuration value (`old_value`). * * On success, return 0. On failure, set msg_out to a newly allocated * string containing an error message, and return -1. */ typedef int (*check_transition_fn_t)(const void *old_value, const void *value, char **msg_out); /** * Validation function: normalize members of `value`, and compute derived * members. * * This function is called before any other validation of `value`, and must * not assume that validate_fn or check_transition_fn has passed. * * On success, return 0. On failure, set msg_out to a newly allocated * string containing an error message, and return -1. */ typedef int (*pre_normalize_fn_t)(void *value, char **msg_out); /** * Validation function: normalize members of `value`, and compute derived * members. * * This function is called after validation of `value`, and may * assume that validate_fn or check_transition_fn has passed. * * On success, return 0. On failure, set msg_out to a newly allocated * string containing an error message, and return -1. */ typedef int (*post_normalize_fn_t)(void *value, char **msg_out); /** * Legacy function to validate whether a given configuration is * well-formed and consistent. * * The configuration to validate is passed as newval. The previous * configuration, if any, is provided in oldval. * * This API is deprecated, since it mixes the responsibilities of * pre_normalize_fn_t, post_normalize_fn_t, validate_fn_t, and * check_transition_fn_t. No new instances of this function type should * be written. * * On success, return 0. On failure, set *msg_out to a newly allocated * error message, and return -1. */ typedef int (*legacy_validate_fn_t)(const void *oldval, void *newval, char **msg_out); struct config_mgr_t; /** * Callback to clear all non-managed fields of a configuration object. * * obj 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 * configuration or storage format. */ typedef struct config_format_t { size_t size; /**< Size of the struct that everything gets parsed into. */ struct_magic_decl_t magic; /**< Magic number info for this struct. */ const config_abbrev_t *abbrevs; /**< List of abbreviations that we expand * when parsing this format. */ const config_deprecation_t *deprecations; /** List of deprecated options */ const config_var_t *vars; /**< List of variables we recognize, their default * values, and where we stick them in the * structure. */ /** Early-stage normalization callback. Invoked by config_validate(). */ pre_normalize_fn_t pre_normalize_fn; /** Configuration validation function. Invoked by config_validate(). */ validate_fn_t validate_fn; /** Legacy validation function. Invoked by config_validate(). */ legacy_validate_fn_t legacy_validate_fn; /** Transition checking function. Invoked by config_validate(). */ check_transition_fn_t check_transition_fn; /** Late-stage normalization callback. Invoked by config_validate(). */ post_normalize_fn_t post_normalize_fn; 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; /** * If true, this format describes a top-level configuration, with * a suite containing multiple sub-configuration objects. */ bool has_config_suite; /** The position of a config_suite_t pointer within the toplevel object. * Ignored unless have_config_suite is true. */ ptrdiff_t config_suite_offset; } config_format_t; #endif /* !defined(TOR_SRC_LIB_CONF_CONFTYPES_H) */