diff options
author | Nick Mathewson <nickm@torproject.org> | 2016-11-22 09:05:52 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2016-11-30 14:42:53 -0500 |
commit | de617a471442342fc2abafdde4e250fd31eb45ac (patch) | |
tree | 7f2fbc4b163aa826d4ab71b255f1f48ad2f8de8f /src | |
parent | 8e43398986313f31bfda53aa798263972bf24c11 (diff) | |
download | tor-de617a471442342fc2abafdde4e250fd31eb45ac.tar.gz tor-de617a471442342fc2abafdde4e250fd31eb45ac.zip |
Maintain a list of all the origin circuits.
We'll want this for upgrading waiting circuits.
Diffstat (limited to 'src')
-rw-r--r-- | src/or/circuitlist.c | 39 | ||||
-rw-r--r-- | src/or/or.h | 4 |
2 files changed, 43 insertions, 0 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index 0189412df0..c274534759 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -85,6 +85,10 @@ /** A global list of all circuits at this hop. */ static smartlist_t *global_circuitlist = NULL; +/** A global list of all origin circuits. Every element of this is also + * an element of global_circuitlist. */ +static smartlist_t *global_origin_circuit_list = NULL; + /** A list of all the circuits in CIRCUIT_STATE_CHAN_WAIT. */ static smartlist_t *circuits_pending_chans = NULL; @@ -523,6 +527,19 @@ circuit_close_all_marked(void) } circ->global_circuitlist_idx = -1; + /* Remove it from the origin circuit list, if appropriate. */ + if (CIRCUIT_IS_ORIGIN(circ)) { + origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ); + int origin_idx = origin_circ->global_origin_circuit_list_idx; + smartlist_del(global_origin_circuit_list, origin_idx); + if (origin_idx < smartlist_len(global_origin_circuit_list)) { + origin_circuit_t *replacement = + smartlist_get(global_origin_circuit_list, origin_idx); + replacement->global_origin_circuit_list_idx = origin_idx; + } + origin_circ->global_origin_circuit_list_idx = -1; + } + circuit_about_to_free(circ); circuit_free(circ); } SMARTLIST_FOREACH_END(circ); @@ -780,6 +797,13 @@ origin_circuit_new(void) init_circuit_base(TO_CIRCUIT(circ)); + /* Add to origin-list. */ + if (!global_origin_circuit_list) + global_origin_circuit_list = smartlist_new(); + smartlist_add(global_origin_circuit_list, circ); + circ->global_origin_circuit_list_idx = + smartlist_len(global_origin_circuit_list) - 1; + circuit_build_times_update_last_circ(get_circuit_build_times_mutable()); return circ; @@ -837,6 +861,18 @@ circuit_free(circuit_t *circ) mem = ocirc; memlen = sizeof(origin_circuit_t); tor_assert(circ->magic == ORIGIN_CIRCUIT_MAGIC); + + if (ocirc->global_origin_circuit_list_idx != -1) { + int idx = ocirc->global_origin_circuit_list_idx; + origin_circuit_t *c2 = smartlist_get(global_origin_circuit_list, idx); + tor_assert(c2 == ocirc); + smartlist_del(global_origin_circuit_list, idx); + if (idx < smartlist_len(global_origin_circuit_list)) { + c2 = smartlist_get(global_origin_circuit_list, idx); + c2->global_origin_circuit_list_idx = idx; + } + } + if (ocirc->build_state) { extend_info_free(ocirc->build_state->chosen_exit); circuit_free_cpath_node(ocirc->build_state->pending_final_cpath); @@ -977,6 +1013,9 @@ circuit_free_all(void) smartlist_free(lst); global_circuitlist = NULL; + smartlist_free(global_origin_circuit_list); + global_origin_circuit_list = NULL; + smartlist_free(circuits_pending_chans); circuits_pending_chans = NULL; diff --git a/src/or/or.h b/src/or/or.h index 8282731eea..c8f39f90d9 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3157,6 +3157,10 @@ typedef struct origin_circuit_t { * whether this circuit can be used. */ struct circuit_guard_state_t *guard_state; + /** Index into global_origin_circuit_list for this circuit. -1 if not + * present. */ + int global_origin_circuit_list_idx; + /** How many more relay_early cells can we send on this circuit, according * to the specification? */ unsigned int remaining_relay_early_cells : 4; |