diff options
author | Karsten Loesing <karsten.loesing@gmx.net> | 2013-05-24 12:29:42 +0200 |
---|---|---|
committer | Karsten Loesing <karsten.loesing@gmx.net> | 2013-05-25 19:51:38 +0200 |
commit | 26b49f525d5b2a4781755d72738491c016dd15a9 (patch) | |
tree | 98fbbb6fe3b79612e2c0adc2a44c5b83480a0720 /src/or/relay.c | |
parent | 2f893624abb65a0df4f0f8ca6fbbe0c00fbf216a (diff) | |
download | tor-26b49f525d5b2a4781755d72738491c016dd15a9.tar.gz tor-26b49f525d5b2a4781755d72738491c016dd15a9.zip |
Tweak CELL_STATS event based on comments by nickm.
- Move cell_command_to_string from control.c to command.c.
- Use accessor for global_circuitlist instead of extern.
- Add a struct for cell statistics by command instead of six arrays.
- Split up control_event_circuit_cell_stats by using two helper functions.
- Add TestingEnableCellStatsEvent option.
- Prepare functions for testing.
- Rename a few variables and document a few things better.
Diffstat (limited to 'src/or/relay.c')
-rw-r--r-- | src/or/relay.c | 122 |
1 files changed, 73 insertions, 49 deletions
diff --git a/src/or/relay.c b/src/or/relay.c index 02b3b1c5ca..66c24f3f23 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -2046,7 +2046,7 @@ static mp_pool_t *cell_pool = NULL; static mp_pool_t *it_pool = NULL; /** Memory pool to allocate insertion_command_elem_t objects used for cell - * statistics in TestingTorNetwork mode. */ + * statistics if CELL_STATS events are enabled. */ static mp_pool_t *ic_pool = NULL; /** Allocate structures to hold cells. */ @@ -2058,7 +2058,7 @@ init_cell_pool(void) } /** Free all storage used to hold cells (and insertion times/commands if we - * measure cell statistics and/or are in TestingTorNetwork mode). */ + * measure cell statistics and/or if CELL_STATS events are enabled). */ void free_cell_pool(void) { @@ -2153,16 +2153,68 @@ cell_queue_append(cell_queue_t *queue, packed_cell_t *cell) ++queue->n; } +/** Append command of type <b>command</b> in direction to <b>queue</b> for + * CELL_STATS event. */ +static void +cell_command_queue_append(cell_queue_t *queue, uint8_t command) +{ + insertion_command_queue_t *ic_queue = queue->insertion_commands; + if (!ic_pool) + ic_pool = mp_pool_new(sizeof(insertion_command_elem_t), 1024); + if (!ic_queue) { + ic_queue = tor_malloc_zero(sizeof(insertion_command_queue_t)); + queue->insertion_commands = ic_queue; + } + if (ic_queue->last && ic_queue->last->command == command) { + ic_queue->last->counter++; + } else { + insertion_command_elem_t *elem = mp_pool_get(ic_pool); + elem->next = NULL; + elem->command = command; + elem->counter = 1; + if (ic_queue->last) { + ic_queue->last->next = elem; + ic_queue->last = elem; + } else { + ic_queue->first = ic_queue->last = elem; + } + } +} + +/** Retrieve oldest command from <b>queue</b> and write it to + * <b>command</b> for CELL_STATS event. Return 0 for success, -1 + * otherwise. */ +static int +cell_command_queue_pop(uint8_t *command, cell_queue_t *queue) +{ + int res = -1; + insertion_command_queue_t *ic_queue = queue->insertion_commands; + if (ic_queue && ic_queue->first) { + insertion_command_elem_t *ic_elem = ic_queue->first; + ic_elem->counter--; + if (ic_elem->counter < 1) { + ic_queue->first = ic_elem->next; + if (ic_elem == ic_queue->last) + ic_queue->last = NULL; + mp_pool_release(ic_elem); + } + *command = ic_elem->command; + res = 0; + } + return res; +} + /** Append a newly allocated copy of <b>cell</b> to the end of the - * <b>exit_ward</b> (or app-ward) <b>queue</b> of <b>circ</b>. */ + * <b>exitward</b> (or app-ward) <b>queue</b> of <b>circ</b>. */ void cell_queue_append_packed_copy(circuit_t *circ, cell_queue_t *queue, - int exit_ward, const cell_t *cell, + int exitward, const cell_t *cell, int wide_circ_ids) { 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 || get_options()->TestingTorNetwork) { + if (get_options()->CellStatistics || + get_options()->TestingEnableCellStatsEvent) { struct timeval now; uint32_t added; insertion_time_queue_t *it_queue = queue->insertion_times; @@ -2193,35 +2245,15 @@ cell_queue_append_packed_copy(circuit_t *circ, cell_queue_t *queue, } /* Remember that we added a cell to the queue, and remember the cell * command. */ - if (get_options()->TestingTorNetwork) { - insertion_command_queue_t *ic_queue = queue->insertion_commands; + if (get_options()->TestingEnableCellStatsEvent) { testing_cell_stats_entry_t *ent = tor_malloc_zero(sizeof(testing_cell_stats_entry_t)); ent->command = cell->command; - ent->exit_ward = exit_ward; + ent->exitward = exitward; if (!circ->testing_cell_stats) circ->testing_cell_stats = smartlist_new(); smartlist_add(circ->testing_cell_stats, ent); - if (!ic_pool) - ic_pool = mp_pool_new(sizeof(insertion_command_elem_t), 1024); - if (!ic_queue) { - ic_queue = tor_malloc_zero(sizeof(insertion_command_queue_t)); - queue->insertion_commands = ic_queue; - } - if (ic_queue->last && ic_queue->last->command == cell->command) { - ic_queue->last->counter++; - } else { - insertion_command_elem_t *elem = mp_pool_get(ic_pool); - elem->next = NULL; - elem->command = cell->command; - elem->counter = 1; - if (ic_queue->last) { - ic_queue->last->next = elem; - ic_queue->last = elem; - } else { - ic_queue->first = ic_queue->last = elem; - } - } + cell_command_queue_append(queue, cell->command); } cell_queue_append(queue, copy); } @@ -2429,7 +2461,7 @@ channel_flush_from_first_active_circuit(channel_t *chan, int max) /* Calculate the exact time that this cell has spent in the queue. */ if (get_options()->CellStatistics || - get_options()->TestingTorNetwork) { + get_options()->TestingEnableCellStatsEvent) { struct timeval tvnow; uint32_t flushed; uint32_t cell_waiting_time; @@ -2460,28 +2492,20 @@ channel_flush_from_first_active_circuit(channel_t *chan, int max) or_circ->total_cell_waiting_time += cell_waiting_time; or_circ->processed_cells++; } - if (get_options()->TestingTorNetwork) { - insertion_command_queue_t *ic_queue = queue->insertion_commands; - if (!ic_queue || !ic_queue->first) { - log_info(LD_BUG, "Cannot determine command of cell, which " - "is a bug, because TestingTorNetwork cannot " - "be enabled while running."); + if (get_options()->TestingEnableCellStatsEvent) { + uint8_t command; + if (cell_command_queue_pop(&command, queue) < 0) { + log_info(LD_GENERAL, "Cannot determine command of cell. " + "Looks like the CELL_STATS event was " + "recently enabled."); } else { testing_cell_stats_entry_t *ent = tor_malloc_zero(sizeof(testing_cell_stats_entry_t)); - insertion_command_elem_t *ic_elem = ic_queue->first; - ent->command = ic_elem->command; - ic_elem->counter--; - if (ic_elem->counter < 1) { - ic_queue->first = ic_elem->next; - if (ic_elem == ic_queue->last) - ic_queue->last = NULL; - mp_pool_release(ic_elem); - } + ent->command = command; ent->waiting_time = (unsigned int)cell_waiting_time / 10; ent->removed = 1; if (circ->n_chan == chan) - ent->exit_ward = 1; + ent->exitward = 1; if (!circ->testing_cell_stats) circ->testing_cell_stats = smartlist_new(); smartlist_add(circ->testing_cell_stats, ent); @@ -2542,12 +2566,12 @@ append_cell_to_circuit_queue(circuit_t *circ, channel_t *chan, { cell_queue_t *queue; int streams_blocked; - int exit_ward; + int exitward; if (circ->marked_for_close) return; - exit_ward = (direction == CELL_DIRECTION_OUT); - if (exit_ward) { + exitward = (direction == CELL_DIRECTION_OUT); + if (exitward) { queue = &circ->n_chan_cells; streams_blocked = circ->streams_blocked_on_n_chan; } else { @@ -2556,7 +2580,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(circ, queue, exit_ward, cell, + cell_queue_append_packed_copy(circ, queue, exitward, cell, chan->wide_circ_ids); /* If we have too many cells on the circuit, we should stop reading from |