mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 04:13:28 +01:00
close idle tls conns early
This commit is contained in:
parent
b264192083
commit
67b38d5068
6
changes/close_idle_conns_faster
Normal file
6
changes/close_idle_conns_faster
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
o Major bugfixes:
|
||||||
|
- Make relays more aggressive about closing TLS connections that
|
||||||
|
have no circuits on them. Tens of thousands of them were piling
|
||||||
|
up at the fast relays, causing the relays to run out of sockets
|
||||||
|
and memory. Bugfix on 0.2.0.22-rc (where clients started tunneling
|
||||||
|
their directory fetches over TLS).
|
@ -663,6 +663,15 @@ directory_info_has_arrived(time_t now, int from_cache)
|
|||||||
consider_testing_reachability(1, 1);
|
consider_testing_reachability(1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** How long do we wait before killing OR connections with no circuits?
|
||||||
|
* In Tor versions up to 0.2.1.25 and 0.2.2.12-alpha, we waited 15 minutes
|
||||||
|
* before cancelling these connections, which caused fast relays to accrue
|
||||||
|
* many many idle connections. Hopefully 3 minutes is low enough that
|
||||||
|
* it kills most idle connections, without being so low that we cause
|
||||||
|
* clients to bounce on and off.
|
||||||
|
*/
|
||||||
|
#define IDLE_OR_CONN_TIMEOUT 180
|
||||||
|
|
||||||
/** Perform regular maintenance tasks for a single connection. This
|
/** Perform regular maintenance tasks for a single connection. This
|
||||||
* function gets run once per second per connection by run_scheduled_events.
|
* function gets run once per second per connection by run_scheduled_events.
|
||||||
*/
|
*/
|
||||||
@ -673,6 +682,8 @@ run_connection_housekeeping(int i, time_t now)
|
|||||||
connection_t *conn = smartlist_get(connection_array, i);
|
connection_t *conn = smartlist_get(connection_array, i);
|
||||||
or_options_t *options = get_options();
|
or_options_t *options = get_options();
|
||||||
or_connection_t *or_conn;
|
or_connection_t *or_conn;
|
||||||
|
int past_keepalive =
|
||||||
|
now >= conn->timestamp_lastwritten + options->KeepalivePeriod;
|
||||||
|
|
||||||
if (conn->outbuf && !buf_datalen(conn->outbuf) && conn->type == CONN_TYPE_OR)
|
if (conn->outbuf && !buf_datalen(conn->outbuf) && conn->type == CONN_TYPE_OR)
|
||||||
TO_OR_CONN(conn)->timestamp_lastempty = now;
|
TO_OR_CONN(conn)->timestamp_lastempty = now;
|
||||||
@ -707,6 +718,9 @@ run_connection_housekeeping(int i, time_t now)
|
|||||||
if (!connection_speaks_cells(conn))
|
if (!connection_speaks_cells(conn))
|
||||||
return; /* we're all done here, the rest is just for OR conns */
|
return; /* we're all done here, the rest is just for OR conns */
|
||||||
|
|
||||||
|
/* If we haven't written to an OR connection for a while, then either nuke
|
||||||
|
the connection or send a keepalive, depending. */
|
||||||
|
|
||||||
or_conn = TO_OR_CONN(conn);
|
or_conn = TO_OR_CONN(conn);
|
||||||
|
|
||||||
if (or_conn->is_bad_for_new_circs && !or_conn->n_circuits) {
|
if (or_conn->is_bad_for_new_circs && !or_conn->n_circuits) {
|
||||||
@ -721,52 +735,45 @@ run_connection_housekeeping(int i, time_t now)
|
|||||||
"Tor gave up on the connection");
|
"Tor gave up on the connection");
|
||||||
connection_mark_for_close(conn);
|
connection_mark_for_close(conn);
|
||||||
conn->hold_open_until_flushed = 1;
|
conn->hold_open_until_flushed = 1;
|
||||||
return;
|
} else if (past_keepalive && !connection_state_is_open(conn)) {
|
||||||
}
|
/* We never managed to actually get this connection open and happy. */
|
||||||
|
log_info(LD_OR,"Expiring non-open OR connection to fd %d (%s:%d).",
|
||||||
/* If we haven't written to an OR connection for a while, then either nuke
|
conn->s,conn->address, conn->port);
|
||||||
the connection or send a keepalive, depending. */
|
connection_mark_for_close(conn);
|
||||||
if (now >= conn->timestamp_lastwritten + options->KeepalivePeriod) {
|
conn->hold_open_until_flushed = 1;
|
||||||
int maxCircuitlessPeriod = options->MaxCircuitDirtiness*3/2;
|
} else if (we_are_hibernating() && !or_conn->n_circuits &&
|
||||||
if (!connection_state_is_open(conn)) {
|
!buf_datalen(conn->outbuf)) {
|
||||||
/* We never managed to actually get this connection open and happy. */
|
/* We're hibernating, there's no circuits, and nothing to flush.*/
|
||||||
log_info(LD_OR,"Expiring non-open OR connection to fd %d (%s:%d).",
|
log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
|
||||||
conn->s,conn->address, conn->port);
|
"[Hibernating or exiting].",
|
||||||
connection_mark_for_close(conn);
|
conn->s,conn->address, conn->port);
|
||||||
conn->hold_open_until_flushed = 1;
|
connection_mark_for_close(conn);
|
||||||
} else if (we_are_hibernating() && !or_conn->n_circuits &&
|
conn->hold_open_until_flushed = 1;
|
||||||
!buf_datalen(conn->outbuf)) {
|
} else if (!or_conn->n_circuits &&
|
||||||
/* We're hibernating, there's no circuits, and nothing to flush.*/
|
now >= or_conn->timestamp_last_added_nonpadding +
|
||||||
log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
|
IDLE_OR_CONN_TIMEOUT) {
|
||||||
"[Hibernating or exiting].",
|
log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
|
||||||
conn->s,conn->address, conn->port);
|
"[idle %d].", conn->s,conn->address, conn->port,
|
||||||
connection_mark_for_close(conn);
|
(int)(now - or_conn->timestamp_last_added_nonpadding));
|
||||||
conn->hold_open_until_flushed = 1;
|
connection_mark_for_close(conn);
|
||||||
} else if (!or_conn->n_circuits &&
|
conn->hold_open_until_flushed = 1;
|
||||||
now >= or_conn->timestamp_last_added_nonpadding +
|
} else if (
|
||||||
maxCircuitlessPeriod) {
|
now >= or_conn->timestamp_lastempty + options->KeepalivePeriod*10 &&
|
||||||
log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
|
now >= conn->timestamp_lastwritten + options->KeepalivePeriod*10) {
|
||||||
"[idle].", conn->s,conn->address, conn->port);
|
log_fn(LOG_PROTOCOL_WARN,LD_PROTOCOL,
|
||||||
connection_mark_for_close(conn);
|
"Expiring stuck OR connection to fd %d (%s:%d). (%d bytes to "
|
||||||
conn->hold_open_until_flushed = 1;
|
"flush; %d seconds since last write)",
|
||||||
} else if (
|
conn->s, conn->address, conn->port,
|
||||||
now >= or_conn->timestamp_lastempty + options->KeepalivePeriod*10 &&
|
(int)buf_datalen(conn->outbuf),
|
||||||
now >= conn->timestamp_lastwritten + options->KeepalivePeriod*10) {
|
(int)(now-conn->timestamp_lastwritten));
|
||||||
log_fn(LOG_PROTOCOL_WARN,LD_PROTOCOL,
|
connection_mark_for_close(conn);
|
||||||
"Expiring stuck OR connection to fd %d (%s:%d). (%d bytes to "
|
} else if (past_keepalive && !buf_datalen(conn->outbuf)) {
|
||||||
"flush; %d seconds since last write)",
|
/* send a padding cell */
|
||||||
conn->s, conn->address, conn->port,
|
log_fn(LOG_DEBUG,LD_OR,"Sending keepalive to (%s:%d)",
|
||||||
(int)buf_datalen(conn->outbuf),
|
conn->address, conn->port);
|
||||||
(int)(now-conn->timestamp_lastwritten));
|
memset(&cell,0,sizeof(cell_t));
|
||||||
connection_mark_for_close(conn);
|
cell.command = CELL_PADDING;
|
||||||
} else if (!buf_datalen(conn->outbuf)) {
|
connection_or_write_cell_to_buf(&cell, or_conn);
|
||||||
/* either in clique mode, or we've got a circuit. send a padding cell. */
|
|
||||||
log_fn(LOG_DEBUG,LD_OR,"Sending keepalive to (%s:%d)",
|
|
||||||
conn->address, conn->port);
|
|
||||||
memset(&cell,0,sizeof(cell_t));
|
|
||||||
cell.command = CELL_PADDING;
|
|
||||||
connection_or_write_cell_to_buf(&cell, or_conn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user