diff options
author | Nick Mathewson <nickm@torproject.org> | 2016-02-10 15:42:11 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2016-02-10 15:42:11 -0500 |
commit | ee75c02691888a0cb7ee34e4f18436c523f92f0d (patch) | |
tree | 9203d14e32f0a9c34a6af01a1e40e71065db80b4 /src | |
parent | 69c47ab5fd608ecd47ddd3c1d2f041a2b41791b5 (diff) | |
parent | ae0f858602739abbe17277860c060ecc70aa3003 (diff) | |
download | tor-ee75c02691888a0cb7ee34e4f18436c523f92f0d.tar.gz tor-ee75c02691888a0cb7ee34e4f18436c523f92f0d.zip |
Merge remote-tracking branch 'andrea/bug18116'
Diffstat (limited to 'src')
-rw-r--r-- | src/or/circuitlist.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index dcbeb1e2bb..9b7df75cd8 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -53,6 +53,7 @@ static void cpath_ref_decref(crypt_path_reference_t *cpath_ref); //static void circuit_set_rend_token(or_circuit_t *circ, int is_rend_circ, // const uint8_t *token); static void circuit_clear_rend_token(or_circuit_t *circ); +static void circuit_about_to_free_terminal(circuit_t *circ); static void circuit_about_to_free(circuit_t *circ); /********* END VARIABLES ************/ @@ -901,6 +902,7 @@ circuit_free_all(void) } } tmp->global_circuitlist_idx = -1; + circuit_about_to_free_terminal(tmp); circuit_free(tmp); SMARTLIST_DEL_CURRENT(lst, tmp); } SMARTLIST_FOREACH_END(tmp); @@ -1744,6 +1746,32 @@ circuit_mark_for_close_, (circuit_t *circ, int reason, int line, smartlist_add(circuits_pending_close, circ); } +/** Called immediately before freeing a marked circuit <b>circ</b> from + * circuit_free_all() while shutting down Tor; this is a safe-at-shutdown + * version of circuit_about_to_free(). It's important that it at least + * do circuitmux_detach_circuit() when appropriate. + */ +static void +circuit_about_to_free_terminal(circuit_t *circ) +{ + + if (circ->n_chan) { + circuit_clear_cell_queue(circ, circ->n_chan); + circuitmux_detach_circuit(circ->n_chan->cmux, circ); + circuit_set_n_circid_chan(circ, 0, NULL); + } + + if (! CIRCUIT_IS_ORIGIN(circ)) { + or_circuit_t *or_circ = TO_OR_CIRCUIT(circ); + + if (or_circ->p_chan) { + circuit_clear_cell_queue(circ, or_circ->p_chan); + circuitmux_detach_circuit(or_circ->p_chan->cmux, circ); + circuit_set_p_circid_chan(or_circ, 0, NULL); + } + } +} + /** Called immediately before freeing a marked circuit <b>circ</b>. * Disconnects the circuit from other data structures, launches events * as appropriate, and performs other housekeeping. |