tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

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 }