Browse Source

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>
David Goulet 6 years ago
parent
commit
1d864987cb
3 changed files with 49 additions and 1 deletions
  1. 6 1
      src/or/config.c
  2. 41 0
      src/or/main.c
  3. 2 0
      src/or/main.h

+ 6 - 1
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;
 }

+ 41 - 0
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

+ 2 - 0
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;