netstatus.c (4906B)
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 netstatus.c 9 * @brief Track whether the network is disabled, dormant, etc. 10 **/ 11 12 #include "core/or/or.h" 13 #include "core/mainloop/netstatus.h" 14 #include "core/mainloop/mainloop.h" 15 #include "core/mainloop/mainloop_state_st.h" 16 #include "app/config/config.h" 17 #include "feature/hibernate/hibernate.h" 18 19 #include "app/config/or_state_st.h" 20 21 /** Return true iff our network is in some sense disabled or shutting down: 22 * either we're hibernating, entering hibernation, or the network is turned 23 * off with DisableNetwork. */ 24 int 25 net_is_disabled(void) 26 { 27 return get_options()->DisableNetwork || we_are_hibernating(); 28 } 29 30 /** Return true iff our network is in some sense "completely disabled" either 31 * we're fully hibernating or the network is turned off with 32 * DisableNetwork. */ 33 int 34 net_is_completely_disabled(void) 35 { 36 return get_options()->DisableNetwork || we_are_fully_hibernating(); 37 } 38 39 /** 40 * The time at which we've last seen "user activity" -- that is, any activity 41 * that should keep us as a participant on the network. 42 * 43 * This is not actually the true time. We will adjust this forward if 44 * our clock jumps, or if Tor is shut down for a while, so that the time 45 * since our last activity remains as it was before the jump or shutdown. 46 */ 47 static time_t last_user_activity_seen = 0; 48 49 /** 50 * True iff we are currently a "network participant" -- that is, we 51 * are building circuits, fetching directory information, and so on. 52 **/ 53 static bool participating_on_network = false; 54 55 /** 56 * Record the fact that we have seen "user activity" at the time now. Move 57 * "last activity seen" time forwards, but never backwards. 58 * 59 * If we were previously not participating on the network, set our 60 * participation status to true, and launch periodic events as appropriate. 61 **/ 62 void 63 note_user_activity(time_t now) 64 { 65 last_user_activity_seen = MAX(now, last_user_activity_seen); 66 67 if (! participating_on_network) { 68 log_notice(LD_GENERAL, "Tor is no longer dormant."); 69 set_network_participation(true); 70 schedule_rescan_periodic_events(); 71 } 72 } 73 74 /** 75 * Change the time at which "user activity" was last seen to <b>now</b>. 76 * 77 * Unlike note_user_actity, this function sets the time without checking 78 * whether it is in the past, and without causing any rescan of periodic events 79 * or change in participation status. 80 */ 81 void 82 reset_user_activity(time_t now) 83 { 84 last_user_activity_seen = now; 85 } 86 87 /** 88 * Return the most recent time at which we recorded "user activity". 89 **/ 90 time_t 91 get_last_user_activity_time(void) 92 { 93 return last_user_activity_seen; 94 } 95 96 /** 97 * Set the field that remembers whether we are currently participating on the 98 * network. Does not schedule or un-schedule periodic events. 99 **/ 100 void 101 set_network_participation(bool participation) 102 { 103 participating_on_network = participation; 104 } 105 106 /** 107 * Return true iff we are currently participating on the network. 108 **/ 109 bool 110 is_participating_on_network(void) 111 { 112 return participating_on_network; 113 } 114 115 /** 116 * Update 'state' with the last time at which we were active on the network. 117 **/ 118 void 119 netstatus_flush_to_state(mainloop_state_t *state, time_t now) 120 { 121 state->Dormant = ! participating_on_network; 122 if (participating_on_network) { 123 time_t sec_since_activity = MAX(0, now - last_user_activity_seen); 124 state->MinutesSinceUserActivity = (int)(sec_since_activity / 60); 125 } else { 126 state->MinutesSinceUserActivity = 0; 127 } 128 } 129 130 /** 131 * Update our current view of network participation from an or_state_t object. 132 **/ 133 void 134 netstatus_load_from_state(const mainloop_state_t *state, time_t now) 135 { 136 time_t last_activity; 137 if (state->Dormant == -1) { // Initial setup. 138 if (get_options()->DormantOnFirstStartup) { 139 last_activity = 0; 140 participating_on_network = false; 141 } else { 142 // Start up as active, treat activity as happening now. 143 last_activity = now; 144 participating_on_network = true; 145 } 146 } else if (state->Dormant) { 147 last_activity = 0; 148 participating_on_network = false; 149 } else { 150 last_activity = now - 60 * state->MinutesSinceUserActivity; 151 participating_on_network = true; 152 } 153 if (get_options()->DormantCanceledByStartup) { 154 last_activity = now; 155 participating_on_network = true; 156 } 157 if (! get_options()->DormantTimeoutEnabled) { 158 participating_on_network = true; 159 } 160 reset_user_activity(last_activity); 161 } 162 163 /** 164 * Adjust the time at which the user was last active by <b>seconds_diff</b> 165 * in response to a clock jump. 166 */ 167 void 168 netstatus_note_clock_jumped(time_t seconds_diff) 169 { 170 time_t last_active = get_last_user_activity_time(); 171 if (last_active) 172 reset_user_activity(last_active + seconds_diff); 173 }