summaryrefslogtreecommitdiff
path: root/src/or/relay.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2013-03-21 14:51:27 -0400
committerNick Mathewson <nickm@torproject.org>2013-06-13 10:14:00 -0400
commit43d53e6d86acaf7555c31730a8230fa0cdf31306 (patch)
treec12b3285f417aad70b913662006e8572edf708b6 /src/or/relay.c
parent801eea03ad71dafd31cc6bfa06fa5e421aa95cd6 (diff)
downloadtor-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.c19
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. */