commit be371250305b0ac50c1fafda8acd13812894ab92 Merge: 03b3216 2b10e99 Author: Andrea Shepard andrea@torproject.org Date: Tue Oct 30 14:39:14 2012 -0700
Merge branch 'bsd_queue' of ssh://git-rw.torproject.org/nickm/tor
LICENSE | 29 +++ changes/bsd_queue | 7 + src/ext/README | 8 + src/ext/include.am | 3 +- src/ext/tor_queue.h | 568 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/or/channel.c | 349 ++++++++++++------------------- src/or/channel.h | 13 +- 7 files changed, 755 insertions(+), 222 deletions(-)
diff --cc src/or/channel.c index 5552d39,7f3c6f5..cd5972f --- a/src/or/channel.c +++ b/src/or/channel.c @@@ -82,7 -81,37 +83,37 @@@ static uint64_t n_channels_allocated = * If more than one channel exists, follow the next_with_same_id pointer * as a linked list. */ - static digestmap_t *channel_identity_map = NULL; + HT_HEAD(channel_idmap, channel_idmap_entry_s) channel_identity_map = + HT_INITIALIZER(); + + typedef struct channel_idmap_entry_s { + HT_ENTRY(channel_idmap_entry_s) node; + uint8_t digest[DIGEST_LEN]; + LIST_HEAD(channel_list_s, channel_s) channel_list; + } channel_idmap_entry_t; + + static INLINE unsigned + channel_idmap_hash(const channel_idmap_entry_t *ent) + { + const unsigned *a = (const unsigned *)ent->digest; + #if SIZEOF_INT == 4 + return a[0] ^ a[1] ^ a[2] ^ a[3] ^ a[4]; + #elif SIZEOF_INT == 8 + return a[0] ^ a[1]; + #endif + } + + static INLINE int + channel_idmap_eq(const channel_idmap_entry_t *a, + const channel_idmap_entry_t *b) + { + return tor_memeq(a->digest, b->digest, DIGEST_LEN); + } + + HT_PROTOTYPE(channel_idmap, channel_idmap_entry_s, node, channel_idmap_hash, + channel_idmap_eq); + HT_GENERATE(channel_idmap, channel_idmap_entry_s, node, channel_idmap_hash, - channel_idmap_eq, 0.5, tor_malloc, tor_realloc, _tor_free); ++ channel_idmap_eq, 0.5, tor_malloc, tor_realloc, tor_free_);
static cell_queue_entry_t * cell_queue_entry_dup(cell_queue_entry_t *q); static void cell_queue_entry_free(cell_queue_entry_t *q, int handed_off); @@@ -881,52 -832,25 +852,43 @@@ channel_listener_free(channel_listener_ static void channel_force_free(channel_t *chan) { + cell_queue_entry_t *cell, *cell_tmp; tor_assert(chan);
+ log_debug(LD_CHANNEL, + "Force-freeing channel " U64_FORMAT " at %p", + U64_PRINTF_ARG(chan->global_identifier), chan); + + /* + * Get rid of cmux policy before we do anything, so cmux policies don't + * see channels in weird half-freed states. + */ + if (chan->cmux) { + circuitmux_set_policy(chan->cmux, NULL); + } + /* Call a free method if there is one */ if (chan->free) chan->free(chan);
channel_clear_remote_end(chan);
+ /* Get rid of cmux */ + if (chan->cmux) { + circuitmux_free(chan->cmux); + chan->cmux = NULL; + } + /* We might still have a cell queue; kill it */ - if (chan->incoming_queue) { - SMARTLIST_FOREACH_BEGIN(chan->incoming_queue, - cell_queue_entry_t *, q) { - cell_queue_entry_free(q, 0); - } SMARTLIST_FOREACH_END(q); - - smartlist_free(chan->incoming_queue); - chan->incoming_queue = NULL; + SIMPLEQ_FOREACH_SAFE(cell, &chan->incoming_queue, next, cell_tmp) { + cell_queue_entry_free(cell, 0); } + SIMPLEQ_INIT(&chan->incoming_queue);
/* Outgoing cell queue is similar, but we can have to free packed cells */ - if (chan->outgoing_queue) { - SMARTLIST_FOREACH_BEGIN(chan->outgoing_queue, - cell_queue_entry_t *, q) { - cell_queue_entry_free(q, 0); - } SMARTLIST_FOREACH_END(q); - - smartlist_free(chan->outgoing_queue); - chan->outgoing_queue = NULL; + SIMPLEQ_FOREACH_SAFE(cell, &chan->outgoing_queue, next, cell_tmp) { + cell_queue_entry_free(cell, 0); } + SIMPLEQ_INIT(&chan->outgoing_queue);
tor_free(chan); } diff --cc src/or/channel.h index d90335c,1e7279a..d210655 --- a/src/or/channel.h +++ b/src/or/channel.h @@@ -6,10 -6,11 +6,11 @@@ * \brief Header file for channel.c **/
-#ifndef _TOR_CHANNEL_H -#define _TOR_CHANNEL_H +#ifndef TOR_CHANNEL_H +#define TOR_CHANNEL_H
#include "or.h" + #include "tor_queue.h" #include "circuitmux.h"
/* Channel handler function pointer typedefs */