tor/src/feature/dirauth/dirauth_periodic.c
Nick Mathewson 6f42efaa59 Move voteflags.[ch] to become dirauth only.
For various reasons, this was a nontrivial movement.  There are
several places in the code where we do something like "update the
flags on this routerstatus or node if we're an authority", and at
least one where we pretended to be an authority when we weren't.
2019-05-02 09:22:13 -04:00

162 lines
4.7 KiB
C

/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2019, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "core/or/or.h"
#include "app/config/or_options_st.h"
#include "core/mainloop/netstatus.h"
#include "feature/dirauth/reachability.h"
#include "feature/stats/rephist.h"
#include "feature/dirauth/bridgeauth.h"
#include "feature/dirauth/dirvote.h"
#include "feature/dirauth/dirauth_periodic.h"
#include "feature/dirauth/authmode.h"
#include "core/mainloop/periodic.h"
#define DECLARE_EVENT(name, roles, flags) \
static periodic_event_item_t name ## _event = \
PERIODIC_EVENT(name, \
PERIODIC_EVENT_ROLE_##roles, \
flags)
#define FL(name) (PERIODIC_EVENT_FLAG_##name)
/**
* 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;
/* 1e. Periodically, if we're a v3 authority, we check whether our cert is
* 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;
}
DECLARE_EVENT(check_authority_cert, DIRAUTH, 0);
/**
* 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);
}
DECLARE_EVENT(dirvote, DIRAUTH, FL(NEED_NET));
/** Reschedule the directory-authority voting event. Run this whenever the
* schedule has changed. */
void
reschedule_dirvote(const or_options_t *options)
{
if (authdir_mode_v3(options)) {
periodic_event_reschedule(&dirvote_event);
}
}
/**
* 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;
}
DECLARE_EVENT(save_stability, AUTHORITIES, 0);
/**
* 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()) {
/* try to determine reachability of the other Tor relays */
dirserv_test_reachability(now);
}
return REACHABILITY_TEST_INTERVAL;
}
DECLARE_EVENT(launch_reachability_tests, AUTHORITIES, FL(NEED_NET));
/**
* 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;
/* 1d. Periodically, we discount older stability information so that new
* 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);
}
DECLARE_EVENT(downrate_stability, AUTHORITIES, 0);
/**
* Periodic callback: if we're the bridge authority, write a networkstatus
* file to disk.
*/
static int
write_bridge_ns_callback(time_t now, const or_options_t *options)
{
if (options->BridgeAuthoritativeDir) {
bridgeauth_dump_bridge_status_to_file(now);
#define BRIDGE_STATUSFILE_INTERVAL (30*60)
return BRIDGE_STATUSFILE_INTERVAL;
}
return PERIODIC_EVENT_NO_UPDATE;
}
DECLARE_EVENT(write_bridge_ns, BRIDGEAUTH, 0);
void
dirauth_register_periodic_events(void)
{
periodic_events_register(&downrate_stability_event);
periodic_events_register(&launch_reachability_tests_event);
periodic_events_register(&save_stability_event);
periodic_events_register(&check_authority_cert_event);
periodic_events_register(&dirvote_event);
periodic_events_register(&write_bridge_ns_event);
}