[tor/master] Properly detach circuits from cmuxes when calling circuit_free_all() on shutdown again

commit ae0f858602739abbe17277860c060ecc70aa3003 Author: Andrea Shepard <andrea@torproject.org> Date: Wed Feb 10 05:35:03 2016 +0000 Properly detach circuits from cmuxes when calling circuit_free_all() on shutdown again --- changes/bug18116 | 3 +++ src/or/circuitlist.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/changes/bug18116 b/changes/bug18116 new file mode 100644 index 0000000..23ff8f7 --- /dev/null +++ b/changes/bug18116 @@ -0,0 +1,3 @@ + o Major bugfixes: + - Correctly handle detaching circuits from cmuxes when doing + circuit_free_all() on shutdown again; fixes bug #18116. diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index dcbeb1e..9b7df75 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.
participants (1)
-
nickm@torproject.org