Пример #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;
}
Пример #2
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;
}
Пример #3
0
/** Deallocate space associated with circ.
 */
static void
circuit_free(circuit_t *circ)
{
  void *mem;
  size_t memlen;
  if (!circ)
    return;

  if (CIRCUIT_IS_ORIGIN(circ)) {
    origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
    mem = ocirc;
    memlen = sizeof(origin_circuit_t);
    tor_assert(circ->magic == ORIGIN_CIRCUIT_MAGIC);
    if (ocirc->build_state) {
        extend_info_free(ocirc->build_state->chosen_exit);
        circuit_free_cpath_node(ocirc->build_state->pending_final_cpath);
        cpath_ref_decref(ocirc->build_state->service_pending_final_cpath_ref);
    }
    tor_free(ocirc->build_state);

    circuit_free_cpath(ocirc->cpath);

    crypto_pk_free(ocirc->intro_key);
    rend_data_free(ocirc->rend_data);

    tor_free(ocirc->dest_address);
    if (ocirc->socks_username) {
      memwipe(ocirc->socks_username, 0x12, ocirc->socks_username_len);
      tor_free(ocirc->socks_username);
    }
    if (ocirc->socks_password) {
      memwipe(ocirc->socks_password, 0x06, ocirc->socks_password_len);
      tor_free(ocirc->socks_password);
    }
  } else {
    or_circuit_t *ocirc = TO_OR_CIRCUIT(circ);
    /* Remember cell statistics for this circuit before deallocating. */
    if (get_options()->CellStatistics)
      rep_hist_buffer_stats_add_circ(circ, time(NULL));
    mem = ocirc;
    memlen = sizeof(or_circuit_t);
    tor_assert(circ->magic == OR_CIRCUIT_MAGIC);

    crypto_cipher_free(ocirc->p_crypto);
    crypto_digest_free(ocirc->p_digest);
    crypto_cipher_free(ocirc->n_crypto);
    crypto_digest_free(ocirc->n_digest);

    if (ocirc->rend_splice) {
      or_circuit_t *other = ocirc->rend_splice;
      tor_assert(other->_base.magic == OR_CIRCUIT_MAGIC);
      other->rend_splice = NULL;
    }

    /* remove from map. */
    circuit_set_p_circid_orconn(ocirc, 0, NULL);

    /* Clear cell queue _after_ removing it from the map.  Otherwise our
     * "active" checks will be violated. */
    cell_queue_clear(&ocirc->p_conn_cells);
  }

  extend_info_free(circ->n_hop);
  tor_free(circ->n_conn_onionskin);

  /* Remove from map. */
  circuit_set_n_circid_orconn(circ, 0, NULL);

  /* Clear cell queue _after_ removing it from the map.  Otherwise our
   * "active" checks will be violated. */
  cell_queue_clear(&circ->n_conn_cells);

  memwipe(mem, 0xAA, memlen); /* poison memory */
  tor_free(mem);
}
Пример #4
0
/** Deallocate space associated with circ.
 */
static void
circuit_free(circuit_t *circ)
{
  void *mem;
  size_t memlen;
  tor_assert(circ);
  if (CIRCUIT_IS_ORIGIN(circ)) {
    origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
    mem = ocirc;
    memlen = sizeof(origin_circuit_t);
    tor_assert(circ->magic == ORIGIN_CIRCUIT_MAGIC);
    if (ocirc->build_state) {
      if (ocirc->build_state->chosen_exit)
        extend_info_free(ocirc->build_state->chosen_exit);
      if (ocirc->build_state->pending_final_cpath)
        circuit_free_cpath_node(ocirc->build_state->pending_final_cpath);
    }
    tor_free(ocirc->build_state);

    circuit_free_cpath(ocirc->cpath);
    if (ocirc->intro_key)
      crypto_free_pk_env(ocirc->intro_key);
    if (ocirc->rend_data)
      rend_data_free(ocirc->rend_data);
  } else {
    or_circuit_t *ocirc = TO_OR_CIRCUIT(circ);
    mem = ocirc;
    memlen = sizeof(or_circuit_t);
    tor_assert(circ->magic == OR_CIRCUIT_MAGIC);

    if (ocirc->p_crypto)
      crypto_free_cipher_env(ocirc->p_crypto);
    if (ocirc->p_digest)
      crypto_free_digest_env(ocirc->p_digest);
    if (ocirc->n_crypto)
      crypto_free_cipher_env(ocirc->n_crypto);
    if (ocirc->n_digest)
      crypto_free_digest_env(ocirc->n_digest);

    if (ocirc->rend_splice) {
      or_circuit_t *other = ocirc->rend_splice;
      tor_assert(other->_base.magic == OR_CIRCUIT_MAGIC);
      other->rend_splice = NULL;
    }

    /* remove from map. */
    circuit_set_p_circid_orconn(ocirc, 0, NULL);

    /* Clear cell queue _after_ removing it from the map.  Otherwise our
     * "active" checks will be violated. */
    cell_queue_clear(&ocirc->p_conn_cells);
  }

  if (circ->n_hop)
    extend_info_free(circ->n_hop);
  tor_free(circ->n_conn_onionskin);

  /* Remove from map. */
  circuit_set_n_circid_orconn(circ, 0, NULL);

  /* Clear cell queue _after_ removing it from the map.  Otherwise our
   * "active" checks will be violated. */
  cell_queue_clear(&circ->n_conn_cells);

  memset(circ, 0xAA, memlen); /* poison memory */
  tor_free(mem);
}
Пример #5
0
static void
test_cq_manip(void *arg)
{
  packed_cell_t *pc1=NULL, *pc2=NULL, *pc3=NULL, *pc4=NULL, *pc_tmp=NULL;
  cell_queue_t cq;
  cell_t cell;
  (void) arg;

  cell_queue_init(&cq);
  tt_int_op(cq.n, OP_EQ, 0);

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

  tt_ptr_op(NULL, OP_EQ, cell_queue_pop(&cq));

  /* Add and remove a singleton. */
  cell_queue_append(&cq, pc1);
  tt_int_op(cq.n, OP_EQ, 1);
  tt_ptr_op(pc1, OP_EQ, cell_queue_pop(&cq));
  tt_int_op(cq.n, OP_EQ, 0);

  /* Add and remove four items */
  cell_queue_append(&cq, pc4);
  cell_queue_append(&cq, pc3);
  cell_queue_append(&cq, pc2);
  cell_queue_append(&cq, pc1);
  tt_int_op(cq.n, OP_EQ, 4);
  tt_ptr_op(pc4, OP_EQ, cell_queue_pop(&cq));
  tt_ptr_op(pc3, OP_EQ, cell_queue_pop(&cq));
  tt_ptr_op(pc2, OP_EQ, cell_queue_pop(&cq));
  tt_ptr_op(pc1, OP_EQ, cell_queue_pop(&cq));
  tt_int_op(cq.n, OP_EQ, 0);
  tt_ptr_op(NULL, OP_EQ, cell_queue_pop(&cq));

  /* Try a packed copy (wide, then narrow, which is a bit of a cheat, since a
   * real cell queue has only one type.) */
  memset(&cell, 0, sizeof(cell));
  cell.circ_id = 0x12345678;
  cell.command = 10;
  strlcpy((char*)cell.payload, "Lorax ipsum gruvvulus thneed amet, snergelly "
          "once-ler lerkim, sed do barbaloot tempor gluppitus ut labore et "
          "truffula magna aliqua.",
          sizeof(cell.payload));
  cell_queue_append_packed_copy(NULL /*circ*/, &cq, 0 /*exitward*/, &cell,
                                1 /*wide*/, 0 /*stats*/);
  cell.circ_id = 0x2013;
  cell_queue_append_packed_copy(NULL /*circ*/, &cq, 0 /*exitward*/, &cell,
                                0 /*wide*/, 0 /*stats*/);
  tt_int_op(cq.n, OP_EQ, 2);

  pc_tmp = cell_queue_pop(&cq);
  tt_int_op(cq.n, OP_EQ, 1);
  tt_ptr_op(pc_tmp, OP_NE, NULL);
  tt_mem_op(pc_tmp->body, OP_EQ, "\x12\x34\x56\x78\x0a", 5);
  tt_mem_op(pc_tmp->body+5, OP_EQ, cell.payload, sizeof(cell.payload));
  packed_cell_free(pc_tmp);

  pc_tmp = cell_queue_pop(&cq);
  tt_int_op(cq.n, OP_EQ, 0);
  tt_ptr_op(pc_tmp, OP_NE, NULL);
  tt_mem_op(pc_tmp->body, OP_EQ, "\x20\x13\x0a", 3);
  tt_mem_op(pc_tmp->body+3, OP_EQ, cell.payload, sizeof(cell.payload));
  packed_cell_free(pc_tmp);
  pc_tmp = NULL;

  tt_ptr_op(NULL, OP_EQ, cell_queue_pop(&cq));

  /* Now make sure cell_queue_clear works. */
  cell_queue_append(&cq, pc2);
  cell_queue_append(&cq, pc1);
  tt_int_op(cq.n, OP_EQ, 2);
  cell_queue_clear(&cq);
  pc2 = pc1 = NULL; /* prevent double-free */
  tt_int_op(cq.n, OP_EQ, 0);

 done:
  packed_cell_free(pc1);
  packed_cell_free(pc2);
  packed_cell_free(pc3);
  packed_cell_free(pc4);
  packed_cell_free(pc_tmp);

  cell_queue_clear(&cq);
}