aboutsummaryrefslogtreecommitdiff
path: root/src/or/circuitlist.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2014-03-23 00:20:05 -0400
committerNick Mathewson <nickm@torproject.org>2014-03-23 00:20:05 -0400
commit2cfc4453c246bbd964cb9849bc5959bb1c510ae7 (patch)
tree67aa401eef9323e8baff9d01a45490bbd82e939c /src/or/circuitlist.c
parentf4e2c72beef2821a6f30a31ad487d9d7911df0dc (diff)
parentd769cab3e50979807a526b3ebc5c341c13b12e97 (diff)
downloadtor-2cfc4453c246bbd964cb9849bc5959bb1c510ae7.tar.gz
tor-2cfc4453c246bbd964cb9849bc5959bb1c510ae7.zip
Merge remote-tracking branch 'public/bug9683_rebased'
Diffstat (limited to 'src/or/circuitlist.c')
-rw-r--r--src/or/circuitlist.c63
1 files changed, 59 insertions, 4 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index b2eb730c8c..867a9cd0a3 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -1144,12 +1144,58 @@ void
circuit_unlink_all_from_channel(channel_t *chan, int reason)
{
circuit_t *circ;
+ smartlist_t *detached = smartlist_new();
- channel_unlink_all_circuits(chan);
+#define DEBUG_CIRCUIT_UNLINK_ALL
- TOR_LIST_FOREACH(circ, &global_circuitlist, head) {
+ channel_unlink_all_circuits(chan, detached);
+
+#ifdef DEBUG_CIRCUIT_UNLINK_ALL
+ {
+ smartlist_t *detached_2 = smartlist_new();
+ int mismatch = 0, badlen = 0;
+
+ TOR_LIST_FOREACH(circ, &global_circuitlist, head) {
+ if (circ->n_chan == chan ||
+ (!CIRCUIT_IS_ORIGIN(circ) &&
+ TO_OR_CIRCUIT(circ)->p_chan == chan)) {
+ smartlist_add(detached_2, circ);
+ }
+ }
+
+ if (smartlist_len(detached) != smartlist_len(detached_2)) {
+ log_warn(LD_BUG, "List of detached circuits had the wrong length! "
+ "(got %d, should have gotten %d)",
+ (int)smartlist_len(detached),
+ (int)smartlist_len(detached_2));
+ badlen = 1;
+ }
+ smartlist_sort_pointers(detached);
+ smartlist_sort_pointers(detached_2);
+
+ SMARTLIST_FOREACH(detached, circuit_t *, c,
+ if (c != smartlist_get(detached_2, c_sl_idx))
+ mismatch = 1;
+ );
+
+ if (mismatch)
+ log_warn(LD_BUG, "Mismatch in list of detached circuits.");
+
+ if (badlen || mismatch) {
+ smartlist_free(detached);
+ detached = detached_2;
+ } else {
+ log_notice(LD_CIRC, "List of %d circuits was as expected.",
+ (int)smartlist_len(detached));
+ smartlist_free(detached_2);
+ }
+ }
+#endif
+
+ SMARTLIST_FOREACH_BEGIN(detached, circuit_t *, circ) {
int mark = 0;
if (circ->n_chan == chan) {
+
circuit_set_n_circid_chan(circ, 0, NULL);
mark = 1;
@@ -1165,9 +1211,16 @@ circuit_unlink_all_from_channel(channel_t *chan, int reason)
mark = 1;
}
}
- if (mark && !circ->marked_for_close)
+ if (!mark) {
+ log_warn(LD_BUG, "Circuit on detached list which I had no reason "
+ "to mark");
+ continue;
+ }
+ if (!circ->marked_for_close)
circuit_mark_for_close(circ, reason);
- }
+ } SMARTLIST_FOREACH_END(circ);
+
+ smartlist_free(detached);
}
/** Return a circ such that
@@ -1541,6 +1594,7 @@ circuit_mark_for_close_, (circuit_t *circ, int reason, int line,
channel_send_destroy(circ->n_circ_id, circ->n_chan, reason);
}
circuitmux_detach_circuit(circ->n_chan->cmux, circ);
+ circuit_set_n_circid_chan(circ, 0, NULL);
}
if (! CIRCUIT_IS_ORIGIN(circ)) {
@@ -1574,6 +1628,7 @@ circuit_mark_for_close_, (circuit_t *circ, int reason, int line,
channel_send_destroy(or_circ->p_circ_id, or_circ->p_chan, reason);
}
circuitmux_detach_circuit(or_circ->p_chan->cmux, circ);
+ circuit_set_p_circid_chan(or_circ, 0, NULL);
}
} else {
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);