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 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 331 : net_is_disabled(void) 26 : { 27 331 : 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 0 : net_is_completely_disabled(void) 35 : { 36 0 : 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 11 : note_user_activity(time_t now) 64 : { 65 11 : last_user_activity_seen = MAX(now, last_user_activity_seen); 66 : 67 11 : if (! participating_on_network) { 68 6 : log_notice(LD_GENERAL, "Tor is no longer dormant."); 69 6 : set_network_participation(true); 70 6 : schedule_rescan_periodic_events(); 71 : } 72 11 : } 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 21 : reset_user_activity(time_t now) 83 : { 84 21 : last_user_activity_seen = now; 85 21 : } 86 : 87 : /** 88 : * Return the most recent time at which we recorded "user activity". 89 : **/ 90 : time_t 91 26 : get_last_user_activity_time(void) 92 : { 93 26 : 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 23 : set_network_participation(bool participation) 102 : { 103 23 : participating_on_network = participation; 104 23 : } 105 : 106 : /** 107 : * Return true iff we are currently participating on the network. 108 : **/ 109 : bool 110 381 : is_participating_on_network(void) 111 : { 112 381 : 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 6 : netstatus_flush_to_state(mainloop_state_t *state, time_t now) 120 : { 121 6 : state->Dormant = ! participating_on_network; 122 6 : if (participating_on_network) { 123 5 : time_t sec_since_activity = MAX(0, now - last_user_activity_seen); 124 5 : state->MinutesSinceUserActivity = (int)(sec_since_activity / 60); 125 : } else { 126 1 : state->MinutesSinceUserActivity = 0; 127 : } 128 6 : } 129 : 130 : /** 131 : * Update our current view of network participation from an or_state_t object. 132 : **/ 133 : void 134 8 : netstatus_load_from_state(const mainloop_state_t *state, time_t now) 135 : { 136 8 : time_t last_activity; 137 8 : if (state->Dormant == -1) { // Initial setup. 138 5 : if (get_options()->DormantOnFirstStartup) { 139 0 : last_activity = 0; 140 0 : participating_on_network = false; 141 : } else { 142 : // Start up as active, treat activity as happening now. 143 5 : last_activity = now; 144 5 : participating_on_network = true; 145 : } 146 3 : } else if (state->Dormant) { 147 2 : last_activity = 0; 148 2 : participating_on_network = false; 149 : } else { 150 1 : last_activity = now - 60 * state->MinutesSinceUserActivity; 151 1 : participating_on_network = true; 152 : } 153 8 : if (get_options()->DormantCanceledByStartup) { 154 1 : last_activity = now; 155 1 : participating_on_network = true; 156 : } 157 8 : if (! get_options()->DormantTimeoutEnabled) { 158 0 : participating_on_network = true; 159 : } 160 8 : reset_user_activity(last_activity); 161 8 : } 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 2 : netstatus_note_clock_jumped(time_t seconds_diff) 169 : { 170 2 : time_t last_active = get_last_user_activity_time(); 171 2 : if (last_active) 172 2 : reset_user_activity(last_active + seconds_diff); 173 2 : }