summaryrefslogtreecommitdiff
path: root/src/or/circuitbuild.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/circuitbuild.c')
-rw-r--r--src/or/circuitbuild.c118
1 files changed, 74 insertions, 44 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index b1335cc24c..f244aeaff0 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -290,7 +290,7 @@ circuit_build_times_init(circuit_build_times_t *cbt)
}
/**
- * Rewind our timeout history by n timeout positions.
+ * Rewind our build time history by n positions.
*/
static void
circuit_build_times_rewind_history(circuit_build_times_t *cbt, int n)
@@ -317,7 +317,7 @@ circuit_build_times_rewind_history(circuit_build_times_t *cbt, int n)
}
/**
- * Add a new timeout value <b>time</b> to the set of build times. Time
+ * Add a new build time value <b>time</b> to the set of build times. Time
* units are milliseconds.
*
* circuit_build_times <b>cbt</a> is a circular array, so loop around when
@@ -359,7 +359,7 @@ circuit_build_times_max(circuit_build_times_t *cbt)
build_time_t max_build_time = 0;
for (i = 0; i < CBT_NCIRCUITS_TO_OBSERVE; i++) {
if (cbt->circuit_build_times[i] > max_build_time
- && cbt->circuit_build_times[i] != CBT_BUILD_TIMEOUT)
+ && cbt->circuit_build_times[i] != CBT_BUILD_ABANDONED)
max_build_time = cbt->circuit_build_times[i];
}
return max_build_time;
@@ -407,7 +407,7 @@ circuit_build_times_create_histogram(circuit_build_times_t *cbt,
// calculate histogram
for (i = 0; i < CBT_NCIRCUITS_TO_OBSERVE; i++) {
if (cbt->circuit_build_times[i] == 0
- || cbt->circuit_build_times[i] == CBT_BUILD_TIMEOUT)
+ || cbt->circuit_build_times[i] == CBT_BUILD_ABANDONED)
continue; /* 0 <-> uninitialized */
c = (cbt->circuit_build_times[i] / CBT_BIN_WIDTH);
@@ -489,11 +489,11 @@ circuit_build_times_update_state(circuit_build_times_t *cbt,
*next = NULL;
state->TotalBuildTimes = cbt->total_build_times;
- state->CircuitBuildTimeoutCount = 0;
+ state->CircuitBuildAbandonedCount = 0;
for (i = 0; i < CBT_NCIRCUITS_TO_OBSERVE; i++) {
- if (cbt->circuit_build_times[i] == CBT_BUILD_TIMEOUT)
- state->CircuitBuildTimeoutCount++;
+ if (cbt->circuit_build_times[i] == CBT_BUILD_ABANDONED)
+ state->CircuitBuildAbandonedCount++;
}
for (i = 0; i < nbins; i++) {
@@ -567,7 +567,7 @@ circuit_build_times_filter_timeouts(circuit_build_times_t *cbt)
if (cbt->circuit_build_times[i] > max_timeout) {
build_time_t replaced = cbt->circuit_build_times[i];
num_filtered++;
- cbt->circuit_build_times[i] = CBT_BUILD_TIMEOUT;
+ cbt->circuit_build_times[i] = CBT_BUILD_ABANDONED;
log_debug(LD_CIRC, "Replaced timeout %d with %d", replaced,
cbt->circuit_build_times[i]);
@@ -644,7 +644,7 @@ circuit_build_times_parse_state(circuit_build_times_t *cbt,
break;
}
- if (loaded_cnt+count+state->CircuitBuildTimeoutCount
+ if (loaded_cnt+count+state->CircuitBuildAbandonedCount
> state->TotalBuildTimes) {
log_warn(LD_CIRC,
"Too many build times in state file. "
@@ -665,9 +665,9 @@ circuit_build_times_parse_state(circuit_build_times_t *cbt,
}
log_info(LD_CIRC,
- "Adding %d timeouts.", state->CircuitBuildTimeoutCount);
- for (i=0; i < state->CircuitBuildTimeoutCount; i++) {
- loaded_times[loaded_cnt++] = CBT_BUILD_TIMEOUT;
+ "Adding %d timeouts.", state->CircuitBuildAbandonedCount);
+ for (i=0; i < state->CircuitBuildAbandonedCount; i++) {
+ loaded_times[loaded_cnt++] = CBT_BUILD_ABANDONED;
}
if (loaded_cnt != state->TotalBuildTimes) {
@@ -693,7 +693,7 @@ circuit_build_times_parse_state(circuit_build_times_t *cbt,
circuit_build_times_set_timeout(cbt);
- if (!state->CircuitBuildTimeoutCount && cbt->total_build_times) {
+ if (!state->CircuitBuildAbandonedCount && cbt->total_build_times) {
circuit_build_times_filter_timeouts(cbt);
}
@@ -715,7 +715,7 @@ circuit_build_times_update_alpha(circuit_build_times_t *cbt)
{
build_time_t *x=cbt->circuit_build_times;
double a = 0;
- int n=0,i=0,timeout_count=0;
+ int n=0,i=0,abandoned_count=0;
build_time_t max_time=0;
/* http://en.wikipedia.org/wiki/Pareto_distribution#Parameter_estimation */
@@ -732,8 +732,8 @@ circuit_build_times_update_alpha(circuit_build_times_t *cbt)
if (x[i] < cbt->Xm) {
a += tor_mathlog(cbt->Xm);
- } else if (x[i] == CBT_BUILD_TIMEOUT) {
- timeout_count++;
+ } else if (x[i] == CBT_BUILD_ABANDONED) {
+ abandoned_count++;
} else {
a += tor_mathlog(x[i]);
if (x[i] > max_time)
@@ -750,13 +750,13 @@ circuit_build_times_update_alpha(circuit_build_times_t *cbt)
tor_assert(max_time > 0);
- a += timeout_count*tor_mathlog(max_time);
+ a += abandoned_count*tor_mathlog(max_time);
a -= n*tor_mathlog(cbt->Xm);
// Estimator comes from Eq #4 in:
// "Bayesian estimation based on trimmed samples from Pareto populations"
// by Arturo J. Fernández. We are right-censored only.
- a = (n-timeout_count)/a;
+ a = (n-abandoned_count)/a;
cbt->alpha = a;
}
@@ -907,16 +907,27 @@ circuit_build_times_network_circ_success(circuit_build_times_t *cbt)
}
/**
- * A circuit just timed out. If there has been no recent network activity
- * at all, but this circuit was launched back when we thought the network
- * was live, increment the number of "nonlive" circuit timeouts.
- *
- * Also distinguish between whether it failed before the first hop
- * and record that in our history for later deciding if the network has
- * changed.
+ * A circuit just timed out. If it failed after the first hop, record it
+ * in our history for later deciding if the network speed has changed.
*/
static void
circuit_build_times_network_timeout(circuit_build_times_t *cbt,
+ int did_onehop)
+{
+ if (did_onehop) {
+ cbt->liveness.timeouts_after_firsthop[cbt->liveness.after_firsthop_idx]=1;
+ cbt->liveness.after_firsthop_idx++;
+ cbt->liveness.after_firsthop_idx %= cbt->liveness.num_recent_circs;
+ }
+}
+
+/**
+ * A circuit was just forcibly closed. If there has been no recent network
+ * activity at all, but this circuit was launched back when we thought the
+ * network was live, increment the number of "nonlive" circuit timeouts.
+ */
+static void
+circuit_build_times_network_close(circuit_build_times_t *cbt,
int did_onehop, time_t start_time)
{
time_t now = time(NULL);
@@ -940,11 +951,6 @@ circuit_build_times_network_timeout(circuit_build_times_t *cbt,
start_time, now);
}
cbt->liveness.nonlive_timeouts++;
- } else if (did_onehop) {
- /* Count a one-hop timeout */
- cbt->liveness.timeouts_after_firsthop[cbt->liveness.after_firsthop_idx]=1;
- cbt->liveness.after_firsthop_idx++;
- cbt->liveness.after_firsthop_idx %= cbt->liveness.num_recent_circs;
}
}
@@ -1010,8 +1016,6 @@ circuit_build_times_network_check_live(circuit_build_times_t *cbt)
* Also resets the entire timeout history in this case and causes us
* to restart the process of building test circuits and estimating a
* new timeout.
- *
- * XXX: All this may have been broken by the close_ms change!
*/
int
circuit_build_times_network_check_changed(circuit_build_times_t *cbt)
@@ -1091,7 +1095,7 @@ circuit_build_times_timeout_rate(const circuit_build_times_t *cbt)
* update our timeout estimate.
*/
int
-circuit_build_times_add_timeout(circuit_build_times_t *cbt,
+circuit_build_times_count_close(circuit_build_times_t *cbt,
int did_onehop,
time_t start_time)
{
@@ -1101,22 +1105,38 @@ circuit_build_times_add_timeout(circuit_build_times_t *cbt,
return 0;
}
- // XXX: All this has changed due to close_ms
- circuit_build_times_network_timeout(cbt, did_onehop, start_time);
+ /* Record this force-close to help determine if the network is dead */
+ circuit_build_times_network_close(cbt, did_onehop, start_time);
/* Only count timeouts if network is live.. */
if (!circuit_build_times_network_check_live(cbt)) {
return 0;
}
- /* If there are a ton of timeouts, we should reduce
- * the circuit build timeout */
- if (circuit_build_times_network_check_changed(cbt)) {
- return 0;
+ circuit_build_times_add_time(cbt, CBT_BUILD_ABANDONED);
+ return 1;
+}
+
+/**
+ * Update timeout counts to determine if we need to expire
+ * our build time history due to excessive timeouts.
+ */
+void
+circuit_build_times_count_timeout(circuit_build_times_t *cbt,
+ int did_onehop)
+{
+ if (circuit_build_times_disabled()) {
+ cbt->close_ms = cbt->timeout_ms
+ = circuit_build_times_get_initial_timeout();
+ return;
}
- circuit_build_times_add_time(cbt, CBT_BUILD_TIMEOUT);
- return 1;
+ circuit_build_times_network_timeout(cbt, did_onehop);
+
+ /* If there are a ton of timeouts, we should reset
+ * the circuit build timeout.
+ */
+ circuit_build_times_network_check_changed(cbt);
}
/**
@@ -1804,9 +1824,15 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
log_notice(LD_CIRC, "Strange value for circuit build time: %ldmsec. "
"Assuming clock jump.", timediff);
} else if (!circuit_build_times_disabled()) {
- circuit_build_times_add_time(&circ_times, (build_time_t)timediff);
- circuit_build_times_network_circ_success(&circ_times);
- circuit_build_times_set_timeout(&circ_times);
+ /* Don't count circuit times if the network was not live */
+ if (circuit_build_times_network_check_live(&circ_times)) {
+ circuit_build_times_add_time(&circ_times, (build_time_t)timediff);
+ circuit_build_times_set_timeout(&circ_times);
+ }
+
+ if (circ->_base.purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT) {
+ circuit_build_times_network_circ_success(&circ_times);
+ }
}
}
log_info(LD_CIRC,"circuit built!");
@@ -1829,6 +1855,10 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
}
circuit_rep_hist_note_result(circ);
circuit_has_opened(circ); /* do other actions as necessary */
+
+ /* We're done with measurement circuits here. Just close them */
+ if (circ->_base.purpose == CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT)
+ circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_FINISHED);
return 0;
}