summaryrefslogtreecommitdiff
path: root/src/or/circuitlist.c
diff options
context:
space:
mode:
authorMike Perry <mikeperry-git@torproject.org>2017-02-21 21:28:00 -0500
committerNick Mathewson <nickm@torproject.org>2017-05-08 13:49:22 -0400
commitd5a151a06788c28ac1c50398c6e571d484774f47 (patch)
treed2e4f2719130250e428f1991a01511c89e589a29 /src/or/circuitlist.c
parentb0e92634d85a3bf7612a6ce0339b96e4aad1e0bb (diff)
downloadtor-d5a151a06788c28ac1c50398c6e571d484774f47.tar.gz
tor-d5a151a06788c28ac1c50398c6e571d484774f47.zip
Bug 17592: Clean up connection timeout logic.
This unifies CircuitIdleTimeout and PredictedCircsRelevanceTime into a single option, and randomizes it. It also gives us control over the default value as well as relay-to-relay connection lifespan through the consensus. Conflicts: src/or/circuituse.c src/or/config.c src/or/main.c src/test/testing_common.c
Diffstat (limited to 'src/or/circuitlist.c')
-rw-r--r--src/or/circuitlist.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 54a7db9dbf..1a3b7bb288 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -78,6 +78,7 @@
#include "rephist.h"
#include "routerlist.h"
#include "routerset.h"
+#include "channelpadding.h"
#include "ht.h"
@@ -814,6 +815,11 @@ init_circuit_base(circuit_t *circ)
circ->global_circuitlist_idx = smartlist_len(circuit_get_global_list()) - 1;
}
+/** If we haven't yet decided on a good timeout value for circuit
+ * building, we close idle circuits aggressively so we can get more
+ * data points. */
+#define IDLE_TIMEOUT_WHILE_LEARNING (1*60)
+
/** Allocate space for a new circuit, initializing with <b>p_circ_id</b>
* and <b>p_conn</b>. Add it to the global circuit list.
*/
@@ -841,6 +847,41 @@ origin_circuit_new(void)
circuit_build_times_update_last_circ(get_circuit_build_times_mutable());
+ if (! circuit_build_times_disabled(get_options()) &&
+ circuit_build_times_needs_circuits(get_circuit_build_times())) {
+ /* Circuits should be shorter lived if we need more of them
+ * for learning a good build timeout */
+ circ->circuit_idle_timeout = IDLE_TIMEOUT_WHILE_LEARNING;
+ } else {
+ // This should always be larger than the current port prediction time
+ // remaining, or else we'll end up with the case where a circuit times out
+ // and another one is built, effectively doubling the timeout window.
+ //
+ // We also randomize it by up to 5% more (ie 5% of 0 to 3600 seconds,
+ // depending on how much circuit prediction time is remaining) so that
+ // we don't close a bunch of unused circuits all at the same time.
+ int prediction_time_remaining =
+ predicted_ports_prediction_time_remaining(time(NULL));
+ circ->circuit_idle_timeout = prediction_time_remaining+1+
+ crypto_rand_int(1+prediction_time_remaining/20);
+
+ if (circ->circuit_idle_timeout <= 0) {
+ log_warn(LD_BUG,
+ "Circuit chose a negative idle timeout of %d based on "
+ "%d seconds of predictive building remaining.",
+ circ->circuit_idle_timeout,
+ prediction_time_remaining);
+ circ->circuit_idle_timeout = IDLE_TIMEOUT_WHILE_LEARNING;
+ }
+
+ log_info(LD_CIRC,
+ "Circuit " U64_FORMAT " chose an idle timeout of %d based on "
+ "%d seconds of predictive building remaining.",
+ U64_PRINTF_ARG(circ->global_identifier),
+ circ->circuit_idle_timeout,
+ prediction_time_remaining);
+ }
+
return circ;
}