diff options
author | Nick Mathewson <nickm@torproject.org> | 2013-03-21 14:51:27 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2013-06-13 10:14:00 -0400 |
commit | 43d53e6d86acaf7555c31730a8230fa0cdf31306 (patch) | |
tree | c12b3285f417aad70b913662006e8572edf708b6 /src/or/relay.c | |
parent | 801eea03ad71dafd31cc6bfa06fa5e421aa95cd6 (diff) | |
download | tor-43d53e6d86acaf7555c31730a8230fa0cdf31306.tar.gz tor-43d53e6d86acaf7555c31730a8230fa0cdf31306.zip |
Implementation of a fix for bug 7912
I added the code to pass a destroy cell to a queueing function rather
than writing it immediately, and the code to remember that we
shouldn't reuse the circuit id until the destroy is actually sent, and
the code to release the circuit id once the destroy has been sent...
and then I finished by hooking destroy_cell_queue into the rest of
Tor.
Diffstat (limited to 'src/or/relay.c')
-rw-r--r-- | src/or/relay.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/src/or/relay.c b/src/or/relay.c index 0ca3e56fd5..ec860269a6 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -2140,11 +2140,11 @@ cell_queue_append(cell_queue_t *queue, packed_cell_t *cell) /** Append a newly allocated copy of <b>cell</b> to the end of <b>queue</b> */ void cell_queue_append_packed_copy(cell_queue_t *queue, const cell_t *cell, - int wide_circ_ids) + int wide_circ_ids, int use_stats) { packed_cell_t *copy = packed_cell_copy(cell, wide_circ_ids); /* Remember the time when this cell was put in the queue. */ - if (get_options()->CellStatistics) { + if (get_options()->CellStatistics && use_stats) { struct timeval now; uint32_t added; insertion_time_queue_t *it_queue = queue->insertion_times; @@ -2339,7 +2339,7 @@ channel_flush_from_first_active_circuit(channel_t *chan, int max) { circuitmux_t *cmux = NULL; int n_flushed = 0; - cell_queue_t *queue; + cell_queue_t *queue, *destroy_queue=NULL; circuit_t *circ; or_circuit_t *or_circ; int streams_blocked; @@ -2352,7 +2352,16 @@ channel_flush_from_first_active_circuit(channel_t *chan, int max) /* Main loop: pick a circuit, send a cell, update the cmux */ while (n_flushed < max) { - circ = circuitmux_get_first_active_circuit(cmux); + circ = circuitmux_get_first_active_circuit(cmux, &destroy_queue); + if (destroy_queue) { + /* this code is duplicated from some of the logic below. Ugly! XXXX */ + tor_assert(destroy_queue->n > 0); + cell = cell_queue_pop(destroy_queue); + channel_write_packed_cell(chan, cell); + cell = NULL; + ++n_flushed; + continue; + } /* If it returns NULL, no cells left to send */ if (!circ) break; assert_cmux_ok_paranoid(chan); @@ -2474,7 +2483,7 @@ append_cell_to_circuit_queue(circuit_t *circ, channel_t *chan, streams_blocked = circ->streams_blocked_on_p_chan; } - cell_queue_append_packed_copy(queue, cell, chan->wide_circ_ids); + cell_queue_append_packed_copy(queue, cell, chan->wide_circ_ids, 1); /* If we have too many cells on the circuit, we should stop reading from * the edge streams for a while. */ |