diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-04-23 11:02:05 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-04-23 11:02:05 -0400 |
commit | 192c7c8bf9a3c53d32e83557ebc62cf7cfa3b1ca (patch) | |
tree | d702b143ee6e486f413494ae53786d8625234769 /src/or/main.c | |
parent | 3527f4b8a4f002e7b910eacd4ead6e9044cb4003 (diff) | |
parent | 665e23c59a370157c5e3526e29590798b1933ed5 (diff) | |
download | tor-192c7c8bf9a3c53d32e83557ebc62cf7cfa3b1ca.tar.gz tor-192c7c8bf9a3c53d32e83557ebc62cf7cfa3b1ca.zip |
Merge remote-tracking branch 'dgoulet/ticket25762_034_05'
Diffstat (limited to 'src/or/main.c')
-rw-r--r-- | src/or/main.c | 192 |
1 files changed, 137 insertions, 55 deletions
diff --git a/src/or/main.c b/src/or/main.c index 40ca8e059b..d64c40240d 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -150,6 +150,7 @@ static int run_main_loop_until_done(void); static void process_signal(int sig); static void shutdown_did_not_work_callback(evutil_socket_t fd, short event, void *arg) ATTR_NORETURN; +static void rescan_periodic_events(const or_options_t *options); /********* START VARIABLES **********/ @@ -1328,69 +1329,86 @@ static int periodic_events_initialized = 0; #undef CALLBACK #define CALLBACK(name) \ static int name ## _callback(time_t, const or_options_t *) -CALLBACK(rotate_onion_key); -CALLBACK(check_onion_keys_expiry_time); -CALLBACK(check_ed_keys); -CALLBACK(launch_descriptor_fetches); -CALLBACK(rotate_x509_certificate); CALLBACK(add_entropy); -CALLBACK(launch_reachability_tests); -CALLBACK(downrate_stability); -CALLBACK(save_stability); CALLBACK(check_authority_cert); +CALLBACK(check_canonical_channels); +CALLBACK(check_descriptor); +CALLBACK(check_dns_honesty); +CALLBACK(check_ed_keys); CALLBACK(check_expired_networkstatus); -CALLBACK(write_stats_file); -CALLBACK(record_bridge_stats); +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(check_descriptor); -CALLBACK(check_for_reachability_bw); -CALLBACK(fetch_networkstatus); CALLBACK(retry_listeners); -CALLBACK(expire_old_ciruits_serverside); -CALLBACK(check_dns_honesty); +CALLBACK(rotate_onion_key); +CALLBACK(rotate_x509_certificate); +CALLBACK(save_stability); CALLBACK(write_bridge_ns); -CALLBACK(heartbeat); -CALLBACK(clean_consdiffmgr); -CALLBACK(reset_padding_counts); -CALLBACK(check_canonical_channels); -CALLBACK(hs_service); +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) - -static periodic_event_item_t periodic_events[] = { - CALLBACK(rotate_onion_key), - CALLBACK(check_onion_keys_expiry_time), - CALLBACK(check_ed_keys), - CALLBACK(launch_descriptor_fetches), - CALLBACK(rotate_x509_certificate), - CALLBACK(add_entropy), - CALLBACK(launch_reachability_tests), - CALLBACK(downrate_stability), - CALLBACK(save_stability), - CALLBACK(check_authority_cert), - CALLBACK(check_expired_networkstatus), - CALLBACK(write_stats_file), - CALLBACK(record_bridge_stats), - CALLBACK(clean_caches), - CALLBACK(rend_cache_failure_clean), - CALLBACK(retry_dns), - CALLBACK(check_descriptor), - CALLBACK(check_for_reachability_bw), - CALLBACK(fetch_networkstatus), - CALLBACK(retry_listeners), - CALLBACK(expire_old_ciruits_serverside), - CALLBACK(check_dns_honesty), - CALLBACK(write_bridge_ns), - CALLBACK(heartbeat), - CALLBACK(clean_consdiffmgr), - CALLBACK(reset_padding_counts), - CALLBACK(check_canonical_channels), - CALLBACK(hs_service), +#define CALLBACK(name, r) PERIODIC_EVENT(name, r) + +STATIC periodic_event_item_t periodic_events[] = { + /* 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 @@ -1432,6 +1450,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; @@ -1446,11 +1490,10 @@ initialize_periodic_events_cb(evutil_socket_t fd, short events, void *data) (void) fd; (void) events; (void) data; + tor_event_free(initialize_periodic_events_event); - int i; - for (i = 0; periodic_events[i].name; ++i) { - periodic_event_launch(&periodic_events[i]); - } + + rescan_periodic_events(get_options()); } /** Set up all the members of periodic_events[], and configure them all to be @@ -1461,6 +1504,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]); @@ -1491,6 +1535,44 @@ teardown_periodic_events(void) periodic_events_initialized = 0; } +/** Do a pass at all our periodic events, disable those we don't need anymore + * and enable 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]; + + /* Enable the event if needed. It is safe to enable an event that was + * already enabled. Same goes for disabling it. */ + if (item->roles & roles) { + log_debug(LD_GENERAL, "Launching periodic event %s", item->name); + periodic_event_enable(item); + } else { + log_debug(LD_GENERAL, "Disabling periodic event %s", item->name); + periodic_event_disable(item); + } + } +} + +/* We just got new options globally set, see if we need to enabled or disable + * periodic events. */ +void +periodic_events_on_new_options(const or_options_t *options) +{ + /* Only if we've already initialized the events, rescan the list which will + * enable or disable events depending on our roles. This will be called at + * bootup and we don't want this function to initialize the events because + * they aren't set up at this stage. */ + 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 |