|
@@ -75,7 +75,6 @@
|
|
|
#include "feature/control/control.h"
|
|
|
#include "feature/control/control_events.h"
|
|
|
#include "feature/dirauth/authmode.h"
|
|
|
-#include "feature/dirauth/reachability.h"
|
|
|
#include "feature/dircache/consdiffmgr.h"
|
|
|
#include "feature/dircache/dirserv.h"
|
|
|
#include "feature/dircommon/directory.h"
|
|
@@ -106,9 +105,6 @@
|
|
|
|
|
|
#include <event2/event.h>
|
|
|
|
|
|
-#include "feature/dirauth/dirvote.h"
|
|
|
-#include "feature/dirauth/authmode.h"
|
|
|
-
|
|
|
#include "core/or/cell_st.h"
|
|
|
#include "core/or/entry_connection_st.h"
|
|
|
#include "feature/nodelist/networkstatus_st.h"
|
|
@@ -1346,7 +1342,6 @@ static int periodic_events_initialized = 0;
|
|
|
#define CALLBACK(name) \
|
|
|
static int name ## _callback(time_t, const or_options_t *)
|
|
|
CALLBACK(add_entropy);
|
|
|
-CALLBACK(check_authority_cert);
|
|
|
CALLBACK(check_canonical_channels);
|
|
|
CALLBACK(check_descriptor);
|
|
|
CALLBACK(check_dns_honesty);
|
|
@@ -1356,14 +1351,11 @@ 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);
|
|
|
CALLBACK(heartbeat);
|
|
|
CALLBACK(hs_service);
|
|
|
CALLBACK(launch_descriptor_fetches);
|
|
|
-CALLBACK(launch_reachability_tests);
|
|
|
CALLBACK(prune_old_routers);
|
|
|
CALLBACK(reachability_warnings);
|
|
|
CALLBACK(record_bridge_stats);
|
|
@@ -1373,7 +1365,6 @@ CALLBACK(retry_dns);
|
|
|
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);
|
|
@@ -1387,7 +1378,7 @@ CALLBACK(second_elapsed);
|
|
|
PERIODIC_EVENT(name, PERIODIC_EVENT_ROLE_ ## r, f)
|
|
|
#define FL(name) (PERIODIC_EVENT_FLAG_ ## name)
|
|
|
|
|
|
-STATIC periodic_event_item_t periodic_events[] = {
|
|
|
+STATIC periodic_event_item_t mainloop_periodic_events[] = {
|
|
|
|
|
|
|
|
|
* that to be safe. */
|
|
@@ -1428,15 +1419,6 @@ STATIC periodic_event_item_t periodic_events[] = {
|
|
|
CALLBACK(retry_dns, ROUTER, 0),
|
|
|
CALLBACK(rotate_onion_key, ROUTER, 0),
|
|
|
|
|
|
-
|
|
|
- CALLBACK(downrate_stability, AUTHORITIES, 0),
|
|
|
- CALLBACK(launch_reachability_tests, AUTHORITIES, FL(NEED_NET)),
|
|
|
- CALLBACK(save_stability, AUTHORITIES, 0),
|
|
|
-
|
|
|
-
|
|
|
- CALLBACK(check_authority_cert, DIRAUTH, 0),
|
|
|
- CALLBACK(dirvote, DIRAUTH, FL(NEED_NET)),
|
|
|
-
|
|
|
|
|
|
CALLBACK(check_canonical_channels, RELAY, FL(NEED_NET)),
|
|
|
CALLBACK(check_dns_honesty, RELAY, FL(NEED_NET)),
|
|
@@ -1470,7 +1452,6 @@ 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;
|
|
@@ -1485,24 +1466,7 @@ static periodic_event_item_t *prune_old_routers_event=NULL;
|
|
|
void
|
|
|
reset_all_main_loop_timers(void)
|
|
|
{
|
|
|
- int i;
|
|
|
- for (i = 0; periodic_events[i].name; ++i) {
|
|
|
- periodic_event_reschedule(&periodic_events[i]);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
- * Return NULL if no such event is found.
|
|
|
- */
|
|
|
-static periodic_event_item_t *
|
|
|
-find_periodic_event(const char *name)
|
|
|
-{
|
|
|
- int i;
|
|
|
- for (i = 0; periodic_events[i].name; ++i) {
|
|
|
- if (strcmp(name, periodic_events[i].name) == 0)
|
|
|
- return &periodic_events[i];
|
|
|
- }
|
|
|
- return NULL;
|
|
|
+ periodic_events_reset_all();
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1565,9 +1529,9 @@ initialize_periodic_events_cb(evutil_socket_t fd, short events, void *data)
|
|
|
rescan_periodic_events(get_options());
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- * launched from a callback. */
|
|
|
-STATIC void
|
|
|
+
|
|
|
+ * all to be launched from a callback. */
|
|
|
+void
|
|
|
initialize_periodic_events(void)
|
|
|
{
|
|
|
if (periodic_events_initialized)
|
|
@@ -1575,37 +1539,33 @@ initialize_periodic_events(void)
|
|
|
|
|
|
periodic_events_initialized = 1;
|
|
|
|
|
|
-
|
|
|
- int i;
|
|
|
- for (i = 0; periodic_events[i].name; ++i) {
|
|
|
- periodic_event_setup(&periodic_events[i]);
|
|
|
+ for (int i = 0; mainloop_periodic_events[i].name; ++i) {
|
|
|
+ periodic_events_register(&mainloop_periodic_events[i]);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
#define NAMED_CALLBACK(name) \
|
|
|
- STMT_BEGIN name ## _event = find_periodic_event( #name ); STMT_END
|
|
|
+ STMT_BEGIN name ## _event = periodic_events_find( #name ); STMT_END
|
|
|
|
|
|
NAMED_CALLBACK(check_descriptor);
|
|
|
NAMED_CALLBACK(prune_old_routers);
|
|
|
- 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(
|
|
|
- tor_libevent_get_base(),
|
|
|
- initialize_periodic_events_cb, NULL);
|
|
|
- event_add(initialize_periodic_events_event, &one_second);
|
|
|
}
|
|
|
|
|
|
STATIC void
|
|
|
teardown_periodic_events(void)
|
|
|
{
|
|
|
- int i;
|
|
|
- for (i = 0; periodic_events[i].name; ++i) {
|
|
|
- periodic_event_destroy(&periodic_events[i]);
|
|
|
- }
|
|
|
+ periodic_events_disconnect_all();
|
|
|
+ check_descriptor_event = NULL;
|
|
|
+ fetch_networkstatus_event = NULL;
|
|
|
+ launch_descriptor_fetches_event = NULL;
|
|
|
+ check_dns_honesty_event = NULL;
|
|
|
+ save_state_event = NULL;
|
|
|
+ prune_old_routers_event = NULL;
|
|
|
periodic_events_initialized = 0;
|
|
|
}
|
|
|
|
|
@@ -1640,40 +1600,7 @@ rescan_periodic_events(const or_options_t *options)
|
|
|
{
|
|
|
tor_assert(options);
|
|
|
|
|
|
-
|
|
|
- * 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) {
|
|
|
- periodic_event_item_t *item = &periodic_events[i];
|
|
|
-
|
|
|
- int enable = !!(item->roles & roles);
|
|
|
-
|
|
|
-
|
|
|
- if (net_is_disabled() &&
|
|
|
- (item->flags & PERIODIC_EVENT_FLAG_NEED_NET)) {
|
|
|
- enable = 0;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- * already enabled. Same goes for disabling it. */
|
|
|
- if (enable) {
|
|
|
- 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);
|
|
|
- if (item->flags & PERIODIC_EVENT_FLAG_RUN_ON_DISABLE) {
|
|
|
- periodic_event_schedule_and_disable(item);
|
|
|
- } else {
|
|
|
- periodic_event_disable(item);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ periodic_events_rescan_by_roles(get_my_roles(options), net_is_disabled());
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1681,13 +1608,7 @@ rescan_periodic_events(const or_options_t *options)
|
|
|
void
|
|
|
periodic_events_on_new_options(const or_options_t *options)
|
|
|
{
|
|
|
-
|
|
|
- * 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);
|
|
|
- }
|
|
|
+ rescan_periodic_events(options);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1770,29 +1691,6 @@ mainloop_schedule_shutdown(int delay_sec)
|
|
|
mainloop_event_schedule(scheduled_shutdown_ev, &delay_tv);
|
|
|
}
|
|
|
|
|
|
-#define LONGEST_TIMER_PERIOD (30 * 86400)
|
|
|
-
|
|
|
- * clipped to the range [1 second, LONGEST_TIMER_PERIOD]. */
|
|
|
-static inline int
|
|
|
-safe_timer_diff(time_t now, time_t next)
|
|
|
-{
|
|
|
- if (next > now) {
|
|
|
-
|
|
|
- * and nothing that could run Tor. It's a bug if 'next' is around then.
|
|
|
- * On 64-bit systems with signed TIME_MIN, TIME_MIN is before the Big
|
|
|
- * Bang. We cannot extrapolate past a singularity, but there was probably
|
|
|
- * nothing that could run Tor then, either.
|
|
|
- **/
|
|
|
- tor_assert(next > TIME_MIN + LONGEST_TIMER_PERIOD);
|
|
|
-
|
|
|
- if (next - LONGEST_TIMER_PERIOD > now)
|
|
|
- return LONGEST_TIMER_PERIOD;
|
|
|
- return (int)(next - now);
|
|
|
- } else {
|
|
|
- return 1;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
|
|
|
* second.
|
|
|
*/
|
|
@@ -2061,102 +1959,6 @@ check_network_participation_callback(time_t now, const or_options_t *options)
|
|
|
return CHECK_PARTICIPATION_INTERVAL;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- * Periodic callback: if we're an authority, make sure we test
|
|
|
- * the routers on the network for reachability.
|
|
|
- */
|
|
|
-static int
|
|
|
-launch_reachability_tests_callback(time_t now, const or_options_t *options)
|
|
|
-{
|
|
|
- if (authdir_mode_tests_reachability(options) &&
|
|
|
- !net_is_disabled()) {
|
|
|
-
|
|
|
- dirserv_test_reachability(now);
|
|
|
- }
|
|
|
- return REACHABILITY_TEST_INTERVAL;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
- * Periodic callback: if we're an authority, discount the stability
|
|
|
- * information (and other rephist information) that's older.
|
|
|
- */
|
|
|
-static int
|
|
|
-downrate_stability_callback(time_t now, const or_options_t *options)
|
|
|
-{
|
|
|
- (void)options;
|
|
|
-
|
|
|
- * stability info counts more, and save the stability information to disk as
|
|
|
- * appropriate. */
|
|
|
- time_t next = rep_hist_downrate_old_runs(now);
|
|
|
- return safe_timer_diff(now, next);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
- * Periodic callback: if we're an authority, record our measured stability
|
|
|
- * information from rephist in an mtbf file.
|
|
|
- */
|
|
|
-static int
|
|
|
-save_stability_callback(time_t now, const or_options_t *options)
|
|
|
-{
|
|
|
- if (authdir_mode_tests_reachability(options)) {
|
|
|
- if (rep_hist_record_mtbf_data(now, 1)<0) {
|
|
|
- log_warn(LD_GENERAL, "Couldn't store mtbf data.");
|
|
|
- }
|
|
|
- }
|
|
|
-#define SAVE_STABILITY_INTERVAL (30*60)
|
|
|
- return SAVE_STABILITY_INTERVAL;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
- * Periodic callback: if we're an authority, check on our authority
|
|
|
- * certificate (the one that authenticates our authority signing key).
|
|
|
- */
|
|
|
-static int
|
|
|
-check_authority_cert_callback(time_t now, const or_options_t *options)
|
|
|
-{
|
|
|
- (void)now;
|
|
|
- (void)options;
|
|
|
-
|
|
|
- * close to expiring and warn the admin if it is. */
|
|
|
- v3_authority_check_key_expiry();
|
|
|
-#define CHECK_V3_CERTIFICATE_INTERVAL (5*60)
|
|
|
- return CHECK_V3_CERTIFICATE_INTERVAL;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
- * 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)) {
|
|
|
-
|
|
|
- * 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);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
- * 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.
|
|
@@ -2798,8 +2600,7 @@ dns_servers_relaunch_checks(void)
|
|
|
{
|
|
|
if (server_mode(get_options())) {
|
|
|
dns_reset_correctness_checks();
|
|
|
- if (periodic_events_initialized) {
|
|
|
- tor_assert(check_dns_honesty_event);
|
|
|
+ if (check_dns_honesty_event) {
|
|
|
periodic_event_reschedule(check_dns_honesty_event);
|
|
|
}
|
|
|
}
|
|
@@ -2809,8 +2610,6 @@ dns_servers_relaunch_checks(void)
|
|
|
void
|
|
|
initialize_mainloop_events(void)
|
|
|
{
|
|
|
- initialize_periodic_events();
|
|
|
-
|
|
|
if (!schedule_active_linked_connections_event) {
|
|
|
schedule_active_linked_connections_event =
|
|
|
mainloop_event_postloop_new(schedule_active_linked_connections_cb, NULL);
|
|
@@ -2828,9 +2627,17 @@ do_main_loop(void)
|
|
|
|
|
|
* events being present does not assert.
|
|
|
*/
|
|
|
- initialize_periodic_events();
|
|
|
+ tor_assert(periodic_events_initialized);
|
|
|
initialize_mainloop_events();
|
|
|
|
|
|
+ periodic_events_connect_all();
|
|
|
+
|
|
|
+ struct timeval one_second = { 1, 0 };
|
|
|
+ initialize_periodic_events_event = tor_evtimer_new(
|
|
|
+ tor_libevent_get_base(),
|
|
|
+ initialize_periodic_events_cb, NULL);
|
|
|
+ event_add(initialize_periodic_events_event, &one_second);
|
|
|
+
|
|
|
#ifdef HAVE_SYSTEMD_209
|
|
|
uint64_t watchdog_delay;
|
|
|
|