main: Specialize the periodic events on a per-role basis

In tor, we have a series of possible "roles" that the tor daemon can be
enabled for. They are:

  Client, Bridge, Relay, Authority (directory or bridge) and Onion service.

They can be combined sometimes. For instance, a Directory Authority is also a
Relay. This adds a "roles" field to a periodic event item object which is used
to know for which roles the event is for.

The next step is to enable the event only if the roles apply. No behavior
change at this commit.

Pars of #25762

Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
David Goulet 2018-04-16 15:50:50 -04:00
parent 269cd5dba7
commit ed89bb3253
2 changed files with 74 additions and 31 deletions

View File

@ -1348,37 +1348,54 @@ CALLBACK(write_stats_file);
#undef CALLBACK
/* Now we declare an array of periodic_event_item_t for each periodic event */
#define CALLBACK(name) PERIODIC_EVENT(name)
#define CALLBACK(name, r) PERIODIC_EVENT(name, r)
static periodic_event_item_t periodic_events[] = {
CALLBACK(add_entropy),
CALLBACK(check_authority_cert),
CALLBACK(check_canonical_channels),
CALLBACK(check_descriptor),
CALLBACK(check_dns_honesty),
CALLBACK(check_ed_keys),
CALLBACK(check_expired_networkstatus),
CALLBACK(check_for_reachability_bw),
CALLBACK(check_onion_keys_expiry_time),
CALLBACK(clean_caches),
CALLBACK(clean_consdiffmgr),
CALLBACK(downrate_stability),
CALLBACK(expire_old_ciruits_serverside),
CALLBACK(fetch_networkstatus),
CALLBACK(heartbeat),
CALLBACK(hs_service),
CALLBACK(launch_descriptor_fetches),
CALLBACK(launch_reachability_tests),
CALLBACK(record_bridge_stats),
CALLBACK(rend_cache_failure_clean),
CALLBACK(reset_padding_counts),
CALLBACK(retry_dns),
CALLBACK(retry_listeners),
CALLBACK(rotate_onion_key),
CALLBACK(rotate_x509_certificate),
CALLBACK(save_stability),
CALLBACK(write_bridge_ns),
CALLBACK(write_stats_file),
/* Everyone needs to run those. */
CALLBACK(add_entropy, PERIODIC_EVENT_ROLE_ALL),
CALLBACK(check_expired_networkstatus, PERIODIC_EVENT_ROLE_ALL),
CALLBACK(clean_caches, PERIODIC_EVENT_ROLE_ALL),
CALLBACK(fetch_networkstatus, PERIODIC_EVENT_ROLE_ALL),
CALLBACK(heartbeat, PERIODIC_EVENT_ROLE_ALL),
CALLBACK(launch_descriptor_fetches, PERIODIC_EVENT_ROLE_ALL),
CALLBACK(reset_padding_counts, PERIODIC_EVENT_ROLE_ALL),
CALLBACK(retry_listeners, PERIODIC_EVENT_ROLE_ALL),
CALLBACK(rotate_x509_certificate, PERIODIC_EVENT_ROLE_ALL),
CALLBACK(write_stats_file, PERIODIC_EVENT_ROLE_ALL),
/* Routers (bridge and relay) only. */
CALLBACK(check_descriptor, PERIODIC_EVENT_ROLE_ROUTER),
CALLBACK(check_ed_keys, PERIODIC_EVENT_ROLE_ROUTER),
CALLBACK(check_for_reachability_bw, PERIODIC_EVENT_ROLE_ROUTER),
CALLBACK(check_onion_keys_expiry_time, PERIODIC_EVENT_ROLE_ROUTER),
CALLBACK(clean_consdiffmgr, PERIODIC_EVENT_ROLE_ROUTER),
CALLBACK(expire_old_ciruits_serverside, PERIODIC_EVENT_ROLE_ROUTER),
CALLBACK(retry_dns, PERIODIC_EVENT_ROLE_ROUTER),
CALLBACK(rotate_onion_key, PERIODIC_EVENT_ROLE_ROUTER),
/* Authorities (bridge and directory) only. */
CALLBACK(downrate_stability, PERIODIC_EVENT_ROLE_AUTHORITIES),
CALLBACK(launch_reachability_tests, PERIODIC_EVENT_ROLE_AUTHORITIES),
CALLBACK(save_stability, PERIODIC_EVENT_ROLE_AUTHORITIES),
/* Directory authority only. */
CALLBACK(check_authority_cert, PERIODIC_EVENT_ROLE_DIRAUTH),
/* Relay only. */
CALLBACK(check_canonical_channels, PERIODIC_EVENT_ROLE_RELAY),
CALLBACK(check_dns_honesty, PERIODIC_EVENT_ROLE_RELAY),
/* Hidden Service service only. */
CALLBACK(hs_service, PERIODIC_EVENT_ROLE_HS_SERVICE),
/* Bridge only. */
CALLBACK(record_bridge_stats, PERIODIC_EVENT_ROLE_BRIDGE),
/* Client only. */
CALLBACK(rend_cache_failure_clean, PERIODIC_EVENT_ROLE_CLIENT),
/* Bridge Authority only. */
CALLBACK(write_bridge_ns, PERIODIC_EVENT_ROLE_BRIDGEAUTH),
END_OF_PERIODIC_EVENTS
};
#undef CALLBACK

View File

@ -6,6 +6,29 @@
#define PERIODIC_EVENT_NO_UPDATE (-1)
/* Tor roles for which a periodic event item is for. An event can be for
* multiple roles, they can be combined. */
#define PERIODIC_EVENT_ROLE_CLIENT (1U << 0)
#define PERIODIC_EVENT_ROLE_RELAY (1U << 1)
#define PERIODIC_EVENT_ROLE_BRIDGE (1U << 2)
#define PERIODIC_EVENT_ROLE_DIRAUTH (1U << 3)
#define PERIODIC_EVENT_ROLE_BRIDGEAUTH (1U << 4)
#define PERIODIC_EVENT_ROLE_HS_SERVICE (1U << 5)
/* Helper macro to make it a bit less annoying to defined groups of roles that
* are often used. */
/* Router that is a Bridge or Relay. */
#define PERIODIC_EVENT_ROLE_ROUTER \
(PERIODIC_EVENT_ROLE_BRIDGE | PERIODIC_EVENT_ROLE_RELAY)
/* Authorities that is both bridge and directory. */
#define PERIODIC_EVENT_ROLE_AUTHORITIES \
(PERIODIC_EVENT_ROLE_BRIDGEAUTH | PERIODIC_EVENT_ROLE_DIRAUTH)
/* All roles. */
#define PERIODIC_EVENT_ROLE_ALL \
(PERIODIC_EVENT_ROLE_AUTHORITIES | PERIODIC_EVENT_ROLE_CLIENT | \
PERIODIC_EVENT_ROLE_HS_SERVICE | PERIODIC_EVENT_ROLE_ROUTER)
/** Callback function for a periodic event to take action. The return value
* influences the next time the function will get called. Return
* PERIODIC_EVENT_NO_UPDATE to not update <b>last_action_time</b> and be polled
@ -23,11 +46,14 @@ typedef struct periodic_event_item_t {
struct mainloop_event_t *ev; /**< Libevent callback we're using to implement
* this */
const char *name; /**< Name of the function -- for debug */
/* Bitmask of roles define above for which this event applies. */
uint32_t roles;
} periodic_event_item_t;
/** events will get their interval from first execution */
#define PERIODIC_EVENT(fn) { fn##_callback, 0, NULL, #fn }
#define END_OF_PERIODIC_EVENTS { NULL, 0, NULL, NULL }
#define PERIODIC_EVENT(fn, r) { fn##_callback, 0, NULL, #fn, r }
#define END_OF_PERIODIC_EVENTS { NULL, 0, NULL, NULL, 0 }
void periodic_event_launch(periodic_event_item_t *event);
void periodic_event_setup(periodic_event_item_t *event);