dirauth_periodic.c (4911B)
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 check_authority_cert_callback(time_t now, const or_options_t *options) 42 { 43 (void)now; 44 (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 v3_authority_check_key_expiry(); 48 #define CHECK_V3_CERTIFICATE_INTERVAL (5*60) 49 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 dirvote_callback(time_t now, const or_options_t *options) 62 { 63 if (!authdir_mode_v3(options)) { 64 tor_assert_nonfatal_unreached(); 65 return 3600; 66 } 67 68 time_t next = dirvote_act(options, now); 69 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 return 3600; 74 } 75 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 reschedule_dirvote(const or_options_t *options) 84 { 85 if (authdir_mode_v3(options)) { 86 periodic_event_reschedule(&dirvote_event); 87 } 88 } 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 save_stability_callback(time_t now, const or_options_t *options) 96 { 97 if (authdir_mode_tests_reachability(options)) { 98 if (rep_hist_record_mtbf_data(now, 1)<0) { 99 log_warn(LD_GENERAL, "Couldn't store mtbf data."); 100 } 101 } 102 #define SAVE_STABILITY_INTERVAL (30*60) 103 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 launch_reachability_tests_callback(time_t now, const or_options_t *options) 114 { 115 if (authdir_mode_tests_reachability(options) && 116 !net_is_disabled()) { 117 /* try to determine reachability of the other Tor relays */ 118 dirserv_test_reachability(now); 119 } 120 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 downrate_stability_callback(time_t now, const or_options_t *options) 131 { 132 (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 time_t next = rep_hist_downrate_old_runs(now); 137 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 write_bridge_ns_callback(time_t now, const or_options_t *options) 148 { 149 if (options->BridgeAuthoritativeDir) { 150 bridgeauth_dump_bridge_status_to_file(now); 151 #define BRIDGE_STATUSFILE_INTERVAL (30*60) 152 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 dirauth_register_periodic_events(void) 161 { 162 periodic_events_register(&downrate_stability_event); 163 periodic_events_register(&launch_reachability_tests_event); 164 periodic_events_register(&save_stability_event); 165 periodic_events_register(&check_authority_cert_event); 166 periodic_events_register(&dirvote_event); 167 periodic_events_register(&write_bridge_ns_event); 168 }