static void test_relay_close_circuit(void *arg) { channel_t *nchan = NULL, *pchan = NULL; or_circuit_t *orcirc = NULL; cell_t *cell = NULL; int old_count, new_count; (void)arg; /* Make fake channels to be nchan and pchan for the circuit */ nchan = new_fake_channel(); tt_assert(nchan); pchan = new_fake_channel(); tt_assert(pchan); /* Make a fake orcirc */ orcirc = new_fake_orcirc(nchan, pchan); tt_assert(orcirc); circuitmux_attach_circuit(nchan->cmux, TO_CIRCUIT(orcirc), CELL_DIRECTION_OUT); circuitmux_attach_circuit(pchan->cmux, TO_CIRCUIT(orcirc), CELL_DIRECTION_IN); /* Make a cell */ cell = tor_malloc_zero(sizeof(cell_t)); make_fake_cell(cell); MOCK(scheduler_channel_has_waiting_cells, scheduler_channel_has_waiting_cells_mock); MOCK(assert_circuit_ok, assert_circuit_ok_mock); /* Append it */ old_count = get_mock_scheduler_has_waiting_cells_count(); append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), nchan, cell, CELL_DIRECTION_OUT, 0); new_count = get_mock_scheduler_has_waiting_cells_count(); tt_int_op(new_count, OP_EQ, old_count + 1); /* Now try the reverse direction */ old_count = get_mock_scheduler_has_waiting_cells_count(); append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), pchan, cell, CELL_DIRECTION_IN, 0); new_count = get_mock_scheduler_has_waiting_cells_count(); tt_int_op(new_count, OP_EQ, old_count + 1); /* Ensure our write totals are 0 */ tt_u64_op(find_largest_max(write_array), OP_EQ, 0); /* Mark the circuit for close */ circuit_mark_for_close(TO_CIRCUIT(orcirc), 0); /* Check our write totals. */ advance_obs(write_array); commit_max(write_array); /* Check for two cells plus overhead */ tt_u64_op(find_largest_max(write_array), OP_EQ, 2*(get_cell_network_size(nchan->wide_circ_ids) +TLS_PER_CELL_OVERHEAD)); UNMOCK(scheduler_channel_has_waiting_cells); /* Get rid of the fake channels */ MOCK(scheduler_release_channel, scheduler_release_channel_mock); channel_mark_for_close(nchan); channel_mark_for_close(pchan); UNMOCK(scheduler_release_channel); /* Shut down channels */ channel_free_all(); done: tor_free(cell); if (orcirc) { circuitmux_detach_circuit(nchan->cmux, TO_CIRCUIT(orcirc)); circuitmux_detach_circuit(pchan->cmux, TO_CIRCUIT(orcirc)); cell_queue_clear(&orcirc->base_.n_chan_cells); cell_queue_clear(&orcirc->p_chan_cells); } tor_free(orcirc); free_fake_channel(nchan); free_fake_channel(pchan); UNMOCK(assert_circuit_ok); return; }
/* Test inbound cell. The callstack is: * channel_process_cell() * -> chan->cell_handler() * * This test is about checking if we can process an inbound cell down to the * channel handler. */ static void test_channel_inbound_cell(void *arg) { channel_t *chan = NULL; cell_t *cell = NULL; int old_count; (void) arg; /* The channel will be freed so we need to hijack this so the scheduler * doesn't get confused. */ MOCK(scheduler_release_channel, scheduler_release_channel_mock); /* Accept cells to lower layer */ test_chan_accept_cells = 1; chan = new_fake_channel(); tt_assert(chan); /* Start it off in OPENING */ chan->state = CHANNEL_STATE_OPENING; /* Try to register it */ channel_register(chan); tt_int_op(chan->registered, OP_EQ, 1); /* Open it */ channel_change_state_open(chan); tt_int_op(chan->state, OP_EQ, CHANNEL_STATE_OPEN); tt_int_op(chan->has_been_open, OP_EQ, 1); /* Receive a cell now. */ cell = tor_malloc_zero(sizeof(*cell)); make_fake_cell(cell); old_count = test_chan_fixed_cells_recved; channel_process_cell(chan, cell); tt_int_op(test_chan_fixed_cells_recved, OP_EQ, old_count); tt_assert(monotime_coarse_is_zero(&chan->timestamp_xfer)); tt_u64_op(chan->timestamp_active, OP_EQ, 0); tt_u64_op(chan->timestamp_recv, OP_EQ, 0); /* Setup incoming cell handlers. We don't care about var cell, the channel * layers is not handling those. */ channel_set_cell_handlers(chan, chan_test_cell_handler, NULL); tt_ptr_op(chan->cell_handler, OP_EQ, chan_test_cell_handler); /* Now process the cell, we should see it. */ old_count = test_chan_fixed_cells_recved; channel_process_cell(chan, cell); tt_int_op(test_chan_fixed_cells_recved, OP_EQ, old_count + 1); /* We should have a series of timestamp set. */ tt_assert(!monotime_coarse_is_zero(&chan->timestamp_xfer)); tt_u64_op(chan->timestamp_active, OP_NE, 0); tt_u64_op(chan->timestamp_recv, OP_NE, 0); tt_assert(monotime_coarse_is_zero(&chan->next_padding_time)); tt_u64_op(chan->n_cells_recved, OP_EQ, 1); tt_u64_op(chan->n_bytes_recved, OP_EQ, get_cell_network_size(0)); /* Close it */ old_count = test_close_called; channel_mark_for_close(chan); tt_int_op(chan->state, OP_EQ, CHANNEL_STATE_CLOSING); tt_int_op(chan->reason_for_closing, OP_EQ, CHANNEL_CLOSE_REQUESTED); tt_int_op(test_close_called, OP_EQ, old_count + 1); /* This closes the channe so it calls in the scheduler, make sure of it. */ old_count = test_releases_count; chan_test_finish_close(chan); tt_int_op(test_releases_count, OP_EQ, old_count + 1); tt_int_op(chan->state, OP_EQ, CHANNEL_STATE_CLOSED); /* The channel will be free, lets make sure it is not accessible. */ uint64_t chan_id = chan->global_identifier; tt_ptr_op(channel_find_by_global_id(chan_id), OP_EQ, chan); channel_run_cleanup(); chan = channel_find_by_global_id(chan_id); tt_assert(chan == NULL); done: tor_free(cell); UNMOCK(scheduler_release_channel); }
static void test_relay_append_cell_to_circuit_queue(void *arg) { channel_t *nchan = NULL, *pchan = NULL; or_circuit_t *orcirc = NULL; cell_t *cell = NULL; int old_count, new_count; (void)arg; /* Make fake channels to be nchan and pchan for the circuit */ nchan = new_fake_channel(); tt_assert(nchan); pchan = new_fake_channel(); tt_assert(pchan); /* Make a fake orcirc */ orcirc = new_fake_orcirc(nchan, pchan); tt_assert(orcirc); circuitmux_attach_circuit(nchan->cmux, TO_CIRCUIT(orcirc), CELL_DIRECTION_OUT); circuitmux_attach_circuit(pchan->cmux, TO_CIRCUIT(orcirc), CELL_DIRECTION_IN); /* Make a cell */ cell = tor_malloc_zero(sizeof(cell_t)); make_fake_cell(cell); MOCK(scheduler_channel_has_waiting_cells, scheduler_channel_has_waiting_cells_mock); /* Append it */ old_count = get_mock_scheduler_has_waiting_cells_count(); append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), nchan, cell, CELL_DIRECTION_OUT, 0); new_count = get_mock_scheduler_has_waiting_cells_count(); tt_int_op(new_count, OP_EQ, old_count + 1); /* Now try the reverse direction */ old_count = get_mock_scheduler_has_waiting_cells_count(); append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), pchan, cell, CELL_DIRECTION_IN, 0); new_count = get_mock_scheduler_has_waiting_cells_count(); tt_int_op(new_count, OP_EQ, old_count + 1); UNMOCK(scheduler_channel_has_waiting_cells); /* Get rid of the fake channels */ MOCK(scheduler_release_channel, scheduler_release_channel_mock); channel_mark_for_close(nchan); channel_mark_for_close(pchan); UNMOCK(scheduler_release_channel); /* Shut down channels */ channel_free_all(); done: tor_free(cell); if (orcirc) { circuitmux_detach_circuit(nchan->cmux, TO_CIRCUIT(orcirc)); circuitmux_detach_circuit(pchan->cmux, TO_CIRCUIT(orcirc)); cell_queue_clear(&orcirc->base_.n_chan_cells); cell_queue_clear(&orcirc->p_chan_cells); } tor_free(orcirc); free_fake_channel(nchan); free_fake_channel(pchan); return; }