|
@@ -36,6 +36,7 @@
|
|
|
#include "rendclient.h"
|
|
|
#include "rendservice.h"
|
|
|
#include "statefile.h"
|
|
|
+#include "circuitlist.h"
|
|
|
|
|
|
#undef log
|
|
|
#include <math.h>
|
|
@@ -610,6 +611,77 @@ circuit_build_times_rewind_history(circuit_build_times_t *cbt, int n)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+
|
|
|
+ * Perform the build time work that needs to be done when a circuit
|
|
|
+ * completes a hop.
|
|
|
+ *
|
|
|
+ * This function decides if we should record a circuit's build time
|
|
|
+ * in our histogram data and other statistics, and if so, records it.
|
|
|
+ * It also will mark circuits that have already timed out as
|
|
|
+ * measurement-only circuits, so they can continue to build but
|
|
|
+ * not get used.
|
|
|
+ *
|
|
|
+ * For this, we want to consider circuits that will eventually make
|
|
|
+ * it to the third hop. For circuits longer than 3 hops, we want to
|
|
|
+ * record their build time when they reach the third hop, but let
|
|
|
+ * them continue (and not count them later). For circuits that are
|
|
|
+ * exactly 3 hops, this will count them when they are completed. We
|
|
|
+ * do this so that CBT is always gathering statistics on circuits
|
|
|
+ * of the same length, regardless of their type.
|
|
|
+ */
|
|
|
+void
|
|
|
+circuit_build_times_handle_completed_hop(origin_circuit_t *circ)
|
|
|
+{
|
|
|
+ struct timeval end;
|
|
|
+ long timediff;
|
|
|
+
|
|
|
+
|
|
|
+ * handle it.. */
|
|
|
+ if (circuit_build_times_disabled(get_options())) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * way? If so, handle it below. If not, just return (and let
|
|
|
+ * circuit_expire_building() eventually take care of it).
|
|
|
+ */
|
|
|
+ if (!circuit_timeout_want_to_count_circ(circ)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * add it to our buildtimes. */
|
|
|
+ if (circuit_get_cpath_opened_len(circ) == DEFAULT_ROUTE_LEN) {
|
|
|
+ tor_gettimeofday(&end);
|
|
|
+ timediff = tv_mdiff(&circ->base_.timestamp_began, &end);
|
|
|
+
|
|
|
+
|
|
|
+ * it off at, we probably had a suspend event along this codepath,
|
|
|
+ * and we should discard the value.
|
|
|
+ */
|
|
|
+ if (timediff < 0 ||
|
|
|
+ timediff > 2*get_circuit_build_close_time_ms()+1000) {
|
|
|
+ log_notice(LD_CIRC, "Strange value for circuit build time: %ldmsec. "
|
|
|
+ "Assuming clock jump. Purpose %d (%s)", timediff,
|
|
|
+ circ->base_.purpose,
|
|
|
+ circuit_purpose_to_string(circ->base_.purpose));
|
|
|
+ } else {
|
|
|
+
|
|
|
+ if (circuit_build_times_network_check_live(
|
|
|
+ get_circuit_build_times())) {
|
|
|
+ circuit_build_times_add_time(get_circuit_build_times_mutable(),
|
|
|
+ (build_time_t)timediff);
|
|
|
+ circuit_build_times_set_timeout(get_circuit_build_times_mutable());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (circ->base_.purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT) {
|
|
|
+ circuit_build_times_network_circ_success(
|
|
|
+ get_circuit_build_times_mutable());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
* Add a new build time value <b>time</b> to the set of build times. Time
|
|
|
* units are milliseconds.
|
|
@@ -1285,9 +1357,14 @@ circuit_build_times_network_is_live(circuit_build_times_t *cbt)
|
|
|
}
|
|
|
|
|
|
|
|
|
- * Called to indicate that we completed a circuit. Because this circuit
|
|
|
+ * Called to indicate that we "completed" a circuit. Because this circuit
|
|
|
* succeeded, it doesn't count as a timeout-after-the-first-hop.
|
|
|
*
|
|
|
+ * (For the purposes of the cbt code, we consider a circuit "completed" if
|
|
|
+ * it has 3 hops, regardless of its final hop count. We do this because
|
|
|
+ * we're trying to answer the question, "how long should a circuit take to
|
|
|
+ * reach the 3-hop count".)
|
|
|
+ *
|
|
|
* This is used by circuit_build_times_network_check_changed() to determine
|
|
|
* if we had too many recent timeouts and need to reset our learned timeout
|
|
|
* to something higher.
|