Exemple #1
0
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;
}
Exemple #2
0
/* 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);
}
Exemple #3
0
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;
}