diff options
Diffstat (limited to 'src/or/main.c')
-rw-r--r-- | src/or/main.c | 105 |
1 files changed, 91 insertions, 14 deletions
diff --git a/src/or/main.c b/src/or/main.c index 47275c84f5..b492166f87 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -59,6 +59,7 @@ #include "circuitbuild.h" #include "circuitlist.h" #include "circuituse.h" +#include "circuitmux_ewma.h" #include "command.h" #include "compress.h" #include "config.h" @@ -72,7 +73,6 @@ #include "crypto_s2k.h" #include "directory.h" #include "dirserv.h" -#include "dirvote.h" #include "dns.h" #include "dnsserv.h" #include "dos.h" @@ -103,7 +103,7 @@ #include "routerlist.h" #include "routerparse.h" #include "scheduler.h" -#include "shared_random.h" +#include "dirauth/shared_random.h" #include "statefile.h" #include "status.h" #include "tor_api.h" @@ -118,6 +118,8 @@ #include <event2/event.h> +#include "dirauth/dirvote.h" + #ifdef HAVE_SYSTEMD # if defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) /* Systemd's use of gcc's __INCLUDE_LEVEL__ extension macro appears to confuse @@ -1352,6 +1354,7 @@ CALLBACK(check_for_reachability_bw); CALLBACK(check_onion_keys_expiry_time); CALLBACK(clean_caches); CALLBACK(clean_consdiffmgr); +CALLBACK(dirvote); CALLBACK(downrate_stability); CALLBACK(expire_old_ciruits_serverside); CALLBACK(fetch_networkstatus); @@ -1367,6 +1370,7 @@ CALLBACK(retry_listeners); CALLBACK(rotate_onion_key); CALLBACK(rotate_x509_certificate); CALLBACK(save_stability); +CALLBACK(save_state); CALLBACK(write_bridge_ns); CALLBACK(write_stats_file); @@ -1388,6 +1392,7 @@ STATIC periodic_event_item_t periodic_events[] = { CALLBACK(reset_padding_counts, PERIODIC_EVENT_ROLE_ALL, 0), CALLBACK(retry_listeners, PERIODIC_EVENT_ROLE_ALL, PERIODIC_EVENT_FLAG_NEED_NET), + CALLBACK(save_state, PERIODIC_EVENT_ROLE_ALL, 0), CALLBACK(rotate_x509_certificate, PERIODIC_EVENT_ROLE_ALL, 0), CALLBACK(write_stats_file, PERIODIC_EVENT_ROLE_ALL, 0), @@ -1398,7 +1403,6 @@ STATIC periodic_event_item_t periodic_events[] = { CALLBACK(check_for_reachability_bw, PERIODIC_EVENT_ROLE_ROUTER, PERIODIC_EVENT_FLAG_NEED_NET), CALLBACK(check_onion_keys_expiry_time, PERIODIC_EVENT_ROLE_ROUTER, 0), - CALLBACK(clean_consdiffmgr, PERIODIC_EVENT_ROLE_ROUTER, 0), CALLBACK(expire_old_ciruits_serverside, PERIODIC_EVENT_ROLE_ROUTER, PERIODIC_EVENT_FLAG_NEED_NET), CALLBACK(retry_dns, PERIODIC_EVENT_ROLE_ROUTER, 0), @@ -1412,6 +1416,7 @@ STATIC periodic_event_item_t periodic_events[] = { /* Directory authority only. */ CALLBACK(check_authority_cert, PERIODIC_EVENT_ROLE_DIRAUTH, 0), + CALLBACK(dirvote, PERIODIC_EVENT_ROLE_DIRAUTH, PERIODIC_EVENT_FLAG_NEED_NET), /* Relay only. */ CALLBACK(check_canonical_channels, PERIODIC_EVENT_ROLE_RELAY, @@ -1432,6 +1437,9 @@ STATIC periodic_event_item_t periodic_events[] = { /* Bridge Authority only. */ CALLBACK(write_bridge_ns, PERIODIC_EVENT_ROLE_BRIDGEAUTH, 0), + /* Directory server only. */ + CALLBACK(clean_consdiffmgr, PERIODIC_EVENT_ROLE_DIRSERVER, 0), + END_OF_PERIODIC_EVENTS }; #undef CALLBACK @@ -1441,9 +1449,11 @@ STATIC periodic_event_item_t periodic_events[] = { * can access them by name. We also keep them inside periodic_events[] * so that we can implement "reset all timers" in a reasonable way. */ static periodic_event_item_t *check_descriptor_event=NULL; +static periodic_event_item_t *dirvote_event=NULL; static periodic_event_item_t *fetch_networkstatus_event=NULL; static periodic_event_item_t *launch_descriptor_fetches_event=NULL; static periodic_event_item_t *check_dns_honesty_event=NULL; +static periodic_event_item_t *save_state_event=NULL; /** Reset all the periodic events so we'll do all our actions again as if we * just started up. @@ -1488,6 +1498,7 @@ get_my_roles(const or_options_t *options) int is_bridgeauth = authdir_mode_bridge(options); int is_hidden_service = !!hs_service_get_num_services() || !!rend_num_services(); + int is_dirserver = dir_server_mode(options); if (is_bridge) roles |= PERIODIC_EVENT_ROLE_BRIDGE; if (is_client) roles |= PERIODIC_EVENT_ROLE_CLIENT; @@ -1495,6 +1506,7 @@ get_my_roles(const or_options_t *options) 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; + if (is_dirserver) roles |= PERIODIC_EVENT_ROLE_DIRSERVER; return roles; } @@ -1537,9 +1549,11 @@ initialize_periodic_events(void) STMT_BEGIN name ## _event = find_periodic_event( #name ); STMT_END NAMED_CALLBACK(check_descriptor); + NAMED_CALLBACK(dirvote); NAMED_CALLBACK(fetch_networkstatus); NAMED_CALLBACK(launch_descriptor_fetches); NAMED_CALLBACK(check_dns_honesty); + NAMED_CALLBACK(save_state); struct timeval one_second = { 1, 0 }; initialize_periodic_events_event = tor_evtimer_new( @@ -1565,6 +1579,13 @@ rescan_periodic_events(const or_options_t *options) { tor_assert(options); + /* Avoid scanning the event list if we haven't initialized it yet. This is + * particularly useful for unit tests in order to avoid initializing main + * loop events everytime. */ + if (!periodic_events_initialized) { + return; + } + int roles = get_my_roles(options); for (int i = 0; periodic_events[i].name; ++i) { @@ -1610,8 +1631,9 @@ periodic_events_on_new_options(const or_options_t *options) void reschedule_descriptor_update_check(void) { - tor_assert(check_descriptor_event); - periodic_event_reschedule(check_descriptor_event); + if (check_descriptor_event) { + periodic_event_reschedule(check_descriptor_event); + } } /** @@ -1705,10 +1727,6 @@ run_scheduled_events(time_t now) accounting_run_housekeeping(now); } - if (authdir_mode_v3(options)) { - dirvote_act(options, now); - } - /* 3a. Every second, we examine pending circuits and prune the * ones which have been pending for more than a few seconds. * We do this before step 4, so it can try building more if @@ -1749,10 +1767,6 @@ run_scheduled_events(time_t now) run_connection_housekeeping(i, now); } - /* 8b. And if anything in our state is ready to get flushed to disk, we - * flush it. */ - or_state_save(now); - /* 11b. check pending unconfigured managed proxies */ if (!net_is_disabled() && pt_proxies_configuration_pending()) pt_configure_remaining_proxies(); @@ -1965,6 +1979,40 @@ check_authority_cert_callback(time_t now, const or_options_t *options) } /** + * Scheduled callback: Run directory-authority voting functionality. + * + * The schedule is a bit complicated here, so dirvote_act() manages the + * schedule itself. + **/ +static int +dirvote_callback(time_t now, const or_options_t *options) +{ + if (!authdir_mode_v3(options)) { + tor_assert_nonfatal_unreached(); + return 3600; + } + + time_t next = dirvote_act(options, now); + if (BUG(next == TIME_MAX)) { + /* This shouldn't be returned unless we called dirvote_act() without + * being an authority. If it happens, maybe our configuration will + * fix itself in an hour or so? */ + return 3600; + } + return safe_timer_diff(now, next); +} + +/** Reschedule the directory-authority voting event. Run this whenever the + * schedule has changed. */ +void +reschedule_dirvote(const or_options_t *options) +{ + if (periodic_events_initialized && authdir_mode_v3(options)) { + periodic_event_reschedule(dirvote_event); + } +} + +/** * Periodic callback: If our consensus is too old, recalculate whether * we can actually use it. */ @@ -1987,6 +2035,34 @@ check_expired_networkstatus_callback(time_t now, const or_options_t *options) } /** + * Scheduled callback: Save the state file to disk if appropriate. + */ +static int +save_state_callback(time_t now, const or_options_t *options) +{ + (void) options; + (void) or_state_save(now); // only saves if appropriate + const time_t next_write = get_or_state()->next_write; + if (next_write == TIME_MAX) { + return 86400; + } + return safe_timer_diff(now, next_write); +} + +/** Reschedule the event for saving the state file. + * + * Run this when the state becomes dirty. */ +void +reschedule_or_state_save(void) +{ + if (save_state_event == NULL) { + /* This can happen early on during startup. */ + return; + } + periodic_event_reschedule(save_state_event); +} + +/** * Periodic callback: Write statistics to disk if appropriate. */ static int @@ -2338,7 +2414,7 @@ static int clean_consdiffmgr_callback(time_t now, const or_options_t *options) { (void)now; - if (server_mode(options)) { + if (dir_server_mode(options)) { consdiffmgr_cleanup(); } return CDM_CLEAN_CALLBACK_INTERVAL; @@ -3529,6 +3605,7 @@ tor_free_all(int postfork) consdiffmgr_free_all(); hs_free_all(); dos_free_all(); + circuitmux_ewma_free_all(); if (!postfork) { config_free_all(); or_state_free_all(); |