[tor-commits] [tor/master] main: Launch periodic events by roles

nickm at torproject.org nickm at torproject.org
Mon Apr 23 15:04:20 UTC 2018


commit a4fcdc5decfe60bbd95aee2e5586e90c40b73225
Author: David Goulet <dgoulet at torproject.org>
Date:   Tue Apr 17 09:31:50 2018 -0400

    main: Launch periodic events by roles
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 src/or/main.c          | 40 +++++++++++++++++++++++++++++++++++++---
 src/or/networkstatus.c |  2 +-
 src/or/networkstatus.h |  2 ++
 src/or/periodic.c      | 12 +++++++++++-
 src/or/periodic.h      | 14 ++++++++++++--
 5 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/src/or/main.c b/src/or/main.c
index 5ca6277c1..52e83822e 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1437,6 +1437,32 @@ find_periodic_event(const char *name)
   return NULL;
 }
 
+/** Return a bitmask of the roles this tor instance is configured for using
+ * the given options. */
+static int
+get_my_roles(const or_options_t *options)
+{
+  tor_assert(options);
+
+  int roles = 0;
+  int is_bridge = options->BridgeRelay;
+  int is_client = any_client_port_set(options);
+  int is_relay = server_mode(options);
+  int is_dirauth = authdir_mode_v3(options);
+  int is_bridgeauth = authdir_mode_bridge(options);
+  int is_hidden_service = !!hs_service_get_num_services() ||
+                          !!rend_num_services();
+
+  if (is_bridge) roles |= PERIODIC_EVENT_ROLE_BRIDGE;
+  if (is_client) roles |= PERIODIC_EVENT_ROLE_CLIENT;
+  if (is_relay) roles |= PERIODIC_EVENT_ROLE_RELAY;
+  if (is_dirauth) roles |= PERIODIC_EVENT_ROLE_DIRAUTH;
+  if (is_bridgeauth) roles |= PERIODIC_EVENT_ROLE_BRIDGEAUTH;
+  if (is_hidden_service) roles |= PERIODIC_EVENT_ROLE_HS_SERVICE;
+
+  return roles;
+}
+
 /** Event to run initialize_periodic_events_cb */
 static struct event *initialize_periodic_events_event = NULL;
 
@@ -1451,10 +1477,17 @@ initialize_periodic_events_cb(evutil_socket_t fd, short events, void *data)
   (void) fd;
   (void) events;
   (void) data;
+
+  int roles = get_my_roles(get_options());
+
   tor_event_free(initialize_periodic_events_event);
-  int i;
-  for (i = 0; periodic_events[i].name; ++i) {
-    periodic_event_launch(&periodic_events[i]);
+
+  for (int i = 0; periodic_events[i].name; ++i) {
+    periodic_event_item_t *item = &periodic_events[i];
+    if (item->roles & roles && !periodic_event_is_enabled(item)) {
+      periodic_event_launch(item);
+      log_debug(LD_GENERAL, "Launching periodic event %s", item->name);
+    }
   }
 }
 
@@ -1466,6 +1499,7 @@ initialize_periodic_events(void)
   tor_assert(periodic_events_initialized == 0);
   periodic_events_initialized = 1;
 
+  /* Set up all periodic events. We'll launch them by roles. */
   int i;
   for (i = 0; periodic_events[i].name; ++i) {
     periodic_event_setup(&periodic_events[i]);
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 5f19792c7..b0db0cecb 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -1680,7 +1680,7 @@ networkstatus_set_current_consensus_from_ns(networkstatus_t *c,
  * XXXX If we need this elsewhere at any point, we should make it nonstatic
  * XXXX and move it into another file.
  */
-static int
+int
 any_client_port_set(const or_options_t *options)
 {
   return (options->SocksPort_set ||
diff --git a/src/or/networkstatus.h b/src/or/networkstatus.h
index 1851a55e8..04cf277d2 100644
--- a/src/or/networkstatus.h
+++ b/src/or/networkstatus.h
@@ -140,6 +140,8 @@ void vote_routerstatus_free_(vote_routerstatus_t *rs);
 #define vote_routerstatus_free(rs) \
   FREE_AND_NULL(vote_routerstatus_t, vote_routerstatus_free_, (rs))
 
+int any_client_port_set(const or_options_t *options);
+
 #ifdef NETWORKSTATUS_PRIVATE
 #ifdef TOR_UNIT_TESTS
 STATIC int networkstatus_set_current_consensus_from_ns(networkstatus_t *c,
diff --git a/src/or/periodic.c b/src/or/periodic.c
index fa40965de..42bea3ae6 100644
--- a/src/or/periodic.c
+++ b/src/or/periodic.c
@@ -78,7 +78,10 @@ periodic_event_dispatch(mainloop_event_t *ev, void *data)
 void
 periodic_event_reschedule(periodic_event_item_t *event)
 {
-  periodic_event_set_interval(event, 1);
+  /* Don't reschedule a disabled event. */
+  if (periodic_event_is_enabled(event)) {
+    periodic_event_set_interval(event, 1);
+  }
 }
 
 /** Initializes the libevent backend for a periodic event. */
@@ -104,9 +107,15 @@ periodic_event_launch(periodic_event_item_t *event)
     log_err(LD_BUG, "periodic_event_launch without periodic_event_setup");
     tor_assert(0);
   }
+  /* Event already enabled? This is a bug */
+  if (periodic_event_is_enabled(event)) {
+    log_err(LD_BUG, "periodic_event_launch on an already enabled event");
+    tor_assert(0);
+  }
 
   // Initial dispatch
   periodic_event_dispatch(event->ev, event);
+  event->enabled = 1;
 }
 
 /** Release all storage associated with <b>event</b> */
@@ -117,5 +126,6 @@ periodic_event_destroy(periodic_event_item_t *event)
     return;
   mainloop_event_free(event->ev);
   event->last_action_time = 0;
+  event->enabled = 0;
 }
 
diff --git a/src/or/periodic.h b/src/or/periodic.h
index 4544ae276..1b346a1cc 100644
--- a/src/or/periodic.h
+++ b/src/or/periodic.h
@@ -49,11 +49,21 @@ typedef struct periodic_event_item_t {
 
   /* Bitmask of roles define above for which this event applies. */
   uint32_t roles;
+  /* Indicate that this event has been enabled that is scheduled. */
+  unsigned int enabled : 1;
 } periodic_event_item_t;
 
 /** events will get their interval from first execution */
-#define PERIODIC_EVENT(fn, r) { fn##_callback, 0, NULL, #fn, r }
-#define END_OF_PERIODIC_EVENTS { NULL, 0, NULL, NULL, 0 }
+#define PERIODIC_EVENT(fn, r) { fn##_callback, 0, NULL, #fn, r, 0 }
+#define END_OF_PERIODIC_EVENTS { NULL, 0, NULL, NULL, 0, 0 }
+
+/* Return true iff the given event was setup before thus is enabled to be
+ * scheduled. */
+static inline int
+periodic_event_is_enabled(const periodic_event_item_t *item)
+{
+  return item->enabled;
+}
 
 void periodic_event_launch(periodic_event_item_t *event);
 void periodic_event_setup(periodic_event_item_t *event);





More information about the tor-commits mailing list