tor-commits
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
September 2019
- 21 participants
- 2044 discussions

[translation/abouttor-homepage] https://gitweb.torproject.org/translation.git/commit/?h=abouttor-homepage
by translation@torproject.org 04 Sep '19
by translation@torproject.org 04 Sep '19
04 Sep '19
commit ccf4c4bd93ab48a8a686b13869108069f55c8b1f
Author: Translation commit bot <translation(a)torproject.org>
Date: Wed Sep 4 15:15:07 2019 +0000
https://gitweb.torproject.org/translation.git/commit/?h=abouttor-homepage
---
nl/aboutTor.dtd | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nl/aboutTor.dtd b/nl/aboutTor.dtd
index aba1d4600..b4ac52c46 100644
--- a/nl/aboutTor.dtd
+++ b/nl/aboutTor.dtd
@@ -22,7 +22,7 @@
<!ENTITY aboutTor.torbrowser_user_manual.accesskey "h">
<!ENTITY aboutTor.torbrowser_user_manual.label "Tor Browser-handleiding">
-<!ENTITY aboutTor.tor_mission.label "Het Tor Project is een organisatie zonder winstoogmerk (volgens sectie 501(c)(3) van het Amerikaanse belastingreglement) die rechten en vrijheden van de mens bevordert door het maken en toepassen van vrije, open-broncode anonimiteits- en privacytechnologieën, door de onbeperkte beschikbaarheid en het gebruik van zulke technologieën te ondersteunen en door zich in te zetten om het begrip voor die technologieën, zowel in de wetenschap als bij het algemeen publiek, te bevorderen.">
+<!ENTITY aboutTor.tor_mission.label "Het Tor Project is een US 501(c)(3)-non-profitorganisatie die de rechten en vrijheden van de mens bevordert door vrije en open source anonimiteits- en privacytechnologie te maken en toe te passen, hun onbeperkte beschikbaarheid en gebruik te steunen, en hun wetenschappelijke en populaire begrip te bevorderen.">
<!ENTITY aboutTor.getInvolved.label "Meedoen »">
<!ENTITY aboutTor.getInvolved.link "https://www.torproject.org/getinvolved/volunteer.html.en">
1
0

[translation/tor_outreach_md] https://gitweb.torproject.org/translation.git/commit/?h=tor_outreach_md
by translation@torproject.org 04 Sep '19
by translation@torproject.org 04 Sep '19
04 Sep '19
commit 53c84b203426542ae64bc6ae81d46312496afe43
Author: Translation commit bot <translation(a)torproject.org>
Date: Wed Sep 4 14:53:26 2019 +0000
https://gitweb.torproject.org/translation.git/commit/?h=tor_outreach_md
---
tor-outreach2019-2020-nl.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tor-outreach2019-2020-nl.md b/tor-outreach2019-2020-nl.md
index bb03f5a92..53b5c34b8 100644
--- a/tor-outreach2019-2020-nl.md
+++ b/tor-outreach2019-2020-nl.md
@@ -154,7 +154,7 @@ Tor for Desktop
torproject.org/download
TOR ON MOBILE
-### Android
+### Android
Tor Browser for Android is available from GooglePlay.
### iOS
1
0

[translation/donatepages-messagespot] https://gitweb.torproject.org/translation.git/commit/?h=donatepages-messagespot
by translation@torproject.org 04 Sep '19
by translation@torproject.org 04 Sep '19
04 Sep '19
commit 8a4d89ae72e88be2333a27c6ad54001c1004422e
Author: Translation commit bot <translation(a)torproject.org>
Date: Wed Sep 4 14:45:37 2019 +0000
https://gitweb.torproject.org/translation.git/commit/?h=donatepages-message…
---
locale/nl/LC_MESSAGES/messages.po | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/locale/nl/LC_MESSAGES/messages.po b/locale/nl/LC_MESSAGES/messages.po
index 102695828..ab3f6941c 100644
--- a/locale/nl/LC_MESSAGES/messages.po
+++ b/locale/nl/LC_MESSAGES/messages.po
@@ -14,11 +14,11 @@
# Ash <ash(a)eduif.nl>, 2019
# erinm, 2019
# Tonnes <tonnes.mb(a)gmail.com>, 2019
-# Meteor OID, 2019
+# Meteor0id, 2019
#
msgid ""
msgstr ""
-"Last-Translator: Meteor OID, 2019\n"
+"Last-Translator: Meteor0id, 2019\n"
"Language-Team: Dutch (https://www.transifex.com/otf/teams/1519/nl/)\n"
"Language: nl\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -734,12 +734,11 @@ msgid ""
msgstr ""
"Het Tor Project is een organisatie zonder winstoogmerk (volgens sectie "
"501(c)(3) van het Amerikaanse belastingreglement) die de rechten en "
-"vrijheden van de mens bevordert door gratis anonimiteits- en "
-"privacytechnologie met een open-broncode te creëren en toe te passen. "
-"Daarnaast steunt het Tor Project de onbeperkte beschikbaarheid en het "
-"gebruik van zulke technologie en zet het zich in om het begrip voor die "
-"technologieën zowel in de wetenschap als bij het algemeen publiek te "
-"bevorderen."
+"vrijheden van de mens bevordert door het maken en toepassen van vrije, open-"
+"broncode anonimiteits- en privacytechnologieën, door de onbeperkte "
+"beschikbaarheid en het gebruik van zulke technologieën te ondersteunen en "
+"door zich in te zetten om het begrip voor die technologieën, zowel in de "
+"wetenschap als bij het algemeen publiek, te bevorderen."
#: tmp/cache_locale/92/92eb639bc328f3dd569fa22b60c4360b6fe38f1a4cd80a14fce862d91bd765cb.php:49
msgid "Subscribe to Our Newsletter"
1
0
commit 34f3fcef408a91275561e86afc3bd1d2da3b0375
Merge: 46a382065 4bcfa286f
Author: David Goulet <dgoulet(a)torproject.org>
Date: Wed Sep 4 10:33:49 2019 -0400
Merge branch 'tor-github/pr/1290'
changes/ticket31240 | 5 +
src/app/config/config.c | 157 +++----
src/app/config/config.h | 5 +-
src/app/config/confparse.c | 746 +++++++++++++++++++++++-------
src/app/config/confparse.h | 86 ++--
src/app/config/or_options_st.h | 9 +
src/app/config/or_state_st.h | 9 +
src/app/config/statefile.c | 43 +-
src/feature/dirauth/shared_random_state.c | 43 +-
src/test/fuzz/fuzzing_common.c | 5 +-
src/test/include.am | 1 +
src/test/test.c | 1 +
src/test/test.h | 1 +
src/test/test_config.c | 92 ++--
src/test/test_confmgr.c | 325 +++++++++++++
src/test/test_confparse.c | 383 ++++++++++-----
src/test/test_dir_handle_get.c | 3 +-
src/test/test_entrynodes.c | 30 +-
src/test/test_helpers.c | 2 +-
src/test/test_hs_service.c | 10 +-
src/test/test_options.c | 14 +-
src/test/test_pt.c | 2 +-
22 files changed, 1483 insertions(+), 489 deletions(-)
1
0
commit 4bcfa286f6b37a98c510459f9cd1ea78f957ea9f
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Wed Sep 4 10:31:45 2019 -0400
changes file for 31240
---
changes/ticket31240 | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/changes/ticket31240 b/changes/ticket31240
new file mode 100644
index 000000000..0fe37ff44
--- /dev/null
+++ b/changes/ticket31240
@@ -0,0 +1,5 @@
+ 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.
1
0

04 Sep '19
commit c683896b7c2700e2b209167c699f8d2413a805b2
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Wed Sep 4 08:42:34 2019 -0400
Update routerset reset test to use new mgr API.
---
src/test/test_confparse.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/test/test_confparse.c b/src/test/test_confparse.c
index cf2e8a80e..bd2b5cdf1 100644
--- a/src/test/test_confparse.c
+++ b/src/test/test_confparse.c
@@ -610,7 +610,7 @@ test_confparse_reset(void *arg)
tt_int_op(tst->interval, OP_EQ, 10);
tt_ptr_op(tst->routerset, OP_NE, NULL);
- config_reset_line(&test_fmt, tst, "routerset", 0);
+ config_reset_line(mgr, tst, "routerset", 0);
tt_ptr_op(tst->routerset, OP_EQ, NULL);
done:
1
0

04 Sep '19
commit e8dc513bd012c9d7e1a5908c72056d5be52e760e
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Jul 19 06:45:54 2019 -0400
Add a config_mgr_t type to wrap config_format_t
Remember that our goal in the present refactoring is to allow each
subsystem to declare its own configuration structure and
variables. To do this, each module will get its own
config_format_t, and so we'll want a different structure that wraps
several config_format_t objects. This is a "config_mgr_t".
---
src/app/config/config.c | 60 ++++++----
src/app/config/config.h | 5 +-
src/app/config/confparse.c | 145 +++++++++++++++--------
src/app/config/confparse.h | 47 +++++---
src/app/config/statefile.c | 33 ++++--
src/feature/dirauth/shared_random_state.c | 27 ++++-
src/test/test_confparse.c | 183 +++++++++++++++++-------------
src/test/test_helpers.c | 2 +-
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 4bc807a6f..76feed000 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 c6feb89fe..44f09e5ee 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 699fc0e3d..9c4c6a277 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 3633c2a80..a6a2450ae 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 d997d3932..a44bcf6fb 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 c2ad3e7cc..a552e621c 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 ec018f0c5..8a921531f 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 b4389f2d1..31a6540ef 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 b39cd4f1e..b6ab97b4a 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, "");
1
0

[tor/master] Start teaching config_mgr_t to handle sub-objects and sub-formats
by dgoulet@torproject.org 04 Sep '19
by dgoulet@torproject.org 04 Sep '19
04 Sep '19
commit 769fe817174d238c2c4a615872d6df9a0379dfc6
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Mon Jul 22 13:53:36 2019 -0400
Start teaching config_mgr_t to handle sub-objects and sub-formats
The eventual design here will be that multiple config_format_t
objects get registered with a single config_mgr_t. That
config_mgr_t manages a "top-level" object, which has a pointer to
the other objects.
I had earlier thought of a different design, where there would be no
top-level object, and config_mgr_t would deal with a container
instead. But this would require a bunch of invasive refactoring
that I don't think we should do just yet.
---
src/app/config/confparse.c | 363 +++++++++++++++++++++++++++++++--------------
1 file changed, 248 insertions(+), 115 deletions(-)
diff --git a/src/app/config/confparse.c b/src/app/config/confparse.c
index 9c4c6a277..0964321ad 100644
--- a/src/app/config/confparse.c
+++ b/src/app/config/confparse.c
@@ -37,8 +37,38 @@
#include "lib/string/printf.h"
#include "lib/string/util_string.h"
+/**
+ * A managed_var_t is an internal wrapper around a config_var_t in
+ * a config_format_t structure. It is used by config_mgr_t to
+ * keep track of which option goes with which structure. */
+typedef struct managed_var_t {
+ /**
+ * A pointer to the config_var_t for this option.
+ */
+ const config_var_t *cvar;
+ /**
+ * The index of the object in which this option is stored. It is
+ * IDX_TOPLEVEL to indicate that the object is the top-level object.
+ **/
+ int object_idx;
+} managed_var_t;
+
static void config_reset(const config_mgr_t *fmt, void *options,
- const config_var_t *var, int use_defaults);
+ const managed_var_t *var, int use_defaults);
+static void config_mgr_register_fmt(config_mgr_t *mgr,
+ const config_format_t *fmt,
+ int object_idx);
+
+/** Release all storage held in a managed_var_t. */
+static void
+managed_var_free_(managed_var_t *mv)
+{
+ if (!mv)
+ return;
+ tor_free(mv);
+}
+#define managed_var_free(mv) \
+ FREE_AND_NULL(managed_var_t, managed_var_free_, (mv))
struct config_mgr_t {
/** The 'top-level' configuration format. This one is used for legacy
@@ -48,8 +78,17 @@ struct config_mgr_t {
* contains. A subsequent commit will add more. XXXX)
*/
const config_format_t *toplevel;
+ /** A smartlist of managed_var_t objects for all configuration formats. */
+ smartlist_t *all_vars;
+ /** A smartlist of config_abbrev_t objects for all abbreviations. These
+ * objects are */
+ smartlist_t *all_abbrevs;
+ /** A smartlist of config_deprecation_t for all configuration formats. */
+ smartlist_t *all_deprecations;
};
+#define IDX_TOPLEVEL (-1)
+
/** Create a new config_mgr_t to manage a set of configuration objects to be
* wrapped under <b>toplevel_fmt</b>. */
config_mgr_t *
@@ -57,15 +96,81 @@ config_mgr_new(const config_format_t *toplevel_fmt)
{
config_mgr_t *mgr = tor_malloc_zero(sizeof(config_mgr_t));
mgr->toplevel = toplevel_fmt;
+ mgr->all_vars = smartlist_new();
+ mgr->all_abbrevs = smartlist_new();
+ mgr->all_deprecations = smartlist_new();
+
+ config_mgr_register_fmt(mgr, toplevel_fmt, IDX_TOPLEVEL);
return mgr;
}
+/** Add a config_format_t to a manager, with a specified (unique) index. */
+static void
+config_mgr_register_fmt(config_mgr_t *mgr,
+ const config_format_t *fmt,
+ int object_idx)
+{
+ int i;
+
+ /* register variables */
+ for (i = 0; fmt->vars[i].member.name; ++i) {
+ managed_var_t *mv = tor_malloc_zero(sizeof(managed_var_t));
+ mv->cvar = &fmt->vars[i];
+ mv->object_idx = object_idx;
+ smartlist_add(mgr->all_vars, mv);
+ }
+
+ /* register abbrevs */
+ if (fmt->abbrevs) {
+ for (i = 0; fmt->abbrevs[i].abbreviated; ++i) {
+ smartlist_add(mgr->all_abbrevs, (void*)&fmt->abbrevs[i]);
+ }
+ }
+
+ /* register deprecations. */
+ if (fmt->deprecations) {
+ const config_deprecation_t *d;
+ for (d = fmt->deprecations; d->name; ++d) {
+ smartlist_add(mgr->all_deprecations, (void*)d);
+ }
+ }
+}
+
+/**
+ * Return a pointer to the configuration object within <b>toplevel</b> whose
+ * index is <b>idx</b>.
+ *
+ * NOTE: XXXX Eventually, there will be multiple objects supported within the
+ * toplevel object. For example, the or_options_t will contain pointers
+ * to configuration objects for other modules. This function gets
+ * the sub-object for a particular modules.
+ */
+static void *
+config_mgr_get_obj_mutable(const config_mgr_t *mgr, void *toplevel, int idx)
+{
+ (void)mgr;
+ tor_assert(idx == IDX_TOPLEVEL); // nothing else is implemented yet XXXX
+ tor_assert(toplevel);
+ return toplevel;
+}
+
+/** As config_mgr_get_obj_mutable(), but return a const pointer. */
+static const void *
+config_mgr_get_obj(const config_mgr_t *mgr, const void *toplevel, int idx)
+{
+ return config_mgr_get_obj_mutable(mgr, (void*)toplevel, idx);
+}
+
/** Release all storage held in <b>mgr</b> */
void
config_mgr_free_(config_mgr_t *mgr)
{
if (!mgr)
return;
+ SMARTLIST_FOREACH(mgr->all_vars, managed_var_t *, mv, managed_var_free(mv));
+ smartlist_free(mgr->all_vars);
+ smartlist_free(mgr->all_abbrevs);
+ smartlist_free(mgr->all_deprecations);
memset(mgr, 0, sizeof(*mgr));
tor_free(mgr);
}
@@ -94,27 +199,23 @@ const char *
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;
- for (i=0; fmt->abbrevs[i].abbreviated; ++i) {
+ SMARTLIST_FOREACH_BEGIN(mgr->all_abbrevs, const config_abbrev_t *, abbrev) {
/* Abbreviations are case insensitive. */
- if (!strcasecmp(option,fmt->abbrevs[i].abbreviated) &&
- (command_line || !fmt->abbrevs[i].commandline_only)) {
- if (warn_obsolete && fmt->abbrevs[i].warn) {
+ if (!strcasecmp(option, abbrev->abbreviated) &&
+ (command_line || !abbrev->commandline_only)) {
+ if (warn_obsolete && abbrev->warn) {
log_warn(LD_CONFIG,
"The configuration option '%s' is deprecated; "
"use '%s' instead.",
- fmt->abbrevs[i].abbreviated,
- fmt->abbrevs[i].full);
+ abbrev->abbreviated,
+ abbrev->full);
}
/* Keep going through the list in case we want to rewrite it more.
* (We could imagine recursing here, but I don't want to get the
* user into an infinite loop if we craft our list wrong.) */
- option = fmt->abbrevs[i].full;
+ option = abbrev->full;
}
- }
+ } SMARTLIST_FOREACH_END(abbrev);
return option;
}
@@ -124,62 +225,89 @@ config_expand_abbrev(const config_mgr_t *mgr, const char *option,
const char *
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))
+ if (BUG(mgr == NULL) || BUG(key == NULL))
return NULL; // LCOV_EXCL_LINE
- if (fmt->deprecations == NULL)
- return NULL;
- const config_deprecation_t *d;
- for (d = fmt->deprecations; d->name; ++d) {
+ SMARTLIST_FOREACH_BEGIN(mgr->all_deprecations, const config_deprecation_t *,
+ d) {
if (!strcasecmp(d->name, key)) {
return d->why_deprecated ? d->why_deprecated : "";
}
- }
+ } SMARTLIST_FOREACH_END(d);
return NULL;
}
-/** If <b>key</b> is a configuration option, return the corresponding const
- * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
- * warn, and return the corresponding const config_var_t. Otherwise return
- * NULL.
+/**
+ * Find the managed_var_t object for a variable whose name is <b>name</b>
+ * according to <b>mgr</b>. Return that object, or NULL if none exists.
+ *
+ * If <b>allow_truncated</b> is true, then accept any variable whose
+ * name begins with <b>name</b>.
+ *
+ * If <b>idx_out</b> is not NULL, set *<b>idx_out</b> to the position of
+ * that variable within mgr->all_vars, or to -1 if the variable is
+ * not found.
*/
-const config_var_t *
-config_find_option(const config_mgr_t *mgr, const char *key)
+static const managed_var_t *
+config_mgr_find_var(const config_mgr_t *mgr,
+ const char *key,
+ bool allow_truncated, int *idx_out)
{
- const config_format_t *fmt = mgr->toplevel;
- int i;
- size_t keylen = strlen(key);
+ const size_t keylen = strlen(key);
+ if (idx_out)
+ *idx_out = -1;
+
if (!keylen)
return NULL; /* if they say "--" on the command line, it's not an option */
+
/* First, check for an exact (case-insensitive) match */
- for (i=0; fmt->vars[i].member.name; ++i) {
- if (!strcasecmp(key, fmt->vars[i].member.name)) {
- return &fmt->vars[i];
+ SMARTLIST_FOREACH_BEGIN(mgr->all_vars, const managed_var_t *, mv) {
+ if (!strcasecmp(mv->cvar->member.name, key)) {
+ if (idx_out)
+ *idx_out = mv_sl_idx;
+ return mv;
}
- }
+ } SMARTLIST_FOREACH_END(mv);
+
+ if (!allow_truncated)
+ return NULL;
+
/* If none, check for an abbreviated match */
- for (i=0; fmt->vars[i].member.name; ++i) {
- if (!strncasecmp(key, fmt->vars[i].member.name, keylen)) {
+ SMARTLIST_FOREACH_BEGIN(mgr->all_vars, const managed_var_t *, mv) {
+ if (!strncasecmp(key, mv->cvar->member.name, keylen)) {
log_warn(LD_CONFIG, "The abbreviation '%s' is deprecated. "
"Please use '%s' instead",
- key, fmt->vars[i].member.name);
- return &fmt->vars[i];
+ key, mv->cvar->member.name);
+ if (idx_out)
+ *idx_out = mv_sl_idx;
+ return mv;
}
- }
+ } SMARTLIST_FOREACH_END(mv);
+
/* Okay, unrecognized option */
return NULL;
}
+/** If <b>key</b> is a configuration option, return the corresponding const
+ * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
+ * warn, and return the corresponding const config_var_t. Otherwise return
+ * NULL.
+ */
+const config_var_t *
+config_find_option(const config_mgr_t *mgr, const char *key)
+{
+ const managed_var_t *mv = config_mgr_find_var(mgr, key, true, NULL);
+ if (mv)
+ return mv->cvar;
+ else
+ return NULL;
+}
+
/** Return the number of option entries in <b>fmt</b>. */
static int
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)
- ;
- return i;
+ return smartlist_len(mgr->all_vars);
}
bool
@@ -213,16 +341,17 @@ static int
config_assign_value(const config_mgr_t *mgr, void *options,
config_line_t *c, char **msg)
{
- const config_var_t *var;
+ const managed_var_t *var;
const config_format_t *fmt = mgr->toplevel;
CONFIG_CHECK(fmt, options);
- var = config_find_option(mgr, c->key);
+ var = config_mgr_find_var(mgr, c->key, true, NULL);
tor_assert(var);
- tor_assert(!strcmp(c->key, var->member.name));
+ tor_assert(!strcmp(c->key, var->cvar->member.name));
+ void *object = config_mgr_get_obj_mutable(mgr, options, var->object_idx);
- return struct_var_kvassign(options, c, msg, &var->member);
+ return struct_var_kvassign(object, c, msg, &var->cvar->member);
}
/** Mark every linelist in <b>options</b> "fragile", so that fresh assignments
@@ -230,16 +359,13 @@ config_assign_value(const config_mgr_t *mgr, void *options,
static void
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(mgr);
tor_assert(options);
- for (i = 0; fmt->vars[i].member.name; ++i) {
- const config_var_t *var = &fmt->vars[i];
- struct_var_mark_fragile(options, &var->member);
- }
+ SMARTLIST_FOREACH_BEGIN(mgr->all_vars, const managed_var_t *, mv) {
+ void *object = config_mgr_get_obj_mutable(mgr, options, mv->object_idx);
+ struct_var_mark_fragile(object, &mv->cvar->member);
+ } SMARTLIST_FOREACH_END(mv);
}
void
@@ -270,12 +396,13 @@ config_assign_line(const config_mgr_t *mgr, void *options,
const unsigned use_defaults = flags & CAL_USE_DEFAULTS;
const unsigned clear_first = flags & CAL_CLEAR_FIRST;
const unsigned warn_deprecations = flags & CAL_WARN_DEPRECATIONS;
- const config_var_t *var;
+ const managed_var_t *mvar;
CONFIG_CHECK(fmt, options);
- var = config_find_option(mgr, c->key);
- if (!var) {
+ int var_index = -1;
+ mvar = config_mgr_find_var(mgr, c->key, true, &var_index);
+ if (!mvar) {
if (fmt->extra) {
void *lvalue = STRUCT_VAR_P(options, fmt->extra->offset);
log_info(LD_CONFIG,
@@ -289,44 +416,47 @@ config_assign_line(const config_mgr_t *mgr, void *options,
}
}
+ const config_var_t *cvar = mvar->cvar;
+ tor_assert(cvar);
+
/* Put keyword into canonical case. */
- if (strcmp(var->member.name, c->key)) {
+ if (strcmp(cvar->member.name, c->key)) {
tor_free(c->key);
- c->key = tor_strdup(var->member.name);
+ c->key = tor_strdup(cvar->member.name);
}
const char *deprecation_msg;
if (warn_deprecations &&
- (deprecation_msg = config_find_deprecation(mgr, var->member.name))) {
- warn_deprecated_option(var->member.name, deprecation_msg);
+ (deprecation_msg = config_find_deprecation(mgr, cvar->member.name))) {
+ warn_deprecated_option(cvar->member.name, deprecation_msg);
}
if (!strlen(c->value)) {
/* reset or clear it, then return */
if (!clear_first) {
- if (config_var_is_cumulative(var) && c->command != CONFIG_LINE_CLEAR) {
+ if (config_var_is_cumulative(cvar) && c->command != CONFIG_LINE_CLEAR) {
/* We got an empty linelist from the torrc or command line.
As a special case, call this an error. Warn and ignore. */
log_warn(LD_CONFIG,
"Linelist option '%s' has no value. Skipping.", c->key);
} else { /* not already cleared */
- config_reset(mgr, options, var, use_defaults);
+ config_reset(mgr, options, mvar, 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(mgr, options, var, use_defaults); // LCOV_EXCL_LINE
+ config_reset(mgr, options, mvar, use_defaults); // LCOV_EXCL_LINE
}
- if (options_seen && ! config_var_is_cumulative(var)) {
+ if (options_seen && ! config_var_is_cumulative(cvar)) {
/* We're tracking which options we've seen, and this option is not
* supposed to occur more than once. */
- int var_index = (int)(var - fmt->vars);
+ tor_assert(var_index >= 0);
if (bitarray_is_set(options_seen, var_index)) {
log_warn(LD_CONFIG, "Option '%s' used more than once; all but the last "
- "value will be ignored.", var->member.name);
+ "value will be ignored.", cvar->member.name);
}
bitarray_set(options_seen, var_index);
}
@@ -343,11 +473,11 @@ 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;
+ const managed_var_t *var;
CONFIG_CHECK(fmt, options);
- var = config_find_option(mgr, key);
+ var = config_mgr_find_var(mgr, key, true, NULL);
if (!var)
return; /* give error on next pass. */
@@ -388,7 +518,7 @@ config_line_t *
config_get_assigned_option(const config_mgr_t *mgr, const void *options,
const char *key, int escape_val)
{
- const config_var_t *var;
+ const managed_var_t *var;
config_line_t *result;
const config_format_t *fmt = mgr->toplevel;
@@ -396,13 +526,14 @@ config_get_assigned_option(const config_mgr_t *mgr, const void *options,
CONFIG_CHECK(fmt, options);
- var = config_find_option(mgr, key);
+ var = config_mgr_find_var(mgr, key, true, NULL);
if (!var) {
log_warn(LD_CONFIG, "Unknown option '%s'. Failing.", key);
return NULL;
}
+ const void *object = config_mgr_get_obj(mgr, options, var->object_idx);
- result = struct_var_kvencode(options, &var->member);
+ result = struct_var_kvencode(object, &var->cvar->member);
if (escape_val) {
config_line_t *line;
@@ -526,10 +657,10 @@ config_assign(const config_mgr_t *mgr, 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(void *options,
- const config_var_t *var)
+config_clear(const config_mgr_t *mgr, void *options, const managed_var_t *var)
{
- struct_var_free(options, &var->member);
+ void *object = config_mgr_get_obj_mutable(mgr, options, var->object_idx);
+ struct_var_free(object, &var->cvar->member);
}
/** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
@@ -537,19 +668,21 @@ config_clear(void *options,
* Called by config_init() and option_reset_line() and option_assign_line(). */
static void
config_reset(const config_mgr_t *mgr, void *options,
- const config_var_t *var, int use_defaults)
+ const managed_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(options, var); /* clear it first */
+ config_clear(mgr, options, var); /* clear it first */
+
if (!use_defaults)
return; /* all done */
- if (var->initvalue) {
+
+ if (var->cvar->initvalue) {
c = tor_malloc_zero(sizeof(config_line_t));
- c->key = tor_strdup(var->member.name);
- c->value = tor_strdup(var->initvalue);
+ c->key = tor_strdup(var->cvar->member.name);
+ c->value = tor_strdup(var->cvar->initvalue);
if (config_assign_value(mgr, options, c, &msg) < 0) {
// LCOV_EXCL_START
log_warn(LD_BUG, "Failed to assign default: %s", msg);
@@ -564,7 +697,6 @@ config_reset(const config_mgr_t *mgr, void *options,
void
config_free_(const config_mgr_t *mgr, void *options)
{
- int i;
const config_format_t *fmt = mgr->toplevel;
if (!options)
@@ -572,8 +704,9 @@ config_free_(const config_mgr_t *mgr, void *options)
tor_assert(fmt);
- for (i=0; fmt->vars[i].member.name; ++i)
- config_clear(options, &(fmt->vars[i]));
+ SMARTLIST_FOREACH_BEGIN(mgr->all_vars, const managed_var_t *, mv) {
+ config_clear(mgr, options, mv);
+ } SMARTLIST_FOREACH_END(mv);
if (fmt->extra) {
config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->offset);
@@ -595,36 +728,39 @@ config_is_same(const config_mgr_t *mgr,
CONFIG_CHECK(fmt, o1);
CONFIG_CHECK(fmt, o2);
- const config_var_t *var = config_find_option(mgr, name);
+ const managed_var_t *var = config_mgr_find_var(mgr, name, true, NULL);
if (!var) {
return true;
}
+ const void *obj1 = config_mgr_get_obj(mgr, o1, var->object_idx);
+ const void *obj2 = config_mgr_get_obj(mgr, o2, var->object_idx);
- return struct_var_eq(o1, o2, &var->member);
+ return struct_var_eq(obj1, obj2, &var->cvar->member);
}
/** Copy storage held by <b>old</b> into a new or_options_t and return it. */
void *
config_dup(const config_mgr_t *mgr, const void *old)
{
- const config_format_t *fmt = mgr->toplevel;
void *newopts;
- int i;
newopts = config_new(mgr);
- for (i=0; fmt->vars[i].member.name; ++i) {
- if (config_var_is_contained(&fmt->vars[i])) {
+ SMARTLIST_FOREACH_BEGIN(mgr->all_vars, managed_var_t *, mv) {
+ if (config_var_is_contained(mv->cvar)) {
// Something else will copy this option, or it doesn't need copying.
continue;
}
- if (struct_var_copy(newopts, old, &fmt->vars[i].member) < 0) {
+ const void *oldobj = config_mgr_get_obj(mgr, old, mv->object_idx);
+ void *newobj = config_mgr_get_obj_mutable(mgr, newopts, mv->object_idx);
+ if (struct_var_copy(newobj, oldobj, &mv->cvar->member) < 0) {
// LCOV_EXCL_START
log_err(LD_BUG, "Unable to copy value for %s.",
- fmt->vars[i].member.name);
+ mv->cvar->member.name);
tor_assert_unreached();
// LCOV_EXCL_STOP
}
- }
+ } SMARTLIST_FOREACH_END(mv);
+
return newopts;
}
/** Set all vars in the configuration object <b>options</b> to their default
@@ -632,17 +768,14 @@ config_dup(const config_mgr_t *mgr, const void *old)
void
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);
- for (i=0; fmt->vars[i].member.name; ++i) {
- var = &fmt->vars[i];
- if (!var->initvalue)
+ SMARTLIST_FOREACH_BEGIN(mgr->all_vars, const managed_var_t *, mv) {
+ if (!mv->cvar->initvalue)
continue; /* defaults to NULL or 0 */
- config_reset(mgr, options, var, 1);
- }
+ config_reset(mgr, options, mv, 1);
+ } SMARTLIST_FOREACH_END(mv);
}
/** Allocate and return a new string holding the written-out values of the vars
@@ -654,13 +787,12 @@ 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;
+ smartlist_t *elements;
const void *defaults = default_options;
void *defaults_tmp = NULL;
config_line_t *line, *assigned;
char *result;
- int i;
char *msg = NULL;
if (defaults == NULL) {
@@ -680,24 +812,24 @@ config_dump(const config_mgr_t *mgr, const void *default_options,
}
elements = smartlist_new();
- for (i=0; fmt->vars[i].member.name; ++i) {
+ SMARTLIST_FOREACH_BEGIN(mgr->all_vars, managed_var_t *, mv) {
int comment_option = 0;
- if (config_var_is_contained(&fmt->vars[i])) {
+ if (config_var_is_contained(mv->cvar)) {
// Something else will dump this option, or it doesn't need dumping.
continue;
}
/* Don't save 'hidden' control variables. */
- if (fmt->vars[i].flags & CVFLAG_NODUMP)
+ if (mv->cvar->flags & CVFLAG_NODUMP)
continue;
- if (minimal && config_is_same(mgr, options, defaults,
- fmt->vars[i].member.name))
+ const char *name = mv->cvar->member.name;
+ if (minimal && config_is_same(mgr, options, defaults, name))
continue;
else if (comment_defaults &&
- config_is_same(mgr, options, defaults, fmt->vars[i].member.name))
+ config_is_same(mgr, options, defaults, name))
comment_option = 1;
line = assigned =
- config_get_assigned_option(mgr, options, fmt->vars[i].member.name, 1);
+ config_get_assigned_option(mgr, options, name, 1);
for (; line; line = line->next) {
if (!strcmpstart(line->key, "__")) {
@@ -710,7 +842,7 @@ config_dump(const config_mgr_t *mgr, const void *default_options,
line->key, line->value);
}
config_free_lines(assigned);
- }
+ } SMARTLIST_FOREACH_END(mv);
if (fmt->extra) {
line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->offset);
@@ -735,14 +867,15 @@ config_dump(const config_mgr_t *mgr, const void *default_options,
bool
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)) {
+
+ SMARTLIST_FOREACH_BEGIN(mgr->all_vars, const managed_var_t *, mv) {
+ if (!struct_var_ok(options, &mv->cvar->member)) {
log_fn(severity, LD_BUG, "Invalid value for %s",
- fmt->vars[i].member.name);
+ mv->cvar->member.name);
all_ok = false;
}
- }
+ } SMARTLIST_FOREACH_END(mv);
+
return all_ok;
}
1
0

[tor/master] Fix every place in config.c that knew about option_vars_.
by dgoulet@torproject.org 04 Sep '19
by dgoulet@torproject.org 04 Sep '19
04 Sep '19
commit 627ab9dba32d590830ff4da908ee8f98f768b5e1
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Mon Jul 22 16:02:32 2019 -0400
Fix every place in config.c that knew about option_vars_.
Iterating over this array was once a good idea, but now that we are
going to have a separate structure for each submodule's
configuration variables, we should indirect through the config_mgr_t
object.
---
src/app/config/config.c | 37 +++++++++++++++++++------------------
src/app/config/confparse.c | 25 +++++++++++++++++++++++++
src/app/config/confparse.h | 2 ++
3 files changed, 46 insertions(+), 18 deletions(-)
diff --git a/src/app/config/config.c b/src/app/config/config.c
index 1fe4bd9c5..246f52a64 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -2655,25 +2655,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. */
@@ -8125,34 +8125,34 @@ 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 triple-underscore options */
- if (option_vars_[i].flags & CVFLAG_INVISIBLE)
+ if (var->flags & CVFLAG_INVISIBLE)
continue;
const char *type = struct_var_get_typename(&var->member);
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
* to add the defaults manually.
@@ -8163,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) {
/*
diff --git a/src/app/config/confparse.c b/src/app/config/confparse.c
index 32899a559..0f0950dd8 100644
--- a/src/app/config/confparse.c
+++ b/src/app/config/confparse.c
@@ -175,6 +175,31 @@ config_mgr_free_(config_mgr_t *mgr)
tor_free(mgr);
}
+/** Return a new smartlist_t containing a config_var_t for every variable that
+ * <b>mgr</b> knows about. The elements of this smartlist do not need
+ * to be freed. */
+smartlist_t *
+config_mgr_list_vars(const config_mgr_t *mgr)
+{
+ smartlist_t *result = smartlist_new();
+ tor_assert(mgr);
+ SMARTLIST_FOREACH(mgr->all_vars, managed_var_t *, mv,
+ smartlist_add(result, (void*) mv->cvar));
+ return result;
+}
+
+/** Return a new smartlist_t containing the names of all deprecated variables.
+ * The elements of this smartlist do not need to be freed. */
+smartlist_t *
+config_mgr_list_deprecated_vars(const config_mgr_t *mgr)
+{
+ smartlist_t *result = smartlist_new();
+ tor_assert(mgr);
+ SMARTLIST_FOREACH(mgr->all_deprecations, config_deprecation_t *, d,
+ smartlist_add(result, &d->name));
+ return result;
+}
+
/** Allocate an empty configuration object of a given format type. */
void *
config_new(const config_mgr_t *mgr)
diff --git a/src/app/config/confparse.h b/src/app/config/confparse.h
index e2647637a..105103503 100644
--- a/src/app/config/confparse.h
+++ b/src/app/config/confparse.h
@@ -75,6 +75,8 @@ 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))
+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);
/** Macro: assert that <b>cfg</b> has the right magic field for format
* <b>fmt</b>. */
1
0

[tor/master] Lower responsibility for listing changed options into confparse.c
by dgoulet@torproject.org 04 Sep '19
by dgoulet@torproject.org 04 Sep '19
04 Sep '19
commit 89a3051365a9a089397e64a18053d80337034ff8
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Mon Jul 22 15:27:26 2019 -0400
Lower responsibility for listing changed options into confparse.c
---
src/app/config/config.c | 36 +++++++-----------------------------
src/app/config/confparse.c | 40 ++++++++++++++++++++++++++++++++++++++++
src/app/config/confparse.h | 2 ++
3 files changed, 49 insertions(+), 29 deletions(-)
diff --git a/src/app/config/config.c b/src/app/config/config.c
index 444ce481c..1fe4bd9c5 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -964,9 +964,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
@@ -988,35 +985,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]; // 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(get_options_mgr(), new_val, old_options, var_name)) {
- line = config_get_assigned_option(get_options_mgr(), new_val,
- var_name, 1);
-
- if (line) {
- config_line_t *next;
- for (; line; line = next) {
- next = 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);
- }
- }
+ 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);
}
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) {
diff --git a/src/app/config/confparse.c b/src/app/config/confparse.c
index 16fb6dbc5..32899a559 100644
--- a/src/app/config/confparse.c
+++ b/src/app/config/confparse.c
@@ -738,6 +738,46 @@ config_is_same(const config_mgr_t *mgr,
return struct_var_eq(obj1, obj2, &var->cvar->member);
}
+/**
+ * Return a list of the options which have changed between <b>options1</b> and
+ * <b>options2</b>. If an option has reverted to its default value, it has a
+ * value entry of NULL.
+ **/
+config_line_t *
+config_get_changes(const config_mgr_t *mgr,
+ const void *options1, const void *options2)
+{
+ config_line_t *result = NULL;
+ config_line_t **next = &result;
+ SMARTLIST_FOREACH_BEGIN(mgr->all_vars, managed_var_t *, mv) {
+ if (config_var_is_contained(mv->cvar)) {
+ /* something else will check this var, or it doesn't need checking */
+ continue;
+ }
+ const void *obj1 = config_mgr_get_obj(mgr, options1, mv->object_idx);
+ const void *obj2 = config_mgr_get_obj(mgr, options2, mv->object_idx);
+
+ if (struct_var_eq(obj1, obj2, &mv->cvar->member)) {
+ continue;
+ }
+
+ const char *varname = mv->cvar->member.name;
+ config_line_t *line =
+ config_get_assigned_option(mgr, options2, varname, 1);
+
+ if (line) {
+ *next = line;
+ } else {
+ *next = tor_malloc_zero(sizeof(config_line_t));
+ (*next)->key = tor_strdup(varname);
+ }
+ while (*next)
+ next = &(*next)->next;
+ } SMARTLIST_FOREACH_END(mv);
+
+ return result;
+}
+
/** Copy storage held by <b>old</b> into a new or_options_t and return it. */
void *
config_dup(const config_mgr_t *mgr, const void *old)
diff --git a/src/app/config/confparse.h b/src/app/config/confparse.h
index 6e1e8cb3e..e2647637a 100644
--- a/src/app/config/confparse.h
+++ b/src/app/config/confparse.h
@@ -100,6 +100,8 @@ struct config_line_t *config_get_assigned_option(const config_mgr_t *mgr,
int config_is_same(const config_mgr_t *fmt,
const void *o1, const void *o2,
const char *name);
+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,
1
0