Пример #1
0
static circuit_t *
dummy_origin_circuit_new(int n_cells)
{
  origin_circuit_t *circ = origin_circuit_new();
  int i;
  cell_t cell;

  for (i=0; i < n_cells; ++i) {
    crypto_rand((void*)&cell, sizeof(cell));
    cell_queue_append_packed_copy(TO_CIRCUIT(circ),
                                  &TO_CIRCUIT(circ)->n_chan_cells,
                                  1, &cell, 1, 0);
  }

  TO_CIRCUIT(circ)->purpose = CIRCUIT_PURPOSE_C_GENERAL;
  return TO_CIRCUIT(circ);
}
Пример #2
0
origin_circuit_t *
add_opened_threehop(void)
{
  origin_circuit_t *or_circ = origin_circuit_new();
  extend_info_t fakehop;
  memset(&fakehop, 0, sizeof(fakehop));

  TO_CIRCUIT(or_circ)->purpose = CIRCUIT_PURPOSE_C_GENERAL;

  or_circ->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
  or_circ->build_state->desired_path_len = DEFAULT_ROUTE_LEN;

  onion_append_hop(&or_circ->cpath, &fakehop);
  onion_append_hop(&or_circ->cpath, &fakehop);
  onion_append_hop(&or_circ->cpath, &fakehop);

  or_circ->has_opened = 1;
  TO_CIRCUIT(or_circ)->state = CIRCUIT_STATE_OPEN;
  TO_CIRCUIT(or_circ)->purpose = CIRCUIT_PURPOSE_C_GENERAL;

  return or_circ;
}
Пример #3
0
origin_circuit_t *
build_unopened_fourhop(struct timeval circ_start_time)
{
  origin_circuit_t *or_circ = origin_circuit_new();
  extend_info_t *fakehop = tor_malloc_zero(sizeof(extend_info_t));
  memset(fakehop, 0, sizeof(extend_info_t));

  TO_CIRCUIT(or_circ)->purpose = CIRCUIT_PURPOSE_C_GENERAL;
  TO_CIRCUIT(or_circ)->timestamp_began = circ_start_time;
  TO_CIRCUIT(or_circ)->timestamp_created = circ_start_time;

  or_circ->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
  or_circ->build_state->desired_path_len = 4;

  onion_append_hop(&or_circ->cpath, fakehop);
  onion_append_hop(&or_circ->cpath, fakehop);
  onion_append_hop(&or_circ->cpath, fakehop);
  onion_append_hop(&or_circ->cpath, fakehop);

  tor_free(fakehop);

  return or_circ;
}
Пример #4
0
static void
test_circuit_n_cells(void *arg)
{
  packed_cell_t *pc1=NULL, *pc2=NULL, *pc3=NULL, *pc4=NULL, *pc5=NULL;
  origin_circuit_t *origin_c=NULL;
  or_circuit_t *or_c=NULL;

  (void)arg;

  pc1 = packed_cell_new();
  pc2 = packed_cell_new();
  pc3 = packed_cell_new();
  pc4 = packed_cell_new();
  pc5 = packed_cell_new();
  tt_assert(pc1 && pc2 && pc3 && pc4 && pc5);

  or_c = or_circuit_new(0, NULL);
  origin_c = origin_circuit_new();
  origin_c->base_.purpose = CIRCUIT_PURPOSE_C_GENERAL;

  tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(or_c)), OP_EQ, 0);
  cell_queue_append(&or_c->p_chan_cells, pc1);
  tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(or_c)), OP_EQ, 1);
  cell_queue_append(&or_c->base_.n_chan_cells, pc2);
  cell_queue_append(&or_c->base_.n_chan_cells, pc3);
  tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(or_c)), OP_EQ, 3);

  tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(origin_c)), OP_EQ, 0);
  cell_queue_append(&origin_c->base_.n_chan_cells, pc4);
  cell_queue_append(&origin_c->base_.n_chan_cells, pc5);
  tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(origin_c)), OP_EQ, 2);

 done:
  circuit_free_(TO_CIRCUIT(or_c));
  circuit_free_(TO_CIRCUIT(origin_c));
}
Пример #5
0
/* Test outbound cell. The callstack is:
 *  channel_flush_some_cells()
 *   -> channel_flush_from_first_active_circuit()
 *     -> channel_write_packed_cell()
 *       -> write_packed_cell()
 *         -> chan->write_packed_cell() fct ptr.
 *
 * This test goes from a cell in a circuit up to the channel write handler
 * that should put them on the connection outbuf. */
static void
test_channel_outbound_cell(void *arg)
{
  int old_count;
  channel_t *chan = NULL;
  packed_cell_t *p_cell = NULL, *p_cell2 = NULL;
  origin_circuit_t *circ = NULL;
  cell_queue_t *queue;

  (void) arg;

  /* Set the test time to be mocked, since this test assumes that no
   * time will pass, ewma values will not need to be re-scaled, and so on */
  monotime_enable_test_mocking();
  monotime_set_mock_time_nsec(U64_LITERAL(1000000000) * 12345);

  cmux_ewma_set_options(NULL,NULL);

  /* 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;

  /* Setup a valid circuit to queue a cell. */
  circ = origin_circuit_new();
  tt_assert(circ);
  /* Circuit needs an origin purpose to be considered origin. */
  TO_CIRCUIT(circ)->purpose = CIRCUIT_PURPOSE_C_GENERAL;
  TO_CIRCUIT(circ)->n_circ_id = 42;
  /* This is the outbound test so use the next channel queue. */
  queue = &TO_CIRCUIT(circ)->n_chan_cells;
  /* Setup packed cell to queue on the circuit. */
  p_cell = packed_cell_new();
  tt_assert(p_cell);
  p_cell2 = packed_cell_new();
  tt_assert(p_cell2);
  /* Setup a channel to put the circuit on. */
  chan = new_fake_channel();
  tt_assert(chan);
  chan->state = CHANNEL_STATE_OPENING;
  channel_change_state_open(chan);
  /* Outbound channel. */
  channel_mark_outgoing(chan);
  /* Try to register it so we can clean it through the channel cleanup
   * process. */
  channel_register(chan);
  tt_int_op(chan->registered, OP_EQ, 1);
  /* Set EWMA policy so we can pick it when flushing. */
  circuitmux_set_policy(chan->cmux, &ewma_policy);
  tt_ptr_op(circuitmux_get_policy(chan->cmux), OP_EQ, &ewma_policy);

  /* Register circuit to the channel circid map which will attach the circuit
   * to the channel's cmux as well. */
  circuit_set_n_circid_chan(TO_CIRCUIT(circ), 42, chan);
  tt_int_op(channel_num_circuits(chan), OP_EQ, 1);
  /* Test the cmux state. */
  tt_ptr_op(TO_CIRCUIT(circ)->n_mux, OP_EQ, chan->cmux);
  tt_int_op(circuitmux_is_circuit_attached(chan->cmux, TO_CIRCUIT(circ)),
            OP_EQ, 1);

  /* Flush the channel without any cell on it. */
  old_count = test_cells_written;
  ssize_t flushed = channel_flush_some_cells(chan, 1);
  tt_i64_op(flushed, OP_EQ, 0);
  tt_int_op(test_cells_written, OP_EQ, old_count);
  tt_int_op(channel_more_to_flush(chan), OP_EQ, 0);
  tt_int_op(circuitmux_num_active_circuits(chan->cmux), OP_EQ, 0);
  tt_int_op(circuitmux_num_cells(chan->cmux), OP_EQ, 0);
  tt_int_op(circuitmux_is_circuit_active(chan->cmux, TO_CIRCUIT(circ)),
            OP_EQ, 0);
  tt_u64_op(chan->n_cells_xmitted, OP_EQ, 0);
  tt_u64_op(chan->n_bytes_xmitted, OP_EQ, 0);

  /* Queue cell onto the next queue that is the outbound direction. Than
   * update its cmux so the circuit can be picked when flushing cells. */
  cell_queue_append(queue, p_cell);
  p_cell = NULL;
  tt_int_op(queue->n, OP_EQ, 1);
  cell_queue_append(queue, p_cell2);
  p_cell2 = NULL;
  tt_int_op(queue->n, OP_EQ, 2);

  update_circuit_on_cmux(TO_CIRCUIT(circ), CELL_DIRECTION_OUT);
  tt_int_op(circuitmux_num_active_circuits(chan->cmux), OP_EQ, 1);
  tt_int_op(circuitmux_num_cells(chan->cmux), OP_EQ, 2);
  tt_int_op(circuitmux_is_circuit_active(chan->cmux, TO_CIRCUIT(circ)),
            OP_EQ, 1);

  /* From this point on, we have a queued cell on an active circuit attached
   * to the channel's cmux. */

  /* Flush the first cell. This is going to go down the call stack. */
  old_count = test_cells_written;
  flushed = channel_flush_some_cells(chan, 1);
  tt_i64_op(flushed, OP_EQ, 1);
  tt_int_op(test_cells_written, OP_EQ, old_count + 1);
  tt_int_op(circuitmux_num_cells(chan->cmux), OP_EQ, 1);
  tt_int_op(channel_more_to_flush(chan), OP_EQ, 1);
  /* Circuit should remain active because there is a second cell queued. */
  tt_int_op(circuitmux_is_circuit_active(chan->cmux, TO_CIRCUIT(circ)),
            OP_EQ, 1);
  /* Should still be attached. */
  tt_int_op(circuitmux_is_circuit_attached(chan->cmux, TO_CIRCUIT(circ)),
            OP_EQ, 1);
  tt_u64_op(chan->n_cells_xmitted, OP_EQ, 1);
  tt_u64_op(chan->n_bytes_xmitted, OP_EQ, get_cell_network_size(0));

  /* Flush second cell. This is going to go down the call stack. */
  old_count = test_cells_written;
  flushed = channel_flush_some_cells(chan, 1);
  tt_i64_op(flushed, OP_EQ, 1);
  tt_int_op(test_cells_written, OP_EQ, old_count + 1);
  tt_int_op(circuitmux_num_cells(chan->cmux), OP_EQ, 0);
  tt_int_op(channel_more_to_flush(chan), OP_EQ, 0);
  /* No more cells should make the circuit inactive. */
  tt_int_op(circuitmux_is_circuit_active(chan->cmux, TO_CIRCUIT(circ)),
            OP_EQ, 0);
  /* Should still be attached. */
  tt_int_op(circuitmux_is_circuit_attached(chan->cmux, TO_CIRCUIT(circ)),
            OP_EQ, 1);
  tt_u64_op(chan->n_cells_xmitted, OP_EQ, 2);
  tt_u64_op(chan->n_bytes_xmitted, OP_EQ, get_cell_network_size(0) * 2);

 done:
  if (circ) {
    circuit_free_(TO_CIRCUIT(circ));
  }
  tor_free(p_cell);
  channel_free_all();
  UNMOCK(scheduler_release_channel);
  monotime_disable_test_mocking();
}