diff options
author | David Goulet <dgoulet@torproject.org> | 2018-04-17 09:44:01 -0400 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2018-04-23 10:57:28 -0400 |
commit | 1d864987cbdab4286eed8f3a86a488759dc322ae (patch) | |
tree | 4198fedb4c0e0a850386935d6330628978b0ec03 /src | |
parent | a4fcdc5decfe60bbd95aee2e5586e90c40b73225 (diff) | |
download | tor-1d864987cbdab4286eed8f3a86a488759dc322ae.tar.gz tor-1d864987cbdab4286eed8f3a86a488759dc322ae.zip |
config: Set up periodic events when options changes
In case we transitionned to a new role in Tor, we need to launch and/or
destroy some periodic events.
Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/or/config.c | 7 | ||||
-rw-r--r-- | src/or/main.c | 41 | ||||
-rw-r--r-- | src/or/main.h | 2 |
3 files changed, 49 insertions, 1 deletions
diff --git a/src/or/config.c b/src/or/config.c index 9c0b321b56..1923afe7d0 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -903,8 +903,13 @@ set_options(or_options_t *new_val, char **msg) smartlist_free(elements); } - if (old_options != global_options) + if (old_options != global_options) { or_options_free(old_options); + /* If we are here it means we've successfully applied the new options and + * that the global options have been changed to the new values. We'll + * check if we need to remove or add periodic events. */ + periodic_events_on_new_options(global_options); + } return 0; } diff --git a/src/or/main.c b/src/or/main.c index 52e83822ef..eb8835198a 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -1530,6 +1530,47 @@ teardown_periodic_events(void) periodic_events_initialized = 0; } +/** Do a pass at all our periodic events, destroy those we don't need anymore + * and enabled those we need now using the given options. */ +static void +rescan_periodic_events(const or_options_t *options) +{ + tor_assert(options); + + int roles = get_my_roles(options); + + for (int i = 0; periodic_events[i].name; ++i) { + periodic_event_item_t *item = &periodic_events[i]; + int is_enabled = periodic_event_is_enabled(item); + int need_item = (item->roles & roles); + + /* We need this event but it is *not* enabled. */ + if (need_item && !is_enabled) { + periodic_event_launch(item); + continue; + } + /* We do *not* need this event but it is enabled. */ + if (!need_item && is_enabled) { + periodic_event_destroy(item); + continue; + } + } +} + +/* We just got new options globally set, see if we need to destroy or setup + * periodic events. */ +void +periodic_events_on_new_options(const or_options_t *options) +{ + /* Only if we've already initialized once the events, teardown them all and + * reinitialize. It is just simpler that way instead of going through all + * currently enabled events and trying to destroy only the one that could be + * affected. */ + if (periodic_events_initialized) { + rescan_periodic_events(options); + } +} + /** * Update our schedule so that we'll check whether we need to update our * descriptor immediately, rather than after up to CHECK_DESCRIPTOR_INTERVAL diff --git a/src/or/main.h b/src/or/main.h index e50d14d4d9..5220b13216 100644 --- a/src/or/main.h +++ b/src/or/main.h @@ -86,6 +86,8 @@ uint64_t get_main_loop_success_count(void); uint64_t get_main_loop_error_count(void); uint64_t get_main_loop_idle_count(void); +void periodic_events_on_new_options(const or_options_t *options); + extern time_t time_of_process_start; extern int quiet_level; extern token_bucket_rw_t global_bucket; |