diff options
author | Mike Perry <mikeperry-git@torproject.org> | 2017-12-07 00:04:09 +0000 |
---|---|---|
committer | Mike Perry <mikeperry-git@torproject.org> | 2017-12-07 00:04:38 +0000 |
commit | ed89588c4fa672eb8a85c8c5cdce4f7ec08bc9d8 (patch) | |
tree | 8d52b6a7a71ddf8aedcff9fa28f6d82776f1e560 /src/or/circuitlist.c | |
parent | b5d4cd1b4178bfa285fc5c512a29daa2580d96b8 (diff) | |
download | tor-ed89588c4fa672eb8a85c8c5cdce4f7ec08bc9d8.tar.gz tor-ed89588c4fa672eb8a85c8c5cdce4f7ec08bc9d8.zip |
Bug #23114: Time out circuits immediately.
This changes the purpose of circuits that are past the timeout to measurement
*as they are built*, ensuring accurate application of the timeout logic.
Diffstat (limited to 'src/or/circuitlist.c')
-rw-r--r-- | src/or/circuitlist.c | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index 20fa03306e..fbf10fc0a4 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -109,6 +109,14 @@ static void cpath_ref_decref(crypt_path_reference_t *cpath_ref); static void circuit_about_to_free_atexit(circuit_t *circ); static void circuit_about_to_free(circuit_t *circ); +/** + * A cached value of the current state of the origin circuit list. Has the + * value 1 if we saw any opened circuits recently (since the last call to + * circuit_any_opened_circuits(), which gets called around once a second by + * circuit_expire_building). 0 otherwise. + */ +static int any_opened_circs_cached_val = 0; + /********* END VARIABLES ************/ /** A map from channel and circuit ID to circuit. (Lookup performance is @@ -597,6 +605,56 @@ circuit_get_global_origin_circuit_list(void) return global_origin_circuit_list; } +/** + * Return true if we have any opened general-purpose 3 hop + * origin circuits. + * + * The result from this function is cached for use by + * circuit_any_opened_circuits_cached(). + */ +int +circuit_any_opened_circuits(void) +{ + SMARTLIST_FOREACH_BEGIN(circuit_get_global_origin_circuit_list(), + const origin_circuit_t *, next_circ) { + if (!TO_CIRCUIT(next_circ)->marked_for_close && + next_circ->has_opened && + TO_CIRCUIT(next_circ)->state == CIRCUIT_STATE_OPEN && + TO_CIRCUIT(next_circ)->purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT && + next_circ->build_state && + next_circ->build_state->desired_path_len == DEFAULT_ROUTE_LEN) { + circuit_cache_opened_circuit_state(1); + return 1; + } + } SMARTLIST_FOREACH_END(next_circ); + + circuit_cache_opened_circuit_state(0); + return 0; +} + +/** + * Cache the "any circuits opened" state, as specified in param + * circuits_are_opened. This is a helper function to update + * the circuit opened status whenever we happen to look at the + * circuit list. + */ +void +circuit_cache_opened_circuit_state(int circuits_are_opened) +{ + any_opened_circs_cached_val = circuits_are_opened; +} + +/** + * Return true if there were any opened circuits since the last call to + * circuit_any_opened_circuits(), or since circuit_expire_building() last + * ran (it runs roughly once per second). + */ +int +circuit_any_opened_circuits_cached(void) +{ + return any_opened_circs_cached_val; +} + /** Function to make circ-\>state human-readable */ const char * circuit_state_to_string(int state) @@ -1792,7 +1850,7 @@ circuit_get_cpath_len(origin_circuit_t *circ) /** Return the number of opened hops in circuit's path. * If circ has no entries, or is NULL, returns 0. */ int -circuit_get_cpath_opened_len(origin_circuit_t *circ) +circuit_get_cpath_opened_len(const origin_circuit_t *circ) { int n = 0; if (circ && circ->cpath) { |