瀏覽代碼

Implement circuitmux_detach_all_circuits() in circuitmux.c

Andrea Shepard 11 年之前
父節點
當前提交
fd31dd440c
共有 1 個文件被更改,包括 69 次插入0 次删除
  1. 69 0
      src/or/circuitmux.c

+ 69 - 0
src/or/circuitmux.c

@@ -8,6 +8,7 @@
 
 #include "or.h"
 #include "channel.h"
+#include "circuitlist.h"
 #include "circuitmux.h"
 
 /*
@@ -197,6 +198,74 @@ circuitmux_alloc(void)
   return rv;
 }
 
+/**
+ * Detach all circuits from a circuitmux (use before circuitmux_free())
+ */
+
+void
+circuitmux_detach_all_circuits(circuitmux_t *cmux)
+{
+  chanid_circid_muxinfo_t **i = NULL, *to_remove;
+  channel_t *chan = NULL;
+  circuit_t *circ = NULL;
+
+  tor_assert(cmux);
+
+  i = HT_START(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
+  while (i) {
+    to_remove = *i;
+    i = HT_NEXT_RMV(chanid_circid_muxinfo_map, cmux->chanid_circid_map, i);
+    if (to_remove) {
+      /* Find a channel and circuit */
+      chan = channel_find_by_global_id(to_remove->chan_id);
+      if (chan) {
+        circ = circuit_get_by_circid_channel(to_remove->circ_id, chan);
+        if (circ) {
+          /* Clear the circuit's mux for this direction */
+          if (to_remove->muxinfo.direction == CELL_DIRECTION_OUT) {
+            /* Clear n_mux */
+            circ->n_mux = NULL;
+          } else if (circ->magic == OR_CIRCUIT_MAGIC) {
+            /*
+             * It has a sensible p_chan and direction == CELL_DIRECTION_IN,
+             * so clear p_mux.
+             */
+            TO_OR_CIRCUIT(circ)->p_mux = NULL;
+          } else {
+            /* Complain and move on */
+            log_warn(LD_CIRC,
+                     "Circuit %d/channel " U64_FORMAT " had direction == "
+                     "CELL_DIRECTION_IN, but isn't an or_circuit_t",
+                     to_remove->circ_id,
+                     U64_PRINTF_ARG(to_remove->chan_id));
+          }
+
+          /* TODO update active_circuits / active_circuit_pqueue */
+        } else {
+          /* Complain and move on */
+          log_warn(LD_CIRC,
+                   "Couldn't find circuit %d (for channel " U64_FORMAT ")",
+                   to_remove->circ_id,
+                   U64_PRINTF_ARG(to_remove->chan_id));
+        }
+      } else {
+        /* Complain and move on */
+        log_warn(LD_CIRC,
+                 "Couldn't find channel " U64_FORMAT " (for circuit id %d)",
+                 U64_PRINTF_ARG(to_remove->chan_id),
+                 to_remove->circ_id);
+      }
+
+      /* Free it */
+      tor_free(to_remove);
+    }
+  }
+
+  cmux->n_circuits = 0;
+  cmux->n_active_circuits = 0;
+  cmux->n_cells = 0;
+}
+
 /**
  * Free a circuitmux_t; the circuits must be detached first with
  * circuitmux_detach_all_circuits().