From b25b8150c282c28d3fa23330891fda7adbbfe584 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 4 Dec 2018 11:56:05 -0500 Subject: 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. --- src/app/config/or_state_st.h | 7 +++++++ src/app/config/statefile.c | 8 ++++++++ 2 files changed, 15 insertions(+) (limited to 'src/app/config') diff --git a/src/app/config/or_state_st.h b/src/app/config/or_state_st.h index d95df6236b..00968d3731 100644 --- a/src/app/config/or_state_st.h +++ b/src/app/config/or_state_st.h @@ -87,6 +87,13 @@ struct or_state_t { /** When did we last rotate our onion key? "0" for 'no idea'. */ 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 diff --git a/src/app/config/statefile.c b/src/app/config/statefile.c index 4ba7be1519..97b96f1149 100644 --- a/src/app/config/statefile.c +++ b/src/app/config/statefile.c @@ -34,6 +34,7 @@ #include "app/config/config.h" #include "app/config/confparse.h" #include "core/mainloop/mainloop.h" +#include "core/mainloop/netstatus.h" #include "core/mainloop/connection.h" #include "feature/control/control.h" #include "feature/client/entrynodes.h" @@ -132,6 +133,9 @@ static config_var_t state_vars_[] = { VAR("CircuitBuildTimeBin", LINELIST_S, BuildtimeHistogram, NULL), VAR("BuildtimeHistogram", LINELIST_V, BuildtimeHistogram, NULL), + V(MinutesSinceUserActivity, UINT, NULL), + V(Dormant, AUTOBOOL, "auto"), + END_OF_CONFIG_VARS }; @@ -309,6 +313,8 @@ or_state_set(or_state_t *new_state) get_circuit_build_times_mutable(),global_state) < 0) { ret = -1; } + netstatus_load_from_state(global_state, time(NULL)); + return ret; } @@ -500,6 +506,8 @@ or_state_save(time_t now) entry_guards_update_state(global_state); rep_hist_update_state(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())) accounting_run_housekeeping(now); -- cgit v1.2.3-54-g00ecf From 4f558843151f0c49c077d3d9a1cd8a187904a024 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 4 Dec 2018 12:07:23 -0500 Subject: Add an option to start tor in dormant mode for the first time. --- doc/tor.1.txt | 11 ++++++++++- src/app/config/config.c | 1 + src/app/config/or_options_st.h | 4 ++++ src/core/mainloop/netstatus.c | 10 ++++++++-- 4 files changed, 23 insertions(+), 3 deletions(-) (limited to 'src/app/config') diff --git a/doc/tor.1.txt b/doc/tor.1.txt index 8e6ec7f1a2..82c9e34de4 100644 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@ -1803,11 +1803,20 @@ The following options are useful only for clients (that is, if Does not affect servers or onion services. Must be at least 10 minutes. (Default: 24 hours) -[[DormantTimeoutDisabledByIdleStreams]] **DormantTimeoutDisabledByIdleStreams **0**|**1**:: +[[DormantTimeoutDisabledByIdleStreams]] **DormantTimeoutDisabledByIdleStreams** **0**|**1**:: If true, then any open client stream (even one not reading or writing) counts as client activity for the purpose of DormantClientTimeout. If false, then only network activity counts. (Default: 1) +[[DormantOnFirstStartup]] **DormantOnFirstStartup** **0**|**1**:: + If true, then the first time Tor starts up with a fresh DataDirectory, + it starts in dormant mode, and takes no actions until the user has made + a request. (This mode is recommended if installing a Tor client for a + user who might not actually use it.) If false, Tor bootstraps the first + time it is started, whether it sees a user request or not. + + + After the first time Tor starts, it begins in dormant mode if it was + dormant before, and not otherwise. (Default: 0) SERVER OPTIONS -------------- diff --git a/src/app/config/config.c b/src/app/config/config.c index d40e362b32..dcefa3d6a4 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -392,6 +392,7 @@ static config_var_t option_vars_[] = { OBSOLETE("DNSListenAddress"), V(DormantClientTimeout, INTERVAL, "24 hours"), V(DormantTimeoutDisabledByIdleStreams, BOOL, "1"), + V(DormantOnFirstStartup, BOOL, "0"), /* DoS circuit creation options. */ V(DoSCircuitCreationEnabled, AUTOBOOL, "auto"), V(DoSCircuitCreationMinConnections, UINT, "0"), diff --git a/src/app/config/or_options_st.h b/src/app/config/or_options_st.h index 9065248a9c..c2bc1079a5 100644 --- a/src/app/config/or_options_st.h +++ b/src/app/config/or_options_st.h @@ -1085,6 +1085,10 @@ struct or_options_t { * from becoming dormant. **/ int DormantTimeoutDisabledByIdleStreams; + + /** Boolean: true if Tor should be dormant the first time it starts with + * a datadirectory; false otherwise. */ + int DormantOnFirstStartup; }; #endif diff --git a/src/core/mainloop/netstatus.c b/src/core/mainloop/netstatus.c index 59fd8f8037..2426baae34 100644 --- a/src/core/mainloop/netstatus.c +++ b/src/core/mainloop/netstatus.c @@ -129,8 +129,14 @@ 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; + if (get_options()->DormantOnFirstStartup) { + last_activity = 0; + participating_on_network = false; + } else { + // Start up as active, treat activity as happening now. + last_activity = now; + participating_on_network = true; + } } else if (state->Dormant) { last_activity = 0; participating_on_network = false; -- cgit v1.2.3-54-g00ecf