aboutsummaryrefslogtreecommitdiff
path: root/src/or/connection_or.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2014-04-09 11:13:37 -0400
committerNick Mathewson <nickm@torproject.org>2014-06-11 11:27:04 -0400
commit463f6628d316cecdd612b4a78cd5349ab4a824c5 (patch)
tree427a4293b3cef5fdd75bef8a7f06389ab0ce7ceb /src/or/connection_or.c
parent24e0b1088acd94ceae3109107fa354b89309e2b7 (diff)
downloadtor-463f6628d316cecdd612b4a78cd5349ab4a824c5.tar
tor-463f6628d316cecdd612b4a78cd5349ab4a824c5.tar.gz
Give each or_connection_t a slightly randomized idle_timeout
Instead of killing an or_connection_t that has had no circuits for the last 3 minutes, give every or_connection_t a randomized timeout, so that an observer can't so easily infer from the connection close time the time at which its last circuit closed. Also, increase the base timeout for canonical connections from 3 minutes to 15 minutes. Fix for ticket 6799.
Diffstat (limited to 'src/or/connection_or.c')
-rw-r--r--src/or/connection_or.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 8e7cd9ea5..f03b18ddf 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -756,6 +756,45 @@ connection_or_update_token_buckets(smartlist_t *conns,
});
}
+/** How long do we wait before killing non-canonical 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-4.5 minutes is low enough
+ * that it kills most idle connections, without being so low that we cause
+ * clients to bounce on and off.
+ *
+ * For canonical connections, the limit is higher, at 15-22.5 minutes.
+ *
+ * For each OR connection, we randomly add up to 50% extra to its idle_timeout
+ * field, to avoid exposing when exactly the last circuit closed. Since we're
+ * storing idle_timeout in a uint16_t, don't let these values get higher than
+ * 12 hours or so without revising connection_or_set_canonical and/or expanding
+ * idle_timeout.
+ */
+#define IDLE_OR_CONN_TIMEOUT_NONCANONICAL 180
+#define IDLE_OR_CONN_TIMEOUT_CANONICAL 900
+
+/* Mark <b>or_conn</b> as canonical if <b>is_canonical</b> is set, and
+ * non-canonical otherwise. Adjust idle_timeout accordingly.
+ */
+void
+connection_or_set_canonical(or_connection_t *or_conn,
+ int is_canonical)
+{
+ const unsigned int timeout_base = is_canonical ?
+ IDLE_OR_CONN_TIMEOUT_CANONICAL : IDLE_OR_CONN_TIMEOUT_NONCANONICAL;
+
+ if (bool_eq(is_canonical, or_conn->is_canonical) &&
+ or_conn->idle_timeout != 0) {
+ /* Don't recalculate an existing idle_timeout unless the canonical
+ * status changed. */
+ return;
+ }
+
+ or_conn->is_canonical = !! is_canonical; /* force to a 1-bit boolean */
+ or_conn->idle_timeout = timeout_base + crypto_rand_int(timeout_base / 2);
+}
+
/** If we don't necessarily know the router we're connecting to, but we
* have an addr/port/id_digest, then fill in as much as we can. Start
* by checking to see if this describes a router we know.
@@ -780,7 +819,7 @@ connection_or_init_conn_from_address(or_connection_t *conn,
/* XXXX proposal 186 is making this more complex. For now, a conn
is canonical when it uses the _preferred_ address. */
if (tor_addr_eq(&conn->base_.addr, &node_ap.addr))
- conn->is_canonical = 1;
+ connection_or_set_canonical(conn, 1);
if (!started_here) {
/* Override the addr/port, so our log messages will make sense.
* This is dangerous, since if we ever try looking up a conn by