Ejemplo n.º 1
0
void
command_setup_channel(channel_t *chan)
{
  tor_assert(chan);

  channel_set_cell_handlers(chan,
                            command_process_cell,
                            command_process_var_cell);
}
Ejemplo n.º 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);
}
Ejemplo n.º 3
0
static void
test_channel_dumpstats(void *arg)
{
  channel_t *ch = NULL;
  cell_t *cell = NULL;
  packed_cell_t *p_cell = NULL;
  int old_count;

  (void)arg;

  /* Mock these for duration of the test */
  MOCK(scheduler_channel_doesnt_want_writes,
       scheduler_channel_doesnt_want_writes_mock);
  MOCK(scheduler_release_channel,
       scheduler_release_channel_mock);

  /* Set up a new fake channel */
  ch = new_fake_channel();
  tt_assert(ch);

  /* Try to register it */
  channel_register(ch);
  tt_assert(ch->registered);

  /* Set up mock */
  dump_statistics_mock_target = ch;
  dump_statistics_mock_matches = 0;
  MOCK(channel_dump_statistics,
       chan_test_channel_dump_statistics_mock);

  /* Call channel_dumpstats() */
  channel_dumpstats(LOG_DEBUG);

  /* Assert that we hit the mock */
  tt_int_op(dump_statistics_mock_matches, OP_EQ, 1);

  /* Close the channel */
  channel_mark_for_close(ch);
  tt_int_op(ch->state, OP_EQ, CHANNEL_STATE_CLOSING);
  chan_test_finish_close(ch);
  tt_int_op(ch->state, OP_EQ, CHANNEL_STATE_CLOSED);

  /* Try again and hit the finished channel */
  channel_dumpstats(LOG_DEBUG);
  tt_int_op(dump_statistics_mock_matches, OP_EQ, 2);

  channel_run_cleanup();
  ch = NULL;

  /* Now we should hit nothing */
  channel_dumpstats(LOG_DEBUG);
  tt_int_op(dump_statistics_mock_matches, OP_EQ, 2);

  /* Unmock */
  UNMOCK(channel_dump_statistics);
  dump_statistics_mock_target = NULL;
  dump_statistics_mock_matches = 0;

  /* Now make another channel */
  ch = new_fake_channel();
  tt_assert(ch);
  channel_register(ch);
  tt_int_op(ch->registered, OP_EQ, 1);
  /* Lie about its age so dumpstats gets coverage for rate calculations */
  ch->timestamp_created = time(NULL) - 30;
  tt_int_op(ch->timestamp_created, OP_GT, 0);
  tt_int_op(time(NULL), OP_GT, ch->timestamp_created);

  /* Put cells through it both ways to make the counters non-zero */
  p_cell = packed_cell_new();
  test_chan_accept_cells = 1;
  old_count = test_cells_written;
  channel_write_packed_cell(ch, p_cell);
  tt_int_op(test_cells_written, OP_EQ, old_count + 1);
  tt_u64_op(ch->n_bytes_xmitted, OP_GT, 0);
  tt_u64_op(ch->n_cells_xmitted, OP_GT, 0);

  /* Receive path */
  channel_set_cell_handlers(ch,
                            chan_test_cell_handler,
                            chan_test_var_cell_handler);
  tt_ptr_op(channel_get_cell_handler(ch), OP_EQ, chan_test_cell_handler);
  tt_ptr_op(channel_get_var_cell_handler(ch), OP_EQ,
            chan_test_var_cell_handler);
  cell = tor_malloc_zero(sizeof(*cell));
  old_count = test_chan_fixed_cells_recved;
  channel_process_cell(ch, cell);
  tt_int_op(test_chan_fixed_cells_recved, OP_EQ, old_count + 1);
  tt_u64_op(ch->n_bytes_recved, OP_GT, 0);
  tt_u64_op(ch->n_cells_recved, OP_GT, 0);

  /* Test channel_dump_statistics */
  ch->describe_transport = chan_test_describe_transport;
  ch->dumpstats = chan_test_dumpstats;
  test_chan_should_be_canonical = 1;
  ch->is_canonical = test_chan_is_canonical;
  old_count = test_dumpstats_calls;
  channel_dump_statistics(ch, LOG_DEBUG);
  tt_int_op(test_dumpstats_calls, OP_EQ, old_count + 1);

  /* Close the channel */
  channel_mark_for_close(ch);
  tt_int_op(ch->state, OP_EQ, CHANNEL_STATE_CLOSING);
  chan_test_finish_close(ch);
  tt_int_op(ch->state, OP_EQ, CHANNEL_STATE_CLOSED);
  channel_run_cleanup();
  ch = NULL;

 done:
  free_fake_channel(ch);
  tor_free(cell);

  UNMOCK(scheduler_channel_doesnt_want_writes);
  UNMOCK(scheduler_release_channel);

  return;
}