Line data Source code
1 : /* Copyright (c) 2001 Matej Pfajfar.
2 : * Copyright (c) 2001-2004, Roger Dingledine.
3 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 : * Copyright (c) 2007-2021, The Tor Project, Inc. */
5 : /* See LICENSE for licensing information */
6 :
7 : /**
8 : * @file dirauth_periodic.c
9 : * @brief Peridoic events for directory authorities.
10 : **/
11 :
12 : #include "core/or/or.h"
13 :
14 : #include "app/config/or_options_st.h"
15 : #include "core/mainloop/netstatus.h"
16 : #include "feature/dirauth/reachability.h"
17 : #include "feature/stats/rephist.h"
18 :
19 : #include "feature/dirauth/bridgeauth.h"
20 : #include "feature/dirauth/dirvote.h"
21 : #include "feature/dirauth/dirauth_periodic.h"
22 : #include "feature/dirauth/authmode.h"
23 :
24 : #include "core/mainloop/periodic.h"
25 :
26 : #ifndef COCCI
27 : #define DECLARE_EVENT(name, roles, flags) \
28 : static periodic_event_item_t name ## _event = \
29 : PERIODIC_EVENT(name, \
30 : PERIODIC_EVENT_ROLE_##roles, \
31 : flags)
32 : #endif /* !defined(COCCI) */
33 :
34 : #define FL(name) (PERIODIC_EVENT_FLAG_##name)
35 :
36 : /**
37 : * Periodic callback: if we're an authority, check on our authority
38 : * certificate (the one that authenticates our authority signing key).
39 : */
40 : static int
41 0 : check_authority_cert_callback(time_t now, const or_options_t *options)
42 : {
43 0 : (void)now;
44 0 : (void)options;
45 : /* 1e. Periodically, if we're a v3 authority, we check whether our cert is
46 : * close to expiring and warn the admin if it is. */
47 0 : v3_authority_check_key_expiry();
48 : #define CHECK_V3_CERTIFICATE_INTERVAL (5*60)
49 0 : return CHECK_V3_CERTIFICATE_INTERVAL;
50 : }
51 :
52 : DECLARE_EVENT(check_authority_cert, DIRAUTH, 0);
53 :
54 : /**
55 : * Scheduled callback: Run directory-authority voting functionality.
56 : *
57 : * The schedule is a bit complicated here, so dirvote_act() manages the
58 : * schedule itself.
59 : **/
60 : static int
61 0 : dirvote_callback(time_t now, const or_options_t *options)
62 : {
63 0 : if (!authdir_mode_v3(options)) {
64 0 : tor_assert_nonfatal_unreached();
65 0 : return 3600;
66 : }
67 :
68 0 : time_t next = dirvote_act(options, now);
69 0 : if (BUG(next == TIME_MAX)) {
70 : /* This shouldn't be returned unless we called dirvote_act() without
71 : * being an authority. If it happens, maybe our configuration will
72 : * fix itself in an hour or so? */
73 0 : return 3600;
74 : }
75 0 : return safe_timer_diff(now, next);
76 : }
77 :
78 : DECLARE_EVENT(dirvote, DIRAUTH, FL(NEED_NET));
79 :
80 : /** Reschedule the directory-authority voting event. Run this whenever the
81 : * schedule has changed. */
82 : void
83 5 : reschedule_dirvote(const or_options_t *options)
84 : {
85 5 : if (authdir_mode_v3(options)) {
86 0 : periodic_event_reschedule(&dirvote_event);
87 : }
88 5 : }
89 :
90 : /**
91 : * Periodic callback: if we're an authority, record our measured stability
92 : * information from rephist in an mtbf file.
93 : */
94 : static int
95 0 : save_stability_callback(time_t now, const or_options_t *options)
96 : {
97 0 : if (authdir_mode_tests_reachability(options)) {
98 0 : if (rep_hist_record_mtbf_data(now, 1)<0) {
99 0 : log_warn(LD_GENERAL, "Couldn't store mtbf data.");
100 : }
101 : }
102 : #define SAVE_STABILITY_INTERVAL (30*60)
103 0 : return SAVE_STABILITY_INTERVAL;
104 : }
105 :
106 : DECLARE_EVENT(save_stability, AUTHORITIES, 0);
107 :
108 : /**
109 : * Periodic callback: if we're an authority, make sure we test
110 : * the routers on the network for reachability.
111 : */
112 : static int
113 0 : launch_reachability_tests_callback(time_t now, const or_options_t *options)
114 : {
115 0 : if (authdir_mode_tests_reachability(options) &&
116 0 : !net_is_disabled()) {
117 : /* try to determine reachability of the other Tor relays */
118 0 : dirserv_test_reachability(now);
119 : }
120 0 : return REACHABILITY_TEST_INTERVAL;
121 : }
122 :
123 : DECLARE_EVENT(launch_reachability_tests, AUTHORITIES, FL(NEED_NET));
124 :
125 : /**
126 : * Periodic callback: if we're an authority, discount the stability
127 : * information (and other rephist information) that's older.
128 : */
129 : static int
130 0 : downrate_stability_callback(time_t now, const or_options_t *options)
131 : {
132 0 : (void)options;
133 : /* 1d. Periodically, we discount older stability information so that new
134 : * stability info counts more, and save the stability information to disk as
135 : * appropriate. */
136 0 : time_t next = rep_hist_downrate_old_runs(now);
137 0 : return safe_timer_diff(now, next);
138 : }
139 :
140 : DECLARE_EVENT(downrate_stability, AUTHORITIES, 0);
141 :
142 : /**
143 : * Periodic callback: if we're the bridge authority, write a networkstatus
144 : * file to disk.
145 : */
146 : static int
147 0 : write_bridge_ns_callback(time_t now, const or_options_t *options)
148 : {
149 0 : if (options->BridgeAuthoritativeDir) {
150 0 : bridgeauth_dump_bridge_status_to_file(now);
151 : #define BRIDGE_STATUSFILE_INTERVAL (30*60)
152 0 : return BRIDGE_STATUSFILE_INTERVAL;
153 : }
154 : return PERIODIC_EVENT_NO_UPDATE;
155 : }
156 :
157 : DECLARE_EVENT(write_bridge_ns, BRIDGEAUTH, 0);
158 :
159 : void
160 244 : dirauth_register_periodic_events(void)
161 : {
162 244 : periodic_events_register(&downrate_stability_event);
163 244 : periodic_events_register(&launch_reachability_tests_event);
164 244 : periodic_events_register(&save_stability_event);
165 244 : periodic_events_register(&check_authority_cert_event);
166 244 : periodic_events_register(&dirvote_event);
167 244 : periodic_events_register(&write_bridge_ns_event);
168 244 : }
|