commit 8b238d39ece8b9cfb82cba1a61766e719a701edf
parent c75383bd668cbffb4cdb49531fd3edcbcbe3293a
Author: Nick Mathewson <nickm@torproject.org>
Date: Tue, 4 Nov 2025 08:31:52 -0500
KeepaliveIsolateSOCKSAuth: expire based on time of last _use_.
Formerly, we expired circuits affected by KeepaliveIsolateSOCKSAuth
based on the time when a stream was last attached to them, which would
sometimes result in circuits closing immediately after their last stream
was closed. Now, we update the "dirty timestamp" on circuits whenever a
stream is removed, so that they'll expire based on the time when they
last had a circuit.
This implements the "easy version" of proposal 368.
Closes #41157.
Diffstat:
2 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/changes/ticket41157 b/changes/ticket41157
@@ -0,0 +1,6 @@
+ o Minor features (security, reliability):
+ - When KeepaliveIsolateSOCKSAuth is keeping a circuit alive,
+ expire the circuit based on when it was last in use for any stream,
+ not (as we did before) based on when a stream was last attached to it.
+ Closes ticket 41157. Implements a minimal version of
+ Proposal 368.
diff --git a/src/core/or/circuituse.c b/src/core/or/circuituse.c
@@ -79,6 +79,8 @@
STATIC void circuit_expire_old_circuits_clientside(void);
static void circuit_increment_failure_count(void);
+static bool connection_ap_socks_iso_keepalive_enabled(
+ const entry_connection_t *);
/** Check whether the hidden service destination of the stream at
* <b>edge_conn</b> is the same as the destination of the circuit at
@@ -1357,6 +1359,7 @@ void
circuit_detach_stream(circuit_t *circ, edge_connection_t *conn)
{
edge_connection_t *prevconn;
+ bool update_dirty = false;
tor_assert(circ);
tor_assert(conn);
@@ -1364,6 +1367,9 @@ circuit_detach_stream(circuit_t *circ, edge_connection_t *conn)
if (conn->base_.type == CONN_TYPE_AP) {
entry_connection_t *entry_conn = EDGE_TO_ENTRY_CONN(conn);
entry_conn->may_use_optimistic_data = 0;
+ // When KeepAliveIsolateSOCKSAuth is in effect, we update the dirty
+ // time on close as well as on open.
+ update_dirty = connection_ap_socks_iso_keepalive_enabled(entry_conn);
}
conn->cpath_layer = NULL; /* don't keep a stale pointer */
conn->on_circuit = NULL;
@@ -1389,6 +1395,10 @@ circuit_detach_stream(circuit_t *circ, edge_connection_t *conn)
log_debug(LD_APP, "Removing stream %d from circ %u",
conn->stream_id, (unsigned)circ->n_circ_id);
+ if (update_dirty) {
+ circ->timestamp_dirty = approx_time();
+ }
+
/* If the stream was removed, and it was a rend stream, decrement the
* number of streams on the circuit associated with the rend service.
*/