Remember in our state file how long we've spent since user activity

Rather than initializing the "Dormant" status to "off" and the "last
activity" count to "now", initialize them based on our state file:
stay dormant if we were dormant, or remember the amount of time
we've spent inactive.
This commit is contained in:
Nick Mathewson 2018-12-04 11:56:05 -05:00
parent 0d9dc13e08
commit b25b8150c2
5 changed files with 60 additions and 6 deletions

View File

@ -87,6 +87,13 @@ struct or_state_t {
/** When did we last rotate our onion key? "0" for 'no idea'. */ /** When did we last rotate our onion key? "0" for 'no idea'. */
time_t LastRotatedOnionKey; time_t LastRotatedOnionKey;
/** Number of minutes since the last user-initiated request (as defined by
* the dormant net-status system.) Set to zero if we are dormant. */
int MinutesSinceUserActivity;
/** True if we were dormant when we last wrote the file; false if we
* weren't. "auto" on initial startup. */
int Dormant;
}; };
#endif #endif

View File

@ -34,6 +34,7 @@
#include "app/config/config.h" #include "app/config/config.h"
#include "app/config/confparse.h" #include "app/config/confparse.h"
#include "core/mainloop/mainloop.h" #include "core/mainloop/mainloop.h"
#include "core/mainloop/netstatus.h"
#include "core/mainloop/connection.h" #include "core/mainloop/connection.h"
#include "feature/control/control.h" #include "feature/control/control.h"
#include "feature/client/entrynodes.h" #include "feature/client/entrynodes.h"
@ -132,6 +133,9 @@ static config_var_t state_vars_[] = {
VAR("CircuitBuildTimeBin", LINELIST_S, BuildtimeHistogram, NULL), VAR("CircuitBuildTimeBin", LINELIST_S, BuildtimeHistogram, NULL),
VAR("BuildtimeHistogram", LINELIST_V, BuildtimeHistogram, NULL), VAR("BuildtimeHistogram", LINELIST_V, BuildtimeHistogram, NULL),
V(MinutesSinceUserActivity, UINT, NULL),
V(Dormant, AUTOBOOL, "auto"),
END_OF_CONFIG_VARS END_OF_CONFIG_VARS
}; };
@ -309,6 +313,8 @@ or_state_set(or_state_t *new_state)
get_circuit_build_times_mutable(),global_state) < 0) { get_circuit_build_times_mutable(),global_state) < 0) {
ret = -1; ret = -1;
} }
netstatus_load_from_state(global_state, time(NULL));
return ret; return ret;
} }
@ -500,6 +506,8 @@ or_state_save(time_t now)
entry_guards_update_state(global_state); entry_guards_update_state(global_state);
rep_hist_update_state(global_state); rep_hist_update_state(global_state);
circuit_build_times_update_state(get_circuit_build_times(), global_state); circuit_build_times_update_state(get_circuit_build_times(), global_state);
netstatus_flush_to_state(global_state, now);
if (accounting_is_enabled(get_options())) if (accounting_is_enabled(get_options()))
accounting_run_housekeeping(now); accounting_run_housekeeping(now);

View File

@ -1627,6 +1627,7 @@ schedule_rescan_periodic_events,(void))
void void
rescan_periodic_events(const or_options_t *options) rescan_periodic_events(const or_options_t *options)
{ {
puts("RESCAN");
tor_assert(options); tor_assert(options);
/* Avoid scanning the event list if we haven't initialized it yet. This is /* Avoid scanning the event list if we haven't initialized it yet. This is
@ -2818,12 +2819,6 @@ initialize_mainloop_events(void)
int int
do_main_loop(void) do_main_loop(void)
{ {
/* For now, starting Tor always counts as user activity. Later, we might
* have an option to control this.
*/
reset_user_activity(approx_time());
set_network_participation(true);
/* initialize the periodic events first, so that code that depends on the /* initialize the periodic events first, so that code that depends on the
* events being present does not assert. * events being present does not assert.
*/ */

View File

@ -10,6 +10,8 @@
#include "app/config/config.h" #include "app/config/config.h"
#include "feature/hibernate/hibernate.h" #include "feature/hibernate/hibernate.h"
#include "app/config/or_state_st.h"
/** Return true iff our network is in some sense disabled or shutting down: /** Return true iff our network is in some sense disabled or shutting down:
* either we're hibernating, entering hibernation, or the network is turned * either we're hibernating, entering hibernation, or the network is turned
* off with DisableNetwork. */ * off with DisableNetwork. */
@ -31,6 +33,10 @@ net_is_completely_disabled(void)
/** /**
* The time at which we've last seen "user activity" -- that is, any activity * The time at which we've last seen "user activity" -- that is, any activity
* that should keep us as a participant on the network. * that should keep us as a participant on the network.
*
* This is not actually the true time. We will adjust this forward if
* our clock jumps, or if Tor is shut down for a while, so that the time
* since our last activity remains as it was before the jump or shutdown.
*/ */
static time_t last_user_activity_seen = 0; static time_t last_user_activity_seen = 0;
@ -99,3 +105,38 @@ is_participating_on_network(void)
{ {
return participating_on_network; return participating_on_network;
} }
/**
* Update 'state' with the last time at which we were active on the network.
**/
void
netstatus_flush_to_state(or_state_t *state, time_t now)
{
state->Dormant = ! participating_on_network;
if (participating_on_network) {
time_t sec_since_activity = MAX(0, now - last_user_activity_seen);
state->MinutesSinceUserActivity = (int)(sec_since_activity / 60);
} else {
state->MinutesSinceUserActivity = 0;
}
}
/**
* Update our current view of network participation from an or_state_t object.
**/
void
netstatus_load_from_state(const or_state_t *state, time_t now)
{
time_t last_activity;
if (state->Dormant == -1) { // Initial setup.
last_activity = now;
participating_on_network = true;
} else if (state->Dormant) {
last_activity = 0;
participating_on_network = false;
} else {
last_activity = now - 60 * state->MinutesSinceUserActivity;
participating_on_network = true;
}
reset_user_activity(last_activity);
}

View File

@ -17,4 +17,7 @@ time_t get_last_user_activity_time(void);
void set_network_participation(bool participation); void set_network_participation(bool participation);
bool is_participating_on_network(void); bool is_participating_on_network(void);
void netstatus_flush_to_state(or_state_t *state, time_t now);
void netstatus_load_from_state(const or_state_t *state, time_t now);
#endif #endif