From 0748c06f7c2a44fc1cc378d3afadeebd894c493c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 17 Jun 2013 11:30:56 -0400 Subject: Fix bug 9082: avoid leak when freeing destroy cell queues In my #7912 fix, there wasn't any code to remove entries from the (channel, circuit ID)->circuit map corresponding to queued but un-sent DESTROYs. Spotted by skruffy. Fixes bug 9082; bug not in any released Tor. --- src/or/circuitmux.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/or/circuitmux.c') diff --git a/src/or/circuitmux.c b/src/or/circuitmux.c index f579c3ead..c84e0ce09 100644 --- a/src/or/circuitmux.c +++ b/src/or/circuitmux.c @@ -498,6 +498,31 @@ circuitmux_detach_all_circuits(circuitmux_t *cmux) cmux->n_cells = 0; } +/** Reclaim all circuit IDs currently marked as unusable on chan because + * of pending destroy cells in cmux. + * + * This function must be called AFTER circuits are unlinked from the (channel, + * circuid-id) map with circuit_unlink_all_from_channel(), but before calling + * circuitmux_free(). + */ +void +circuitmux_mark_destroyed_circids_usable(circuitmux_t *cmux, channel_t *chan) +{ + packed_cell_t *cell; + int n_bad = 0; + for (cell = cmux->destroy_cell_queue.head; cell; cell = cell->next) { + circid_t circid = 0; + if (packed_cell_is_destroy(chan, cell, &circid)) { + channel_mark_circid_usable(chan, circid); + } else { + ++n_bad; + } + } + if (n_bad) + log_warn(LD_BUG, "%d cell(s) on destroy queue did not look like a " + "DESTROY cell.", n_bad); +} + /** * Free a circuitmux_t; the circuits must be detached first with * circuitmux_detach_all_circuits(). -- cgit v1.2.3