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

nickm at torproject.org nickm at torproject.org
Wed Feb 10 20:42:22 UTC 2016


commit ae0f858602739abbe17277860c060ecc70aa3003
Author: Andrea Shepard <andrea at 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.





More information about the tor-commits mailing list