mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 13:13:44 +01:00
Add options to control dormant-client feature.
The DormantClientTimeout option controls how long Tor will wait before going dormant. It also provides a way to disable the feature by setting DormantClientTimeout to e.g. "50 years". The DormantTimeoutDisabledByIdleStreams option controls whether open but inactive streams count as "client activity". To implement it, I had to make it so that reading or writing on a client stream *always* counts as activity. Closes ticket 28429.
This commit is contained in:
parent
53ccdb6945
commit
3743f79695
@ -1789,6 +1789,19 @@ The following options are useful only for clients (that is, if
|
||||
Try this many simultaneous connections to download a consensus before
|
||||
waiting for one to complete, timeout, or error out. (Default: 3)
|
||||
|
||||
[[DormantClientTimeout]] **DormantClientTimeout** __N__ **minutes**|**hours**|**days**|**weeks**::
|
||||
If Tor spends this much time without any client activity,
|
||||
enter a dormant state where automatic circuits are not built, and
|
||||
directory information is not fetched.
|
||||
Does not affect servers or onion services. Must be at least 10 minutes.
|
||||
(Default: 24 hours)
|
||||
|
||||
[[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)
|
||||
|
||||
|
||||
SERVER OPTIONS
|
||||
--------------
|
||||
|
||||
|
@ -389,6 +389,8 @@ static config_var_t option_vars_[] = {
|
||||
OBSOLETE("DynamicDHGroups"),
|
||||
VPORT(DNSPort),
|
||||
OBSOLETE("DNSListenAddress"),
|
||||
V(DormantClientTimeout, INTERVAL, "24 hours"),
|
||||
V(DormantTimeoutDisabledByIdleStreams, BOOL, "1"),
|
||||
/* DoS circuit creation options. */
|
||||
V(DoSCircuitCreationEnabled, AUTOBOOL, "auto"),
|
||||
V(DoSCircuitCreationMinConnections, UINT, "0"),
|
||||
@ -3836,6 +3838,10 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
||||
"default.");
|
||||
}
|
||||
|
||||
if (options->DormantClientTimeout < 10*60 && !options->TestingTorNetwork) {
|
||||
REJECT("DormantClientTimeout is too low. It must be at least 10 minutes.");
|
||||
}
|
||||
|
||||
if (options->PathBiasNoticeRate > 1.0) {
|
||||
tor_asprintf(msg,
|
||||
"PathBiasNoticeRate is too high. "
|
||||
|
@ -1072,6 +1072,16 @@ struct or_options_t {
|
||||
|
||||
/** Autobool: Do we refuse single hop client rendezvous? */
|
||||
int DoSRefuseSingleHopClientRendezvous;
|
||||
|
||||
/** Interval: how long without activity does it take for a client
|
||||
* to become dormant?
|
||||
**/
|
||||
int DormantClientTimeout;
|
||||
|
||||
/** Boolean: true if having an idle stream is sufficient to prevent a client
|
||||
* from becoming dormant.
|
||||
**/
|
||||
int DormantTimeoutDisabledByIdleStreams;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -2018,24 +2018,25 @@ check_network_participation_callback(time_t now, const or_options_t *options)
|
||||
goto found_activity;
|
||||
}
|
||||
|
||||
/* XXXX Add an option to never become dormant. */
|
||||
|
||||
/* If we have any currently open entry streams other than "linked"
|
||||
* connections used for directory requests, those count as user activity.
|
||||
*/
|
||||
/* XXXX make this configurable? */
|
||||
if (connection_get_by_type_nonlinked(CONN_TYPE_AP) != NULL) {
|
||||
goto found_activity;
|
||||
if (options->DormantTimeoutDisabledByIdleStreams) {
|
||||
if (connection_get_by_type_nonlinked(CONN_TYPE_AP) != NULL) {
|
||||
goto found_activity;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXXX Make this configurable? */
|
||||
/** How often do we check whether we have had network activity? */
|
||||
#define CHECK_PARTICIPATION_INTERVAL (5*60)
|
||||
|
||||
/** Become dormant if there has been no user activity in this long. */
|
||||
/* XXXX make this configurable! */
|
||||
#define BECOME_DORMANT_AFTER_INACTIVITY (24*60*60)
|
||||
if (get_last_user_activity_time() + BECOME_DORMANT_AFTER_INACTIVITY >= now) {
|
||||
/* Become dormant if there has been no user activity in a long time.
|
||||
* (The funny checks below are in order to prevent overflow.) */
|
||||
time_t time_since_last_activity = 0;
|
||||
if (get_last_user_activity_time() < now)
|
||||
time_since_last_activity = now - get_last_user_activity_time();
|
||||
if (time_since_last_activity >= options->DormantClientTimeout) {
|
||||
log_notice(LD_GENERAL, "No user activity in a long time: becoming"
|
||||
" dormant.");
|
||||
set_network_participation(false);
|
||||
|
@ -62,6 +62,7 @@
|
||||
#include "app/config/config.h"
|
||||
#include "core/mainloop/connection.h"
|
||||
#include "core/mainloop/mainloop.h"
|
||||
#include "core/mainloop/netstatus.h"
|
||||
#include "core/or/channel.h"
|
||||
#include "core/or/circuitbuild.h"
|
||||
#include "core/or/circuitlist.h"
|
||||
@ -297,6 +298,11 @@ connection_edge_process_inbuf(edge_connection_t *conn, int package_partial)
|
||||
}
|
||||
return 0;
|
||||
case AP_CONN_STATE_OPEN:
|
||||
if (! conn->base_.linked) {
|
||||
note_user_activity(approx_time());
|
||||
}
|
||||
|
||||
/* falls through. */
|
||||
case EXIT_CONN_STATE_OPEN:
|
||||
if (connection_edge_package_raw_inbuf(conn, package_partial, NULL) < 0) {
|
||||
/* (We already sent an end cell if possible) */
|
||||
@ -751,6 +757,11 @@ connection_edge_flushed_some(edge_connection_t *conn)
|
||||
{
|
||||
switch (conn->base_.state) {
|
||||
case AP_CONN_STATE_OPEN:
|
||||
if (! conn->base_.linked) {
|
||||
note_user_activity(approx_time());
|
||||
}
|
||||
|
||||
/* falls through. */
|
||||
case EXIT_CONN_STATE_OPEN:
|
||||
connection_edge_consider_sending_sendme(conn);
|
||||
break;
|
||||
|
@ -425,6 +425,7 @@ get_options_test_data(const char *conf)
|
||||
// with options_init(), but about a dozen tests break when I do that.
|
||||
// Being kinda lame and just fixing the immedate breakage for now..
|
||||
result->opt->ConnectionPadding = -1; // default must be "auto"
|
||||
result->opt->DormantClientTimeout = 1800; // must be over 600.
|
||||
|
||||
rv = config_get_lines(conf, &cl, 1);
|
||||
tt_int_op(rv, OP_EQ, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user